From 5a7a72c745e21393c0d99277b6acd22c1e12644c Mon Sep 17 00:00:00 2001 From: Christian Speckner Date: Wed, 10 Jul 2024 08:28:45 +0200 Subject: [PATCH] Logging. --- src/emucore/CartELF.cxx | 56 +++++++++++++++++++++++++++++++---- src/emucore/elf/ElfLinker.cxx | 29 ++++++++++-------- src/emucore/elf/ElfLinker.hxx | 12 ++++---- src/emucore/elf/ElfParser.cxx | 20 ++++++------- 4 files changed, 85 insertions(+), 32 deletions(-) diff --git a/src/emucore/CartELF.cxx b/src/emucore/CartELF.cxx index 8cfd46de9..8ddf2cf90 100644 --- a/src/emucore/CartELF.cxx +++ b/src/emucore/CartELF.cxx @@ -82,16 +82,17 @@ namespace { }; #ifdef DUMP_ELF - void dumpElf(const ElfParser& elfParser) { + void dumpElf(const ElfParser& parser) + { cout << "ELF sections:" << std::endl << std::endl; size_t i = 0; - for (auto& section: elfParser.getSections()) { + for (auto& section: parser.getSections()) { if (section.type != 0x00) cout << i << " " << section << std::endl; i++; } - auto symbols = elfParser.getSymbols(); + auto symbols = parser.getSymbols(); cout << std::endl << "ELF symbols:" << std::endl << std::endl; if (symbols.size() > 0) { i = 0; @@ -100,8 +101,8 @@ namespace { } i = 0; - for (auto& section: elfParser.getSections()) { - auto rels = elfParser.getRelocations(i++); + for (auto& section: parser.getSections()) { + auto rels = parser.getRelocations(i++); if (!rels) continue; cout @@ -111,6 +112,49 @@ namespace { for (auto& rel: *rels) cout << rel << std::endl; } } + + void dumpLinkage(const ElfParser& parser, const ElfLinker& linker) + { + cout << std::endl << "relocated sections:" << std::endl << std::endl; + cout << std::hex << std::setfill('0'); + + const auto& sections = parser.getSections(); + const auto& relocatedSections = linker.getRelocatedSections(); + + for (size_t i = 0; i < sections.size(); i++) { + if (!relocatedSections[i]) continue; + + cout + << sections[i].name + << " @ 0x"<< std::setw(8) << (relocatedSections[i]->offset + + (relocatedSections[i]->type == ElfLinker::SectionType::text ? ADDR_TEXT_BASE : ADDR_DATA_BASE) + ) + << " size 0x" << std::setw(8) << sections[i].size << std::endl; + } + + cout << std::endl << "relocated symbols:" << std::endl << std::endl; + + const auto& symbols = parser.getSymbols(); + const auto& relocatedSymbols = linker.getRelocatedSymbols(); + + for (size_t i = 0; i < symbols.size(); i++) { + if (!relocatedSymbols[i]) continue; + + cout + << symbols[i].name + << " = 0x" << std::setw(8) << relocatedSymbols[i]->value; + + if (relocatedSymbols[i]->section) { + cout << (*relocatedSymbols[i]->section == ElfLinker::SectionType::text ? " (text)" : " (data)"); + } else { + cout << " (abs)"; + } + + cout << std::endl; + } + + cout << std::dec; + } #endif } @@ -153,6 +197,8 @@ CartridgeELF::CartridgeELF(const ByteBuffer& image, size_t size, string_view md5 } #ifdef DUMP_ELF + dumpLinkage(elfParser, elfLinker); + cout << std::endl << "ARM entrypoint: 0x" diff --git a/src/emucore/elf/ElfLinker.cxx b/src/emucore/elf/ElfLinker.cxx index 31e91f1b2..e3c2299ec 100644 --- a/src/emucore/elf/ElfLinker.cxx +++ b/src/emucore/elf/ElfLinker.cxx @@ -78,7 +78,7 @@ void ElfLinker::link(const vector& externalSymbols) for (size_t i = 0; i < sections.size(); i++) { const auto& relocatedSection = myRelocatedSections[i]; - if (!relocatedSection.has_value()) continue; + if (!relocatedSection) continue; const auto& section = sections[i]; if (section.type != ElfParser::SHT_PROGBITS) continue; @@ -192,6 +192,16 @@ ElfLinker::RelocatedSymbol ElfLinker::findRelocatedSymbol(string_view name) cons ElfSymbolResolutionError::raise("symbol not found"); } +const vector>& ElfLinker::getRelocatedSections() const +{ + return myRelocatedSections; +} + +const vector>& ElfLinker::getRelocatedSymbols() const +{ + return myRelocatedSymbols; +} + void ElfLinker::applyRelocation(const ElfParser::Relocation& relocation, size_t iSection) { const auto& targetSection = myParser.getSections()[iSection]; @@ -204,6 +214,11 @@ void ElfLinker::applyRelocation(const ElfParser::Relocation& relocation, size_t "unable to relocate " + symbol.name + " in " + targetSection.name + ": symbol could not be relocated" ); + if (relocation.offset + 4 > targetSection.size) + ElfLinkError::raise( + "unable to relocate " + symbol.name + " in " + targetSection.name + ": target out of range" + ); + uInt8* target = (targetSectionRelocated.type == SectionType::text ? myTextData : myDataData).get() + targetSectionRelocated.offset + relocation.offset; @@ -212,11 +227,6 @@ void ElfLinker::applyRelocation(const ElfParser::Relocation& relocation, size_t case ElfParser::R_ARM_ABS32: case ElfParser::R_ARM_TARGET1: { - if (relocation.offset + 4 > targetSection.size) - ElfLinkError::raise( - "unable to relocate " + symbol.name + " in " + targetSection.name + ": target out of range" - ); - const uInt32 value = relocatedSymbol->value + relocation.addend.value_or(read32(target)); write32(target, value | (symbol.type == ElfParser::STT_FUNC ? 0x01 : 0)); @@ -226,18 +236,13 @@ void ElfLinker::applyRelocation(const ElfParser::Relocation& relocation, size_t case ElfParser::R_ARM_THM_CALL: case ElfParser::R_ARM_THM_JUMP24: { - if (relocation.offset + 4 > targetSection.size) - ElfLinkError::raise( - "unable to relocate " + symbol.name + " in " + targetSection.name + ": target out of range" - ); - const uInt32 op = read32(target); Int32 offset = relocatedSymbol->value + relocation.addend.value_or(elfUtil::decode_B_BL(op)) - (targetSectionRelocated.type == SectionType::text ? myTextBase : myDataBase) - targetSectionRelocated.offset - relocation.offset - 4; - if ((offset >> 25) != -1 && (offset >> 25) != 0) + if ((offset >> 24) != -1 && (offset >> 24) != 0) ElfLinkError::raise("unable to relocate jump: offset out of bounds"); write32(target, elfUtil::encode_B_BL(offset, relocation.type == ElfParser::R_ARM_THM_CALL)); diff --git a/src/emucore/elf/ElfLinker.hxx b/src/emucore/elf/ElfLinker.hxx index 8c98fbe21..d805c7854 100644 --- a/src/emucore/elf/ElfLinker.hxx +++ b/src/emucore/elf/ElfLinker.hxx @@ -59,6 +59,11 @@ class ElfLinker { enum class SectionType: uInt8 { text, data }; + struct RelocatedSection { + SectionType type; + uInt32 offset; + }; + struct RelocatedSymbol { optional section; uInt32 value; @@ -87,11 +92,8 @@ class ElfLinker { RelocatedSymbol findRelocatedSymbol(string_view name) const; - private: - struct RelocatedSection { - SectionType type; - uInt32 offset; - }; + const vector>& getRelocatedSections() const; + const vector>& getRelocatedSymbols() const; private: void applyRelocation(const ElfParser::Relocation& relocation, size_t iSection); diff --git a/src/emucore/elf/ElfParser.cxx b/src/emucore/elf/ElfParser.cxx index 5577ff635..3aef479ac 100644 --- a/src/emucore/elf/ElfParser.cxx +++ b/src/emucore/elf/ElfParser.cxx @@ -329,12 +329,12 @@ ostream& operator<<(ostream& os, const ElfParser::Symbol symbol) os << symbol.nameOffset << " " << symbol.name - << std::hex << std::setw(4) << std::setfill('0') - << " value=0x" << symbol.value - << " size=0x" << symbol.size + << std::hex << std::setfill('0') + << " value=0x" << std::setw(8) << symbol.value + << " size=0x" << std::setw(8) << symbol.size << std::setw(1) - << " bind=0x" << (int)symbol.bind - << " type=0x" << (int)symbol.type; + << " bind=0x" << std::setw(2) << (int)symbol.bind + << " type=0x" << std::setw(2) << (int)symbol.type; os.copyfmt(reset); @@ -351,13 +351,13 @@ ostream& operator<<(ostream& os, const ElfParser::Relocation rel) os << rel.symbolName << " :" - << std::hex << std::setw(4) << std::setfill('0') - << " offset=0x" << rel.offset - << " info=0x" << rel.info - << " type=0x" << (int)rel.type; + << std::hex << std::setfill('0') + << " offset=0x" << std::setw(8) << rel.offset + << " info=0x" << std::setw(8) << rel.info + << " type=0x" << std::setw(2) << (int)rel.type; if (rel.addend.has_value()) - os << " addend=0x" << *rel.addend; + os << " addend=0x" << std::setw(8) << *rel.addend; os.copyfmt(reset);