From d6e014b3a9addf7743c59a80b25ec252c1d617a8 Mon Sep 17 00:00:00 2001 From: Elad <18193363+elad335@users.noreply.github.com> Date: Tue, 7 Jan 2025 13:41:41 +0200 Subject: [PATCH] PPU LLVM: Function table dependent resolver hashing --- Utilities/bin_patch.cpp | 5 +++++ rpcs3/Emu/Cell/PPUAnalyser.h | 2 +- rpcs3/Emu/Cell/PPUModule.cpp | 1 + rpcs3/Emu/Cell/PPUThread.cpp | 19 ++++++++++++++++--- rpcs3/Emu/Cell/lv2/sys_overlay.h | 1 - 5 files changed, 23 insertions(+), 5 deletions(-) diff --git a/Utilities/bin_patch.cpp b/Utilities/bin_patch.cpp index 49b19f5bda..f106a8afb9 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::stable_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..8278954b75 100644 --- a/rpcs3/Emu/Cell/PPUThread.cpp +++ b/rpcs3/Emu/Cell/PPUThread.cpp @@ -4898,6 +4898,22 @@ 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 (fpos >= info.funcs.size()) + { + // Hash the entire function grouped addresses for the integrity of the symbol resolver function + // Potentially occuring during patches + + std::vector> addrs(info.funcs.size()); + usz addr_index = 0; + + for (const ppu_function& func : info.funcs) + { + addrs[addr_index] = func.addr; + } + + sha1_update(&ctx, addrs.data(), addrs.size() * sizeof(be_t)); + } + if (false) { const be_t forced_upd = 3; @@ -4920,7 +4936,6 @@ bool ppu_initialize(const ppu_module& info, bool check_only, u64 file_s accurate_fpcc, accurate_vnan, accurate_nj_mode, - contains_symbol_resolver, __bitset_enum_max }; @@ -4950,8 +4965,6 @@ bool ppu_initialize(const ppu_module& info, bool check_only, u64 file_s settings += ppu_settings::accurate_vnan, settings -= ppu_settings::fixup_vnan, fmt::throw_exception("VNAN Not implemented"); if (g_cfg.core.ppu_use_nj_bit) settings += ppu_settings::accurate_nj_mode, settings -= ppu_settings::fixup_nj_denormals, fmt::throw_exception("NJ Not implemented"); - if (fpos >= info.funcs.size()) - settings += ppu_settings::contains_symbol_resolver; // Avoid invalidating all modules for this purpose // Write version, hash, CPU, settings fmt::append(obj_name, "v6-kusa-%s-%s-%s.obj", fmt::base57(output, 16), fmt::base57(settings), jit_compiler::cpu(g_cfg.core.llvm_cpu)); 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&){}