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
This commit is contained in:
parent
6d53aaed21
commit
cf36d4ba58
|
@ -65,6 +65,17 @@ void ABI_PopAllCalleeSavedRegsAndAdjustStack() {
|
||||||
POP(EBP);
|
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) {
|
void ABI_AlignStack(unsigned int frameSize) {
|
||||||
// Mac OS X requires the stack to be 16-byte aligned before every call.
|
// 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
|
// 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.
|
// expect that GCC on Windows acts the same as GCC on Linux in this respect.
|
||||||
// It would be nice if someone could verify this.
|
// It would be nice if someone could verify this.
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
frameSize += 4; // reserve space for return address
|
unsigned int fillSize =
|
||||||
unsigned int paddedSize = (frameSize + 15) & -16;
|
ABI_GetAlignedFrameSize(frameSize) - (frameSize + 4);
|
||||||
unsigned int fillSize = paddedSize - frameSize;
|
|
||||||
if (fillSize != 0) {
|
if (fillSize != 0) {
|
||||||
SUB(32, R(ESP), Imm8(fillSize));
|
SUB(32, R(ESP), Imm8(fillSize));
|
||||||
}
|
}
|
||||||
|
@ -84,16 +94,10 @@ void ABI_AlignStack(unsigned int frameSize) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ABI_RestoreStack(unsigned int frameSize) {
|
void ABI_RestoreStack(unsigned int frameSize) {
|
||||||
frameSize += 4; // reserve space for return address
|
unsigned int alignedSize = ABI_GetAlignedFrameSize(frameSize);
|
||||||
unsigned int paddedSize =
|
alignedSize -= 4; // return address is POPped at end of call
|
||||||
#ifdef __GNUC__
|
if (alignedSize != 0) {
|
||||||
(frameSize + 15) & -16;
|
ADD(32, R(ESP), Imm8(alignedSize));
|
||||||
#else
|
|
||||||
frameSize;
|
|
||||||
#endif
|
|
||||||
paddedSize -= 4; // return address is already consumed
|
|
||||||
if (paddedSize != 0) {
|
|
||||||
ADD(32, R(ESP), Imm8(paddedSize));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,6 +141,10 @@ void ABI_CallFunctionAC(void *func, const Gen::OpArg &arg1, u32 param2)
|
||||||
CALL(func);
|
CALL(func);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned int ABI_GetAlignedFrameSize(unsigned int frameSize) {
|
||||||
|
return frameSize;
|
||||||
|
}
|
||||||
|
|
||||||
void ABI_AlignStack(unsigned int /*frameSize*/) {
|
void ABI_AlignStack(unsigned int /*frameSize*/) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -103,6 +103,7 @@ void ABI_PopAllCalleeSavedRegsAndAdjustStack();
|
||||||
void ABI_PushAllCallerSavedRegsAndAdjustStack();
|
void ABI_PushAllCallerSavedRegsAndAdjustStack();
|
||||||
void ABI_PopAllCallerSavedRegsAndAdjustStack();
|
void ABI_PopAllCallerSavedRegsAndAdjustStack();
|
||||||
|
|
||||||
|
unsigned int ABI_GetAlignedFrameSize(unsigned int frameSize);
|
||||||
void ABI_AlignStack(unsigned int frameSize);
|
void ABI_AlignStack(unsigned int frameSize);
|
||||||
void ABI_RestoreStack(unsigned int frameSize);
|
void ABI_RestoreStack(unsigned int frameSize);
|
||||||
|
|
||||||
|
|
|
@ -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
|
// trickery : we simply re-push the parameters. might not be optimal, but that doesn't really
|
||||||
// matter.
|
// matter.
|
||||||
ABI_AlignStack(num_params * 4);
|
ABI_AlignStack(num_params * 4);
|
||||||
|
unsigned int alignedSize = ABI_GetAlignedFrameSize(num_params * 4);
|
||||||
for (int i = 0; i < num_params; i++) {
|
for (int i = 0; i < num_params; i++) {
|
||||||
// ESP is changing, so we do not need 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);
|
CALL(function);
|
||||||
ABI_RestoreStack(num_params * 4);
|
ABI_RestoreStack(num_params * 4);
|
||||||
|
|
Loading…
Reference in New Issue