Update N64Recomp for live recompiler, refactor reference symbol handling in preparation of live recompiled mods

This commit is contained in:
Mr-Wiseguy 2024-12-28 15:54:50 -05:00
parent 1361c48f59
commit b018d16366
4 changed files with 34 additions and 26 deletions

@ -1 +1 @@
Subproject commit d5ab74220da3d8468d6873ed29afbcad03b890f5 Subproject commit 1bb41ec136b5ad89c3e6ab1ed46e4cbf1c98bd0d

View file

@ -258,7 +258,7 @@ namespace recomp {
virtual bool good() = 0; virtual bool good() = 0;
virtual uint32_t get_api_version() = 0; virtual uint32_t get_api_version() = 0;
virtual void set_imported_function(size_t import_index, GenericFunction func) = 0; virtual void set_imported_function(size_t import_index, GenericFunction func) = 0;
virtual void set_reference_symbol_pointer(size_t symbol_index, recomp_func_t* ptr) = 0; virtual CodeModLoadError populate_reference_symbols(const N64Recomp::Context& recompiler_context, std::string& error_param) = 0;
virtual void set_base_event_index(uint32_t global_event_index) = 0; virtual void set_base_event_index(uint32_t global_event_index) = 0;
virtual uint32_t get_base_event_index() = 0; virtual uint32_t get_base_event_index() = 0;
virtual void set_recomp_trigger_event_pointer(void (*ptr)(uint8_t* rdram, recomp_context* ctx, uint32_t index)) = 0; virtual void set_recomp_trigger_event_pointer(void (*ptr)(uint8_t* rdram, recomp_context* ctx, uint32_t index)) = 0;
@ -333,9 +333,7 @@ namespace recomp {
bool good() final; bool good() final;
uint32_t get_api_version() final; uint32_t get_api_version() final;
void set_imported_function(size_t import_index, GenericFunction func) final; void set_imported_function(size_t import_index, GenericFunction func) final;
void set_reference_symbol_pointer(size_t symbol_index, recomp_func_t* ptr) final { CodeModLoadError populate_reference_symbols(const N64Recomp::Context& context, std::string& error_param) final;
reference_symbol_funcs[symbol_index] = ptr;
};
void set_base_event_index(uint32_t global_event_index) final { void set_base_event_index(uint32_t global_event_index) final {
*base_event_index = global_event_index; *base_event_index = global_event_index;
}; };

View file

@ -2,7 +2,7 @@
#include "json/json.hpp" #include "json/json.hpp"
#include "n64recomp.h" #include "recompiler/context.h"
#include "librecomp/mods.hpp" #include "librecomp/mods.hpp"
recomp::mods::ZipModFileHandle::~ZipModFileHandle() { recomp::mods::ZipModFileHandle::~ZipModFileHandle() {

View file

@ -6,7 +6,7 @@
#include "librecomp/mods.hpp" #include "librecomp/mods.hpp"
#include "librecomp/overlays.hpp" #include "librecomp/overlays.hpp"
#include "librecomp/game.hpp" #include "librecomp/game.hpp"
#include "n64recomp.h" #include "recompiler/context.h"
// Architecture detection. // Architecture detection.
@ -389,6 +389,28 @@ void recomp::mods::NativeCodeHandle::set_imported_function(size_t import_index,
}, func); }, func);
} }
recomp::mods::CodeModLoadError recomp::mods::NativeCodeHandle::populate_reference_symbols(const N64Recomp::Context& context, std::string& error_param) {
size_t reference_symbol_index = 0;
for (const auto& section : context.sections) {
for (const auto& reloc : section.relocs) {
if (reloc.type == N64Recomp::RelocType::R_MIPS_26 && reloc.reference_symbol && context.is_regular_reference_section(reloc.target_section)) {
recomp_func_t* cur_func = recomp::overlays::get_func_by_section_index_function_offset(reloc.target_section, reloc.target_section_offset);
if (cur_func == nullptr) {
std::stringstream error_param_stream{};
error_param_stream << std::hex <<
"section: " << reloc.target_section <<
" func offset: 0x" << reloc.target_section_offset;
error_param = error_param_stream.str();
return CodeModLoadError::InvalidReferenceSymbol;
}
reference_symbol_funcs[reference_symbol_index] = cur_func;
reference_symbol_index++;
}
}
}
return CodeModLoadError::Good;
}
void patch_func(recomp_func_t* target_func, recomp::mods::GenericFunction replacement_func) { void patch_func(recomp_func_t* target_func, recomp::mods::GenericFunction replacement_func) {
uint8_t* target_func_u8 = reinterpret_cast<uint8_t*>(target_func); uint8_t* target_func_u8 = reinterpret_cast<uint8_t*>(target_func);
size_t offset = 0; size_t offset = 0;
@ -953,25 +975,13 @@ recomp::mods::CodeModLoadError recomp::mods::ModContext::load_mod_code(uint8_t*
} }
recomp::mods::CodeModLoadError recomp::mods::ModContext::resolve_code_dependencies(recomp::mods::ModHandle& mod, std::string& error_param) { recomp::mods::CodeModLoadError recomp::mods::ModContext::resolve_code_dependencies(recomp::mods::ModHandle& mod, std::string& error_param) {
// Reference symbols from the base recomp.1:1 with relocs for offline mods. // Reference symbols.
// TODO this won't be needed for LuaJIT recompilation, so move this logic into the code handle. std::string reference_syms_error_param{};
size_t reference_symbol_index = 0; CodeModLoadError reference_syms_error = mod.code_handle->populate_reference_symbols(*mod.recompiler_context, reference_syms_error_param);
for (const auto& section : mod.recompiler_context->sections) {
for (const auto& reloc : section.relocs) { if (reference_syms_error != CodeModLoadError::Good) {
if (reloc.type == N64Recomp::RelocType::R_MIPS_26 && reloc.reference_symbol && mod.recompiler_context->is_regular_reference_section(reloc.target_section)) { error_param = std::move(reference_syms_error_param);
recomp_func_t* cur_func = recomp::overlays::get_func_by_section_index_function_offset(reloc.target_section, reloc.target_section_offset); return reference_syms_error;
if (cur_func == nullptr) {
std::stringstream error_param_stream{};
error_param_stream << std::hex <<
"section: " << reloc.target_section <<
" func offset: 0x" << reloc.target_section_offset;
error_param = error_param_stream.str();
return CodeModLoadError::InvalidReferenceSymbol;
}
mod.code_handle->set_reference_symbol_pointer(reference_symbol_index, cur_func);
reference_symbol_index++;
}
}
} }
// Create a list of dependencies ordered by their index in the recompiler context. // Create a list of dependencies ordered by their index in the recompiler context.