Skip to content

Commit

Permalink
Elf2rpl: Fix order of sections inside the .rpx (#11)
Browse files Browse the repository at this point in the history
* elf2rpl: Fix "LOADER" section relocation inside .elf
* elf2rpl: Fix detecting failed offset calculations
  • Loading branch information
Maschell authored Jul 2, 2024
1 parent 07bc257 commit 9320942
Showing 1 changed file with 19 additions and 29 deletions.
48 changes: 19 additions & 29 deletions src/elf2rpl/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -717,6 +717,11 @@ calculateSectionOffsets(ElfFile &file)
auto offset = file.header.shoff;
offset += align_up(static_cast<uint32_t>((file.sections.size() - file.num_discarded_sections) * sizeof(elf::SectionHeader)), 64);

// Set all offsets to 0, so we can detect sections we didn't relocate
for (auto &section : file.sections) {
section->header.offset = 0u;
}

for (auto &section : file.sections) {
if (section->header.type == elf::SHT_NOBITS ||
section->header.type == elf::SHT_NULL) {
Expand Down Expand Up @@ -764,35 +769,20 @@ calculateSectionOffsets(ElfFile &file)
}

// Next the "readMin / readMax" sections, which are:
// - !(flags & SHF_EXECINSTR) || type == SHT_RPL_EXPORTS
// - !(flags & SHF_WRITE)
// - type == SHT_RPL_EXPORTS || SHT_RPL_IMPORTS
// - !(flags & (SHF_EXECINSTR | SHF_WRITE))
// - flags & SHF_ALLOC
for (auto &section : file.sections) {
if (section->header.size == 0 ||
section->header.type == elf::SHT_RPL_FILEINFO ||
section->header.type == elf::SHT_RPL_IMPORTS ||
section->header.type == elf::SHT_RPL_CRCS ||
section->header.type == elf::SHT_NOBITS) {
continue;
}

if ((!(section->header.flags & elf::SHF_EXECINSTR) ||
section->header.type == elf::SHT_RPL_EXPORTS) &&
!(section->header.flags & elf::SHF_WRITE) &&
(section->header.flags & elf::SHF_ALLOC)) {
section->header.offset = offset;
section->header.size = static_cast<uint32_t>(section->data.size());
offset += section->header.size;
}
}

// Import sections are part of the read sections, but have execinstr flag set
// so let's insert them here to avoid complicating the above logic.
for (auto &section : file.sections) {
if (section->header.type == elf::SHT_RPL_IMPORTS) {
section->header.offset = offset;
section->header.size = static_cast<uint32_t>(section->data.size());
offset += section->header.size;
// See: https://github.com/decaf-emu/decaf-emu/blob/e6c528a20a41c34e0f9eb91dd3da40f119db2dee/src/libdecaf/src/cafe/loader/cafe_loader_setup.cpp#L575
for (auto &section: file.sections) {
if (section->header.size > 0 &&
(section->header.flags & elf::SHF_ALLOC)) {
if (section->header.type == elf::SHT_RPL_EXPORTS ||
section->header.type == elf::SHT_RPL_IMPORTS ||
!(section->header.flags & (elf::SHF_EXECINSTR | elf::SHF_WRITE))) {
section->header.offset = offset;
section->header.size = static_cast<uint32_t>(section->data.size());
offset += section->header.size;
}
}
}

Expand Down Expand Up @@ -840,7 +830,7 @@ calculateSectionOffsets(ElfFile &file)
if (section->header.offset == 0 &&
section->header.type != elf::SHT_NULL &&
section->header.type != elf::SHT_NOBITS) {
fmt::print("Failed to calculate offset for section {}\n", section->index);
fmt::print("Failed to calculate offset for section {} ({})\n", section->name, section->index);
return false;
}

Expand Down

0 comments on commit 9320942

Please sign in to comment.