mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-20 11:36:13 +00:00
PPU Analyzer: Clean addr_heap fron non-valid code
Should speed up analysis in some cases.
This commit is contained in:
parent
86b7078464
commit
181c92a868
1 changed files with 52 additions and 3 deletions
|
@ -566,6 +566,7 @@ bool ppu_module<lv2_obj>::analyse(u32 lib_toc, u32 entry, const u32 sec_end, con
|
|||
std::vector<std::reference_wrapper<ppu_function_ext>> func_queue;
|
||||
|
||||
// Known references (within segs, addr and value alignment = 4)
|
||||
// For seg0, must be valid code
|
||||
std::set<u32> addr_heap;
|
||||
|
||||
if (entry)
|
||||
|
@ -621,6 +622,49 @@ bool ppu_module<lv2_obj>::analyse(u32 lib_toc, u32 entry, const u32 sec_end, con
|
|||
return true;
|
||||
};
|
||||
|
||||
auto is_valid_code = [](std::span<const be_t<u32>> range, bool is_fixed_addr, u32 /*cia*/)
|
||||
{
|
||||
for (usz index = 0; index < std::min<usz>(range.size(), 10); index++)
|
||||
{
|
||||
const ppu_opcode_t op{+range[index]};
|
||||
|
||||
switch (g_ppu_itype.decode(op.opcode))
|
||||
{
|
||||
case ppu_itype::UNK:
|
||||
{
|
||||
return false;
|
||||
}
|
||||
case ppu_itype::BC:
|
||||
case ppu_itype::B:
|
||||
{
|
||||
if (!is_fixed_addr && op.aa)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
case ppu_itype::BCCTR:
|
||||
case ppu_itype::BCLR:
|
||||
{
|
||||
if (op.opcode & 0xe000)
|
||||
{
|
||||
// Garbage filter
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
// Register new function
|
||||
auto add_func = [&](u32 addr, u32 toc, u32 caller) -> ppu_function_ext&
|
||||
{
|
||||
|
@ -713,6 +757,7 @@ bool ppu_module<lv2_obj>::analyse(u32 lib_toc, u32 entry, const u32 sec_end, con
|
|||
};
|
||||
|
||||
// Find references indiscriminately
|
||||
// For seg0, must be valid code
|
||||
for (const auto& seg : segs)
|
||||
{
|
||||
if (seg.size < 4) continue;
|
||||
|
@ -732,10 +777,15 @@ bool ppu_module<lv2_obj>::analyse(u32 lib_toc, u32 entry, const u32 sec_end, con
|
|||
|
||||
for (const auto& _seg : segs)
|
||||
{
|
||||
if (!_seg.addr) continue;
|
||||
if (!_seg.size) continue;
|
||||
|
||||
if (value >= start && value < end)
|
||||
{
|
||||
if (is_valid_code({ ptr, ptr + (end - value) }, entry != 0, _ptr.addr()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
addr_heap.emplace(value);
|
||||
break;
|
||||
}
|
||||
|
@ -1001,8 +1051,7 @@ bool ppu_module<lv2_obj>::analyse(u32 lib_toc, u32 entry, const u32 sec_end, con
|
|||
|
||||
if (target >= start && target < end && target != iaddr && target != iaddr + 4)
|
||||
{
|
||||
// TODO: Check full executability
|
||||
if (s_ppu_itype.decode(get_ref<u32>(target)) != ppu_itype::UNK)
|
||||
if (is_valid_code({ get_ptr<u32>(target), get_ptr<u32>(end - 4) }, entry != 0, target))
|
||||
{
|
||||
ppu_log.trace("Enqueued PPU function 0x%x using a caller at 0x%x", target, iaddr);
|
||||
add_func(target, 0, 0);
|
||||
|
|
Loading…
Add table
Reference in a new issue