diff --git a/rpcs3/Emu/Cell/PPUAnalyser.cpp b/rpcs3/Emu/Cell/PPUAnalyser.cpp index 7f4dbc3ab5..21d3221ff0 100644 --- a/rpcs3/Emu/Cell/PPUAnalyser.cpp +++ b/rpcs3/Emu/Cell/PPUAnalyser.cpp @@ -529,11 +529,15 @@ namespace ppu_patterns }; } -void ppu_module::analyse(u32 lib_toc, u32 entry) +void ppu_module::analyse(u32 lib_toc, u32 entry, u32 end) { // Assume first segment is executable const u32 start = segs[0].addr; - const u32 end = segs[0].addr + segs[0].size; + + if (end == umax) + { + end = segs[0].addr + segs[0].size; + } // Known TOCs (usually only 1) std::unordered_set TOCs; @@ -1565,6 +1569,12 @@ void ppu_module::analyse(u32 lib_toc, u32 entry) block.size = size; block.toc = func.toc; ppu_log.trace("Block __0x%x added (func=0x%x, size=0x%x, toc=0x%x)", block.addr, _, block.size, block.toc); + + if (!entry) + { + // Workaround for SPRX: update end to the last found function + end = block.addr + block.size; + } } } diff --git a/rpcs3/Emu/Cell/PPUAnalyser.h b/rpcs3/Emu/Cell/PPUAnalyser.h index 24314acf60..86d0d42cd9 100644 --- a/rpcs3/Emu/Cell/PPUAnalyser.h +++ b/rpcs3/Emu/Cell/PPUAnalyser.h @@ -89,7 +89,7 @@ struct ppu_module secs = info.secs; } - void analyse(u32 lib_toc, u32 entry); + void analyse(u32 lib_toc, u32 entry, u32 end = -1); void validate(u32 reloc); }; diff --git a/rpcs3/Emu/Cell/PPUModule.cpp b/rpcs3/Emu/Cell/PPUModule.cpp index 6a89d1d874..fb00c1110e 100644 --- a/rpcs3/Emu/Cell/PPUModule.cpp +++ b/rpcs3/Emu/Cell/PPUModule.cpp @@ -1058,7 +1058,7 @@ std::shared_ptr ppu_load_prx(const ppu_prx_object& elf, const std::stri prx->specials = ppu_load_exports(link, lib_info->exports_start, lib_info->exports_end); prx->imports = ppu_load_imports(prx->relocs, link, lib_info->imports_start, lib_info->imports_end); std::stable_sort(prx->relocs.begin(), prx->relocs.end()); - prx->analyse(lib_info->toc, 0); + prx->analyse(lib_info->toc, 0, std::min(lib_info.addr(), prx->segs[0].addr + prx->segs[0].size)); } else {