From 93209423471ebda393667784f874faf13fdcc22a Mon Sep 17 00:00:00 2001 From: Maschell Date: Tue, 2 Jul 2024 11:40:09 +0200 Subject: [PATCH] Elf2rpl: Fix order of sections inside the .rpx (#11) * elf2rpl: Fix "LOADER" section relocation inside .elf * elf2rpl: Fix detecting failed offset calculations --- src/elf2rpl/main.cpp | 48 ++++++++++++++++++-------------------------- 1 file changed, 19 insertions(+), 29 deletions(-) diff --git a/src/elf2rpl/main.cpp b/src/elf2rpl/main.cpp index 25fa859..884e3cb 100644 --- a/src/elf2rpl/main.cpp +++ b/src/elf2rpl/main.cpp @@ -717,6 +717,11 @@ calculateSectionOffsets(ElfFile &file) auto offset = file.header.shoff; offset += align_up(static_cast((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 §ion : file.sections) { + section->header.offset = 0u; + } + for (auto §ion : file.sections) { if (section->header.type == elf::SHT_NOBITS || section->header.type == elf::SHT_NULL) { @@ -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 §ion : 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(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 §ion : file.sections) { - if (section->header.type == elf::SHT_RPL_IMPORTS) { - section->header.offset = offset; - section->header.size = static_cast(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 §ion: 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(section->data.size()); + offset += section->header.size; + } } } @@ -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; }