From 33a83c42a4abc2a991d60615305689a57a8585b6 Mon Sep 17 00:00:00 2001 From: Christian Speckner Date: Tue, 23 Jul 2024 22:28:34 +0200 Subject: [PATCH] Write out elf image for debugging. --- src/emucore/CartELF.cxx | 35 +++++++++++++++++++++++++++++++++++ src/emucore/CortexM0.cxx | 5 +++++ src/emucore/CortexM0.hxx | 1 + 3 files changed, 41 insertions(+) diff --git a/src/emucore/CartELF.cxx b/src/emucore/CartELF.cxx index cfcd5d8df..e8b779a80 100644 --- a/src/emucore/CartELF.cxx +++ b/src/emucore/CartELF.cxx @@ -17,6 +17,10 @@ #include +#ifdef DUMP_ELF +#include +#endif + #include "System.hxx" #include "ElfParser.hxx" #include "ElfLinker.hxx" @@ -141,6 +145,31 @@ namespace { cout << std::dec; } + + void writeDebugBinary(const ElfLinker& linker) + { + constexpr size_t IMAGE_SIZE = 4 * 0x00100000; + static const char* IMAGE_FILE_NAME = "elf_executable_image.bin"; + + auto binary = make_unique(IMAGE_SIZE); + std::memset(binary.get(), 0, IMAGE_SIZE); + + for (auto segment: {ElfLinker::SegmentType::text, ElfLinker::SegmentType::data, ElfLinker::SegmentType::rodata}) + std::memcpy( + binary.get() + linker.getSegmentBase(segment), + linker.getSegmentData(segment), + linker.getSegmentSize(segment) + ); + + { + std::ofstream binaryFile; + + binaryFile.open(IMAGE_FILE_NAME); + binaryFile.write(reinterpret_cast(binary.get()), 4 * 0x00100000); + } + + cout << "wrote executable image to " << IMAGE_FILE_NAME << std::endl; + } #endif } // namespace @@ -182,6 +211,10 @@ CartridgeELF::CartridgeELF(const ByteBuffer& image, size_t size, string_view md5 throw runtime_error("failed to resolve ARM entrypoint" + string(e.what())); } + for (auto segment: {ElfLinker::SegmentType::text, ElfLinker::SegmentType::data, ElfLinker::SegmentType::rodata}) + if (elfLinker.getSegmentSize(segment) > 0x00100000) + throw runtime_error("segment size exceeds limit"); + #ifdef DUMP_ELF dumpLinkage(elfParser, elfLinker); @@ -189,6 +222,8 @@ CartridgeELF::CartridgeELF(const ByteBuffer& image, size_t size, string_view md5 << "\nARM entrypoint: 0x" << std::hex << std::setw(8) << std::setfill('0') << myArmEntrypoint << std::dec << '\n'; + + writeDebugBinary(elfLinker); #endif } diff --git a/src/emucore/CortexM0.cxx b/src/emucore/CortexM0.cxx index 04988d86c..8fd2aecb2 100644 --- a/src/emucore/CortexM0.cxx +++ b/src/emucore/CortexM0.cxx @@ -476,6 +476,11 @@ CortexM0& CortexM0::setRegister(uInt8 regno, uInt32 value) return *this; } +uInt32 CortexM0::getRegister(uInt32 regno) +{ + return read_register(regno); +} + uInt8 CortexM0::decodeInstructionWord(uInt16 instructionWord) { return static_cast(::decodeInstructionWord(instructionWord)); diff --git a/src/emucore/CortexM0.hxx b/src/emucore/CortexM0.hxx index 0384e9e94..c83d02062 100644 --- a/src/emucore/CortexM0.hxx +++ b/src/emucore/CortexM0.hxx @@ -93,6 +93,7 @@ class CortexM0 CortexM0& reset(); CortexM0& setRegister(uInt8 regno, uInt32 value); + uInt32 getRegister(uInt32 regno); static uInt8 decodeInstructionWord(uInt16 instructionWord);