mirror of
				https://github.com/N64Recomp/N64ModernRuntime.git
				synced 2025-10-30 08:02:29 +00:00 
			
		
		
		
	Fix jump table handling in regenerated relocatable functions (#86)
This commit is contained in:
		
							parent
							
								
									5360099ee2
								
							
						
					
					
						commit
						0afeb089a5
					
				
					 3 changed files with 30 additions and 17 deletions
				
			
		|  | @ -1 +1 @@ | ||||||
| Subproject commit 198de1b5cf6e58415948588584750c51562d58dd | Subproject commit 8781eb44acbf55cb6a109d2aa5529aadb95a419d | ||||||
|  | @ -419,7 +419,7 @@ namespace recomp { | ||||||
|         class LiveRecompilerCodeHandle : public ModCodeHandle { |         class LiveRecompilerCodeHandle : public ModCodeHandle { | ||||||
|         public: |         public: | ||||||
|             LiveRecompilerCodeHandle(const N64Recomp::Context& context, const ModCodeHandleInputs& inputs, |             LiveRecompilerCodeHandle(const N64Recomp::Context& context, const ModCodeHandleInputs& inputs, | ||||||
|                 std::unordered_map<size_t, size_t>&& entry_func_hooks, std::unordered_map<size_t, size_t>&& return_func_hooks); |                 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); | ||||||
| 
 | 
 | ||||||
|             ~LiveRecompilerCodeHandle() = default; |             ~LiveRecompilerCodeHandle() = default; | ||||||
|              |              | ||||||
|  |  | ||||||
|  | @ -420,9 +420,11 @@ recomp::mods::CodeModLoadError recomp::mods::DynamicLibraryCodeHandle::populate_ | ||||||
| 
 | 
 | ||||||
| recomp::mods::LiveRecompilerCodeHandle::LiveRecompilerCodeHandle( | recomp::mods::LiveRecompilerCodeHandle::LiveRecompilerCodeHandle( | ||||||
|     const N64Recomp::Context& context, const ModCodeHandleInputs& inputs, |     const N64Recomp::Context& context, const ModCodeHandleInputs& inputs, | ||||||
|     std::unordered_map<size_t, size_t>&& entry_func_hooks, std::unordered_map<size_t, size_t>&& return_func_hooks) |     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) | ||||||
| { | { | ||||||
|     section_addresses = std::make_unique<int32_t[]>(context.sections.size()); |     if (!regenerated) { | ||||||
|  |        section_addresses = std::make_unique<int32_t[]>(context.sections.size()); | ||||||
|  |     } | ||||||
|     base_event_index = inputs.base_event_index; |     base_event_index = inputs.base_event_index; | ||||||
| 
 | 
 | ||||||
|     N64Recomp::LiveGeneratorInputs recompiler_inputs{ |     N64Recomp::LiveGeneratorInputs recompiler_inputs{ | ||||||
|  | @ -436,10 +438,12 @@ recomp::mods::LiveRecompilerCodeHandle::LiveRecompilerCodeHandle( | ||||||
|         .pause_self = pause_self, |         .pause_self = pause_self, | ||||||
|         .trigger_event = inputs.recomp_trigger_event, |         .trigger_event = inputs.recomp_trigger_event, | ||||||
|         .reference_section_addresses = inputs.reference_section_addresses, |         .reference_section_addresses = inputs.reference_section_addresses, | ||||||
|         .local_section_addresses = section_addresses.get(), |         // Use the reference section addresses as the local section addresses if this is regenerated code so that jump tables work correctly.
 | ||||||
|  |         .local_section_addresses = regenerated ? inputs.reference_section_addresses : section_addresses.get(), | ||||||
|         .run_hook = run_hook, |         .run_hook = run_hook, | ||||||
|         .entry_func_hooks = std::move(entry_func_hooks), |         .entry_func_hooks = std::move(entry_func_hooks), | ||||||
|         .return_func_hooks = std::move(return_func_hooks) |         .return_func_hooks = std::move(return_func_hooks), | ||||||
|  |         .original_section_indices = std::move(original_section_indices) | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     N64Recomp::LiveGenerator generator{ context.functions.size(), recompiler_inputs }; |     N64Recomp::LiveGenerator generator{ context.functions.size(), recompiler_inputs }; | ||||||
|  | @ -759,8 +763,10 @@ std::vector<recomp::mods::ModDetails> recomp::mods::ModContext::get_mod_details( | ||||||
| struct RegeneratedSection { | struct RegeneratedSection { | ||||||
|     uint32_t rom_addr; |     uint32_t rom_addr; | ||||||
|     uint32_t ram_addr; |     uint32_t ram_addr; | ||||||
|  |     uint16_t original_index; | ||||||
|     size_t first_func_index; |     size_t first_func_index; | ||||||
|     size_t first_reloc_index; |     size_t first_reloc_index; | ||||||
|  |     bool relocatable; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| struct RegeneratedFunction { | struct RegeneratedFunction { | ||||||
|  | @ -824,7 +830,7 @@ N64Recomp::Context context_from_regenerated_list(const RegeneratedList& regenlis | ||||||
|         section_out.name = "patch_section_" + std::to_string(section_index); |         section_out.name = "patch_section_" + std::to_string(section_index); | ||||||
|         section_out.bss_section_index = 0; |         section_out.bss_section_index = 0; | ||||||
|         section_out.executable = true; |         section_out.executable = true; | ||||||
|         section_out.relocatable = false; |         section_out.relocatable = section_in.relocatable; | ||||||
|         section_out.has_mips32_relocs = false; |         section_out.has_mips32_relocs = false; | ||||||
| 
 | 
 | ||||||
|         std::vector<size_t>& section_funcs_out = ret.section_functions[section_index]; |         std::vector<size_t>& section_funcs_out = ret.section_functions[section_index]; | ||||||
|  | @ -1127,17 +1133,22 @@ std::vector<recomp::mods::ModLoadErrorDetails> build_regen_list( | ||||||
| 
 | 
 | ||||||
|             if constexpr (patched_regenlist) { |             if constexpr (patched_regenlist) { | ||||||
|                 section_ram_addr = recomp::overlays::get_patch_section_ram_addr(section_index); |                 section_ram_addr = recomp::overlays::get_patch_section_ram_addr(section_index); | ||||||
|  |                 cur_section_relocs = recomp::overlays::get_patch_section_relocs(section_index); | ||||||
|             } |             } | ||||||
|             else { |             else { | ||||||
|                 section_ram_addr = recomp::overlays::get_section_ram_addr(section_index); |                 section_ram_addr = recomp::overlays::get_section_ram_addr(section_index); | ||||||
|  |                 cur_section_relocs = recomp::overlays::get_section_relocs(section_index); | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             // Allocate a new section.
 |             // Allocate a new section.
 | ||||||
|             auto& section_out = regenlist.sections.emplace_back(RegeneratedSection{ |             auto& section_out = regenlist.sections.emplace_back(RegeneratedSection{ | ||||||
|                 .rom_addr = cur_hook_def.section_rom, |                 .rom_addr = cur_hook_def.section_rom, | ||||||
|                 .ram_addr = section_ram_addr, |                 .ram_addr = section_ram_addr, | ||||||
|  |                 .original_index = section_index, | ||||||
|                 .first_func_index = regenlist.functions.size(), |                 .first_func_index = regenlist.functions.size(), | ||||||
|                 .first_reloc_index = regenlist.relocs.size() |                 .first_reloc_index = regenlist.relocs.size(), | ||||||
|  |                 // Patch sections are never relocatable, so a section is relocatable if it has any relocs and is not a base patch section.
 | ||||||
|  |                 .relocatable = !patched_regenlist && !cur_section_relocs.empty() | ||||||
|             }); |             }); | ||||||
| 
 | 
 | ||||||
|             // Update the tracked section fields.
 |             // Update the tracked section fields.
 | ||||||
|  | @ -1145,13 +1156,6 @@ std::vector<recomp::mods::ModLoadErrorDetails> build_regen_list( | ||||||
|             cur_section_vram = section_out.ram_addr; |             cur_section_vram = section_out.ram_addr; | ||||||
|             cur_section_index = section_index; |             cur_section_index = section_index; | ||||||
|             cur_section_reloc_index = 0; |             cur_section_reloc_index = 0; | ||||||
| 
 |  | ||||||
|             if constexpr (patched_regenlist) { |  | ||||||
|                 cur_section_relocs = recomp::overlays::get_patch_section_relocs(cur_section_index); |  | ||||||
|             } |  | ||||||
|             else { |  | ||||||
|                 cur_section_relocs = recomp::overlays::get_section_relocs(cur_section_index); |  | ||||||
|             } |  | ||||||
|          |          | ||||||
|             // Reset the tracked function vram to prevent issues when two functions have the same vram in different sections.
 |             // Reset the tracked function vram to prevent issues when two functions have the same vram in different sections.
 | ||||||
|             cur_function_vram = 0xFFFFFFFF; |             cur_function_vram = 0xFFFFFFFF; | ||||||
|  | @ -1292,7 +1296,15 @@ std::unique_ptr<recomp::mods::LiveRecompilerCodeHandle> apply_regenlist(Regenera | ||||||
|         .do_break = do_break, |         .do_break = do_break, | ||||||
|         .reference_section_addresses = section_addresses, |         .reference_section_addresses = section_addresses, | ||||||
|     }; |     }; | ||||||
|     regenerated_code_handle = std::make_unique<LiveRecompilerCodeHandle>(hook_context, handle_inputs, std::move(regenlist.entry_func_hooks), std::move(regenlist.return_func_hooks)); | 
 | ||||||
|  |     std::vector<size_t> original_section_indices{};  | ||||||
|  |     original_section_indices.resize(regenlist.sections.size()); | ||||||
|  |     for (size_t new_section_index = 0; new_section_index < regenlist.sections.size(); new_section_index++) { | ||||||
|  |         original_section_indices[new_section_index] = regenlist.sections[new_section_index].original_index; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     regenerated_code_handle = std::make_unique<LiveRecompilerCodeHandle>(hook_context, handle_inputs, | ||||||
|  |         std::move(regenlist.entry_func_hooks), std::move(regenlist.return_func_hooks), std::move(original_section_indices), true); | ||||||
| 
 | 
 | ||||||
|     if (!regenerated_code_handle->good()) { |     if (!regenerated_code_handle->good()) { | ||||||
|         return {}; |         return {}; | ||||||
|  | @ -1630,7 +1642,8 @@ recomp::mods::CodeModLoadError recomp::mods::ModContext::load_mod_code(uint8_t* | ||||||
|     } |     } | ||||||
|     // Live recompiler code handle.
 |     // Live recompiler code handle.
 | ||||||
|     else { |     else { | ||||||
|         mod.code_handle = std::make_unique<LiveRecompilerCodeHandle>(*mod.recompiler_context, handle_inputs, std::move(entry_func_hooks), std::move(return_func_hooks)); |         mod.code_handle = std::make_unique<LiveRecompilerCodeHandle>(*mod.recompiler_context, handle_inputs, | ||||||
|  |             std::move(entry_func_hooks), std::move(return_func_hooks), std::vector<size_t>{}, false); | ||||||
|          |          | ||||||
|         if (!mod.code_handle->good()) { |         if (!mod.code_handle->good()) { | ||||||
|             mod.code_handle.reset(); |             mod.code_handle.reset(); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 Wiseguy
						Wiseguy