1
0
mirror of https://github.com/RPCS3/rpcs3.git synced 2024-11-25 04:02:42 +01:00

Imports fixed

This commit is contained in:
Nekotekina 2015-02-28 21:47:37 +03:00
parent 72dcbefff4
commit eaf3787ae6
4 changed files with 114 additions and 14 deletions

View File

@ -663,14 +663,17 @@ namespace PPU_instr
{
using namespace lists;
//static auto LIS = std::bind(ADDIS, std::placeholders::_1, r0, std::placeholders::_2);
//static auto LI = std::bind(ADDI, std::placeholders::_1, r0, std::placeholders::_2);
static auto NOP = std::bind(ORI, r0, r0, 0);
static auto MR = std::bind(OR, std::placeholders::_1, std::placeholders::_2, std::placeholders::_2, false);
static auto BLR = std::bind(BCLR, 0x10 | 0x04, 0, 0, 0);
static auto BCTR = std::bind(BCCTR, 0x10 | 0x04, 0, 0, 0);
static auto BCTRL = std::bind(BCCTR, 0x10 | 0x04, 0, 0, 1);
static auto MTCTR = std::bind(MTSPR, (0x1 << 5) | 0x8, std::placeholders::_1);
inline u32 LIS(u32 reg, u32 imm) { return ADDIS(reg, r0, imm); }
inline u32 LI_(u32 reg, u32 imm) { return ADDI(reg, r0, imm); }
inline u32 NOP() { return ORI(r0, r0, 0); }
inline u32 MR(u32 x, u32 y) { return OR(x, y, y, false); }
inline u32 BLR() { return BCLR(0x10 | 0x04, 0, 0, 0); }
inline u32 BCTR() { return BCCTR(0x10 | 0x04, 0, 0, 0); }
inline u32 BCTRL() { return BCCTR(0x10 | 0x04, 0, 0, 1); }
inline u32 MFCTR(u32 reg) { return MFSPR(reg, 9 << 5); }
inline u32 MTCTR(u32 reg) { return MTSPR(9 << 5, reg); }
inline u32 MFLR(u32 reg) { return MFSPR(reg, 8 << 5); }
inline u32 MTLR(u32 reg) { return MTSPR(8 << 5, reg); }
inline u32 BNE(u32 cr, s32 imm) { return BC(4, 2 | cr << 2, imm, 0, 0); }
inline u32 BEQ(u32 cr, s32 imm) { return BC(12, 2 | cr << 2, imm, 0, 0); }

View File

@ -417,6 +417,102 @@ void hook_ppu_funcs(vm::ptr<u32> base, u32 size)
}
}
bool patch_ppu_import(u32 addr, u32 index)
{
const auto data = vm::ptr<const u32>::make(addr);
using namespace PPU_instr;
// check different patterns:
if (vm::check_addr(addr, 32) &&
(data[0] & 0xffff0000) == LI_(r12, 0) &&
(data[1] & 0xffff0000) == ORIS(r12, r12, 0) &&
(data[2] & 0xffff0000) == LWZ(r12, r12, 0) &&
data[3] == STD(r2, r1, 0x28) &&
data[4] == LWZ(r0, r12, 0) &&
data[5] == LWZ(r2, r12, 4) &&
data[6] == MTCTR(r0) &&
data[7] == BCTR())
{
vm::write32(addr, HACK(index | EIF_SAVE_RTOC | EIF_PERFORM_BLR));
return true;
}
if (vm::check_addr(addr, 12) &&
(data[0] & 0xffff0000) == LI_(r0, 0) &&
(data[1] & 0xffff0000) == ORIS(r0, r0, 0) &&
(data[2] & 0xfc000003) == B(0, 0, 0))
{
const auto sub = vm::ptr<const u32>::make(addr + 8 + ((s32)data[2] << 6 >> 8 << 2));
if (vm::check_addr(sub.addr(), 60) &&
sub[0x0] == STDU(r1, r1, -0x80) &&
sub[0x1] == STD(r2, r1, 0x70) &&
sub[0x2] == MR(r2, r0) &&
sub[0x3] == MFLR(r0) &&
sub[0x4] == STD(r0, r1, 0x90) &&
sub[0x5] == LWZ(r2, r2, 0) &&
sub[0x6] == LWZ(r0, r2, 0) &&
sub[0x7] == LWZ(r2, r2, 4) &&
sub[0x8] == MTCTR(r0) &&
sub[0x9] == BCTRL() &&
sub[0xa] == LD(r2, r1, 0x70) &&
sub[0xb] == ADDI(r1, r1, 0x80) &&
sub[0xc] == LD(r0, r1, 0x10) &&
sub[0xd] == MTLR(r0) &&
sub[0xe] == BLR())
{
vm::write32(addr, HACK(index | EIF_PERFORM_BLR));
return true;
}
}
if (vm::check_addr(addr, 64) &&
data[0x0] == MFLR(r0) &&
data[0x1] == STD(r0, r1, 0x10) &&
data[0x2] == STDU(r1, r1, -0x80) &&
data[0x3] == STD(r2, r1, 0x70) &&
(data[0x4] & 0xffff0000) == LI_(r2, 0) &&
(data[0x5] & 0xffff0000) == ORIS(r2, r2, 0) &&
data[0x6] == LWZ(r2, r2, 0) &&
data[0x7] == LWZ(r0, r2, 0) &&
data[0x8] == LWZ(r2, r2, 4) &&
data[0x9] == MTCTR(r0) &&
data[0xa] == BCTRL() &&
data[0xb] == LD(r2, r1, 0x70) &&
data[0xc] == ADDI(r1, r1, 0x80) &&
data[0xd] == LD(r0, r1, 0x10) &&
data[0xe] == MTLR(r0) &&
data[0xf] == BLR())
{
vm::write32(addr, HACK(index | EIF_PERFORM_BLR));
return true;
}
if (vm::check_addr(addr, 56) &&
(data[0x0] & 0xffff0000) == LI_(r12, 0) &&
(data[0x1] & 0xffff0000) == ORIS(r12, r12, 0) &&
(data[0x2] & 0xffff0000) == LWZ(r12, r12, 0) &&
data[0x3] == STD(r2, r1, 0x28) &&
data[0x4] == MFLR(r0) &&
data[0x5] == STD(r0, r1, 0x20) &&
data[0x6] == LWZ(r0, r12, 0) &&
data[0x7] == LWZ(r2, r12, 4) &&
data[0x8] == MTCTR(r0) &&
data[0x9] == BCTRL() &&
data[0xa] == LD(r0, r1, 0x20) &&
data[0xb] == MTLR(r0) &&
data[0xc] == LD(r2, r1, 0x28) &&
data[0xd] == BLR())
{
vm::write32(addr, HACK(index | EIF_PERFORM_BLR));
return true;
}
return false;
}
Module::Module(const char* name, void(*init)())
: m_is_loaded(false)
, m_name(name)

