@@ -420,9 +420,11 @@ recomp::mods::CodeModLoadError recomp::mods::DynamicLibraryCodeHandle::populate_
420420
421421recomp::mods::LiveRecompilerCodeHandle::LiveRecompilerCodeHandle (
422422 const N64Recomp::Context& context, const ModCodeHandleInputs& inputs,
423- std::unordered_map<size_t , size_t >&& entry_func_hooks, std::unordered_map<size_t , size_t >&& return_func_hooks)
423+ std::unordered_map<size_t , size_t >&& entry_func_hooks, std::unordered_map<size_t , size_t >&& return_func_hooks, std::vector< size_t >&& original_section_indices, bool regenerated )
424424{
425- section_addresses = std::make_unique<int32_t []>(context.sections .size ());
425+ if (!regenerated) {
426+ section_addresses = std::make_unique<int32_t []>(context.sections .size ());
427+ }
426428 base_event_index = inputs.base_event_index ;
427429
428430 N64Recomp::LiveGeneratorInputs recompiler_inputs{
@@ -436,10 +438,12 @@ recomp::mods::LiveRecompilerCodeHandle::LiveRecompilerCodeHandle(
436438 .pause_self = pause_self,
437439 .trigger_event = inputs.recomp_trigger_event ,
438440 .reference_section_addresses = inputs.reference_section_addresses ,
439- .local_section_addresses = section_addresses.get (),
441+ // Use the reference section addresses as the local section addresses if this is regenerated code so that jump tables work correctly.
442+ .local_section_addresses = regenerated ? inputs.reference_section_addresses : section_addresses.get (),
440443 .run_hook = run_hook,
441444 .entry_func_hooks = std::move (entry_func_hooks),
442- .return_func_hooks = std::move (return_func_hooks)
445+ .return_func_hooks = std::move (return_func_hooks),
446+ .original_section_indices = std::move (original_section_indices)
443447 };
444448
445449 N64Recomp::LiveGenerator generator{ context.functions .size (), recompiler_inputs };
@@ -759,8 +763,10 @@ std::vector<recomp::mods::ModDetails> recomp::mods::ModContext::get_mod_details(
759763struct RegeneratedSection {
760764 uint32_t rom_addr;
761765 uint32_t ram_addr;
766+ uint16_t original_index;
762767 size_t first_func_index;
763768 size_t first_reloc_index;
769+ bool relocatable;
764770};
765771
766772struct RegeneratedFunction {
@@ -824,7 +830,7 @@ N64Recomp::Context context_from_regenerated_list(const RegeneratedList& regenlis
824830 section_out.name = " patch_section_" + std::to_string (section_index);
825831 section_out.bss_section_index = 0 ;
826832 section_out.executable = true ;
827- section_out.relocatable = false ;
833+ section_out.relocatable = section_in. relocatable ;
828834 section_out.has_mips32_relocs = false ;
829835
830836 std::vector<size_t >& section_funcs_out = ret.section_functions [section_index];
@@ -1127,31 +1133,29 @@ std::vector<recomp::mods::ModLoadErrorDetails> build_regen_list(
11271133
11281134 if constexpr (patched_regenlist) {
11291135 section_ram_addr = recomp::overlays::get_patch_section_ram_addr (section_index);
1136+ cur_section_relocs = recomp::overlays::get_patch_section_relocs (section_index);
11301137 }
11311138 else {
11321139 section_ram_addr = recomp::overlays::get_section_ram_addr (section_index);
1140+ cur_section_relocs = recomp::overlays::get_section_relocs (section_index);
11331141 }
11341142
11351143 // Allocate a new section.
11361144 auto & section_out = regenlist.sections .emplace_back (RegeneratedSection{
11371145 .rom_addr = cur_hook_def.section_rom ,
11381146 .ram_addr = section_ram_addr,
1147+ .original_index = section_index,
11391148 .first_func_index = regenlist.functions .size (),
1140- .first_reloc_index = regenlist.relocs .size ()
1149+ .first_reloc_index = regenlist.relocs .size (),
1150+ // Patch sections are never relocatable, so a section is relocatable if it has any relocs and is not a base patch section.
1151+ .relocatable = !patched_regenlist && !cur_section_relocs.empty ()
11411152 });
11421153
11431154 // Update the tracked section fields.
11441155 cur_section_rom = section_out.rom_addr ;
11451156 cur_section_vram = section_out.ram_addr ;
11461157 cur_section_index = section_index;
11471158 cur_section_reloc_index = 0 ;
1148-
1149- if constexpr (patched_regenlist) {
1150- cur_section_relocs = recomp::overlays::get_patch_section_relocs (cur_section_index);
1151- }
1152- else {
1153- cur_section_relocs = recomp::overlays::get_section_relocs (cur_section_index);
1154- }
11551159
11561160 // Reset the tracked function vram to prevent issues when two functions have the same vram in different sections.
11571161 cur_function_vram = 0xFFFFFFFF ;
@@ -1292,7 +1296,15 @@ std::unique_ptr<recomp::mods::LiveRecompilerCodeHandle> apply_regenlist(Regenera
12921296 .do_break = do_break,
12931297 .reference_section_addresses = section_addresses,
12941298 };
1295- regenerated_code_handle = std::make_unique<LiveRecompilerCodeHandle>(hook_context, handle_inputs, std::move (regenlist.entry_func_hooks ), std::move (regenlist.return_func_hooks ));
1299+
1300+ std::vector<size_t > original_section_indices{};
1301+ original_section_indices.resize (regenlist.sections .size ());
1302+ for (size_t new_section_index = 0 ; new_section_index < regenlist.sections .size (); new_section_index++) {
1303+ original_section_indices[new_section_index] = regenlist.sections [new_section_index].original_index ;
1304+ }
1305+
1306+ regenerated_code_handle = std::make_unique<LiveRecompilerCodeHandle>(hook_context, handle_inputs,
1307+ std::move (regenlist.entry_func_hooks ), std::move (regenlist.return_func_hooks ), std::move (original_section_indices), true );
12961308
12971309 if (!regenerated_code_handle->good ()) {
12981310 return {};
@@ -1630,7 +1642,8 @@ recomp::mods::CodeModLoadError recomp::mods::ModContext::load_mod_code(uint8_t*
16301642 }
16311643 // Live recompiler code handle.
16321644 else {
1633- mod.code_handle = std::make_unique<LiveRecompilerCodeHandle>(*mod.recompiler_context , handle_inputs, std::move (entry_func_hooks), std::move (return_func_hooks));
1645+ mod.code_handle = std::make_unique<LiveRecompilerCodeHandle>(*mod.recompiler_context , handle_inputs,
1646+ std::move (entry_func_hooks), std::move (return_func_hooks), std::vector<size_t >{}, false );
16341647
16351648 if (!mod.code_handle ->good ()) {
16361649 mod.code_handle .reset ();
0 commit comments