CPU/Recompiler/AArch64: Fix potential stack corruption in function calls
This commit is contained in:
parent
18066239b7
commit
1905d22a9a
|
@ -918,18 +918,22 @@ void CodeGenerator::EmitFunctionCallPtr(Value* return_value, const void* ptr)
|
||||||
if (return_value)
|
if (return_value)
|
||||||
return_value->Discard();
|
return_value->Discard();
|
||||||
|
|
||||||
|
// must be allocated before the stack push
|
||||||
|
Value temp = m_register_cache.AllocateScratch(RegSize_64);
|
||||||
|
|
||||||
// shadow space allocate
|
// shadow space allocate
|
||||||
const u32 adjust_size = PrepareStackForCall();
|
const u32 adjust_size = PrepareStackForCall();
|
||||||
|
|
||||||
// actually call the function
|
// actually call the function
|
||||||
Value temp = m_register_cache.AllocateScratch(RegSize_64);
|
|
||||||
m_emit->Mov(GetHostReg64(temp), reinterpret_cast<uintptr_t>(ptr));
|
m_emit->Mov(GetHostReg64(temp), reinterpret_cast<uintptr_t>(ptr));
|
||||||
m_emit->Blr(GetHostReg64(temp));
|
m_emit->Blr(GetHostReg64(temp));
|
||||||
temp.ReleaseAndClear();
|
|
||||||
|
|
||||||
// shadow space release
|
// shadow space release
|
||||||
RestoreStackAfterCall(adjust_size);
|
RestoreStackAfterCall(adjust_size);
|
||||||
|
|
||||||
|
// must happen after the stack push
|
||||||
|
temp.ReleaseAndClear();
|
||||||
|
|
||||||
// copy out return value if requested
|
// copy out return value if requested
|
||||||
if (return_value)
|
if (return_value)
|
||||||
{
|
{
|
||||||
|
@ -943,6 +947,9 @@ void CodeGenerator::EmitFunctionCallPtr(Value* return_value, const void* ptr, co
|
||||||
if (return_value)
|
if (return_value)
|
||||||
return_value->Discard();
|
return_value->Discard();
|
||||||
|
|
||||||
|
// must be allocated before the stack push
|
||||||
|
Value temp = m_register_cache.AllocateScratch(RegSize_64);
|
||||||
|
|
||||||
// shadow space allocate
|
// shadow space allocate
|
||||||
const u32 adjust_size = PrepareStackForCall();
|
const u32 adjust_size = PrepareStackForCall();
|
||||||
|
|
||||||
|
@ -950,14 +957,15 @@ void CodeGenerator::EmitFunctionCallPtr(Value* return_value, const void* ptr, co
|
||||||
EmitCopyValue(RARG1, arg1);
|
EmitCopyValue(RARG1, arg1);
|
||||||
|
|
||||||
// actually call the function
|
// actually call the function
|
||||||
Value temp = m_register_cache.AllocateScratch(RegSize_64);
|
|
||||||
m_emit->Mov(GetHostReg64(temp), reinterpret_cast<uintptr_t>(ptr));
|
m_emit->Mov(GetHostReg64(temp), reinterpret_cast<uintptr_t>(ptr));
|
||||||
m_emit->Blr(GetHostReg64(temp));
|
m_emit->Blr(GetHostReg64(temp));
|
||||||
temp.ReleaseAndClear();
|
|
||||||
|
|
||||||
// shadow space release
|
// shadow space release
|
||||||
RestoreStackAfterCall(adjust_size);
|
RestoreStackAfterCall(adjust_size);
|
||||||
|
|
||||||
|
// must happen after the stack push
|
||||||
|
temp.ReleaseAndClear();
|
||||||
|
|
||||||
// copy out return value if requested
|
// copy out return value if requested
|
||||||
if (return_value)
|
if (return_value)
|
||||||
{
|
{
|
||||||
|
@ -971,6 +979,9 @@ void CodeGenerator::EmitFunctionCallPtr(Value* return_value, const void* ptr, co
|
||||||
if (return_value)
|
if (return_value)
|
||||||
return_value->Discard();
|
return_value->Discard();
|
||||||
|
|
||||||
|
// must be allocated before the stack push
|
||||||
|
Value temp = m_register_cache.AllocateScratch(RegSize_64);
|
||||||
|
|
||||||
// shadow space allocate
|
// shadow space allocate
|
||||||
const u32 adjust_size = PrepareStackForCall();
|
const u32 adjust_size = PrepareStackForCall();
|
||||||
|
|
||||||
|
@ -979,14 +990,15 @@ void CodeGenerator::EmitFunctionCallPtr(Value* return_value, const void* ptr, co
|
||||||
EmitCopyValue(RARG2, arg2);
|
EmitCopyValue(RARG2, arg2);
|
||||||
|
|
||||||
// actually call the function
|
// actually call the function
|
||||||
Value temp = m_register_cache.AllocateScratch(RegSize_64);
|
|
||||||
m_emit->Mov(GetHostReg64(temp), reinterpret_cast<uintptr_t>(ptr));
|
m_emit->Mov(GetHostReg64(temp), reinterpret_cast<uintptr_t>(ptr));
|
||||||
m_emit->Blr(GetHostReg64(temp));
|
m_emit->Blr(GetHostReg64(temp));
|
||||||
temp.ReleaseAndClear();
|
|
||||||
|
|
||||||
// shadow space release
|
// shadow space release
|
||||||
RestoreStackAfterCall(adjust_size);
|
RestoreStackAfterCall(adjust_size);
|
||||||
|
|
||||||
|
// must happen after the stack push
|
||||||
|
temp.ReleaseAndClear();
|
||||||
|
|
||||||
// copy out return value if requested
|
// copy out return value if requested
|
||||||
if (return_value)
|
if (return_value)
|
||||||
{
|
{
|
||||||
|
@ -1001,6 +1013,9 @@ void CodeGenerator::EmitFunctionCallPtr(Value* return_value, const void* ptr, co
|
||||||
if (return_value)
|
if (return_value)
|
||||||
m_register_cache.DiscardHostReg(return_value->GetHostRegister());
|
m_register_cache.DiscardHostReg(return_value->GetHostRegister());
|
||||||
|
|
||||||
|
// must be allocated before the stack push
|
||||||
|
Value temp = m_register_cache.AllocateScratch(RegSize_64);
|
||||||
|
|
||||||
// shadow space allocate
|
// shadow space allocate
|
||||||
const u32 adjust_size = PrepareStackForCall();
|
const u32 adjust_size = PrepareStackForCall();
|
||||||
|
|
||||||
|
@ -1010,14 +1025,15 @@ void CodeGenerator::EmitFunctionCallPtr(Value* return_value, const void* ptr, co
|
||||||
EmitCopyValue(RARG3, arg3);
|
EmitCopyValue(RARG3, arg3);
|
||||||
|
|
||||||
// actually call the function
|
// actually call the function
|
||||||
Value temp = m_register_cache.AllocateScratch(RegSize_64);
|
|
||||||
m_emit->Mov(GetHostReg64(temp), reinterpret_cast<uintptr_t>(ptr));
|
m_emit->Mov(GetHostReg64(temp), reinterpret_cast<uintptr_t>(ptr));
|
||||||
m_emit->Blr(GetHostReg64(temp));
|
m_emit->Blr(GetHostReg64(temp));
|
||||||
temp.ReleaseAndClear();
|
|
||||||
|
|
||||||
// shadow space release
|
// shadow space release
|
||||||
RestoreStackAfterCall(adjust_size);
|
RestoreStackAfterCall(adjust_size);
|
||||||
|
|
||||||
|
// must happen after the stack push
|
||||||
|
temp.ReleaseAndClear();
|
||||||
|
|
||||||
// copy out return value if requested
|
// copy out return value if requested
|
||||||
if (return_value)
|
if (return_value)
|
||||||
{
|
{
|
||||||
|
@ -1032,6 +1048,9 @@ void CodeGenerator::EmitFunctionCallPtr(Value* return_value, const void* ptr, co
|
||||||
if (return_value)
|
if (return_value)
|
||||||
return_value->Discard();
|
return_value->Discard();
|
||||||
|
|
||||||
|
// must be allocated before the stack push
|
||||||
|
Value temp = m_register_cache.AllocateScratch(RegSize_64);
|
||||||
|
|
||||||
// shadow space allocate
|
// shadow space allocate
|
||||||
const u32 adjust_size = PrepareStackForCall();
|
const u32 adjust_size = PrepareStackForCall();
|
||||||
|
|
||||||
|
@ -1042,14 +1061,15 @@ void CodeGenerator::EmitFunctionCallPtr(Value* return_value, const void* ptr, co
|
||||||
EmitCopyValue(RARG4, arg4);
|
EmitCopyValue(RARG4, arg4);
|
||||||
|
|
||||||
// actually call the function
|
// actually call the function
|
||||||
Value temp = m_register_cache.AllocateScratch(RegSize_64);
|
|
||||||
m_emit->Mov(GetHostReg64(temp), reinterpret_cast<uintptr_t>(ptr));
|
m_emit->Mov(GetHostReg64(temp), reinterpret_cast<uintptr_t>(ptr));
|
||||||
m_emit->Blr(GetHostReg64(temp));
|
m_emit->Blr(GetHostReg64(temp));
|
||||||
temp.ReleaseAndClear();
|
|
||||||
|
|
||||||
// shadow space release
|
// shadow space release
|
||||||
RestoreStackAfterCall(adjust_size);
|
RestoreStackAfterCall(adjust_size);
|
||||||
|
|
||||||
|
// must happen after the stack push
|
||||||
|
temp.ReleaseAndClear();
|
||||||
|
|
||||||
// copy out return value if requested
|
// copy out return value if requested
|
||||||
if (return_value)
|
if (return_value)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue