Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/Emulator/Core/CPU/CPU.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ HyperCPU::CPU::CPU(std::uint16_t core_count, std::uint64_t mem_size, char* binar
: mem_controller(dynamic_cast<IMemoryController*>(new MemoryControllerST(mem_size, this))),
core_count(core_count),
total_mem(mem_size),
binary_size(binary_size),
halted(false),
ivt_initialized(false),
io_ctl(std::make_unique<SimpleIOImpl>()) {
Expand Down Expand Up @@ -251,7 +252,7 @@ void HyperCPU::CPU::Run() {
pending_interrupt.reset();
continue;
}

buffer = m_decoder->FetchAndDecode();

switch (buffer.m_opcode) {
Expand Down
1 change: 1 addition & 0 deletions src/Emulator/Core/CPU/CPU.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ namespace HyperCPU {
// Data
std::uint16_t core_count;
std::uint64_t total_mem;
std::uint64_t binary_size;
bool halted;

// General space for registers
Expand Down
5 changes: 5 additions & 0 deletions src/Emulator/Core/CPU/Interrupts/InterruptHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@
#include "PCH/CStd.hpp"

void HyperCPU::CPU::TriggerInterrupt(HyperCPU::cpu_exceptions exception) {
if (*xip >= binary_size) {
spdlog::error("XIP exceeded the binary size, aborting!");
std::abort();
}

if (!ivt_initialized || pending_interrupt.has_value()) {
spdlog::error("Interrupt was triggered, but failed to execute handler! XIP: {}", *xip);
std::abort();
Expand Down
70 changes: 47 additions & 23 deletions src/Emulator/Main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,45 @@ std::uint64_t ParseMemoryString(const std::string& str) {
return result * multiplier;
}

int VerifyBinaryFile(std::int64_t filesize, HyperCPU::GenericHeader header) {
if (filesize < sizeof(HyperCPU::GenericHeader)) {
spdlog::error("Invalid binary header! (excepted {} bytes, got {})", sizeof(HyperCPU::GenericHeader), filesize);
return 1;
}

if (header.magic != HyperCPU::magic) {
spdlog::error("Invalid magic!");
return 1;
}

switch (header.version) {
case HyperCPU::Version::PreRelease:
case HyperCPU::Version::Release1_0:
break;
default:
spdlog::error("Invalid release field!");
return 1;
}

switch (header.type) {
case HyperCPU::FileType::Binary:
break;
case HyperCPU::FileType::Object:
spdlog::error("Executing object files is not supported, please link it first!");
return 1;
default:
spdlog::error("Invalid type field!");
return 1;
}

if (filesize != (sizeof(HyperCPU::GenericHeader) + header.code_size)) {
spdlog::error("Invalid binary code! (expected {} bytes, got {})", header.code_size, (filesize - sizeof(HyperCPU::GenericHeader)));
return 1;
}

return 0;
}

int main(int argc, char** argv) {
#ifdef HCPU_ENABLE_LIBUNWIND
global_bt_controller = BacktraceController(argv[0]);
Expand Down Expand Up @@ -111,36 +150,21 @@ int main(int argc, char** argv) {
}

std::ifstream file(source);
std::int64_t binarysize = std::filesystem::file_size(source) - sizeof(HyperCPU::GenericHeader);

HyperCPU::GenericHeader header = ParseHeader(file);

// Validate header contents
if (header.magic != HyperCPU::magic) {
spdlog::error("Invalid magic!");
if (std::filesystem::file_size(source) < sizeof(HyperCPU::GenericHeader)) {
spdlog::error("The binary file is too small! (No binary header?)");
return 1;
}

std::int64_t filesize = std::filesystem::file_size(source);
std::int64_t binarysize = filesize - sizeof(HyperCPU::GenericHeader);

switch (header.version) {
case HyperCPU::Version::PreRelease:
case HyperCPU::Version::Release1_0:
break;
default:
spdlog::error("Invalid release field!");
return 1;
}
HyperCPU::GenericHeader header = ParseHeader(file);

switch (header.type) {
case HyperCPU::FileType::Binary:
break;
case HyperCPU::FileType::Object:
spdlog::error("Executing object files is not supported, please link it first!");
return 1;
default:
spdlog::error("Invalid type field!");
if (VerifyBinaryFile(filesize, header)) {
return 1;
}

std::unique_ptr<char[]> buf(new char[binarysize]);
file.read(buf.get(), binarysize);

Expand Down
4 changes: 2 additions & 2 deletions tests/fixtures.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ class CPU_TEST : public ::testing::Test {
HyperCPU::CPU cpu;

CPU_TEST()
: cpu(1, 4096) {
: cpu(1, 4096, nullptr, 4096) {
}
};

Expand Down Expand Up @@ -131,7 +131,7 @@ class EXCEPTION_TEST : public ::testing::Test {
HyperCPU::CPU cpu;

EXCEPTION_TEST()
: cpu(1, 4096) {
: cpu(1, 4096, nullptr, 4096) {
}

virtual void SetUp() {
Expand Down