Permalink
Browse files

Ge: Avoid executing invalid pointers.

May help #3407 and related errors, as well as crashes and execution of
garbage.  This stops immediately on a bad pointer, rather than trying to
push through.
  • Loading branch information...
unknownbrackets committed Aug 25, 2018
1 parent 17de6ad commit d13f76308d7a43c1f5d1055d895c6d531fe4ec96
Showing with 11 additions and 8 deletions.
  1. +3 −3 Core/HLE/sceGe.cpp
  2. +8 −5 GPU/GPUCommon.cpp
View
@@ -353,10 +353,10 @@ u32 sceGeListEnQueueHead(u32 listAddress, u32 stallAddress, int callbackId, u32
auto optParam = PSPPointer<PspGeListArgs>::Create(optParamAddr);
u32 listID = gpu->EnqueueList(listAddress, stallAddress, __GeSubIntrBase(callbackId), optParam, true);
if ((int)listID >= 0)
if ((int)listID >= 0) {
listID = LIST_ID_MAGIC ^ listID;
DEBUG_LOG(SCEGE, "List %i enqueued at head.", listID);
DEBUG_LOG(SCEGE, "List %i enqueued at head.", listID);
}
hleEatCycles(480);
CoreTiming::ForceCheck();
return listID;
View
@@ -632,8 +632,10 @@ u32 GPUCommon::EnqueueList(u32 listpc, u32 stall, int subIntrBase, PSPPointer<Ps
// Check alignment
// TODO Check the context and stack alignement too
if (((listpc | stall) & 3) != 0)
if (((listpc | stall) & 3) != 0 || !Memory::IsValidAddress(listpc)) {
ERROR_LOG_REPORT(G3D, "sceGeListEnqueue: invalid address %08x", listpc);
return SCE_KERNEL_ERROR_INVALID_POINTER;
}
int id = -1;
u64 currentTicks = CoreTiming::GetTicks();
@@ -1165,12 +1167,11 @@ void GPUCommon::Execute_Origin(u32 op, u32 diff) {
void GPUCommon::Execute_Jump(u32 op, u32 diff) {
const u32 target = gstate_c.getRelativeAddress(op & 0x00FFFFFC);
#ifdef _DEBUG
if (!Memory::IsValidAddress(target)) {
ERROR_LOG_REPORT(G3D, "JUMP to illegal address %08x - ignoring! data=%06x", target, op & 0x00FFFFFF);
UpdateState(GPUSTATE_ERROR);
return;
}
#endif
UpdatePC(currentList->pc, target - 4);
currentList->pc = target - 4; // pc will be increased after we return, counteract that
}
@@ -1184,6 +1185,7 @@ void GPUCommon::Execute_BJump(u32 op, u32 diff) {
currentList->pc = target - 4; // pc will be increased after we return, counteract that
} else {
ERROR_LOG_REPORT(G3D, "BJUMP to illegal address %08x - ignoring! data=%06x", target, op & 0x00FFFFFF);
UpdateState(GPUSTATE_ERROR);
}
}
}
@@ -1194,12 +1196,11 @@ void GPUCommon::Execute_Call(u32 op, u32 diff) {
// Saint Seiya needs correct support for relative calls.
const u32 retval = currentList->pc + 4;
const u32 target = gstate_c.getRelativeAddress(op & 0x00FFFFFC);
#ifdef _DEBUG
if (!Memory::IsValidAddress(target)) {
ERROR_LOG_REPORT(G3D, "CALL to illegal address %08x - ignoring! data=%06x", target, op & 0x00FFFFFF);
UpdateState(GPUSTATE_ERROR);
return;
}
#endif
// Bone matrix optimization - many games will CALL a bone matrix (!).
// We don't optimize during recording - so the matrix data gets recorded.
@@ -1304,6 +1305,7 @@ void GPUCommon::Execute_End(u32 op, u32 diff) {
u32 target = (((signal << 16) | enddata) & 0xFFFFFFFC) - 4;
if (!Memory::IsValidAddress(target)) {
ERROR_LOG_REPORT(G3D, "Signal with Jump: bad address. signal/end: %04x %04x", signal, enddata);
UpdateState(GPUSTATE_ERROR);
} else {
UpdatePC(currentList->pc, target);
currentList->pc = target;
@@ -1321,6 +1323,7 @@ void GPUCommon::Execute_End(u32 op, u32 diff) {
ERROR_LOG_REPORT(G3D, "Signal with Call: stack full. signal/end: %04x %04x", signal, enddata);
} else if (!Memory::IsValidAddress(target)) {
ERROR_LOG_REPORT(G3D, "Signal with Call: bad address. signal/end: %04x %04x", signal, enddata);
UpdateState(GPUSTATE_ERROR);
} else {
// TODO: This might save/restore other state...
auto &stackEntry = currentList->stack[currentList->stackptr++];

0 comments on commit d13f763

Please sign in to comment.