about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2022-03-25 19:10:34 +0100
committerptitSeb <sebastien.chev@gmail.com>2022-03-25 19:10:34 +0100
commitb17d80247656f5679a24bf5b43920eca524a7089 (patch)
treed615925b4f5feab7763f1f2d476fe2f0839668cf /src
parent9ebdf642984d5f617ac35e5183c1802b37be6d86 (diff)
downloadbox64-b17d80247656f5679a24bf5b43920eca524a7089.tar.gz
box64-b17d80247656f5679a24bf5b43920eca524a7089.zip
Fixed RunFunction and DynaCall/EmuCall with stack arguments
Diffstat (limited to 'src')
-rwxr-xr-xsrc/dynarec/dynarec.c2
-rwxr-xr-xsrc/emu/x64emu.c4
-rwxr-xr-xsrc/tools/callback.c31
3 files changed, 25 insertions, 12 deletions
diff --git a/src/dynarec/dynarec.c b/src/dynarec/dynarec.c
index c7f54590..ae9a2184 100755
--- a/src/dynarec/dynarec.c
+++ b/src/dynarec/dynarec.c
@@ -118,8 +118,6 @@ void DynaCall(x64emu_t* emu, uintptr_t addr)
         uint64_t old_rsi = R_RSI;
         uint64_t old_rbp = R_RBP;
         uint64_t old_rip = R_RIP;
-        Push64(emu, GetRBP(emu));   // set frame pointer
-        SetRBP(emu, GetRSP(emu));   // save RSP
         PushExit(emu);
         R_RIP = addr;
         emu->df = d_none;
diff --git a/src/emu/x64emu.c b/src/emu/x64emu.c
index d27fb5fd..2983578d 100755
--- a/src/emu/x64emu.c
+++ b/src/emu/x64emu.c
@@ -459,8 +459,8 @@ void EmuCall(x64emu_t* emu, uintptr_t addr)
     uint64_t old_rsi = R_RSI;
     uint64_t old_rbp = R_RBP;
     uint64_t old_rip = R_RIP;
-    Push64(emu, GetRBP(emu));   // set frame pointer
-    SetRBP(emu, GetRSP(emu));   // save RSP
+    //Push64(emu, GetRBP(emu));   // set frame pointer
+    //SetRBP(emu, GetRSP(emu));   // save RSP
     PushExit(emu);
     R_RIP = addr;
     emu->df = d_none;
diff --git a/src/tools/callback.c b/src/tools/callback.c
index 8cdc117c..0d9b0c5d 100755
--- a/src/tools/callback.c
+++ b/src/tools/callback.c
@@ -19,9 +19,13 @@ uint64_t RunFunction(box64context_t *context, uintptr_t fnc, int nargs, ...)
     (void)context;
 
     x64emu_t *emu = thread_get_emu();
+    int align = (nargs>6)?(((nargs-6)&1)):0;
+    int stackn = align + ((nargs>6)?(nargs-6):0);
 
-    if(nargs>6)
-        R_ESP -= (nargs-6)*sizeof(void*);   // need to push in reverse order
+    Push64(emu, R_RBP); // push rbp
+    R_RBP = R_RSP;      // mov rbp, rsp
+
+    R_RSP -= stackn*sizeof(void*);   // need to push in reverse order
 
     uint64_t *p = (uint64_t*)R_RSP;
 
@@ -38,9 +42,13 @@ uint64_t RunFunction(box64context_t *context, uintptr_t fnc, int nargs, ...)
     }
     va_end (va);
 
+    uintptr_t oldip = R_RIP;
     DynaCall(emu, fnc);
-    if(nargs>6)
-        R_ESP+=((nargs-6)*sizeof(void*));
+
+    if(oldip==R_RIP) {
+        R_RSP = R_RBP;          // mov rsp, rbp
+        R_RBP = Pop64(emu);     // pop rbp
+    }
 
     uint64_t ret = R_RAX;
 
@@ -50,8 +58,13 @@ uint64_t RunFunction(box64context_t *context, uintptr_t fnc, int nargs, ...)
 EXPORTDYN
 uint64_t RunFunctionWithEmu(x64emu_t *emu, int QuitOnLongJump, uintptr_t fnc, int nargs, ...)
 {
-    if(nargs>6)
-        R_ESP -= (nargs-6)*sizeof(void*);   // need to push in reverse order
+    int align = (nargs>6)?(((nargs-6)&1)):0;
+    int stackn = align + ((nargs>6)?(nargs-6):0);
+
+    Push64(emu, R_RBP); // push rbp
+    R_RBP = R_RSP;      // mov rbp, rsp
+
+    R_RSP -= stackn*sizeof(void*);   // need to push in reverse order
 
     uint64_t *p = (uint64_t*)R_RSP;
 
@@ -77,8 +90,10 @@ uint64_t RunFunctionWithEmu(x64emu_t *emu, int QuitOnLongJump, uintptr_t fnc, in
 
     DynaCall(emu, fnc);
 
-    if(oldip==R_RIP && nargs>6)
-        R_ESP+=((nargs-6)*sizeof(void*));   // restore stack only if EIP is the one expected (else, it means return value is not the one expected)
+    if(oldip==R_RIP) {
+        R_RSP = R_RBP;      // restore stack only if EIP is the one expected (else, it means return value is not the one expected)
+        R_RBP = Pop64(emu); //Pop EBP
+    }
 
     emu->quit = old_quit;
     emu->quitonlongjmp = oldlong;