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();
|
||||
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;
|
||||
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);
|
||||
}
|
||||
|
||||
@ -945,11 +945,12 @@ void ld(
|
||||
auto source_address = address<uint16_t, AccessType::Read>(instruction, pointer, context);
|
||||
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;
|
||||
switch(selector) {
|
||||
case Source::DS: context.registers.ds() = 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::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::PreauthorisedRead>(source_segment, source_address); break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1919,8 +1920,8 @@ template <
|
||||
context.memory.preauthorise_read(address, sizeof(uint16_t) * 2);
|
||||
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 cs = context.memory.template access<uint16_t, AccessType::Read>(address + 2);
|
||||
const uint16_t ip = context.memory.template access<uint16_t, AccessType::PreauthorisedRead>(address);
|
||||
const uint16_t cs = context.memory.template access<uint16_t, AccessType::PreauthorisedRead>(address + 2);
|
||||
|
||||
auto flags = context.status.get();
|
||||
Primitive::push<uint16_t, true>(flags, context);
|
||||
|
@ -14,6 +14,8 @@
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
|
||||
#include "NSData+dataWithContentsOfGZippedFile.h"
|
||||
|
||||
@ -125,10 +127,32 @@ struct Memory {
|
||||
}
|
||||
|
||||
// Preauthorisation call-ins.
|
||||
void preauthorise_stack_write(uint32_t) {}
|
||||
void preauthorise_stack_read(uint32_t) {}
|
||||
void preauthorise_read(InstructionSet::x86::Source, uint16_t, uint32_t) {}
|
||||
void preauthorise_read(uint16_t, uint32_t) {}
|
||||
void preauthorise_stack_write(uint32_t length) {
|
||||
uint16_t sp = registers_.sp_;
|
||||
while(length--) {
|
||||
--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.
|
||||
|
||||
@ -179,10 +203,26 @@ struct Memory {
|
||||
Accessed,
|
||||
};
|
||||
|
||||
std::unordered_set<uint32_t> preauthorisations;
|
||||
std::unordered_map<uint32_t, Tag> tags;
|
||||
std::vector<uint8_t> memory;
|
||||
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 physical_address;
|
||||
using Source = InstructionSet::x86::Source;
|
||||
@ -208,6 +248,12 @@ struct Memory {
|
||||
// to a selector, they're just at an absolute location.
|
||||
template <typename IntT, AccessType type>
|
||||
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
|
||||
if(address > 0x10'0000 - sizeof(IntT)) {
|
||||
if constexpr (std::is_same_v<IntT, uint8_t>) {
|
||||
@ -225,7 +271,7 @@ struct Memory {
|
||||
}
|
||||
|
||||
if(tags.find(address) == tags.end()) {
|
||||
printf("Access to unexpected RAM address");
|
||||
printf("Access to unexpected RAM address\n");
|
||||
}
|
||||
tags[address] = tag;
|
||||
return *reinterpret_cast<IntT *>(&memory[address]);
|
||||
|
Loading…
Reference in New Issue
Block a user