@@ -505,18 +505,20 @@ recomp::mods::LiveRecompilerCodeHandle::LiveRecompilerCodeHandle(
505505 N64Recomp::LiveGenerator generator{ context.functions .size (), recompiler_inputs };
506506 std::vector<std::vector<uint32_t >> dummy_static_funcs{};
507507
508+ bool errored = false ;
509+
508510 for (size_t func_index = 0 ; func_index < context.functions .size (); func_index++) {
509511 std::ostringstream dummy_ostream{};
510512
511513 if (!N64Recomp::recompile_function_live (generator, context, func_index, dummy_ostream, dummy_static_funcs, true )) {
512- is_good = false ;
514+ errored = true ;
513515 break ;
514516 }
515517 }
516518
517519 // Generate the code.
518520 recompiler_output = std::make_unique<N64Recomp::LiveGeneratorOutput>(generator.finish ());
519- is_good = recompiler_output->good ;
521+ is_good = !errored && recompiler_output->good ;
520522}
521523
522524void recomp::mods::LiveRecompilerCodeHandle::set_imported_function (size_t import_index, GenericFunction func) {
@@ -2125,22 +2127,28 @@ recomp::mods::CodeModLoadError recomp::mods::ModContext::init_mod_code(uint8_t*
21252127 int32_t cur_section_addr = load_address;
21262128 for (size_t section_index = 0 ; section_index < mod_sections.size (); section_index++) {
21272129 const auto & section = mod_sections[section_index];
2128- for (size_t i = 0 ; i < section.size ; i++) {
2129- MEM_B (i, (gpr)cur_section_addr) = binary_data[section.rom_addr + i];
2130+ // Do not load fixed address sections into mod memory. Use their address as-is.
2131+ if (section.fixed_address ) {
2132+ mod.section_load_addresses [section_index] = section.ram_addr ;
21302133 }
2131- mod.section_load_addresses [section_index] = cur_section_addr;
2132- // Calculate the bss section's address based on the size of this section.
2133- cur_section_addr += section.size ;
2134- // Zero the bss section.
2135- for (size_t i = 0 ; i < section.bss_size ; i++) {
2136- MEM_B (i, (gpr)cur_section_addr) = 0 ;
2134+ else {
2135+ for (size_t i = 0 ; i < section.size ; i++) {
2136+ MEM_B (i, (gpr)cur_section_addr) = binary_data[section.rom_addr + i];
2137+ }
2138+ mod.section_load_addresses [section_index] = cur_section_addr;
2139+ // Calculate the bss section's address based on the size of this section.
2140+ cur_section_addr += section.size ;
2141+ // Zero the bss section.
2142+ for (size_t i = 0 ; i < section.bss_size ; i++) {
2143+ MEM_B (i, (gpr)cur_section_addr) = 0 ;
2144+ }
2145+ // Calculate the next section's address based on the size of the bss section.
2146+ cur_section_addr += section.bss_size ;
2147+ // Align the next section's address to 16 bytes.
2148+ cur_section_addr = (cur_section_addr + 15 ) & ~15 ;
2149+ // Add some empty space between mods to act as a buffer for misbehaving mods that have out of bounds accesses.
2150+ cur_section_addr += 0x400 ;
21372151 }
2138- // Calculate the next section's address based on the size of the bss section.
2139- cur_section_addr += section.bss_size ;
2140- // Align the next section's address to 16 bytes.
2141- cur_section_addr = (cur_section_addr + 15 ) & ~15 ;
2142- // Add some empty space between mods to act as a buffer for misbehaving mods that have out of bounds accesses.
2143- cur_section_addr += 0x400 ;
21442152 }
21452153
21462154 // Iterate over each section again after loading them to perform R_MIPS_32 relocations.
@@ -2203,7 +2211,7 @@ recomp::mods::CodeModLoadError recomp::mods::ModContext::load_mod_code(uint8_t*
22032211 std::unordered_map<size_t , size_t > entry_func_hooks{};
22042212 std::unordered_map<size_t , size_t > return_func_hooks{};
22052213
2206- // Scan the replacements and check for any
2214+ // Scan the replacements to handle hooks on the replaced functions.
22072215 for (const auto & replacement : mod.recompiler_context ->replacements ) {
22082216 // Check if there's a hook slot for the entry of this function.
22092217 HookDefinition entry_def {
0 commit comments