about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2021-03-28 14:31:11 +0200
committerptitSeb <sebastien.chev@gmail.com>2021-03-28 14:31:11 +0200
commitdfe62ceac8a7c8067490b58995ad68cbe296fc24 (patch)
tree37292e5d7808978466390cd5a4038c3fb6c860ce /src
parenta36c9bfe73debeac10b87800020f23cb0d31da09 (diff)
downloadbox64-dfe62ceac8a7c8067490b58995ad68cbe296fc24.tar.gz
box64-dfe62ceac8a7c8067490b58995ad68cbe296fc24.zip
Better Stack handling (backported from box86)
Diffstat (limited to 'src')
-rwxr-xr-xsrc/box64context.c2
-rwxr-xr-xsrc/emu/x64emu.c5
-rwxr-xr-xsrc/emu/x64run.c2
-rwxr-xr-xsrc/libtools/signals.c16
-rwxr-xr-xsrc/libtools/threads.c8
-rwxr-xr-xsrc/tools/box64stack.c9
6 files changed, 27 insertions, 15 deletions
diff --git a/src/box64context.c b/src/box64context.c
index f020191e..01e7c3ca 100755
--- a/src/box64context.c
+++ b/src/box64context.c
@@ -174,8 +174,6 @@ void FreeBox64Context(box64context_t** context)
 
     FreeDLPrivate(&ctx->dlprivate);
 
-    free(ctx->stack);
-
     free(ctx->fullpath);
     free(ctx->box64path);
 
diff --git a/src/emu/x64emu.c b/src/emu/x64emu.c
index f92a81bd..9a162dea 100755
--- a/src/emu/x64emu.c
+++ b/src/emu/x64emu.c
@@ -5,6 +5,7 @@
 #include <unistd.h>
 #include <sys/syscall.h>
 #include <sys/time.h>
+#include <sys/mman.h>
 
 #include "debug.h"
 #include "box64stack.h"
@@ -173,8 +174,8 @@ void CallAllCleanup(x64emu_t *emu)
 
 static void internalFreeX64(x64emu_t* emu)
 {
-    if(emu)
-        free(emu->stack2free);
+    if(emu && emu->stack2free)
+        munmap(emu->stack2free, emu->size_stack);
 }
 
 EXPORTDYN
diff --git a/src/emu/x64run.c b/src/emu/x64run.c
index e894fa87..237f7de1 100755
--- a/src/emu/x64run.c
+++ b/src/emu/x64run.c
@@ -48,7 +48,7 @@ int Run(x64emu_t *emu, int step)
         return 0;
 
     //ref opcode: http://ref.x64asm.net/geek32.html#xA1
-    printf_log(LOG_DEBUG, "Run X86 (%p), RIP=%p, Stack=%p\n", emu, (void*)R_RIP, emu->context->stack);
+    printf_log(LOG_DEBUG, "Run X86 (%p), RIP=%p, Stack=%p\n", emu, (void*)R_RIP, (void*)R_RSP);
 
 x64emurun:
 
