mirror of
https://github.com/N64Recomp/N64Recomp.git
synced 2026-04-27 04:21:51 +00:00
Merge b1be38310b into 81213c1831
This commit is contained in:
commit
cc84b2f891
5 changed files with 30 additions and 4 deletions
|
|
@ -235,6 +235,8 @@ namespace N64Recomp {
|
||||||
bool skip_validating_reference_symbols = true;
|
bool skip_validating_reference_symbols = true;
|
||||||
// Whether all function calls (excluding reference symbols) should go through lookup.
|
// Whether all function calls (excluding reference symbols) should go through lookup.
|
||||||
bool use_lookup_for_all_function_calls = false;
|
bool use_lookup_for_all_function_calls = false;
|
||||||
|
// Whether function calls between relocatable sections is allowed.
|
||||||
|
bool cross_relocatable_section_function_calls = false;
|
||||||
|
|
||||||
//// Only used by the CLI, TODO move this to a struct in the internal headers.
|
//// Only used by the CLI, TODO move this to a struct in the internal headers.
|
||||||
// A mapping of function name to index in the functions vector
|
// A mapping of function name to index in the functions vector
|
||||||
|
|
|
||||||
|
|
@ -417,6 +417,15 @@ N64Recomp::Config::Config(const char* path) {
|
||||||
use_mdebug = false;
|
use_mdebug = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Whether function calls across relocatable sections is allowed (optional)
|
||||||
|
std::optional<bool> cross_relocatable_section_function_calls_opt = input_data["cross_relocatable_section_function_calls"].value<bool>();
|
||||||
|
if (cross_relocatable_section_function_calls_opt.has_value()) {
|
||||||
|
cross_relocatable_section_function_calls = cross_relocatable_section_function_calls_opt.value();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
cross_relocatable_section_function_calls = false;
|
||||||
|
}
|
||||||
|
|
||||||
// Symbols to ignore when parsing mdebug (option, defaults to empty)
|
// Symbols to ignore when parsing mdebug (option, defaults to empty)
|
||||||
toml::node_view mdebug_mappings_data = input_data["mdebug_file_mappings"];
|
toml::node_view mdebug_mappings_data = input_data["mdebug_file_mappings"];
|
||||||
if (mdebug_mappings_data.is_array()) {
|
if (mdebug_mappings_data.is_array()) {
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,7 @@ namespace N64Recomp {
|
||||||
bool use_absolute_symbols;
|
bool use_absolute_symbols;
|
||||||
bool unpaired_lo16_warnings;
|
bool unpaired_lo16_warnings;
|
||||||
bool use_mdebug;
|
bool use_mdebug;
|
||||||
|
bool cross_relocatable_section_function_calls;
|
||||||
bool trace_mode;
|
bool trace_mode;
|
||||||
bool allow_exports;
|
bool allow_exports;
|
||||||
bool strict_patch_mode;
|
bool strict_patch_mode;
|
||||||
|
|
|
||||||
|
|
@ -524,7 +524,8 @@ int main(int argc, char** argv) {
|
||||||
func->name = func->name + "_recomp";
|
func->name = func->name + "_recomp";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Propogate the trace mode parameter.
|
// Propagate config params.
|
||||||
|
context.cross_relocatable_section_function_calls = config.cross_relocatable_section_function_calls;
|
||||||
context.trace_mode = config.trace_mode;
|
context.trace_mode = config.trace_mode;
|
||||||
|
|
||||||
// Apply any single-instruction patches.
|
// Apply any single-instruction patches.
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ enum class JalResolutionResult {
|
||||||
Match,
|
Match,
|
||||||
CreateStatic,
|
CreateStatic,
|
||||||
Ambiguous,
|
Ambiguous,
|
||||||
|
AmbiguousWithRelocatable,
|
||||||
Error
|
Error
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -34,6 +35,7 @@ JalResolutionResult resolve_jal(const N64Recomp::Context& context, size_t cur_se
|
||||||
uint32_t section_vram_end = cur_section.ram_addr + cur_section.size;
|
uint32_t section_vram_end = cur_section.ram_addr + cur_section.size;
|
||||||
bool in_current_section = target_func_vram >= section_vram_start && target_func_vram < section_vram_end;
|
bool in_current_section = target_func_vram >= section_vram_start && target_func_vram < section_vram_end;
|
||||||
bool exact_match_found = false;
|
bool exact_match_found = false;
|
||||||
|
bool found_relocatable_match = false;
|
||||||
|
|
||||||
// Use a thread local to prevent reallocation across runs and to allow multi-threading in the future.
|
// Use a thread local to prevent reallocation across runs and to allow multi-threading in the future.
|
||||||
thread_local std::vector<size_t> matched_funcs{};
|
thread_local std::vector<size_t> matched_funcs{};
|
||||||
|
|
@ -59,10 +61,13 @@ JalResolutionResult resolve_jal(const N64Recomp::Context& context, size_t cur_se
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the function's section isn't relocatable, add the function as a candidate.
|
// If the function's section isn't relocatable or if cross relocatable section function calls are enabled, add the function as a candidate.
|
||||||
const auto& target_func_section = context.sections[target_func.section_index];
|
const auto& target_func_section = context.sections[target_func.section_index];
|
||||||
if (!target_func_section.relocatable) {
|
if (context.cross_relocatable_section_function_calls || !target_func_section.relocatable) {
|
||||||
matched_funcs.push_back(target_func_index);
|
matched_funcs.push_back(target_func_index);
|
||||||
|
if (target_func_section.relocatable) {
|
||||||
|
found_relocatable_match = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -93,6 +98,11 @@ JalResolutionResult resolve_jal(const N64Recomp::Context& context, size_t cur_se
|
||||||
}
|
}
|
||||||
// If there's more than one match, use an indirect jump to resolve the function at runtime.
|
// If there's more than one match, use an indirect jump to resolve the function at runtime.
|
||||||
else {
|
else {
|
||||||
|
// Ambiguous matches where any of the matches are in a relocatable section must be reported differently than normal ambiguous matches.
|
||||||
|
// This is because the loaded address of the function may not be the original address, so a lookup using the original address would fail.
|
||||||
|
if (found_relocatable_match) {
|
||||||
|
return JalResolutionResult::AmbiguousWithRelocatable;
|
||||||
|
}
|
||||||
return JalResolutionResult::Ambiguous;
|
return JalResolutionResult::Ambiguous;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -162,7 +172,7 @@ bool process_instruction(GeneratorType& generator, const N64Recomp::Context& con
|
||||||
uint16_t imm = instr.Get_immediate();
|
uint16_t imm = instr.Get_immediate();
|
||||||
|
|
||||||
// Check if this instruction has a reloc.
|
// Check if this instruction has a reloc.
|
||||||
if (section.relocs.size() > 0 && section.relocs[reloc_index].address == instr_vram) {
|
if (section.relocs.size() > 0 && section.relocs[reloc_index].address == instr_vram && section.relocs[reloc_index].type != N64Recomp::RelocType::R_MIPS_NONE) {
|
||||||
has_reloc = true;
|
has_reloc = true;
|
||||||
// Get the reloc data for this instruction
|
// Get the reloc data for this instruction
|
||||||
const auto& reloc = section.relocs[reloc_index];
|
const auto& reloc = section.relocs[reloc_index];
|
||||||
|
|
@ -326,6 +336,9 @@ bool process_instruction(GeneratorType& generator, const N64Recomp::Context& con
|
||||||
// If a game ever needs to jump between multiple relocatable sections, relocation will be necessary here.
|
// If a game ever needs to jump between multiple relocatable sections, relocation will be necessary here.
|
||||||
call_by_lookup = true;
|
call_by_lookup = true;
|
||||||
break;
|
break;
|
||||||
|
case JalResolutionResult::AmbiguousWithRelocatable:
|
||||||
|
fmt::print(stderr, "Ambiguous jal target 0x{:08X} in function {}, but one or more matches were relocatable. Calling by lookup for relocatable functions with the unrelocated address is not supported.\n", target_func_vram, func.name);
|
||||||
|
return false;
|
||||||
case JalResolutionResult::Error:
|
case JalResolutionResult::Error:
|
||||||
fmt::print(stderr, "Internal error when resolving jal to address 0x{:08X} in function {}. Please report this issue.\n", target_func_vram, func.name);
|
fmt::print(stderr, "Internal error when resolving jal to address 0x{:08X} in function {}. Please report this issue.\n", target_func_vram, func.name);
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue