diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2024-12-23 12:23:07 +0100 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2024-12-23 12:23:18 +0100 |
| commit | ac811324350c4a112d7e2102ecd1c6f0a362a204 (patch) | |
| tree | 465dbb05cd910e83ec21f9f7a543f1a930dd99a3 /src | |
| parent | 946da430388786a8237e2e7d17c7c2535246963f (diff) | |
| download | box64-ac811324350c4a112d7e2102ecd1c6f0a362a204.tar.gz box64-ac811324350c4a112d7e2102ecd1c6f0a362a204.zip | |
Try to improve clone syscal handling ([BOX32] too)
Diffstat (limited to 'src')
| -rw-r--r-- | src/emu/x64syscall.c | 41 | ||||
| -rw-r--r-- | src/emu/x86syscall_32.c | 23 |
2 files changed, 37 insertions, 27 deletions
diff --git a/src/emu/x64syscall.c b/src/emu/x64syscall.c index 3f21842c..ee3e7a8c 100644 --- a/src/emu/x64syscall.c +++ b/src/emu/x64syscall.c @@ -404,16 +404,28 @@ typedef struct old_utsname_s { // int xss; //}; +typedef struct clone_s { + x64emu_t* emu; + void* stack2free; +} clone_t; + static int clone_fn(void* arg) { - x64emu_t *emu = (x64emu_t*)arg; + clone_t* args = arg; + x64emu_t *emu = args->emu; + thread_forget_emu(); thread_set_emu(emu); R_RAX = 0; DynaRun(emu); int ret = R_EAX; FreeX64Emu(&emu); - my_context->stack_clone_used = 0; - return ret; + void* stack2free = args->stack2free; + box_free(args); + if(my_context->stack_clone_used && !stack2free) + my_context->stack_clone_used = 0; + if(stack2free) + box_free(stack2free); // this free the stack, so it will crash very soon! + _exit(ret); } void EXPORT x64Syscall(x64emu_t *emu) @@ -589,37 +601,22 @@ void EXPORT x64Syscall(x64emu_t *emu) void* stack_base = (void*)R_RSI; int stack_size = 0; uintptr_t sp = R_RSI; - if(!R_RSI) { - // allocate a new stack... - int currstack = 0; - if((R_RSP>=(uintptr_t)emu->init_stack) && (R_RSP<=((uintptr_t)emu->init_stack+emu->size_stack))) - currstack = 1; - stack_size = (currstack && emu->size_stack)?emu->size_stack:(1024*1024); - stack_base = mmap(NULL, stack_size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_GROWSDOWN, -1, 0); - // copy value from old stack to new stack - if(currstack) { - memcpy(stack_base, emu->init_stack, stack_size); - sp = (uintptr_t)emu->init_stack + R_RSP - (uintptr_t)stack_base; - } else { - int size_to_copy = (uintptr_t)emu->init_stack + emu->size_stack - (R_RSP); - memcpy(stack_base+stack_size-size_to_copy, (void*)R_RSP, size_to_copy); - sp = (uintptr_t)stack_base+stack_size-size_to_copy; - } - } x64emu_t * newemu = NewX64Emu(emu->context, R_RIP, (uintptr_t)stack_base, stack_size, (R_RSI)?0:1); SetupX64Emu(newemu, emu); CloneEmu(newemu, emu); + clone_t* args = box_calloc(1, sizeof(clone_t)); newemu->regs[_SP].q[0] = sp; // setup new stack pointer + args->emu = newemu; void* mystack = NULL; if(my_context->stack_clone_used) { - mystack = box_malloc(1024*1024); // stack for own process... memory leak, but no practical way to remove it + args->stack2free = mystack = box_malloc(1024*1024); // stack for own process... } else { if(!my_context->stack_clone) my_context->stack_clone = box_malloc(1024*1024); mystack = my_context->stack_clone; my_context->stack_clone_used = 1; } - int64_t ret = clone(clone_fn, (void*)((uintptr_t)mystack+1024*1024), R_RDI, newemu, R_RDX, R_R8, R_R10); + int64_t ret = clone(clone_fn, (void*)((uintptr_t)mystack+1024*1024), R_RDI, args, R_RDX, R_R8, R_R10); S_RAX = ret; } else diff --git a/src/emu/x86syscall_32.c b/src/emu/x86syscall_32.c index da40783c..dc2bf76c 100644 --- a/src/emu/x86syscall_32.c +++ b/src/emu/x86syscall_32.c @@ -265,9 +265,15 @@ pid_t my_vfork(x64emu_t* emu); #define FUTEX_LOCK_PI2 13 #endif +typedef struct clone_s { + x64emu_t* emu; + void* stack2free; +} clone_t; + static int clone32_fn(void* arg) { - x64emu_t *emu = (x64emu_t*)arg; + clone_t* args = arg; + x64emu_t *emu = args->emu; printf_log(LOG_DEBUG, "%04d|New clone32_fn starting with emu=%p (R_ESP=%p)\n", GetTID(), arg, from_ptrv(R_ESP)); thread_forget_emu(); thread_set_emu(emu); @@ -276,8 +282,13 @@ static int clone32_fn(void* arg) int ret = S_EAX; printf_log(LOG_DEBUG, "%04d|clone32_fn ending with ret=%d (emu=%p)\n", GetTID(), ret, arg); FreeX64Emu(&emu); - my_context->stack_clone_used = 0; - return ret; + void* stack2free = args->stack2free; + box_free(args); + if(my_context->stack_clone_used && !stack2free) + my_context->stack_clone_used = 0; + if(stack2free) + box_free(stack2free); // this free the stack, so it will crash very soon! + _exit(ret); } @@ -385,15 +396,17 @@ void EXPORT x86Syscall(x64emu_t *emu) CloneEmu(newemu, emu); newemu->regs[_SP].q[0] = sp; // setup new stack pointer void* mystack = NULL; + clone_t* args = box_calloc(1, sizeof(clone_t)); + args->emu = newemu; if(my_context->stack_clone_used) { - mystack = box_malloc(1024*1024); // stack for own process... memory leak, but no practical way to remove it + args->stack2free = mystack = box_malloc(1024*1024); // stack for own process... } else { if(!my_context->stack_clone) my_context->stack_clone = box_malloc(1024*1024); mystack = my_context->stack_clone; my_context->stack_clone_used = 1; } - int64_t ret = clone(clone32_fn, (void*)((uintptr_t)mystack+1024*1024), R_EBX, newemu, R_EDX, R_EDI, R_ESI); + int64_t ret = clone(clone32_fn, (void*)((uintptr_t)mystack+1024*1024), R_EBX, args, R_EDX, R_EDI, R_ESI); S_RAX = ret; } else |