about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2024-01-22 16:46:45 +0100
committerptitSeb <sebastien.chev@gmail.com>2024-01-22 16:46:45 +0100
commit07be405f48ab2571d9f14fff0b7dd87e10f17949 (patch)
treeb638e3fc4ad52d88a7c95ce40fc1d393ac4cf305 /src
parent92d5210e3729e6d17c0285383478fe4f1a81602a (diff)
downloadbox64-07be405f48ab2571d9f14fff0b7dd87e10f17949.tar.gz
box64-07be405f48ab2571d9f14fff0b7dd87e10f17949.zip
Make sure Stack is aligned properly... (should help #1187 and ~1188)
Diffstat (limited to 'src')
-rw-r--r--src/emu/x64emu.c2
-rw-r--r--src/libtools/signals.c6
-rw-r--r--src/libtools/threads.c7
3 files changed, 13 insertions, 2 deletions
diff --git a/src/emu/x64emu.c b/src/emu/x64emu.c
index 2d747c92..0173ea22 100644
--- a/src/emu/x64emu.c
+++ b/src/emu/x64emu.c
@@ -561,6 +561,8 @@ void EmuCall(x64emu_t* emu, uintptr_t addr)
     uint64_t old_rip = R_RIP;
     //Push64(emu, GetRBP(emu));   // set frame pointer
     //SetRBP(emu, GetRSP(emu));   // save RSP
+    R_RSP -= 200;
+    R_RSP &= ~63LL;
     PushExit(emu);
     R_RIP = addr;
     emu->df = d_none;
diff --git a/src/libtools/signals.c b/src/libtools/signals.c
index 1c654983..f39e1170 100644
--- a/src/libtools/signals.c
+++ b/src/libtools/signals.c
@@ -309,8 +309,10 @@ uint64_t RunFunctionHandler(int* exit, int dynarec, x64_ucontext_t* sigcontext,
     for (int i=0; i<6; ++i)
         emu->segs_serial[i] = 0;
 
+    int align = nargs&1;
+
     if(nargs>6)
-        R_RSP -= (nargs-6)*sizeof(void*);   // need to push in reverse order
+        R_RSP -= (nargs-6+align)*sizeof(void*);   // need to push in reverse order
 
     uint64_t *p = (uint64_t*)R_RSP;
 
@@ -342,7 +344,7 @@ uint64_t RunFunctionHandler(int* exit, int dynarec, x64_ucontext_t* sigcontext,
         EmuCall(emu, fnc);
 
     if(nargs>6 && !emu->flags.longjmp)
-        R_RSP+=((nargs-6)*sizeof(void*));
+        R_RSP+=((nargs-6+align)*sizeof(void*));
 
     if(!emu->flags.longjmp && R_CS==0x33)
         R_CS = old_cs;
diff --git a/src/libtools/threads.c b/src/libtools/threads.c
index dad14fe1..d6a49a8a 100644
--- a/src/libtools/threads.c
+++ b/src/libtools/threads.c
@@ -652,7 +652,14 @@ int EXPORT my_pthread_once(x64emu_t* emu, int* once, void* cb)
 	#endif
 	if(old)
 		return 0;
+    // make some room and align R_RSP before doing the call (maybe it would be simpler to just use Callback functions)
+    Push64(emu, R_RBP); // push rbp
+    R_RBP = R_RSP;      // mov rbp, rsp
+    R_RSP -= 0x200;
+    R_RSP &= ~63LL;
 	DynaCall(emu, (uintptr_t)cb);  // using DynaCall, speedup wine 7.21 initialisation
+	R_RSP = R_RBP;          // mov rsp, rbp
+	R_RBP = Pop64(emu);     // pop rbp
 	return 0;
 }
 EXPORT int my___pthread_once(x64emu_t* emu, void* once, void* cb) __attribute__((alias("my_pthread_once")));