From 81ce18d0d3448308d29ca1cc1a835344571126c9 Mon Sep 17 00:00:00 2001 From: Mr-Wiseguy Date: Thu, 12 Sep 2024 00:09:39 -0400 Subject: [PATCH] Fixed reference symbol pointers not being populated in offline compiled mods --- librecomp/include/librecomp/overlays.hpp | 3 +- librecomp/src/mods.cpp | 38 +++++++++++------------ librecomp/src/overlays.cpp | 39 +++++++++++++++--------- 3 files changed, 46 insertions(+), 34 deletions(-) diff --git a/librecomp/include/librecomp/overlays.hpp b/librecomp/include/librecomp/overlays.hpp index 33a1859..87bb174 100644 --- a/librecomp/include/librecomp/overlays.hpp +++ b/librecomp/include/librecomp/overlays.hpp @@ -29,7 +29,8 @@ namespace recomp { void init_overlays(); const std::unordered_map& get_vrom_to_section_map(); - recomp_func_t* get_func_by_section_ram(uint32_t section_rom, uint32_t function_vram); + recomp_func_t* get_func_by_section_rom_function_vram(uint32_t section_rom, uint32_t function_vram); + recomp_func_t* get_func_by_section_index_function_offset(uint16_t code_section_index, uint32_t function_offset); recomp_func_t* get_base_export(const std::string& export_name); size_t get_base_event_index(const std::string& event_name); size_t num_base_events(); diff --git a/librecomp/src/mods.cpp b/librecomp/src/mods.cpp index f2a01db..9dd418e 100644 --- a/librecomp/src/mods.cpp +++ b/librecomp/src/mods.cpp @@ -788,25 +788,25 @@ recomp::mods::ModLoadError recomp::mods::ModContext::load_mod_code(recomp::mods: } recomp::mods::ModLoadError recomp::mods::ModContext::resolve_dependencies(recomp::mods::ModHandle& mod, std::string& error_param) { - // Reference symbols from the base recomp. - for (size_t reference_sym_index = 0; reference_sym_index < mod.recompiler_context->num_regular_reference_symbols(); reference_sym_index++) { - const N64Recomp::ReferenceSymbol& reference_sym = mod.recompiler_context->get_regular_reference_symbol(reference_sym_index); - uint32_t reference_section_vrom = mod.recompiler_context->get_reference_section_rom(reference_sym.section_index); - uint32_t reference_section_vram = mod.recompiler_context->get_reference_section_vram(reference_sym.section_index); - uint32_t reference_symbol_vram = reference_section_vram + reference_sym.section_offset; - - recomp_func_t* found_func = recomp::overlays::get_func_by_section_ram(reference_section_vrom, reference_symbol_vram); - - if (found_func == nullptr) { - std::stringstream error_param_stream{}; - error_param_stream << std::hex << - "section: 0x" << reference_section_vrom << - " func: 0x" << std::setfill('0') << std::setw(8) << reference_symbol_vram; - error_param = error_param_stream.str(); - return ModLoadError::InvalidReferenceSymbol; + // Reference symbols from the base recomp.1:1 with relocs for offline mods. + // TODO this won't be needed for LuaJIT recompilation, so move this logic into the code handle. + size_t reference_symbol_index = 0; + for (const auto& section : mod.recompiler_context->sections) { + for (const auto& reloc : section.relocs) { + if (reloc.type == N64Recomp::RelocType::R_MIPS_26 && reloc.reference_symbol && mod.recompiler_context->is_regular_reference_section(reloc.target_section)) { + recomp_func_t* cur_func = recomp::overlays::get_func_by_section_index_function_offset(reloc.target_section, reloc.target_section_offset); + if (cur_func == nullptr) { + std::stringstream error_param_stream{}; + error_param_stream << std::hex << + "section: " << reloc.target_section << + " func offset: 0x" << reloc.target_section_offset; + error_param = error_param_stream.str(); + return ModLoadError::InvalidReferenceSymbol; + } + mod.code_handle->set_reference_symbol_pointer(reference_symbol_index, cur_func); + reference_symbol_index++; + } } - - mod.code_handle->set_reference_symbol_pointer(reference_sym_index, found_func); } // Create a list of dependencies ordered by their index in the recompiler context. @@ -896,7 +896,7 @@ recomp::mods::ModLoadError recomp::mods::ModContext::resolve_dependencies(recomp // Apply all the function replacements in the mod. for (const auto& replacement : mod.recompiler_context->replacements) { - recomp_func_t* to_replace = recomp::overlays::get_func_by_section_ram(replacement.original_section_vrom, replacement.original_vram); + recomp_func_t* to_replace = recomp::overlays::get_func_by_section_rom_function_vram(replacement.original_section_vrom, replacement.original_vram); if (to_replace == nullptr) { std::stringstream error_param_stream{}; diff --git a/librecomp/src/overlays.cpp b/librecomp/src/overlays.cpp index e546467..12e18e1 100644 --- a/librecomp/src/overlays.cpp +++ b/librecomp/src/overlays.cpp @@ -254,26 +254,37 @@ void recomp::overlays::init_overlays() { load_patch_functions(); } -recomp_func_t* recomp::overlays::get_func_by_section_ram(uint32_t section_rom, uint32_t function_vram) { +// Finds a function given a section's index and the function's offset into the section. +recomp_func_t* recomp::overlays::get_func_by_section_index_function_offset(uint16_t code_section_index, uint32_t function_offset) { + if (code_section_index >= sections_info.num_code_sections) { + return nullptr; + } + + SectionTableEntry* section = §ions_info.code_sections[code_section_index]; + if (function_offset >= section->size) { + return nullptr; + } + + for (size_t func_index = 0; func_index < section->num_funcs; func_index++) { + if (section->funcs[func_index].offset == function_offset) { + return section->funcs[func_index].func; + } + } + + return nullptr; +} + +// Finds a function given a section's rom address and the function's vram address. +recomp_func_t* recomp::overlays::get_func_by_section_rom_function_vram(uint32_t section_rom, uint32_t function_vram) { auto find_section_it = code_sections_by_rom.find(section_rom); if (find_section_it == code_sections_by_rom.end()) { return nullptr; } SectionTableEntry* section = §ions_info.code_sections[find_section_it->second]; - if (function_vram < section->ram_addr || function_vram >= section->ram_addr + section->size) { - return nullptr; - } - - uint32_t func_offset = function_vram - section->ram_addr; - - for (size_t func_index = 0; func_index < section->num_funcs; func_index++) { - if (section->funcs[func_index].offset == func_offset) { - return section->funcs[func_index].func; - } - } - - return nullptr; + int32_t func_offset = function_vram - section->ram_addr; + + return get_func_by_section_index_function_offset(find_section_it->second, func_offset); } extern "C" recomp_func_t * get_function(int32_t addr) {