Patches/PPU: Extend and improve patching capabilities (code allocations, jumps to any address) (#10779)

* Patches/PPU: Implement dynamic code allocation + Any-Address jump patches

Also fix deallocation path of fixed allocation patches.
This commit is contained in:
Eladash 2021-09-01 13:38:17 +03:00 committed by GitHub
parent ee6e4c493d
commit b40ed5bdb7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 339 additions and 72 deletions

View file

@ -528,6 +528,8 @@ struct ppu_prx_module_info
be_t<u32> unk5;
};
bool ppu_form_branch_to_code(u32 entry, u32 target);
// Load and register exports; return special exports found (nameless module)
static auto ppu_load_exports(ppu_linkage_info* link, u32 exports_start, u32 exports_end)
{
@ -612,20 +614,7 @@ static auto ppu_load_exports(ppu_linkage_info* link, u32 exports_start, u32 expo
// Set exported function
flink.export_addr = target - 4;
if ((target <= _entry && _entry - target <= 0x2000000) || (target > _entry && target - _entry < 0x2000000))
{
// Use relative branch
vm::write32(_entry, ppu_instructions::B(target - _entry));
}
else if (target < 0x2000000)
{
// Use absolute branch if possible
vm::write32(_entry, ppu_instructions::B(target, true));
}
else
{
ppu_loader.fatal("Failed to patch function at 0x%x (0x%x)", _entry, target);
}
ppu_form_branch_to_code(faddr, target);
}
else
{
@ -1267,9 +1256,25 @@ void ppu_unload_prx(const lv2_prx& prx)
// }
//}
// Format patch name
std::string hash = fmt::format("PRX-%s", fmt::base57(prx.sha1));
for (auto& seg : prx.segs)
{
if (!seg.size) continue;
vm::dealloc(seg.addr, vm::main);
const std::string hash_seg = fmt::format("%s-%u", hash, &seg - prx.segs.data());
// Deallocatte memory used for patches
g_fxo->get<patch_engine>().unload(hash_seg);
if (!Emu.GetTitleID().empty())
{
// Alternative patch
g_fxo->get<patch_engine>().unload(Emu.GetTitleID() + '-' + hash_seg);
}
}
}