From 558dee84ca3f242a8da07758668f1f7fff778ac9 Mon Sep 17 00:00:00 2001 From: comex Date: Mon, 15 Sep 2014 22:37:31 -0400 Subject: [PATCH] Wrap some function calls in ABI_Push|PopRegistersAndAdjustStack(0, 0); These calls are made outside of JIT blocks, and thus previously did not read any protection - register use is taken into account and the outer dispatcher stack frame is sufficient. However, if data is to be stored on the stack, these calls must reserve stack shadow space on Windows to avoid clobbering it. --- Source/Core/Core/PowerPC/Jit64/Jit.cpp | 18 ++++++++++++++++++ Source/Core/Core/PowerPC/Jit64/JitAsm.cpp | 5 +++-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/Source/Core/Core/PowerPC/Jit64/Jit.cpp b/Source/Core/Core/PowerPC/Jit64/Jit.cpp index 720375613c..585b7e136f 100644 --- a/Source/Core/Core/PowerPC/Jit64/Jit.cpp +++ b/Source/Core/Core/PowerPC/Jit64/Jit.cpp @@ -174,7 +174,9 @@ void Jit64::WriteCallInterpreter(UGeckoInstruction inst) MOV(32, PPCSTATE(npc), Imm32(js.compilerPC + 4)); } Interpreter::_interpreterInstruction instr = GetInterpreterOp(inst); + ABI_PushRegistersAndAdjustStack(0, 0); ABI_CallFunctionC((void*)instr, inst.hex); + ABI_PopRegistersAndAdjustStack(0, 0); } void Jit64::unknown_instruction(UGeckoInstruction inst) @@ -191,7 +193,9 @@ void Jit64::HLEFunction(UGeckoInstruction _inst) { gpr.Flush(); fpr.Flush(); + ABI_PushRegistersAndAdjustStack(0, 0); ABI_CallFunctionCC((void*)&HLE::Execute, js.compilerPC, _inst.hex); + ABI_PopRegistersAndAdjustStack(0, 0); } void Jit64::DoNothing(UGeckoInstruction _inst) @@ -227,7 +231,9 @@ void Jit64::Cleanup() { if (jo.optimizeGatherPipe && js.fifoBytesThisBlock > 0) { + ABI_PushRegistersAndAdjustStack(0, 0); ABI_CallFunction((void *)&GPFifo::CheckGatherPipe); + ABI_PopRegistersAndAdjustStack(0, 0); } // SPEED HACK: MMCR0/MMCR1 should be checked at run-time, not at compile time. @@ -278,7 +284,9 @@ void Jit64::WriteRfiExitDestInRSCRATCH() MOV(32, PPCSTATE(pc), R(RSCRATCH)); MOV(32, PPCSTATE(npc), R(RSCRATCH)); Cleanup(); + ABI_PushRegistersAndAdjustStack(0, 0); ABI_CallFunction(reinterpret_cast(&PowerPC::CheckExceptions)); + ABI_PopRegistersAndAdjustStack(0, 0); SUB(32, PPCSTATE(downcount), Imm32(js.downcountAmount)); JMP(asm_routines.dispatcher, true); } @@ -288,7 +296,9 @@ void Jit64::WriteExceptionExit() Cleanup(); MOV(32, R(RSCRATCH), PPCSTATE(pc)); MOV(32, PPCSTATE(npc), R(RSCRATCH)); + ABI_PushRegistersAndAdjustStack(0, 0); ABI_CallFunction(reinterpret_cast(&PowerPC::CheckExceptions)); + ABI_PopRegistersAndAdjustStack(0, 0); SUB(32, PPCSTATE(downcount), Imm32(js.downcountAmount)); JMP(asm_routines.dispatcher, true); } @@ -298,7 +308,9 @@ void Jit64::WriteExternalExceptionExit() Cleanup(); MOV(32, R(RSCRATCH), PPCSTATE(pc)); MOV(32, PPCSTATE(npc), R(RSCRATCH)); + ABI_PushRegistersAndAdjustStack(0, 0); ABI_CallFunction(reinterpret_cast(&PowerPC::CheckExternalExceptions)); + ABI_PopRegistersAndAdjustStack(0, 0); SUB(32, PPCSTATE(downcount), Imm32(js.downcountAmount)); JMP(asm_routines.dispatcher, true); } @@ -395,7 +407,11 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc b->normalEntry = normalEntry; if (ImHereDebug) + { + ABI_PushRegistersAndAdjustStack(0, 0); ABI_CallFunction((void *)&ImHere); //Used to get a trace of the last few blocks before a crash, sometimes VERY useful + ABI_PopRegistersAndAdjustStack(0, 0); + } // Conditionally add profiling code. if (Profiler::g_ProfileBlocks) @@ -548,7 +564,9 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc fpr.Flush(); MOV(32, PPCSTATE(pc), Imm32(ops[i].address)); + ABI_PushRegistersAndAdjustStack(0, 0); ABI_CallFunction(reinterpret_cast(&PowerPC::CheckBreakPoints)); + ABI_PopRegistersAndAdjustStack(0, 0); TEST(32, M((void*)PowerPC::GetStatePtr()), Imm32(0xFFFFFFFF)); FixupBranch noBreakpoint = J_CC(CC_Z); diff --git a/Source/Core/Core/PowerPC/Jit64/JitAsm.cpp b/Source/Core/Core/PowerPC/Jit64/JitAsm.cpp index a362768708..dfef055459 100644 --- a/Source/Core/Core/PowerPC/Jit64/JitAsm.cpp +++ b/Source/Core/Core/PowerPC/Jit64/JitAsm.cpp @@ -106,8 +106,9 @@ void Jit64AsmRoutineManager::Generate() SetJumpTarget(notfound); //Ok, no block, let's jit - MOV(32, R(ABI_PARAM1), PPCSTATE(pc)); - CALL((void *)&Jit); + ABI_PushRegistersAndAdjustStack(0, 0); + ABI_CallFunctionA((void *)&Jit, PPCSTATE(pc)); + ABI_PopRegistersAndAdjustStack(0, 0); JMP(dispatcherNoCheck); // no point in special casing this