Sprx: loading / reloc fixes

This commit is contained in:
Jake 2017-06-18 23:59:02 -05:00 committed by Ivan
parent 03268b0838
commit d3df83a3ea
5 changed files with 117 additions and 16 deletions

View File

@ -1081,7 +1081,7 @@ bool SELFDecrypter::DecryptNPDRM(u8 *metadata, u32 metadata_size)
// If not, the data has no NPDRM layer.
if (!ctrl)
{
LOG_WARNING(LOADER, "SELF: No NPDRM control info found!");
LOG_NOTICE(LOADER, "SELF: No NPDRM control info found!");
return true;
}

View File

@ -576,6 +576,16 @@ extern std::string ppu_get_syscall_name(u64 code)
// Get function name by FNID
extern std::string ppu_get_function_name(const std::string& module, u32 fnid)
{
if (module == "") switch (fnid)
{
// these arent the actual hash, but its close enough
case 0x0D10FD3F: return "module_prologue";
case 0x330F7005: return "module_epilogue";
case 0x3ab9a95e: return "module_exit";
case 0xBC9A0086: return "module_start";
case 0xAB779874: return "module_stop";
}
// Check known FNIDs
if (module == "sys_libc" || module == "sys_libm") switch (fnid)
{
@ -2363,6 +2373,78 @@ extern std::string ppu_get_function_name(const std::string& module, u32 fnid)
// Get variable name by VNID
extern std::string ppu_get_variable_name(const std::string& module, u32 vnid)
{
if (module == "") switch (vnid)
{
// these arent the actual hash, but its close enough
case 0xD7F43016: return "module_info";
}
// Check known FNIDs
if (module == "sys_libc") switch (vnid)
{
case 0x071928B0: return "_LNan";
case 0x0A331920: return "_Clocale";
case 0x0B2E15ED: return "_malloc_limit";
case 0x0FBC732D: return "_Zero";
case 0x17667744: return "_LInf";
case 0x210B2F6E: return "_FNan";
case 0x2418F6C0: return "__TT800";
case 0x2470D3BC: return "_Hugeval";
case 0x26A34F81: return "_Flt";
case 0x277A84BB: return "_Mutex_attr";
case 0x29E76A6D: return "_LXbig";
case 0x2CF8B5D1: return "_Wctrans";
case 0x32E56B1A: return "_Stdin";
case 0x3916A06A: return "_FILE_P_Head";
case 0x45EC2DF6: return "_LEps";
case 0x529D4301: return "_Denorm";
case 0x57DBCF27: return "_Inf";
case 0x5FF11EB4: return "_FZero";
case 0x620967C9: return "_Mbcurmax";
case 0x6524499E: return "_FInf";
case 0x67D1406B: return "__ctype_ptr";
case 0x6A09DF41: return "_LRteps";
case 0x73898DB8: return "environ";
case 0x76628EFB: return "_FSnan";
case 0x790B0082: return "_Xbig";
case 0x7AFF3242: return "_Snan";
case 0x7BC88211: return "_Tolotab";
case 0x7F456AF2: return "_Rteps";
case 0x81ACF7C1: return "_LZero";
case 0x8F87ED0C: return "_Times";
case 0x92C43F6D: return "_Eps";
case 0x96E1E748: return "tls_mutex_attr";
case 0x985FC057: return "_Dbl";
case 0x9C8454C9: return "_LSnan";
case 0xAA860D4C: return "_Wctype";
case 0xB5B84F80: return "_LDenorm";
case 0xB5D2F53B: return "_Touptab";
case 0xB6F5F98C: return "_FRteps";
case 0xD59C193C: return "_Nan";
case 0xD698385D: return "_Ldbl";
case 0xD97B0687: return "_Ctype";
case 0xE0BC8D86: return "_Loctab";
case 0xEACE53D6: return "_FDenorm";
case 0xECA056DF: return "_Locale";
case 0xEF25075B: return "_FXbig";
case 0xFB2BD688: return "_Stdout";
case 0xFEFBE065: return "_Stderr";
case 0xFF2F0CC7: return "_FEps";
}
if (module == "sys_libm") switch (vnid)
{
case 0x1CF745BC: return "_LErf_one";
case 0x2259EF96: return "_LGamma_big";
case 0x3ACAD7F1: return "_Erf_small";
case 0x3FB8629D: return "_FErf_one";
case 0x42EB9508: return "_Fenv0";
case 0x4AF28F31: return "_FErf_small";
case 0xA8D907FF: return "_LErf_small";
case 0xAD443E79: return "_Erf_one";
case 0xE9892674: return "_FGamma_big";
case 0xF39005FC: return "_Gamma_big";
}
// Check registered variables
if (const auto sm = ppu_module_manager::get_module(module))
{

View File

@ -348,26 +348,26 @@ static void ppu_patch_variable_refs(u32 vref, u32 vaddr)
{
be_t<u32> type;
be_t<u32> addr;
be_t<u32> unk0;
be_t<u32> addend; // Note: Treating it as addend seems to be correct for now, but still unknown if theres more in this variable
};
for (auto ref = vm::ptr<vref_t>::make(vref); ref->type; ref++)
{
if (ref->unk0) LOG_ERROR(LOADER, "**** VREF(%u): Unknown values (0x%x, 0x%x)", ref->type, ref->addr, ref->unk0);
if (ref->addend) LOG_WARNING(LOADER, "**** VREF(%u): Addend value(0x%x, 0x%x)", ref->type, ref->addr, ref->addend);
// OPs are probably similar to relocations
switch (u32 type = ref->type)
{
case 0x1:
{
const u32 value = vm::_ref<u32>(ref->addr) = vaddr;
const u32 value = vm::_ref<u32>(ref->addr) = vaddr + ref->addend;
LOG_WARNING(LOADER, "**** VREF(1): 0x%x <- 0x%x", ref->addr, value);
break;
}
case 0x4:
case 0x6:
default: LOG_ERROR(LOADER, "**** VREF(%u): Unknown/Illegal type (0x%x, 0x%x)", ref->type, ref->addr, ref->unk0);
default: LOG_ERROR(LOADER, "**** VREF(%u): Unknown/Illegal type (0x%x, 0x%x)", ref->type, ref->addr, ref->addend);
}
}
}
@ -723,52 +723,66 @@ std::shared_ptr<lv2_prx> ppu_load_prx(const ppu_prx_object& elf, const std::stri
switch (const u32 type = rel.type)
{
case 1:
case 1: // R_PPC64_ADDR32
{
const u32 value = vm::_ref<u32>(raddr) = static_cast<u32>(rdata);
LOG_TRACE(LOADER, "**** RELOCATION(1): 0x%x <- 0x%08x (0x%llx)", raddr, value, rdata);
break;
}
case 4:
case 4: //R_PPC64_ADDR16_LO
{
const u16 value = vm::_ref<u16>(raddr) = static_cast<u16>(rdata);
LOG_TRACE(LOADER, "**** RELOCATION(4): 0x%x <- 0x%04x (0x%llx)", raddr, value, rdata);
break;
}
case 5:
case 5: //R_PPC64_ADDR16_HI
{
const u16 value = vm::_ref<u16>(raddr) = static_cast<u16>(rdata >> 16);
LOG_TRACE(LOADER, "**** RELOCATION(5): 0x%x <- 0x%04x (0x%llx)", raddr, value, rdata);
break;
}
case 6:
case 6: //R_PPC64_ADDR16_HA
{
const u16 value = vm::_ref<u16>(raddr) = static_cast<u16>(rdata >> 16) + (rdata & 0x8000 ? 1 : 0);
LOG_TRACE(LOADER, "**** RELOCATION(6): 0x%x <- 0x%04x (0x%llx)", raddr, value, rdata);
break;
}
case 10:
case 10: //R_PPC64_REL24
{
const u32 value = vm::_ref<ppu_bf_t<be_t<u32>, 6, 24>>(raddr) = static_cast<u32>(rdata - raddr) >> 2;
LOG_WARNING(LOADER, "**** RELOCATION(10): 0x%x <- 0x%06x (0x%llx)", raddr, value, rdata);
break;
}
case 44:
case 11: //R_PPC64_REL14
{
const u32 value = vm::_ref<ppu_bf_t<be_t<u32>, 16, 14>>(raddr) = static_cast<u32>(rdata - raddr) >> 2;
LOG_WARNING(LOADER, "**** RELOCATION(11): 0x%x <- 0x%06x (0x%llx)", raddr, value, rdata);
break;
}
case 38: //R_PPC64_ADDR64
{
const u64 value = vm::_ref<u64>(raddr) = rdata;
LOG_TRACE(LOADER, "**** RELOCATION(38): 0x%x <- 0x%016llx (0x%llx)", raddr, value, rdata);
break;
}
case 44: //R_PPC64_REL64
{
const u64 value = vm::_ref<u64>(raddr) = rdata - raddr;
LOG_TRACE(LOADER, "**** RELOCATION(44): 0x%x <- 0x%016llx (0x%llx)", raddr, value, rdata);
break;
}
case 57:
case 57: //R_PPC64_ADDR16_LO_DS
{
const u16 value = vm::_ref<ppu_bf_t<be_t<u16>, 0, 14>>(raddr) = static_cast<u16>(rdata) >> 2;
LOG_WARNING(LOADER, "**** RELOCATION(57): 0x%x <- 0x%04x (0x%llx)", raddr, value, rdata);
LOG_TRACE(LOADER, "**** RELOCATION(57): 0x%x <- 0x%04x (0x%llx)", raddr, value, rdata);
break;
}
@ -821,6 +835,8 @@ std::shared_ptr<lv2_prx> ppu_load_prx(const ppu_prx_object& elf, const std::stri
prx->start.set(prx->specials[0xbc9a0086]);
prx->stop.set(prx->specials[0xab779874]);
prx->exit.set(prx->specials[0x3ab9a95e]);
prx->prologue.set(prx->specials[0x0D10FD3F]);
prx->epilogue.set(prx->specials[0x330F7005]);
prx->name = name;
return prx;
}

View File

@ -196,7 +196,7 @@ error_code _sys_prx_start_module(u32 id, u64 flags, vm::ptr<sys_prx_start_stop_m
//prx->is_started = true;
pOpt->entry.set(prx->start ? prx->start.addr() : ~0ull);
pOpt->entry2.set(prx->prologue ? prx->prologue.addr() : ~0ull);
return CELL_OK;
}
@ -216,6 +216,7 @@ error_code _sys_prx_stop_module(u32 id, u64 flags, vm::ptr<sys_prx_start_stop_mo
//prx->is_started = false;
pOpt->entry.set(prx->stop ? prx->stop.addr() : ~0ull);
pOpt->entry2.set(prx->epilogue ? prx->epilogue.addr() : ~0ull);
return CELL_OK;
}

View File

@ -118,6 +118,8 @@ struct lv2_prx final : lv2_obj, ppu_module
vm::ps3::ptr<s32(u32 argc, vm::ps3::ptr<void> argv)> start = vm::null;
vm::ps3::ptr<s32(u32 argc, vm::ps3::ptr<void> argv)> stop = vm::null;
vm::ps3::ptr<s32(u64 callback, u64 argc, vm::ps3::ptr<void, u64> argv)> prologue = vm::null;
vm::ps3::ptr<s32(u64 callback, u64 argc, vm::ps3::ptr<void, u64> argv)> epilogue = vm::null;
vm::ps3::ptr<s32()> exit = vm::null;
};