mirror of https://github.com/stella-emu/stella.git
Refactoring.
This commit is contained in:
parent
dfdcddbf2e
commit
9c1231bd61
|
@ -211,70 +211,11 @@ void ElfLinker::relocateInitArrays()
|
||||||
myInitArray.resize(initArraySize >> 2);
|
myInitArray.resize(initArraySize >> 2);
|
||||||
myPreinitArray.resize(preinitArraySize >> 2);
|
myPreinitArray.resize(preinitArraySize >> 2);
|
||||||
|
|
||||||
const uInt8* elfData = myParser.getData();
|
copyInitArrays(myInitArray, relocatedInitArrays);
|
||||||
|
copyInitArrays(myPreinitArray, relocatedPreinitArrays);
|
||||||
|
|
||||||
// Copy init arrays
|
applyRelocationsToInitArrays(ElfParser::SHT_INIT_ARRAY, myInitArray, relocatedInitArrays);
|
||||||
for (const auto [iSection, offset]: relocatedInitArrays) {
|
applyRelocationsToInitArrays(ElfParser::SHT_PREINIT_ARRAY, myPreinitArray, relocatedPreinitArrays);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ElfLinker::relocateSymbols(const vector<ExternalSymbol>& externalSymbols)
|
void ElfLinker::relocateSymbols(const vector<ExternalSymbol>& externalSymbols)
|
||||||
|
@ -333,6 +274,20 @@ void ElfLinker::applyRelocationsToSections()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ElfLinker::copyInitArrays(vector<uInt32>& initArray, std::unordered_map<uInt32, uInt32> 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)
|
void ElfLinker::applyRelocationToSection(const ElfParser::Relocation& relocation, size_t iSection)
|
||||||
{
|
{
|
||||||
const auto& targetSection = myParser.getSections()[iSection];
|
const auto& targetSection = myParser.getSections()[iSection];
|
||||||
|
@ -382,6 +337,42 @@ void ElfLinker::applyRelocationToSection(const ElfParser::Relocation& relocation
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ElfLinker::applyRelocationsToInitArrays(uInt8 initArrayType, vector<uInt32>& initArray,
|
||||||
|
std::unordered_map<uInt32, uInt32> 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 ElfLinker::read32(const uInt8* address)
|
||||||
{
|
{
|
||||||
uInt32 value = *(address++);
|
uInt32 value = *(address++);
|
||||||
|
|
|
@ -102,8 +102,11 @@ class ElfLinker {
|
||||||
void relocateInitArrays();
|
void relocateInitArrays();
|
||||||
void relocateSymbols(const vector<ExternalSymbol>& externalSymbols);
|
void relocateSymbols(const vector<ExternalSymbol>& externalSymbols);
|
||||||
void applyRelocationsToSections();
|
void applyRelocationsToSections();
|
||||||
|
void copyInitArrays(vector<uInt32>& initArray, std::unordered_map<uInt32, uInt32> relocatedInitArrays);
|
||||||
|
|
||||||
void applyRelocationToSection(const ElfParser::Relocation& relocation, size_t iSection);
|
void applyRelocationToSection(const ElfParser::Relocation& relocation, size_t iSection);
|
||||||
|
void applyRelocationsToInitArrays(uInt8 initArrayType,
|
||||||
|
vector<uInt32>& initArray, std::unordered_map<uInt32, uInt32> relocatedInitArrays);
|
||||||
|
|
||||||
uInt32 read32(const uInt8* address);
|
uInt32 read32(const uInt8* address);
|
||||||
void write32(uInt8* address, uInt32 value);
|
void write32(uInt8* address, uInt32 value);
|
||||||
|
|
Loading…
Reference in New Issue