Misc: Pattern match to find the bios thread address

This commit is contained in:
ty 2021-05-09 22:08:56 -04:00 committed by lightningterror
parent 91acaa2555
commit 54590a843a
5 changed files with 51 additions and 71 deletions

View File

@ -21,10 +21,11 @@ std::vector<EEThread> getEEThreads()
{ {
std::vector<EEThread> threads; std::vector<EEThread> threads;
if (CurrentBiosInformation == NULL) if (CurrentBiosInformation.threadListAddr <= 0)
return threads; return threads;
u32 start = CurrentBiosInformation->threadListAddr & 0x3fffff; const u32 start = CurrentBiosInformation.threadListAddr & 0x3fffff;
for (int tid = 0; tid < 256; tid++) for (int tid = 0; tid < 256; tid++)
{ {
EEThread thread; EEThread thread;
@ -40,4 +41,3 @@ std::vector<EEThread> getEEThreads()
return threads; return threads;
} }

View File

@ -982,8 +982,43 @@ void SYSCALL()
case Syscall::SetVTLBRefillHandler: case Syscall::SetVTLBRefillHandler:
DevCon.Warning("A tlb refill handler is set. New handler %x", (u32*)PSM(cpuRegs.GPR.n.a1.UL[0])); DevCon.Warning("A tlb refill handler is set. New handler %x", (u32*)PSM(cpuRegs.GPR.n.a1.UL[0]));
break; break;
case Syscall::StartThread:
case Syscall::ChangeThreadPriority:
{
if (CurrentBiosInformation.threadListAddr == 0)
{
u32 offset = 0x0;
// Suprisingly not that slow :)
while (offset < 0x5000) // I find that the instructions are in between 0x4000 -> 0x5000
{
u32 addr = 0x80000000 + offset;
const u32 inst1 = memRead32(addr);
const u32 inst2 = memRead32(addr += 4);
const u32 inst3 = memRead32(addr += 4);
if (ThreadListInstructions[0] == inst1 && // sw v0,0x0(v0)
ThreadListInstructions[1] == inst2 && // no-op
ThreadListInstructions[2] == inst3) // no-op
{
// We've found the instruction pattern!
// We (well, I) know that the thread address is always 0x8001 + the immediate of the 6th instruction from here
const u32 op = memRead32(0x80000000 + offset + (sizeof(u32) * 6));
CurrentBiosInformation.threadListAddr = 0x80010000 + static_cast<u16>(op) - 8; // Subtract 8 because the address here is offset by 8.
DevCon.WriteLn("BIOS: Successfully found the instruction pattern. Assuming the thread list is here: %0x", CurrentBiosInformation.threadListAddr);
break;
}
offset += 4;
}
if (!CurrentBiosInformation.threadListAddr)
{
// We couldn't find the address
CurrentBiosInformation.threadListAddr = -1;
// If you're here because a user has reported this message, this means that the instruction pattern is not present on their bios, or it is aligned weirdly.
Console.Warning("BIOS Warning: Unable to get a thread list offset. The debugger thread and stack frame views will not be functional.");
}
}
}
break;
case Syscall::sceSifSetDma: case Syscall::sceSifSetDma:
// The only thing this code is used for is the one log message, so don't execute it if we aren't logging bios messages. // The only thing this code is used for is the one log message, so don't execute it if we aren't logging bios messages.
if (SysTraceActive(EE.Bios)) if (SysTraceActive(EE.Bios))

View File

@ -21,6 +21,8 @@ enum Syscall : u8
{ {
SetGsCrt = 2, SetGsCrt = 2,
SetVTLBRefillHandler = 13, SetVTLBRefillHandler = 13,
StartThread = 34,
ChangeThreadPriority = 41,
GetOsdConfigParam = 75, GetOsdConfigParam = 75,
GetOsdConfigParam2 = 111, GetOsdConfigParam2 = 111,
sysPrintOut = 117, sysPrintOut = 117,

View File

@ -54,57 +54,7 @@ u32 BiosChecksum;
u32 BiosRegion; u32 BiosRegion;
bool NoOSD; bool NoOSD;
wxString BiosDescription; wxString BiosDescription;
const BiosDebugInformation* CurrentBiosInformation; BiosDebugInformation CurrentBiosInformation;
const BiosDebugInformation biosVersions[] = {
// Notes: The SCPH versions have not been verified
// USA v02.00(14/06/2004) SCPH70012
{ 0x00000200, 0xD778DB8D, 0x8001A640 },
// USA v01.60(19/03/2002) SCPH39004
{ 0x0000013C, 0x0B51A16F, 0x8001A280 },
// USA v01.60(07/02/2002) SCPH39001
{ 0x0000013C, 0x3A75B059, 0x8001A480 },
// Europe v02.20(10/02/2006) SCPH77008
{ 0x00000214, 0xD7EDD771, 0x8001AC00 },
// Europe v02.20(20/06/2005) SCPH75004
{ 0x00000214, 0x0E9C22D3, 0x8001AC00 },
// Europe v02.00(16/06/2004) SCPH70008
{ 0x00000200, 0x3C6AA4F4, 0x8001A640 },
// Europe v02.00(14/06/2004) SCPH70004
{ 0x00000200, 0x9C7B59D3, 0x8001A640 },
{ 0x00000200, 0x8C7B49D3, 0x8001A640 }, // Russian variant
// Europe v02.00(04/11/2004) SCPH50003
{ 0x00000200, 0xBDE56F8E, 0x8001A580 },
// Europe v01.90(23/06/2003) SCPH50004
{ 0x0000015A, 0xE36776DC, 0x8001A640 },
// Europe v01.70(27/02/2003) SCPH50004
{ 0x00000146 ,0x4954F4A2, 0x8001A640 },
// Europe v01.60(19/03/2002) SCPH39004
{ 0x0000013C, 0xFA3F9E90, 0x8001A280 },
// Europe v01.60(04/10/2001) SCPH30004
{ 0x0000013C, 0xB8E26E89, 0x8001A580 },
// Europe v01.60(04/10/2001) SCPH30004R
{ 0x0000013C, 0xEC9058f6, 0x8001A580 },
// Europe v01.20(02/09/2000) SCPH30003
{ 0x00000114, 0xCF83F17A, 0x80017B40 },
// Japan v02.20(05/09/2006) SCPH90006
{ 0x00000214, 0x098047D7, 0x8001AC00 },
// Japan v02.20(20/06/2005) SCPH75004
{ 0x00000214, 0x0E9C22DC, 0x8001AC00 },
// Japan v02.00(14/06/2004) SCPH70000
{ 0x00000200, 0xC9B61306, 0x8001A640 },
// Japan v01.70(06/02/2003) SCPH50000
{ 0x00000146, 0x71C7C144, 0x8001A640 },
// Japan v01.50(18/01/2001) SCPH30000
{ 0x00000132, 0x4FA83C78, 0x80019A00 },
// Japan v01.00(17/01/2000) SCPH10000
{ 0x00000100, 0x22B99C77, 0x80017400 },
// China v01.90(23/06/2003) SCPH50009
{ 0x0000015A, 0xE9D87F1F, 0x8001A640 },
// HK v02.00(14/06/2004) SCPH70006
{ 0x00000200, 0x2E5D0C98, 0x8001A640 }
};
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// Exception::BiosLoadFailed (implementations) // Exception::BiosLoadFailed (implementations)
@ -354,18 +304,7 @@ void LoadBIOS()
if (g_Conf->CurrentIRX.Length() > 3) if (g_Conf->CurrentIRX.Length() > 3)
LoadIrx(g_Conf->CurrentIRX, &eeMem->ROM[0x3C0000]); LoadIrx(g_Conf->CurrentIRX, &eeMem->ROM[0x3C0000]);
CurrentBiosInformation = NULL; CurrentBiosInformation.threadListAddr = 0;
for (size_t i = 0; i < sizeof(biosVersions)/sizeof(biosVersions[0]); i++)
{
if (biosVersions[i].biosChecksum == BiosChecksum && biosVersions[i].biosVersion == BiosVersion)
{
CurrentBiosInformation = &biosVersions[i];
break;
}
}
if (CurrentBiosInformation == NULL)
Console.Warning("BIOS Warning: Unknown BIOS version. The debugger thread and stack frame views will not be functional.");
} }
catch (Exception::BadStream& ex) catch (Exception::BadStream& ex)
{ {

View File

@ -28,19 +28,23 @@ namespace Exception
}; };
} }
const u32 ThreadListInstructions[3] =
{
0xac420000, // sw v0,0x0(v0)
0x00000000, // no-op
0x00000000, // no-op
};
struct BiosDebugInformation struct BiosDebugInformation
{ {
u32 biosVersion;
u32 biosChecksum;
u32 threadListAddr; u32 threadListAddr;
}; };
extern BiosDebugInformation CurrentBiosInformation;
extern u32 BiosVersion; // Used by CDVD extern u32 BiosVersion; // Used by CDVD
extern u32 BiosRegion; // Used by CDVD extern u32 BiosRegion; // Used by CDVD
extern bool NoOSD; // Used for HLE OSD Config Params extern bool NoOSD; // Used for HLE OSD Config Params
extern u32 BiosChecksum; extern u32 BiosChecksum;
extern wxString BiosDescription; extern wxString BiosDescription;
extern const BiosDebugInformation* CurrentBiosInformation;
extern void LoadBIOS(); extern void LoadBIOS();
extern bool IsBIOS(const wxString& filename, wxString& description); extern bool IsBIOS(const wxString& filename, wxString& description);