diff --git a/src/libtools/signals.c b/src/libtools/signals.c
index 9e7aacb8..87373e80 100755
--- a/src/libtools/signals.c
+++ b/src/libtools/signals.c
@@ -282,7 +282,7 @@ static x64emu_t* get_signal_emu()
     x64emu_t *emu = (x64emu_t*)pthread_getspecific(sigemu_key);
     if(!emu) {
         const int stsize = 8*1024;  // small stack for signal handler
-        void* stack = calloc(1, stsize);
+        void* stack = mmap(NULL, stsize, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_GROWSDOWN, -1, 0);
         emu = NewX64Emu(my_context, 0, (uintptr_t)stack, stsize, 1);
         emu->type = EMUTYPE_SIGNAL;
         pthread_setspecific(sigemu_key, emu);
@@ -301,7 +301,13 @@ uint64_t RunFunctionHandler(int* exit, uintptr_t fnc, int nargs, ...)
 //    trace_start = 0; trace_end = 1; // disabling trace, globably for now...
 
     x64emu_t *emu = get_signal_emu();
-    printf_log(LOG_DEBUG, "%04d|signal function handler %p called, ESP=%p\n", GetTID(), (void*)fnc, (void*)R_RSP);
+    x64emu_t *thread_emu = thread_get_emu();
+    x64_stack_t *new_ss = (x64_stack_t*)pthread_getspecific(sigstack_key);
+    if(!new_ss) {
+        // no alternate stack, so signal RSP needs to match thread RSP!
+        R_RSP = thread_emu->regs[_SP].q[0];
+    }
+    printf_log(LOG_DEBUG, "%04d|signal function handler %p  (%s alternate stack) called, RSP=%p\n", GetTID(), (void*)fnc, new_ss?"with":"without", (void*)R_RSP);
     
     /*SetFS(emu, default_fs);*/
     for (int i=0; i<6; ++i)
@@ -779,8 +785,10 @@ exit(-1);
         uint32_t hash = 0;
         if(db)
             hash = X31_hash_code(db->x64_addr, db->x64_size);
-        printf_log(log_minimum, "%04d|%s @%p (%s) (x64pc=%p/%s:\"%s\", rsp=%p), for accessing %p (code=%d/prot=%x), db=%p(%p:%p/%p:%p/%s:%s, hash:%x/%x)", 
-            GetTID(), signame, pc, name, (void*)x64pc, elfname?elfname:"???", x64name?x64name:"???", rsp, addr, info->si_code, 
+        printf_log(log_minimum, "%04d|%s @%p (%s) (x64pc=%p/%s:\"%s\", rsp=%p, stack=%p:%p own=%p), for accessing %p (code=%d/prot=%x), db=%p(%p:%p/%p:%p/%s:%s, hash:%x/%x)", 
+            GetTID(), signame, pc, name, (void*)x64pc, elfname?elfname:"???", x64name?x64name:"???", rsp, 
+            emu->init_stack, emu->init_stack+emu->size_stack, emu->stack2free, 
+            addr, info->si_code, 
             prot, db, db?db->block:0, db?(db->block+db->size):0, 
             db?db->x64_addr:0, db?(db->x64_addr+db->x64_size):0, 
             getAddrFunctionName((uintptr_t)(db?db->x64_addr:0)), (db?db->need_test:0)?"need_stest":"clean", db?db->hash:0, hash);
diff --git a/src/libtools/threads.c b/src/libtools/threads.c
index aab69c76..70041973 100755
--- a/src/libtools/threads.c
+++ b/src/libtools/threads.c
@@ -7,6 +7,7 @@
 #include <signal.h>
 #include <errno.h>
 #include <setjmp.h>
+#include <sys/mman.h>
 
 #include "debug.h"
 #include "box64context.h"
@@ -200,7 +201,7 @@ x64emu_t* thread_get_emu()
 				stacksize = stack_size;
 			pthread_attr_destroy(&attr);
 		}
-		void* stack = calloc(1, stacksize);
+		void* stack = mmap(NULL, stacksize, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_GROWSDOWN, -1, 0);
 		x64emu_t *emu = NewX64Emu(my_context, 0, (uintptr_t)stack, stacksize, 1);
 		SetupX64Emu(emu);
 		thread_set_emu(emu);
@@ -228,6 +229,7 @@ static void* pthread_routine(void* p)
 	et->emu->type = EMUTYPE_MAIN;
 	// setup callstack and run...
 	x64emu_t* emu = et->emu;
+	R_RSP -= 64;	// Gard zone
 	PushExit(emu);
 	R_RIP = et->fnc;
 	R_RDI = (uintptr_t)et->arg;
@@ -290,7 +292,7 @@ EXPORT int my_pthread_create(x64emu_t *emu, void* t, void* attr, void* start_rou
 		stacksize = attr_stacksize;
 		own = 0;
 	} else {
-		stack = malloc(stacksize);
+		stack = mmap(NULL, stacksize, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_GROWSDOWN, -1, 0);
 		own = 1;
 	}
 
@@ -316,7 +318,7 @@ EXPORT int my_pthread_create(x64emu_t *emu, void* t, void* attr, void* start_rou
 void* my_prepare_thread(x64emu_t *emu, void* f, void* arg, int ssize, void** pet)
 {
 	int stacksize = (ssize)?ssize:(2*1024*1024);	//default stack size is 2Mo
-	void* stack = malloc(stacksize);
+	void* stack = mmap(NULL, stacksize, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_GROWSDOWN, -1, 0);
 	emuthread_t *et = (emuthread_t*)calloc(1, sizeof(emuthread_t));
     x64emu_t *emuthread = NewX64Emu(emu->context, (uintptr_t)f, (uintptr_t)stack, stacksize, 1);
 	SetupX64Emu(emuthread);
diff --git a/src/tools/box64stack.c b/src/tools/box64stack.c
index dab38474..94ca4dd3 100755
--- a/src/tools/box64stack.c
+++ b/src/tools/box64stack.c
@@ -2,6 +2,7 @@
 #include <stdlib.h>
 #include <stdint.h>
 #include <string.h>
+#include <sys/mman.h>
 
 #include "box64stack.h"
 #include "box64context.h"
@@ -15,15 +16,17 @@ EXPORTDYN
 int CalcStackSize(box64context_t *context)
 {
     printf_log(LOG_DEBUG, "Calc stack size, based on %d elf(s)\n", context->elfsize);
-    context->stacksz = 8*1024*1024; context->stackalign=4;
+    context->stacksz = 8*1024*1024; context->stackalign=16;
     for (int i=0; i<context->elfsize; ++i)
         CalcStack(context->elfs[i], &context->stacksz, &context->stackalign);
 
-    if (posix_memalign((void**)&context->stack, context->stackalign, context->stacksz)) {
+//    if (posix_memalign((void**)&context->stack, context->stackalign, context->stacksz)) {
+    context->stack = mmap(NULL, context->stacksz, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_GROWSDOWN, -1, 0);
+    if (context->stack==(void*)-1) {
         printf_log(LOG_NONE, "Cannot allocate aligned memory (0x%x/0x%x) for stack\n", context->stacksz, context->stackalign);
         return 1;
     }
-    memset(context->stack, 0, context->stacksz);
+    //memset(context->stack, 0, context->stacksz);
     printf_log(LOG_DEBUG, "Stack is @%p size=0x%x align=0x%x\n", context->stack, context->stacksz, context->stackalign);
 
     return 0;