diff --git a/include/recompiler/context.h b/include/recompiler/context.h index 0d0009b..b30fcf8 100644 --- a/include/recompiler/context.h +++ b/include/recompiler/context.h @@ -566,11 +566,6 @@ namespace N64Recomp { all_reference_sections_relocatable = true; } - bool is_manual_patch_symbol(uint32_t vram) const { - // Zero-sized symbols between 0x8F000000 and 0x90000000 are manually specified symbols for use with patches. - // TODO make this configurable or come up with a more sensible solution for dealing with manual symbols for patches. - return vram >= 0x8F000000 && vram < 0x90000000; - } }; class Generator; @@ -587,6 +582,12 @@ namespace N64Recomp { ModSymbolsError parse_mod_symbols(std::span data, std::span binary, const std::unordered_map& sections_by_vrom, Context& context_out); std::vector symbols_to_bin_v1(const Context& mod_context); + + inline bool is_manual_patch_symbol(uint32_t vram) { + // Zero-sized symbols between 0x8F000000 and 0x90000000 are manually specified symbols for use with patches. + // TODO make this configurable or come up with a more sensible solution for dealing with manual symbols for patches. + return vram >= 0x8F000000 && vram < 0x90000000; + } inline bool validate_mod_id(std::string_view str) { // Disallow empty ids. diff --git a/src/main.cpp b/src/main.cpp index aa28864..65ed8f8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -923,10 +923,26 @@ int main(int argc, char** argv) { // Write the section's relocations. if (!section_relocs.empty()) { + // Determine if reference symbols are being used. + bool reference_symbol_mode = !config.func_reference_syms_file_path.empty(); + fmt::print(overlay_file, "static RelocEntry {}[] = {{\n", section_relocs_array_name); for (const N64Recomp::Reloc& reloc : section_relocs) { - if (reloc.target_section != N64Recomp::SectionAbsolute || context.is_manual_patch_symbol(reloc.target_section_offset)) { + bool emit_reloc = false; + uint16_t target_section = reloc.target_section; + // In reference symbol mode, only emit relocations into the table that point to + // non-absolute reference symbols, events, or manual patch symbols. + if (reference_symbol_mode) { + bool manual_patch_symbol = N64Recomp::is_manual_patch_symbol(reloc.target_section_offset); + bool is_absolute = reloc.target_section == N64Recomp::SectionAbsolute; + emit_reloc = (reloc.reference_symbol && !is_absolute) || target_section == N64Recomp::SectionEvent || manual_patch_symbol; + } + // Otherwise, emit all relocs. + else { + emit_reloc = true; + } + if (emit_reloc) { uint32_t target_section_offset; if (reloc.target_section == N64Recomp::SectionEvent) { target_section_offset = reloc.symbol_index; @@ -1010,7 +1026,7 @@ int main(int argc, char** argv) { std::vector> manual_patch_syms{}; for (const auto& func : context.functions) { - if (func.words.empty() && context.is_manual_patch_symbol(func.vram)) { + if (func.words.empty() && N64Recomp::is_manual_patch_symbol(func.vram)) { manual_patch_syms.emplace_back(func.vram, func.name); } } diff --git a/src/recompilation.cpp b/src/recompilation.cpp index ceb8496..8720837 100644 --- a/src/recompilation.cpp +++ b/src/recompilation.cpp @@ -46,7 +46,7 @@ JalResolutionResult resolve_jal(const N64Recomp::Context& context, size_t cur_se // Zero-sized symbol handling. unless there's only one matching target. if (target_func.words.empty()) { - if (!context.is_manual_patch_symbol(target_func.vram)) { + if (!N64Recomp::is_manual_patch_symbol(target_func.vram)) { continue; } }