Merge pull request #10 from shinyquagsire23/elf2rpl-fixes

Collective fixes for elf2rpl
This commit is contained in:
James 2016-07-17 22:37:11 +01:00 committed by GitHub
commit 2c69f7d9be

View File

@ -543,6 +543,7 @@ write(ElfFile &file, const std::string &filename)
out->header.addralign = 256; out->header.addralign = 256;
} else if (section->address == DataAddress) { } else if (section->address == DataAddress) {
out->header.addralign = 4096; out->header.addralign = 4096;
out->header.flags |= elf::SHF_WRITE; // .rodata needs to be writable?
} else { } else {
out->header.addralign = 32; out->header.addralign = 32;
} }
@ -595,9 +596,27 @@ write(ElfFile &file, const std::string &filename)
} }
} }
// Create RPL import sections, .fimport_*, .dimport_* // Calculate sizes of symbol/string tables so RPL imports are placed after them
auto loadAddress = 0xC0000000; auto loadAddress = 0xC0000000;
auto predictStrTabSize = 1;
auto predictSymTabSize = 1;
auto predictShstrTabSize = 1;
for (auto &symbol : file.symbols) {
predictStrTabSize += symbol->name.size() + 1;
predictSymTabSize += sizeof(elf::Symbol);
}
for (auto &section : outSections) {
predictShstrTabSize += section->name.size() + 1;
}
predictStrTabSize = align_up(predictStrTabSize, 0x10);
predictSymTabSize = align_up(predictSymTabSize, 0x10);
predictShstrTabSize = align_up(predictShstrTabSize, 0x10);
loadAddress += predictStrTabSize + predictSymTabSize + predictShstrTabSize;
// Create RPL import sections, .fimport_*, .dimport_*
for (auto &lib : file.rplImports) { for (auto &lib : file.rplImports) {
auto out = new OutputSection(); auto out = new OutputSection();
out->header.name = -1; out->header.name = -1;
@ -635,6 +654,14 @@ write(ElfFile &file, const std::string &filename)
sectionSymbolItr = addSection(file, outSections, sectionSymbolItr, out); sectionSymbolItr = addSection(file, outSections, sectionSymbolItr, out);
} }
// Prune out unneeded symbols
for (auto i = 0u; i < file.symbols.size(); ++i) {
if (!file.symbols[i]->name.empty() && file.symbols[i]->type == elf::STT_NOTYPE) {
file.symbols.erase(file.symbols.begin() + i);
i--;
}
}
// NOTICE: FROM NOW ON DO NOT MODIFY mSymbols // NOTICE: FROM NOW ON DO NOT MODIFY mSymbols
// Convert relocations // Convert relocations
@ -820,15 +847,17 @@ write(ElfFile &file, const std::string &filename)
} }
} }
loadAddress = 0xC0000000;
// Update symtab, strtab, shstrtab section addresses // Update symtab, strtab, shstrtab section addresses
symTabSection->header.addr = loadAddress; symTabSection->header.addr = loadAddress;
symTabSection->header.size = symTabSection->data.size(); symTabSection->header.size = symTabSection->data.size();
loadAddress = align_up(symTabSection->header.addr + symTabSection->header.size, 4); loadAddress = align_up(symTabSection->header.addr + predictSymTabSize, 16);
strTabSection->header.addr = loadAddress; strTabSection->header.addr = loadAddress;
strTabSection->header.size = strTabSection->data.size(); strTabSection->header.size = strTabSection->data.size();
loadAddress = align_up(strTabSection->header.addr + strTabSection->header.size, 4); loadAddress = align_up(strTabSection->header.addr + predictStrTabSize, 16);
shStrTabSection->header.addr = loadAddress; shStrTabSection->header.addr = loadAddress;
shStrTabSection->header.size = shStrTabSection->data.size(); shStrTabSection->header.size = shStrTabSection->data.size();
@ -853,7 +882,7 @@ write(ElfFile &file, const std::string &filename)
fileInfo.dataAlign = 4096; fileInfo.dataAlign = 4096;
fileInfo.loadSize = 0; fileInfo.loadSize = 0;
fileInfo.loadAlign = 4; fileInfo.loadAlign = 4;
fileInfo.tempSize = 0; // TODO: Figure out what to do with temp size fileInfo.tempSize = 0;
fileInfo.trampAdjust = 0; fileInfo.trampAdjust = 0;
fileInfo.trampAddition = 0; fileInfo.trampAddition = 0;
fileInfo.sdaBase = 0; fileInfo.sdaBase = 0;
@ -881,14 +910,29 @@ write(ElfFile &file, const std::string &filename)
} }
if (section->header.addr >= CodeAddress && section->header.addr < DataAddress) { if (section->header.addr >= CodeAddress && section->header.addr < DataAddress) {
fileInfo.textSize += align_up(size, fileInfo.textAlign); auto val = section->header.addr.value() + section->header.size.value() - CodeAddress;
if(val > fileInfo.textSize) {
fileInfo.textSize = val;
}
} else if (section->header.addr >= DataAddress && section->header.addr < WiiuLoadAddress) { } else if (section->header.addr >= DataAddress && section->header.addr < WiiuLoadAddress) {
fileInfo.dataSize += align_up(size, fileInfo.dataAlign); auto val = section->header.addr.value() + section->header.size.value() - DataAddress;
if(val > fileInfo.dataSize) {
fileInfo.dataSize = val;
}
} else if (section->header.addr >= WiiuLoadAddress) { } else if (section->header.addr >= WiiuLoadAddress) {
fileInfo.loadSize += align_up(size, fileInfo.loadAlign); auto val = section->header.addr.value() + section->header.size.value() - WiiuLoadAddress;
if(val > fileInfo.loadSize) {
fileInfo.loadSize = val;
}
} else if (section->header.type == elf::SHT_RELA) {
fileInfo.tempSize += size;
} }
} }
//TODO: These were calculated based on observation, however some games differ.
fileInfo.sdaBase = align_up(DataAddress + fileInfo.dataSize + fileInfo.heapSize, 64);
fileInfo.sda2Base = align_up(DataAddress + fileInfo.heapSize, 64);
char *fileInfoData = reinterpret_cast<char *>(&fileInfo); char *fileInfoData = reinterpret_cast<char *>(&fileInfo);
fileInfoSection->data.insert(fileInfoSection->data.end(), fileInfoData, fileInfoData + sizeof(elf::RplFileInfo)); fileInfoSection->data.insert(fileInfoSection->data.end(), fileInfoData, fileInfoData + sizeof(elf::RplFileInfo));