diff --git a/Utilities/bin_patch.cpp b/Utilities/bin_patch.cpp index 49b19f5bda..7e4c0709cd 100644 --- a/Utilities/bin_patch.cpp +++ b/Utilities/bin_patch.cpp @@ -1449,6 +1449,8 @@ static usz apply_modification(std::vector& applied, patch_engine::patch_inf void patch_engine::apply(std::vector& applied_total, const std::string& name, std::function mem_translate, u32 filesz, u32 min_addr) { + applied_total.clear(); + if (!m_map.contains(name)) { return; @@ -1597,6 +1599,9 @@ void patch_engine::apply(std::vector& applied_total, const std::string& nam } } } + + // Ensure consistent order + std::sort(applied_total.begin(), applied_total.end()); } void patch_engine::unload(const std::string& name) diff --git a/rpcs3/Emu/Cell/PPUAnalyser.h b/rpcs3/Emu/Cell/PPUAnalyser.h index 9d6f4ef9ed..0b225bc821 100644 --- a/rpcs3/Emu/Cell/PPUAnalyser.h +++ b/rpcs3/Emu/Cell/PPUAnalyser.h @@ -96,6 +96,7 @@ struct ppu_module : public Type std::vector segs{}; std::vector secs{}; std::vector funcs{}; + std::vector applied_patches; std::deque> allocations; std::map addr_to_seg_index; @@ -185,7 +186,6 @@ struct main_ppu_module : public ppu_module { u32 elf_entry{}; u32 seg0_code_end{}; - std::vector applied_patches; // Disable inherited savestate ordering void save(utils::serial&) = delete; diff --git a/rpcs3/Emu/Cell/PPUModule.cpp b/rpcs3/Emu/Cell/PPUModule.cpp index d26f060b7d..48b9837ca7 100644 --- a/rpcs3/Emu/Cell/PPUModule.cpp +++ b/rpcs3/Emu/Cell/PPUModule.cpp @@ -1947,6 +1947,7 @@ shared_ptr ppu_load_prx(const ppu_prx_object& elf, bool virtual_load, c ppu_check_patch_spu_images(*prx, seg); } + prx->applied_patches = applied; prx->analyse(toc, 0, end, applied, exported_funcs); if (!ar && !virtual_load) diff --git a/rpcs3/Emu/Cell/PPUThread.cpp b/rpcs3/Emu/Cell/PPUThread.cpp index 8001b95ac4..0f7b4bcabc 100644 --- a/rpcs3/Emu/Cell/PPUThread.cpp +++ b/rpcs3/Emu/Cell/PPUThread.cpp @@ -4898,6 +4898,25 @@ bool ppu_initialize(const ppu_module& info, bool check_only, u64 file_s sha1_update(&ctx, ensure(info.get_ptr(func.addr)), func.size); } + if (!workload.empty() && fpos >= info.funcs.size()) + { + // Hash the entire function grouped addresses for the integrity of the symbol resolver function + // Potentially occuring during patches + // Avoid doing it for files with a single module such as most PRX + + std::vector> addrs(info.funcs.size() + 1); + usz addr_index = 0; + + for (const ppu_function& func : info.funcs) + { + addrs[addr_index++] = func.addr - reloc; + } + + addrs.back() = ::size32(info.funcs); + + sha1_update(&ctx, reinterpret_cast(addrs.data()), addrs.size() * sizeof(be_t)); + } + if (false) { const be_t forced_upd = 3; diff --git a/rpcs3/Emu/Cell/lv2/sys_overlay.h b/rpcs3/Emu/Cell/lv2/sys_overlay.h index ef1c1ffbd7..1c950a4d0c 100644 --- a/rpcs3/Emu/Cell/lv2/sys_overlay.h +++ b/rpcs3/Emu/Cell/lv2/sys_overlay.h @@ -11,7 +11,6 @@ struct lv2_overlay final : ppu_module u32 entry{}; u32 seg0_code_end{}; - std::vector applied_patches; lv2_overlay() = default; lv2_overlay(utils::serial&){}