From 661c7132c464a93b3334eed5a2bb2a4a692957cd Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Tue, 29 Jan 2013 08:07:36 -0800 Subject: [PATCH] Don't check that the pc is valid every single op. --- GPU/GLES/DisplayListInterpreter.cpp | 9 ++++++++- GPU/GPUCommon.cpp | 10 ++++++---- GPU/Null/NullGpu.cpp | 15 +++++++++++++++ 3 files changed, 29 insertions(+), 5 deletions(-) diff --git a/GPU/GLES/DisplayListInterpreter.cpp b/GPU/GLES/DisplayListInterpreter.cpp index 90a3e29d87..332cfe5971 100644 --- a/GPU/GLES/DisplayListInterpreter.cpp +++ b/GPU/GLES/DisplayListInterpreter.cpp @@ -602,11 +602,13 @@ void GLES_GPU::ExecuteOp(u32 op, u32 diff) { case GE_CMD_CALL: { u32 retval = currentList->pc + 4; + u32 target = (((gstate.base & 0x00FF0000) << 8) | (op & 0xFFFFFC)) & 0xFFFFFFF; if (stackptr == ARRAY_SIZE(stack)) { ERROR_LOG(G3D, "CALL: Stack full!"); + } else if (!Memory::IsValidAddress(target)) { + ERROR_LOG(G3D, "CALL to illegal address %08x - ignoring??", target); } else { stack[stackptr++] = retval; - u32 target = (((gstate.base & 0x00FF0000) << 8) | (op & 0xFFFFFC)) & 0xFFFFFFF; currentList->pc = target - 4; // pc will be increased after we return, counteract that } } @@ -616,6 +618,11 @@ void GLES_GPU::ExecuteOp(u32 op, u32 diff) { { u32 target = (currentList->pc & 0xF0000000) | (stack[--stackptr] & 0x0FFFFFFF); currentList->pc = target - 4; + if (!Memory::IsValidAddress(currentList->pc)) + { + ERROR_LOG(G3D, "Invalid DL PC %08x on return", currentList->pc); + finished = true; + } } break; diff --git a/GPU/GPUCommon.cpp b/GPU/GPUCommon.cpp index b55554aa9e..1dfb2254ac 100644 --- a/GPU/GPUCommon.cpp +++ b/GPU/GPUCommon.cpp @@ -64,13 +64,15 @@ bool GPUCommon::InterpretList(DisplayList &list) u32 op = 0; prev = 0; finished = false; + + if (!Memory::IsValidAddress(list.pc)) { + ERROR_LOG(G3D, "DL PC = %08x WTF!!!!", list.pc); + return true; + } + while (!finished) { list.status = PSP_GE_LIST_DRAWING; - if (!Memory::IsValidAddress(list.pc)) { - ERROR_LOG(G3D, "DL PC = %08x WTF!!!!", list.pc); - return true; - } if (list.pc == list.stall) { list.status = PSP_GE_LIST_STALL_REACHED; diff --git a/GPU/Null/NullGpu.cpp b/GPU/Null/NullGpu.cpp index d808c6ad15..ed9e56ac29 100644 --- a/GPU/Null/NullGpu.cpp +++ b/GPU/Null/NullGpu.cpp @@ -108,6 +108,11 @@ void NullGPU::ExecuteOp(u32 op, u32 diff) u32 target = (((gstate.base & 0x00FF0000) << 8) | (op & 0xFFFFFC)) & 0x0FFFFFFF; DEBUG_LOG(G3D,"DL CMD JUMP - %08x to %08x", currentList->pc, target); currentList->pc = target - 4; // pc will be increased after we return, counteract that + if (!Memory::IsValidAddress(currentList->pc)) + { + ERROR_LOG(G3D, "Invalid DL PC %08x on jump", currentList->pc); + finished = true; + } } break; @@ -118,6 +123,11 @@ void NullGPU::ExecuteOp(u32 op, u32 diff) u32 target = (((gstate.base & 0x00FF0000) << 8) | (op & 0xFFFFFC)) & 0xFFFFFFF; DEBUG_LOG(G3D,"DL CMD CALL - %08x to %08x, ret=%08x", currentList->pc, target, retval); currentList->pc = target - 4; // pc will be increased after we return, counteract that + if (!Memory::IsValidAddress(currentList->pc)) + { + ERROR_LOG(G3D, "Invalid DL PC %08x on call", currentList->pc); + finished = true; + } } break; @@ -127,6 +137,11 @@ void NullGPU::ExecuteOp(u32 op, u32 diff) u32 target = stack[--stackptr] & 0xFFFFFFF; DEBUG_LOG(G3D,"DL CMD RET - from %08x to %08x", currentList->pc, target); currentList->pc = target - 4; + if (!Memory::IsValidAddress(currentList->pc)) + { + ERROR_LOG(G3D, "Invalid DL PC %08x on return", currentList->pc); + finished = true; + } } break;