View File

@ -154,6 +154,8 @@ u32 add_ppu_func_sub(const char group[8], const SearchPatternEntry ops[], size_t
void hook_ppu_funcs(vm::ptr<u32> base, u32 size);
bool patch_ppu_import(u32 addr, u32 index);
#define REG_FUNC(module, name) add_ppu_func(ModuleFunc(get_function_id(#name), 0, &module, bind_func(name)))
#define REG_FUNC_FH(module, name) add_ppu_func(ModuleFunc(get_function_id(#name), MFF_FORCED_HLE, &module, bind_func(name)))

View File

@ -465,14 +465,10 @@ namespace loader
LOG_NOTICE(LOADER, "Imported function '%s' (0x%x)", SysCalls::GetHLEFuncName(nid), addr);
}
if (!vm::check_addr(addr, 4))
if (!patch_ppu_import(addr, index))
{
LOG_ERROR(LOADER, "Failed to inject code for function '%s' (0x%x)", SysCalls::GetHLEFuncName(nid), addr);
}
else
{
vm::write32(addr, HACK(index | EIF_SAVE_RTOC | EIF_PERFORM_BLR));
}
}
}
}
@ -686,7 +682,10 @@ namespace loader
LOG_NOTICE(LOADER, "Imported %sfunction '%s' in '%s' module (0x%x)", is_lle ? "LLE " : "", SysCalls::GetHLEFuncName(nid), module_name, addr);
}
vm::write32(addr, HACK(index | EIF_SAVE_RTOC | EIF_PERFORM_BLR));
if (!patch_ppu_import(addr, index))
{
LOG_ERROR(LOADER, "Failed to inject code at address 0x%x", addr);
}
//if (!func || !func->lle_func)
//{