mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-03-01 16:13:23 +00:00
PPU Analyser fix
This commit is contained in:
parent
7a1fd27ecc
commit
ed7883ba07
@ -467,8 +467,8 @@ std::vector<ppu_function> ppu_analyse(const std::vector<std::pair<u32, u32>>& se
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Secondary attempt (TODO, needs better strategy)
|
// Secondary attempt
|
||||||
if (/*secs.empty() &&*/ lib_toc)
|
if (TOCs.empty() && lib_toc)
|
||||||
{
|
{
|
||||||
add_toc(lib_toc);
|
add_toc(lib_toc);
|
||||||
}
|
}
|
||||||
@ -598,7 +598,7 @@ std::vector<ppu_function> ppu_analyse(const std::vector<std::pair<u32, u32>>& se
|
|||||||
|
|
||||||
if (ptr + 1 <= fend && (ptr[0] & 0xfc000001) == B({}, {}))
|
if (ptr + 1 <= fend && (ptr[0] & 0xfc000001) == B({}, {}))
|
||||||
{
|
{
|
||||||
// Simple gate
|
// Simple trampoline
|
||||||
const u32 target = (ptr[0] & 0x2 ? 0 : ptr.addr()) + ppu_opcode_t{ptr[0]}.bt24;
|
const u32 target = (ptr[0] & 0x2 ? 0 : ptr.addr()) + ppu_opcode_t{ptr[0]}.bt24;
|
||||||
|
|
||||||
if (target == func.addr)
|
if (target == func.addr)
|
||||||
@ -612,7 +612,7 @@ std::vector<ppu_function> ppu_analyse(const std::vector<std::pair<u32, u32>>& se
|
|||||||
|
|
||||||
if (target >= start && target < end)
|
if (target >= start && target < end)
|
||||||
{
|
{
|
||||||
auto& new_func = add_func(target, func.toc, func.addr);
|
auto& new_func = add_func(target, 0, func.addr);
|
||||||
|
|
||||||
if (new_func.blocks.empty())
|
if (new_func.blocks.empty())
|
||||||
{
|
{
|
||||||
@ -623,8 +623,8 @@ std::vector<ppu_function> ppu_analyse(const std::vector<std::pair<u32, u32>>& se
|
|||||||
func.size = 0x4;
|
func.size = 0x4;
|
||||||
func.blocks.emplace(func.addr, func.size);
|
func.blocks.emplace(func.addr, func.size);
|
||||||
func.attr += new_func.attr & ppu_attr::no_return;
|
func.attr += new_func.attr & ppu_attr::no_return;
|
||||||
func.called_from.emplace(target);
|
func.calls.emplace(target);
|
||||||
func.gate_target = target;
|
func.trampoline = target;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -635,12 +635,12 @@ std::vector<ppu_function> ppu_analyse(const std::vector<std::pair<u32, u32>>& se
|
|||||||
ptr[2] == MTCTR(r11) &&
|
ptr[2] == MTCTR(r11) &&
|
||||||
ptr[3] == BCTR())
|
ptr[3] == BCTR())
|
||||||
{
|
{
|
||||||
// Simple gate
|
// 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)
|
if (target >= start && target < end)
|
||||||
{
|
{
|
||||||
auto& new_func = add_func(target, func.toc, func.addr);
|
auto& new_func = add_func(target, 0, func.addr);
|
||||||
|
|
||||||
if (new_func.blocks.empty())
|
if (new_func.blocks.empty())
|
||||||
{
|
{
|
||||||
@ -651,8 +651,8 @@ std::vector<ppu_function> ppu_analyse(const std::vector<std::pair<u32, u32>>& se
|
|||||||
func.size = 0x10;
|
func.size = 0x10;
|
||||||
func.blocks.emplace(func.addr, func.size);
|
func.blocks.emplace(func.addr, func.size);
|
||||||
func.attr += new_func.attr & ppu_attr::no_return;
|
func.attr += new_func.attr & ppu_attr::no_return;
|
||||||
func.called_from.emplace(target);
|
func.calls.emplace(target);
|
||||||
func.gate_target = target;
|
func.trampoline = target;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -663,7 +663,7 @@ std::vector<ppu_function> ppu_analyse(const std::vector<std::pair<u32, u32>>& se
|
|||||||
(ptr[2] & 0xffff0000) == ADDI(r2, r2, {}) &&
|
(ptr[2] & 0xffff0000) == ADDI(r2, r2, {}) &&
|
||||||
(ptr[3] & 0xfc000001) == B({}, {}))
|
(ptr[3] & 0xfc000001) == B({}, {}))
|
||||||
{
|
{
|
||||||
// TOC change gate
|
// Trampoline with TOC
|
||||||
const u32 new_toc = func.toc && func.toc != -1 ? func.toc + (ptr[1] << 16) + s16(ptr[2]) : 0;
|
const u32 new_toc = func.toc && func.toc != -1 ? func.toc + (ptr[1] << 16) + s16(ptr[2]) : 0;
|
||||||
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;
|
||||||
|
|
||||||
@ -671,7 +671,7 @@ std::vector<ppu_function> ppu_analyse(const std::vector<std::pair<u32, u32>>& se
|
|||||||
{
|
{
|
||||||
add_toc(new_toc);
|
add_toc(new_toc);
|
||||||
|
|
||||||
auto& new_func = add_func(target, new_toc, func.addr);
|
auto& new_func = add_func(target, 0, func.addr);
|
||||||
|
|
||||||
if (new_func.blocks.empty())
|
if (new_func.blocks.empty())
|
||||||
{
|
{
|
||||||
@ -682,8 +682,8 @@ std::vector<ppu_function> ppu_analyse(const std::vector<std::pair<u32, u32>>& se
|
|||||||
func.size = 0x10;
|
func.size = 0x10;
|
||||||
func.blocks.emplace(func.addr, func.size);
|
func.blocks.emplace(func.addr, func.size);
|
||||||
func.attr += new_func.attr & ppu_attr::no_return;
|
func.attr += new_func.attr & ppu_attr::no_return;
|
||||||
func.called_from.emplace(target);
|
func.calls.emplace(target);
|
||||||
func.gate_target = target;
|
func.trampoline = target;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -699,6 +699,7 @@ std::vector<ppu_function> ppu_analyse(const std::vector<std::pair<u32, u32>>& se
|
|||||||
ptr[7] == BCTR())
|
ptr[7] == BCTR())
|
||||||
{
|
{
|
||||||
// The most used simple import stub
|
// The most used simple import stub
|
||||||
|
func.toc = -1;
|
||||||
func.size = 0x20;
|
func.size = 0x20;
|
||||||
func.blocks.emplace(func.addr, func.size);
|
func.blocks.emplace(func.addr, func.size);
|
||||||
func.attr += ppu_attr::known_addr;
|
func.attr += ppu_attr::known_addr;
|
||||||
@ -717,7 +718,7 @@ std::vector<ppu_function> ppu_analyse(const std::vector<std::pair<u32, u32>>& se
|
|||||||
p2[6] == MTCTR(r0) &&
|
p2[6] == MTCTR(r0) &&
|
||||||
p2[7] == BCTR())
|
p2[7] == BCTR())
|
||||||
{
|
{
|
||||||
auto& next = add_func(p2.addr(), 0, func.addr);
|
auto& next = add_func(p2.addr(), -1, func.addr);
|
||||||
next.size = 0x20;
|
next.size = 0x20;
|
||||||
next.blocks.emplace(next.addr, next.size);
|
next.blocks.emplace(next.addr, next.size);
|
||||||
next.attr += ppu_attr::known_addr;
|
next.attr += ppu_attr::known_addr;
|
||||||
@ -1017,8 +1018,8 @@ std::vector<ppu_function> ppu_analyse(const std::vector<std::pair<u32, u32>>& se
|
|||||||
{
|
{
|
||||||
if (target < func.addr || target >= func.addr + func.size)
|
if (target < func.addr || target >= func.addr + func.size)
|
||||||
{
|
{
|
||||||
func.called_from.emplace(target);
|
func.calls.emplace(target);
|
||||||
add_func(target, func.toc, func.addr);
|
add_func(target, 0, func.addr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,10 +29,10 @@ struct ppu_function
|
|||||||
bs_t<ppu_attr> attr{};
|
bs_t<ppu_attr> attr{};
|
||||||
|
|
||||||
u32 stack_frame = 0;
|
u32 stack_frame = 0;
|
||||||
u32 gate_target = 0;
|
u32 trampoline = 0;
|
||||||
|
|
||||||
std::map<u32, u32> blocks; // Basic blocks: addr -> size
|
std::map<u32, u32> blocks; // Basic blocks: addr -> size
|
||||||
std::set<u32> called_from; // Set of called functions
|
std::set<u32> calls; // Set of called functions
|
||||||
};
|
};
|
||||||
|
|
||||||
// PPU Module Information
|
// PPU Module Information
|
||||||
|
@ -1252,7 +1252,7 @@ void ppu_load_exec(const ppu_exec_object& elf)
|
|||||||
|
|
||||||
{
|
{
|
||||||
// Analyse executable
|
// Analyse executable
|
||||||
std::vector<ppu_function> main_funcs = ppu_analyse(segments, sections, 0);
|
std::vector<ppu_function> main_funcs = ppu_analyse(segments, sections, vm::read32(elf.header.e_entry + 4));
|
||||||
|
|
||||||
ppu_validate(vfs::get(Emu.GetPath()), main_funcs, 0);
|
ppu_validate(vfs::get(Emu.GetPath()), main_funcs, 0);
|
||||||
|
|
||||||
|
@ -129,7 +129,7 @@ static bool ppu_fallback(ppu_thread& ppu, ppu_opcode_t op)
|
|||||||
{
|
{
|
||||||
if (g_cfg_ppu_decoder.get() == ppu_decoder_type::llvm)
|
if (g_cfg_ppu_decoder.get() == ppu_decoder_type::llvm)
|
||||||
{
|
{
|
||||||
fmt::throw_exception("Unregistered PPU function [0x%08x]", ppu.cia);
|
fmt::throw_exception("Unregistered PPU function");
|
||||||
}
|
}
|
||||||
|
|
||||||
ppu_ref(ppu.cia) = ppu_cache(ppu.cia);
|
ppu_ref(ppu.cia) = ppu_cache(ppu.cia);
|
||||||
@ -141,7 +141,7 @@ extern void ppu_register_range(u32 addr, u32 size)
|
|||||||
if (!size)
|
if (!size)
|
||||||
{
|
{
|
||||||
LOG_ERROR(PPU, "ppu_register_range(0x%x): empty range", addr);
|
LOG_ERROR(PPU, "ppu_register_range(0x%x): empty range", addr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Register executable range at
|
// Register executable range at
|
||||||
|
Loading…
x
Reference in New Issue
Block a user