mirror of
https://github.com/N64Recomp/N64Recomp.git
synced 2025-05-20 02:14:55 +00:00
Implement hook insertion (#73)
* Implement function hook insertion * Fix recompiled code indentation * Add _matherr to renamed_funcs * Replace after_vram by before_vram * Emit dummy value if relocatable_sections_ordered is empty
This commit is contained in:
parent
5c687ee962
commit
6eb7d5bd3e
6 changed files with 440 additions and 330 deletions
62
src/main.cpp
62
src/main.cpp
|
@ -628,6 +628,7 @@ std::unordered_set<std::string> renamed_funcs{
|
|||
"div64_64",
|
||||
"div64_32",
|
||||
"__moddi3",
|
||||
"_matherr",
|
||||
};
|
||||
|
||||
bool read_symbols(RecompPort::Context& context, const ELFIO::elfio& elf_file, ELFIO::section* symtab_section, uint32_t entrypoint, bool has_entrypoint, bool use_absolute_symbols) {
|
||||
|
@ -1499,6 +1500,41 @@ int main(int argc, char** argv) {
|
|||
func.words[instruction_index] = byteswap(patch.value);
|
||||
}
|
||||
|
||||
// Apply any function hooks.
|
||||
for (const RecompPort::FunctionHook& patch : config.function_hooks) {
|
||||
// Check if the specified function exists.
|
||||
auto func_find = context.functions_by_name.find(patch.func_name);
|
||||
if (func_find == context.functions_by_name.end()) {
|
||||
// Function doesn't exist, present an error to the user instead of silently failing to stub it out.
|
||||
// This helps prevent typos in the config file or functions renamed between versions from causing issues.
|
||||
exit_failure(fmt::format("Function {} has a function hook but does not exist!", patch.func_name));
|
||||
}
|
||||
|
||||
RecompPort::Function& func = context.functions[func_find->second];
|
||||
int32_t func_vram = func.vram;
|
||||
|
||||
// Check that the function actually contains this vram address.
|
||||
if (patch.before_vram < func_vram || patch.before_vram >= func_vram + func.words.size() * sizeof(func.words[0])) {
|
||||
exit_failure(fmt::format("Function {} has a function hook for vram 0x{:08X} but doesn't contain that vram address!", patch.func_name, (uint32_t)patch.before_vram));
|
||||
}
|
||||
|
||||
// No after_vram means this will be placed at the start of the function
|
||||
size_t instruction_index = -1;
|
||||
|
||||
// Calculate the instruction index.
|
||||
if (patch.before_vram != 0) {
|
||||
instruction_index = (static_cast<size_t>(patch.before_vram) - func_vram) / sizeof(uint32_t);
|
||||
}
|
||||
|
||||
// Check if a function hook already exits for that instruction index.
|
||||
auto hook_find = func.function_hooks.find(instruction_index);
|
||||
if (hook_find != func.function_hooks.end()) {
|
||||
exit_failure(fmt::format("Function {} already has a function hook for vram 0x{:08X}!", patch.func_name, (uint32_t)patch.before_vram));
|
||||
}
|
||||
|
||||
func.function_hooks[instruction_index] = patch.text;
|
||||
}
|
||||
|
||||
std::ofstream single_output_file;
|
||||
|
||||
if (config.single_file_output) {
|
||||
|
@ -1700,18 +1736,22 @@ int main(int argc, char** argv) {
|
|||
|
||||
|
||||
fmt::print(overlay_file, "static int overlay_sections_by_index[] = {{\n");
|
||||
for (const std::string& section : relocatable_sections_ordered) {
|
||||
// Check if this is an empty overlay
|
||||
if (section == "*") {
|
||||
fmt::print(overlay_file, " -1,\n");
|
||||
}
|
||||
else {
|
||||
auto find_it = relocatable_section_indices.find(section);
|
||||
if (find_it == relocatable_section_indices.end()) {
|
||||
fmt::print(stderr, "Failed to find written section index of relocatable section: {}\n", section);
|
||||
std::exit(EXIT_FAILURE);
|
||||
if (relocatable_sections_ordered.empty()) {
|
||||
fmt::print(overlay_file, " -1,\n");
|
||||
} else {
|
||||
for (const std::string& section : relocatable_sections_ordered) {
|
||||
// Check if this is an empty overlay
|
||||
if (section == "*") {
|
||||
fmt::print(overlay_file, " -1,\n");
|
||||
}
|
||||
else {
|
||||
auto find_it = relocatable_section_indices.find(section);
|
||||
if (find_it == relocatable_section_indices.end()) {
|
||||
fmt::print(stderr, "Failed to find written section index of relocatable section: {}\n", section);
|
||||
std::exit(EXIT_FAILURE);
|
||||
}
|
||||
fmt::print(overlay_file, " {},\n", relocatable_section_indices[section]);
|
||||
}
|
||||
fmt::print(overlay_file, " {},\n", relocatable_section_indices[section]);
|
||||
}
|
||||
}
|
||||
fmt::print(overlay_file, "}};\n");
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue