From cf36d4ba58ed12987107fe44e810f148dca48801 Mon Sep 17 00:00:00 2001 From: Maarten ter Huurne Date: Fri, 5 Sep 2008 01:48:16 +0000 Subject: [PATCH] Fixed ProtectFunction(): it should copy parameters using the padded size. Actually, I am not sure this function is correct, but at least its implementation is now equivalent to the original (before rev 439). git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@441 8ced0084-cf51-0410-be5f-012b33b47a6e --- Source/Core/Common/Src/ABI.cpp | 34 ++++++++++++++++++++------------ Source/Core/Common/Src/ABI.h | 1 + Source/Core/Common/Src/Thunk.cpp | 3 ++- 3 files changed, 24 insertions(+), 14 deletions(-) diff --git a/Source/Core/Common/Src/ABI.cpp b/Source/Core/Common/Src/ABI.cpp index d41225a964..097d6fc45b 100644 --- a/Source/Core/Common/Src/ABI.cpp +++ b/Source/Core/Common/Src/ABI.cpp @@ -65,6 +65,17 @@ void ABI_PopAllCalleeSavedRegsAndAdjustStack() { POP(EBP); } +unsigned int ABI_GetAlignedFrameSize(unsigned int frameSize) { + frameSize += 4; // reserve space for return address + unsigned int alignedSize = +#ifdef __GNUC__ + (frameSize + 15) & -16; +#else + frameSize; +#endif + return alignedSize; +} + void ABI_AlignStack(unsigned int frameSize) { // Mac OS X requires the stack to be 16-byte aligned before every call. // Linux requires the stack to be 16-byte aligned before calls that put SSE @@ -74,9 +85,8 @@ void ABI_AlignStack(unsigned int frameSize) { // expect that GCC on Windows acts the same as GCC on Linux in this respect. // It would be nice if someone could verify this. #ifdef __GNUC__ - frameSize += 4; // reserve space for return address - unsigned int paddedSize = (frameSize + 15) & -16; - unsigned int fillSize = paddedSize - frameSize; + unsigned int fillSize = + ABI_GetAlignedFrameSize(frameSize) - (frameSize + 4); if (fillSize != 0) { SUB(32, R(ESP), Imm8(fillSize)); } @@ -84,16 +94,10 @@ void ABI_AlignStack(unsigned int frameSize) { } void ABI_RestoreStack(unsigned int frameSize) { - frameSize += 4; // reserve space for return address - unsigned int paddedSize = -#ifdef __GNUC__ - (frameSize + 15) & -16; -#else - frameSize; -#endif - paddedSize -= 4; // return address is already consumed - if (paddedSize != 0) { - ADD(32, R(ESP), Imm8(paddedSize)); + unsigned int alignedSize = ABI_GetAlignedFrameSize(frameSize); + alignedSize -= 4; // return address is POPped at end of call + if (alignedSize != 0) { + ADD(32, R(ESP), Imm8(alignedSize)); } } @@ -137,6 +141,10 @@ void ABI_CallFunctionAC(void *func, const Gen::OpArg &arg1, u32 param2) CALL(func); } +unsigned int ABI_GetAlignedFrameSize(unsigned int frameSize) { + return frameSize; +} + void ABI_AlignStack(unsigned int /*frameSize*/) { } diff --git a/Source/Core/Common/Src/ABI.h b/Source/Core/Common/Src/ABI.h index b84e92bef9..2bbd169d00 100644 --- a/Source/Core/Common/Src/ABI.h +++ b/Source/Core/Common/Src/ABI.h @@ -103,6 +103,7 @@ void ABI_PopAllCalleeSavedRegsAndAdjustStack(); void ABI_PushAllCallerSavedRegsAndAdjustStack(); void ABI_PopAllCallerSavedRegsAndAdjustStack(); +unsigned int ABI_GetAlignedFrameSize(unsigned int frameSize); void ABI_AlignStack(unsigned int frameSize); void ABI_RestoreStack(unsigned int frameSize); diff --git a/Source/Core/Common/Src/Thunk.cpp b/Source/Core/Common/Src/Thunk.cpp index 086ad66cbb..73ad098090 100644 --- a/Source/Core/Common/Src/Thunk.cpp +++ b/Source/Core/Common/Src/Thunk.cpp @@ -137,9 +137,10 @@ void *ProtectFunction(void *function, int num_params) // trickery : we simply re-push the parameters. might not be optimal, but that doesn't really // matter. ABI_AlignStack(num_params * 4); + unsigned int alignedSize = ABI_GetAlignedFrameSize(num_params * 4); for (int i = 0; i < num_params; i++) { // ESP is changing, so we do not need i - PUSH(32, MDisp(ESP, num_params * 4)); + PUSH(32, MDisp(ESP, alignedSize - 4)); } CALL(function); ABI_RestoreStack(num_params * 4);