From b334621d763cd22ba7c2c18606a78dcbb9850e9f Mon Sep 17 00:00:00 2001 From: Eladash Date: Wed, 18 May 2022 16:09:27 +0300 Subject: [PATCH] PPU DisAssembler: Prevent false function descriptor detection --- rpcs3/Emu/Cell/PPUThread.cpp | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/rpcs3/Emu/Cell/PPUThread.cpp b/rpcs3/Emu/Cell/PPUThread.cpp index 4289422744..bdf17453ec 100644 --- a/rpcs3/Emu/Cell/PPUThread.cpp +++ b/rpcs3/Emu/Cell/PPUThread.cpp @@ -866,21 +866,27 @@ std::string ppu_thread::dump_regs() const bool is_function = false; u32 toc = 0; - if (const u32 reg_ptr = *vm::get_super_ptr(static_cast(reg)); - vm::check_addr(reg_ptr)) + auto is_exec_code = [&](u32 addr) { - if ((reg | reg_ptr) % 4 == 0 && vm::check_addr(reg_ptr, vm::page_executable)) + return addr % 4 == 0 && vm::check_addr(addr, vm::page_executable) && g_ppu_itype.decode(*vm::get_super_ptr(addr)) != ppu_itype::UNK; + }; + + if (const u32 reg_ptr = *vm::get_super_ptr(static_cast(reg)); + vm::check_addr<8>(reg_ptr) && !vm::check_addr(toc, vm::page_executable)) + { + // Check executability and alignment + if (reg % 4 == 0 && is_exec_code(reg_ptr)) { toc = *vm::get_super_ptr(static_cast(reg + 4)); - if (toc % 4 == 0 && vm::check_addr(toc)) + if (toc % 4 == 0 && vm::check_addr(toc) && !vm::check_addr(toc, vm::page_executable)) { is_function = true; reg = reg_ptr; } } } - else if (reg % 4 == 0 && vm::check_addr(reg, vm::page_executable)) + else if (is_exec_code(reg)) { is_function = true; } @@ -964,7 +970,7 @@ std::string ppu_thread::dump_regs() const else fmt::append(ret, "Reservation Addr: none"); - fmt::append(ret, "Reservation Data (entire cache line):\n"); + fmt::append(ret, "\nReservation Data (entire cache line):\n"); be_t data[32]{}; std::memcpy(data, rdata, sizeof(rdata)); // Show the data even if the reservation was lost inside the atomic loop