mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-19 23:32:28 +00:00
Be more careful as to authorisation.
This commit is contained in:
parent
8d0deeb20e
commit
770803b073
@ -903,9 +903,9 @@ void jump_far(InstructionT &instruction, ContextT &context) {
|
|||||||
const Source source_segment = instruction.data_segment();
|
const Source source_segment = instruction.data_segment();
|
||||||
context.memory.preauthorise_read(source_segment, source_address, sizeof(uint16_t) * 2);
|
context.memory.preauthorise_read(source_segment, source_address, sizeof(uint16_t) * 2);
|
||||||
|
|
||||||
const uint16_t offset = context.memory.template access<uint16_t, AccessType::Read>(source_segment, source_address);
|
const uint16_t offset = context.memory.template access<uint16_t, AccessType::PreauthorisedRead>(source_segment, source_address);
|
||||||
source_address += 2;
|
source_address += 2;
|
||||||
const uint16_t segment =context. memory.template access<uint16_t, AccessType::Read>(source_segment, source_address);
|
const uint16_t segment = context.memory.template access<uint16_t, AccessType::PreauthorisedRead>(source_segment, source_address);
|
||||||
context.flow_controller.jump(segment, offset);
|
context.flow_controller.jump(segment, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -945,11 +945,12 @@ void ld(
|
|||||||
auto source_address = address<uint16_t, AccessType::Read>(instruction, pointer, context);
|
auto source_address = address<uint16_t, AccessType::Read>(instruction, pointer, context);
|
||||||
const Source source_segment = instruction.data_segment();
|
const Source source_segment = instruction.data_segment();
|
||||||
|
|
||||||
destination = context.memory.template access<uint16_t, AccessType::Read>(source_segment, source_address);
|
context.memory.preauthorise_read(source_segment, source_address, 4);
|
||||||
|
destination = context.memory.template access<uint16_t, AccessType::PreauthorisedRead>(source_segment, source_address);
|
||||||
source_address += 2;
|
source_address += 2;
|
||||||
switch(selector) {
|
switch(selector) {
|
||||||
case Source::DS: context.registers.ds() = context.memory.template access<uint16_t, AccessType::Read>(source_segment, source_address); break;
|
case Source::DS: context.registers.ds() = context.memory.template access<uint16_t, AccessType::PreauthorisedRead>(source_segment, source_address); break;
|
||||||
case Source::ES: context.registers.es() = context.memory.template access<uint16_t, AccessType::Read>(source_segment, source_address); break;
|
case Source::ES: context.registers.es() = context.memory.template access<uint16_t, AccessType::PreauthorisedRead>(source_segment, source_address); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1919,8 +1920,8 @@ template <
|
|||||||
context.memory.preauthorise_read(address, sizeof(uint16_t) * 2);
|
context.memory.preauthorise_read(address, sizeof(uint16_t) * 2);
|
||||||
context.memory.preauthorise_stack_write(sizeof(uint16_t) * 3);
|
context.memory.preauthorise_stack_write(sizeof(uint16_t) * 3);
|
||||||
|
|
||||||
const uint16_t ip = context.memory.template access<uint16_t, AccessType::Read>(address);
|
const uint16_t ip = context.memory.template access<uint16_t, AccessType::PreauthorisedRead>(address);
|
||||||
const uint16_t cs = context.memory.template access<uint16_t, AccessType::Read>(address + 2);
|
const uint16_t cs = context.memory.template access<uint16_t, AccessType::PreauthorisedRead>(address + 2);
|
||||||
|
|
||||||
auto flags = context.status.get();
|
auto flags = context.status.get();
|
||||||
Primitive::push<uint16_t, true>(flags, context);
|
Primitive::push<uint16_t, true>(flags, context);
|
||||||
|
@ -14,6 +14,8 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <unordered_set>
|
||||||
|
|
||||||
#include "NSData+dataWithContentsOfGZippedFile.h"
|
#include "NSData+dataWithContentsOfGZippedFile.h"
|
||||||
|
|
||||||
@ -125,10 +127,32 @@ struct Memory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Preauthorisation call-ins.
|
// Preauthorisation call-ins.
|
||||||
void preauthorise_stack_write(uint32_t) {}
|
void preauthorise_stack_write(uint32_t length) {
|
||||||
void preauthorise_stack_read(uint32_t) {}
|
uint16_t sp = registers_.sp_;
|
||||||
void preauthorise_read(InstructionSet::x86::Source, uint16_t, uint32_t) {}
|
while(length--) {
|
||||||
void preauthorise_read(uint16_t, uint32_t) {}
|
--sp;
|
||||||
|
preauthorise(InstructionSet::x86::Source::SS, sp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void preauthorise_stack_read(uint32_t length) {
|
||||||
|
uint16_t sp = registers_.sp_;
|
||||||
|
while(length--) {
|
||||||
|
preauthorise(InstructionSet::x86::Source::SS, sp);
|
||||||
|
++sp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void preauthorise_read(InstructionSet::x86::Source segment, uint16_t start, uint32_t length) {
|
||||||
|
while(length--) {
|
||||||
|
preauthorise(segment, start);
|
||||||
|
++start;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void preauthorise_read(uint32_t start, uint32_t length) {
|
||||||
|
while(length--) {
|
||||||
|
preauthorise(start);
|
||||||
|
++start;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Access call-ins.
|
// Access call-ins.
|
||||||
|
|
||||||
@ -179,10 +203,26 @@ struct Memory {
|
|||||||
Accessed,
|
Accessed,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
std::unordered_set<uint32_t> preauthorisations;
|
||||||
std::unordered_map<uint32_t, Tag> tags;
|
std::unordered_map<uint32_t, Tag> tags;
|
||||||
std::vector<uint8_t> memory;
|
std::vector<uint8_t> memory;
|
||||||
const Registers ®isters_;
|
const Registers ®isters_;
|
||||||
|
|
||||||
|
void preauthorise(uint32_t address) {
|
||||||
|
preauthorisations.insert(address);
|
||||||
|
}
|
||||||
|
void preauthorise(InstructionSet::x86::Source segment, uint16_t address) {
|
||||||
|
preauthorise((segment_base(segment) + address) & 0xf'ffff);
|
||||||
|
}
|
||||||
|
bool test_preauthorisation(uint32_t address) {
|
||||||
|
auto authorisation = preauthorisations.find(address);
|
||||||
|
if(authorisation == preauthorisations.end()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
preauthorisations.erase(authorisation);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t segment_base(InstructionSet::x86::Source segment) {
|
uint32_t segment_base(InstructionSet::x86::Source segment) {
|
||||||
uint32_t physical_address;
|
uint32_t physical_address;
|
||||||
using Source = InstructionSet::x86::Source;
|
using Source = InstructionSet::x86::Source;
|
||||||
@ -208,6 +248,12 @@ struct Memory {
|
|||||||
// to a selector, they're just at an absolute location.
|
// to a selector, they're just at an absolute location.
|
||||||
template <typename IntT, AccessType type>
|
template <typename IntT, AccessType type>
|
||||||
typename ReturnType<IntT, type>::type &access(uint32_t address, Tag tag) {
|
typename ReturnType<IntT, type>::type &access(uint32_t address, Tag tag) {
|
||||||
|
if constexpr (type == AccessType::PreauthorisedRead || type == AccessType::PreauthorisedWrite) {
|
||||||
|
if(!test_preauthorisation(address)) {
|
||||||
|
printf("Non preauthorised access\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Check for address wraparound
|
// Check for address wraparound
|
||||||
if(address > 0x10'0000 - sizeof(IntT)) {
|
if(address > 0x10'0000 - sizeof(IntT)) {
|
||||||
if constexpr (std::is_same_v<IntT, uint8_t>) {
|
if constexpr (std::is_same_v<IntT, uint8_t>) {
|
||||||
@ -225,7 +271,7 @@ struct Memory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(tags.find(address) == tags.end()) {
|
if(tags.find(address) == tags.end()) {
|
||||||
printf("Access to unexpected RAM address");
|
printf("Access to unexpected RAM address\n");
|
||||||
}
|
}
|
||||||
tags[address] = tag;
|
tags[address] = tag;
|
||||||
return *reinterpret_cast<IntT *>(&memory[address]);
|
return *reinterpret_cast<IntT *>(&memory[address]);
|
||||||
|
Loading…
Reference in New Issue
Block a user