PPU Analyzer: Clean addr_heap from non-relocations (PRX)

This commit is contained in:
Elad 2025-01-18 14:47:12 +02:00
parent 5a5e475c6e
commit 58701000cd

View File

@ -573,7 +573,7 @@ bool ppu_module<lv2_obj>::analyse(u32 lib_toc, u32 entry, const u32 sec_end, con
addr_heap.emplace(entry); addr_heap.emplace(entry);
} }
auto verify_func = [&](u32 addr) auto verify_ref = [&](u32 addr)
{ {
if (entry) if (entry)
{ {
@ -582,9 +582,14 @@ bool ppu_module<lv2_obj>::analyse(u32 lib_toc, u32 entry, const u32 sec_end, con
} }
// Check if the storage address exists within relocations // Check if the storage address exists within relocations
constexpr auto compare = [](const ppu_reloc& a, u32 addr) { return a.addr < addr; };
auto it = std::lower_bound(this->relocs.begin(), this->relocs.end(), (addr & -8), compare);
auto end = std::lower_bound(it, this->relocs.end(), (addr & -8) + 8, compare);
for (auto& rel : this->relocs) for (; it != end; it++)
{ {
const ppu_reloc& rel = *it;
if ((rel.addr & -8) == (addr & -8)) if ((rel.addr & -8) == (addr & -8))
{ {
if (rel.type != 38 && rel.type != 44 && (rel.addr & -4) != (addr & -4)) if (rel.type != 38 && rel.type != 44 && (rel.addr & -4) != (addr & -4))
@ -677,7 +682,7 @@ bool ppu_module<lv2_obj>::analyse(u32 lib_toc, u32 entry, const u32 sec_end, con
for (; _ptr <= seg_end;) for (; _ptr <= seg_end;)
{ {
if (ptr[1] == toc && FN(x >= start && x < end && x % 4 == 0)(ptr[0]) && verify_func(_ptr.addr())) if (ptr[1] == toc && FN(x >= start && x < end && x % 4 == 0)(ptr[0]) && verify_ref(_ptr.addr()))
{ {
// New function // New function
ppu_log.trace("OPD*: [0x%x] 0x%x (TOC=0x%x)", _ptr, ptr[0], ptr[1]); ppu_log.trace("OPD*: [0x%x] 0x%x (TOC=0x%x)", _ptr, ptr[0], ptr[1]);
@ -712,7 +717,7 @@ bool ppu_module<lv2_obj>::analyse(u32 lib_toc, u32 entry, const u32 sec_end, con
{ {
const u32 value = *ptr; const u32 value = *ptr;
if (value % 4) if (value % 4 || !verify_ref(_ptr.addr()))
{ {
continue; continue;
} }
@ -771,7 +776,7 @@ bool ppu_module<lv2_obj>::analyse(u32 lib_toc, u32 entry, const u32 sec_end, con
break; break;
} }
if (addr % 4 || addr < start || addr >= end || !verify_func(_ptr.addr())) if (addr % 4 || addr < start || addr >= end || !verify_ref(_ptr.addr()))
{ {
sec_end.set(0); sec_end.set(0);
break; break;
@ -982,7 +987,7 @@ bool ppu_module<lv2_obj>::analyse(u32 lib_toc, u32 entry, const u32 sec_end, con
const ppu_opcode_t op{*ptr}; const ppu_opcode_t op{*ptr};
const ppu_itype::type type = s_ppu_itype.decode(op.opcode); const ppu_itype::type type = s_ppu_itype.decode(op.opcode);
if ((type == ppu_itype::B || type == ppu_itype::BC) && op.lk && (!op.aa || verify_func(iaddr))) if ((type == ppu_itype::B || type == ppu_itype::BC) && op.lk && (!op.aa || verify_ref(iaddr)))
{ {
const u32 target = (op.aa ? 0 : iaddr) + (type == ppu_itype::B ? +op.bt24 : +op.bt14); const u32 target = (op.aa ? 0 : iaddr) + (type == ppu_itype::B ? +op.bt24 : +op.bt14);
@ -1041,7 +1046,7 @@ bool ppu_module<lv2_obj>::analyse(u32 lib_toc, u32 entry, const u32 sec_end, con
{ {
const u32 target = (op.aa ? 0 : iaddr) + (type == ppu_itype::B ? +op.bt24 : +op.bt14); const u32 target = (op.aa ? 0 : iaddr) + (type == ppu_itype::B ? +op.bt24 : +op.bt14);
if (target >= start && target < end && (!op.aa || verify_func(iaddr))) if (target >= start && target < end && (!op.aa || verify_ref(iaddr)))
{ {
if (target < func.addr || target >= func.addr + func.size) if (target < func.addr || target >= func.addr + func.size)
{ {
@ -1104,7 +1109,7 @@ bool ppu_module<lv2_obj>::analyse(u32 lib_toc, u32 entry, const u32 sec_end, con
continue; continue;
} }
if (target >= start && target < end && (~ptr[0] & 0x2 || verify_func(_ptr.addr()))) if (target >= start && target < end && (~ptr[0] & 0x2 || verify_ref(_ptr.addr())))
{ {
auto& new_func = add_func(target, func.toc, func.addr); auto& new_func = add_func(target, func.toc, func.addr);
@ -1132,7 +1137,7 @@ bool ppu_module<lv2_obj>::analyse(u32 lib_toc, u32 entry, const u32 sec_end, con
// Simple trampoline // Simple trampoline
const u32 target = (ptr[0] << 16) + ppu_opcode_t{ptr[1]}.simm16; const u32 target = (ptr[0] << 16) + ppu_opcode_t{ptr[1]}.simm16;
if (target >= start && target < end && verify_func(_ptr.addr())) if (target >= start && target < end && verify_ref(_ptr.addr()))
{ {
auto& new_func = add_func(target, func.toc, func.addr); auto& new_func = add_func(target, func.toc, func.addr);
@ -1202,7 +1207,7 @@ bool ppu_module<lv2_obj>::analyse(u32 lib_toc, u32 entry, const u32 sec_end, con
const u32 toc_add = (ptr[1] << 16) + s16(ptr[2]); const u32 toc_add = (ptr[1] << 16) + s16(ptr[2]);
constexpr u32 func_size = 0x1C; constexpr u32 func_size = 0x1C;
if (target >= start && target < end && verify_func((_ptr + 3).addr()) && target - func.addr >= func_size) if (target >= start && target < end && verify_ref((_ptr + 3).addr()) && target - func.addr >= func_size)
{ {
auto& new_func = add_func(target, 0, func.addr); auto& new_func = add_func(target, 0, func.addr);
@ -1249,7 +1254,7 @@ bool ppu_module<lv2_obj>::analyse(u32 lib_toc, u32 entry, const u32 sec_end, con
const u32 toc_add = (ptr[1] << 16) + s16(ptr[2]); const u32 toc_add = (ptr[1] << 16) + s16(ptr[2]);
const u32 target = (ptr[3] & 0x2 ? 0 : (_ptr + 3).addr()) + ppu_opcode_t{ptr[3]}.bt24; const u32 target = (ptr[3] & 0x2 ? 0 : (_ptr + 3).addr()) + ppu_opcode_t{ptr[3]}.bt24;
if (target >= start && target < end && (~ptr[3] & 0x2 || verify_func((_ptr + 3).addr()))) if (target >= start && target < end && (~ptr[3] & 0x2 || verify_ref((_ptr + 3).addr())))
{ {
auto& new_func = add_func(target, 0, func.addr); auto& new_func = add_func(target, 0, func.addr);
@ -1615,7 +1620,7 @@ bool ppu_module<lv2_obj>::analyse(u32 lib_toc, u32 entry, const u32 sec_end, con
{ {
const u32 target = (op.aa ? 0 : iaddr) + (type == ppu_itype::B ? +op.bt24 : +op.bt14); const u32 target = (op.aa ? 0 : iaddr) + (type == ppu_itype::B ? +op.bt24 : +op.bt14);
if (target >= start && target < end && (!op.aa || verify_func(iaddr))) if (target >= start && target < end && (!op.aa || verify_ref(iaddr)))
{ {
if (target < func.addr || target >= func.addr + func.size) if (target < func.addr || target >= func.addr + func.size)
{ {