From f6e8ccc220d3537a3dcbb90762b22f500e1db472 Mon Sep 17 00:00:00 2001 From: Christian Speckner Date: Fri, 12 Jul 2024 23:23:27 +0200 Subject: [PATCH] Refactoring. --- src/emucore/elf/ElfLinker.cxx | 117 ++++++++++++++++------------------ src/emucore/elf/ElfLinker.hxx | 3 + 2 files changed, 57 insertions(+), 63 deletions(-) diff --git a/src/emucore/elf/ElfLinker.cxx b/src/emucore/elf/ElfLinker.cxx index 3fb81307c..b0e53c8b4 100644 --- a/src/emucore/elf/ElfLinker.cxx +++ b/src/emucore/elf/ElfLinker.cxx @@ -211,70 +211,11 @@ void ElfLinker::relocateInitArrays() myInitArray.resize(initArraySize >> 2); myPreinitArray.resize(preinitArraySize >> 2); - const uInt8* elfData = myParser.getData(); + copyInitArrays(myInitArray, relocatedInitArrays); + copyInitArrays(myPreinitArray, relocatedPreinitArrays); - // Copy init arrays - for (const auto [iSection, offset]: relocatedInitArrays) { - const auto& section = sections[iSection]; - - for (size_t i = 0; i < section.size; i += 4) - myInitArray[(offset + i) >> 2] = read32(elfData + section.offset + i); - } - - for (const auto [iSection, offset]: relocatedPreinitArrays) { - const auto& section = sections[iSection]; - - for (size_t i = 0; i < section.size; i += 4) - myPreinitArray[(offset + i) >> 2] = read32(elfData + section.offset + i); - } - - // Apply relocations - const auto& symbols = myParser.getSymbols(); - - for (size_t iSection = 0; iSection < sections.size(); iSection++) { - const auto& section = sections[iSection]; - if (section.type != ElfParser::SHT_INIT_ARRAY && section.type != ElfParser::SHT_PREINIT_ARRAY) continue; - - const auto& relocations = myParser.getRelocations(iSection); - if (!relocations) continue; - - for (const auto& relocation: *relocations) { - if (relocation.type != ElfParser::R_ARM_ABS32 && relocation.type != ElfParser::R_ARM_TARGET1) - ElfLinkError::raise("unsupported relocation for init table"); - - const auto& relocatedSymbol = myRelocatedSymbols[relocation.symbol]; - if (!relocatedSymbol) - ElfLinkError::raise( - "unable to relocate init section: symbol " + relocation.symbolName + " could not be relocated" - ); - - if (relocatedSymbol->undefined) - Logger::error("unable to relocate symbol " + relocation.symbolName); - - if (relocation.offset + 4 > section.size) - ElfLinkError::raise("unable relocate init section: symbol " + relocation.symbolName + " out of range"); - - switch (section.type) { - case ElfParser::SHT_INIT_ARRAY: - { - const uInt32 index = (relocatedInitArrays.at(iSection) + relocation.offset) >> 2; - const uInt32 value = relocatedSymbol->value + relocation.addend.value_or(myInitArray[index]); - myInitArray[index] = value | (symbols[relocation.symbol].type == ElfParser::STT_FUNC ? 1 : 0); - - break; - } - - case ElfParser::SHT_PREINIT_ARRAY: - { - const uInt32 index = (relocatedPreinitArrays.at(iSection) + relocation.offset) >> 2; - const uInt32 value = relocatedSymbol->value + relocation.addend.value_or(myPreinitArray[index]); - myPreinitArray[index] = value | (symbols[relocation.symbol].type == ElfParser::STT_FUNC ? 1 : 0); - - break; - } - } - } - } + applyRelocationsToInitArrays(ElfParser::SHT_INIT_ARRAY, myInitArray, relocatedInitArrays); + applyRelocationsToInitArrays(ElfParser::SHT_PREINIT_ARRAY, myPreinitArray, relocatedPreinitArrays); } void ElfLinker::relocateSymbols(const vector& externalSymbols) @@ -333,6 +274,20 @@ void ElfLinker::applyRelocationsToSections() } } +void ElfLinker::copyInitArrays(vector& initArray, std::unordered_map relocatedInitArrays) +{ + const uInt8* elfData = myParser.getData(); + const auto& sections = myParser.getSections(); + + // Copy init arrays + for (const auto [iSection, offset]: relocatedInitArrays) { + const auto& section = sections[iSection]; + + for (size_t i = 0; i < section.size; i += 4) + initArray[(offset + i) >> 2] = read32(elfData + section.offset + i); + } +} + void ElfLinker::applyRelocationToSection(const ElfParser::Relocation& relocation, size_t iSection) { const auto& targetSection = myParser.getSections()[iSection]; @@ -382,6 +337,42 @@ void ElfLinker::applyRelocationToSection(const ElfParser::Relocation& relocation } } +void ElfLinker::applyRelocationsToInitArrays(uInt8 initArrayType, vector& initArray, + std::unordered_map relocatedInitArrays) +{ + const auto& symbols = myParser.getSymbols(); + const auto& sections = myParser.getSections(); + + for (size_t iSection = 0; iSection < sections.size(); iSection++) { + const auto& section = sections[iSection]; + if (section.type != initArrayType) continue; + + const auto& relocations = myParser.getRelocations(iSection); + if (!relocations) continue; + + for (const auto& relocation: *relocations) { + if (relocation.type != ElfParser::R_ARM_ABS32 && relocation.type != ElfParser::R_ARM_TARGET1) + ElfLinkError::raise("unsupported relocation for init table"); + + const auto& relocatedSymbol = myRelocatedSymbols[relocation.symbol]; + if (!relocatedSymbol) + ElfLinkError::raise( + "unable to relocate init section: symbol " + relocation.symbolName + " could not be relocated" + ); + + if (relocatedSymbol->undefined) + Logger::error("unable to relocate symbol " + relocation.symbolName); + + if (relocation.offset + 4 > section.size) + ElfLinkError::raise("unable relocate init section: symbol " + relocation.symbolName + " out of range"); + + const uInt32 index = (relocatedInitArrays.at(iSection) + relocation.offset) >> 2; + const uInt32 value = relocatedSymbol->value + relocation.addend.value_or(initArray[index]); + initArray[index] = value | (symbols[relocation.symbol].type == ElfParser::STT_FUNC ? 1 : 0); + } + } +} + uInt32 ElfLinker::read32(const uInt8* address) { uInt32 value = *(address++); diff --git a/src/emucore/elf/ElfLinker.hxx b/src/emucore/elf/ElfLinker.hxx index 794ee59b9..e5096b4fe 100644 --- a/src/emucore/elf/ElfLinker.hxx +++ b/src/emucore/elf/ElfLinker.hxx @@ -102,8 +102,11 @@ class ElfLinker { void relocateInitArrays(); void relocateSymbols(const vector& externalSymbols); void applyRelocationsToSections(); + void copyInitArrays(vector& initArray, std::unordered_map relocatedInitArrays); void applyRelocationToSection(const ElfParser::Relocation& relocation, size_t iSection); + void applyRelocationsToInitArrays(uInt8 initArrayType, + vector& initArray, std::unordered_map relocatedInitArrays); uInt32 read32(const uInt8* address); void write32(uInt8* address, uInt32 value);