Wii IPC HLE: do not clobber memory when launching a new title

It's questionable whether ES_LAUNCH should write *anything* to the
command structure at all, ever, given that it never actually returns
it back through the mailbox. But it *definitely* shouldn't write
anything to it if it has just launched a DOL, because otherwise it might
clobber code/data from the just-loaded application.
This commit is contained in:
Hector Martin 2016-12-01 06:50:19 +09:00
parent 288e75f672
commit 90c2dec02d
1 changed files with 15 additions and 5 deletions

View File

@ -937,6 +937,7 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress)
{
_dbg_assert_(WII_IPC_ES, Buffer.NumberInBuffer == 2);
bool bSuccess = false;
bool bReset = false;
u16 IOSv = 0xffff;
u64 TitleID = Memory::Read_U64(Buffer.InBuffer[0].m_Address);
@ -975,6 +976,7 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress)
MSR = 0;
PC = 0x3400;
bSuccess = true;
bReset = true;
}
else
{
@ -1045,7 +1047,12 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress)
Memory::Write_U32(Memory::Read_U32(0x00003140), 0x00003188);
// TODO: provide correct return code when bSuccess= false
Memory::Write_U32(0, _CommandAddress + 0x4);
// Note: If we just reset the PPC, don't write anything to the command buffer. This
// could clobber the DOL we just loaded.
if (!bReset)
{
Memory::Write_U32(0, _CommandAddress + 0x4);
}
ERROR_LOG(WII_IPC_ES,
"IOCTL_ES_LAUNCH %016" PRIx64 " %08x %016" PRIx64 " %08x %016" PRIx64 " %04x",
@ -1055,10 +1062,13 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress)
// This is necessary because Reset(true) above deleted this object. Ew.
// The original hardware overwrites the command type with the async reply type.
Memory::Write_U32(IPC_REP_ASYNC, _CommandAddress);
// IOS also seems to write back the command that was responded to in the FD field.
Memory::Write_U32(IPC_CMD_IOCTLV, _CommandAddress + 8);
if (!bReset)
{
// The original hardware overwrites the command type with the async reply type.
Memory::Write_U32(IPC_REP_ASYNC, _CommandAddress);
// IOS also seems to write back the command that was responded to in the FD field.
Memory::Write_U32(IPC_CMD_IOCTLV, _CommandAddress + 8);
}
// Generate a "reply" to the IPC command. ES_LAUNCH is unique because it
// involves restarting IOS; IOS generates two acknowledgements in a row.