diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2024-02-06 18:20:11 +0100 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2024-02-06 18:20:11 +0100 |
| commit | ee2580a57fae19e1c47a1af03dcfb3edffe697b3 (patch) | |
| tree | 702dfb0ae7170c0a33c1761fb17cb801d73102f8 /src | |
| parent | 255d5c661e0cf1a4d2bd2664b2cc8cc7587b6226 (diff) | |
| download | box64-ee2580a57fae19e1c47a1af03dcfb3edffe697b3.tar.gz box64-ee2580a57fae19e1c47a1af03dcfb3edffe697b3.zip | |
Reworked, again, exit process
Diffstat (limited to 'src')
| -rw-r--r-- | src/elfs/elfloader.c | 2 | ||||
| -rw-r--r-- | src/elfs/elfloader_private.h | 5 | ||||
| -rw-r--r-- | src/emu/x64emu.c | 44 | ||||
| -rw-r--r-- | src/include/x64emu.h | 7 | ||||
| -rw-r--r-- | src/main.c | 2 | ||||
| -rw-r--r-- | src/wrapped/wrappedlibc.c | 26 |
6 files changed, 51 insertions, 35 deletions
diff --git a/src/elfs/elfloader.c b/src/elfs/elfloader.c index be7b47b2..0b09f2db 100644 --- a/src/elfs/elfloader.c +++ b/src/elfs/elfloader.c @@ -1383,6 +1383,8 @@ void RunElfFini(elfheader_t* h, x64emu_t *emu) if(!h || h->fini_done || !h->init_done) return; h->fini_done = 1; + // Call the registered cxa_atexit functions + CallCleanup(emu, h); #ifdef ANDROID // TODO: Fix .fini_array on Android printf_log(LOG_DEBUG, "Android does not support Fini for %s\n", ElfName(h)); diff --git a/src/elfs/elfloader_private.h b/src/elfs/elfloader_private.h index 59b9b6ac..f13be551 100644 --- a/src/elfs/elfloader_private.h +++ b/src/elfs/elfloader_private.h @@ -5,6 +5,7 @@ typedef struct library_s library_t; typedef struct needed_libs_s needed_libs_t; typedef struct kh_mapsymbols_s kh_mapsymbols_t; typedef struct kh_defaultversion_s kh_defaultversion_t; +typedef struct cleanup_s cleanup_t; #include <elf.h> #include "elfloader.h" @@ -112,6 +113,10 @@ typedef struct elfheader_s { FILE* file; int fileno; + cleanup_t *cleanups; // atexit functions + int clean_sz; + int clean_cap; + kh_mapsymbols_t *mapsymbols; kh_mapsymbols_t *weaksymbols; kh_mapsymbols_t *localsymbols; diff --git a/src/emu/x64emu.c b/src/emu/x64emu.c index 48a8e584..38f2f20a 100644 --- a/src/emu/x64emu.c +++ b/src/emu/x64emu.c @@ -17,6 +17,7 @@ #include "x64run_private.h" #include "callback.h" #include "bridge.h" +#include "elfs/elfloader_private.h" #ifdef HAVE_TRACE #include "x64trace.h" #endif @@ -33,7 +34,6 @@ typedef struct cleanup_s { void* f; int arg; void* a; - void* dso; } cleanup_t; static uint32_t x86emu_parity_tab[8] = @@ -132,7 +132,7 @@ void SetTraceEmu(uintptr_t start, uintptr_t end) } #endif -void AddCleanup(x64emu_t *emu, void *p, void* dso_handle) +void AddCleanup(x64emu_t *emu, void *p) { (void)emu; @@ -142,36 +142,36 @@ void AddCleanup(x64emu_t *emu, void *p, void* dso_handle) } my_context->cleanups[my_context->clean_sz].arg = 0; my_context->cleanups[my_context->clean_sz].a = NULL; - my_context->cleanups[my_context->clean_sz].dso = dso_handle; my_context->cleanups[my_context->clean_sz++].f = p; } -void AddCleanup1Arg(x64emu_t *emu, void *p, void* a, void* dso_handle) +void AddCleanup1Arg(x64emu_t *emu, void *p, void* a, elfheader_t* h) { (void)emu; + if(!h) + return; - if(my_context->clean_sz == my_context->clean_cap) { - my_context->clean_cap += 32; - my_context->cleanups = (cleanup_t*)box_realloc(my_context->cleanups, sizeof(cleanup_t)*my_context->clean_cap); + if(h->clean_sz == h->clean_cap) { + h->clean_cap += 32; + h->cleanups = (cleanup_t*)box_realloc(h->cleanups, sizeof(cleanup_t)*h->clean_cap); } - my_context->cleanups[my_context->clean_sz].arg = 1; - my_context->cleanups[my_context->clean_sz].a = a; - my_context->cleanups[my_context->clean_sz].dso = dso_handle; - my_context->cleanups[my_context->clean_sz++].f = p; + h->cleanups[h->clean_sz].arg = 1; + h->cleanups[h->clean_sz].a = a; + h->cleanups[h->clean_sz++].f = p; } -void CallCleanup(x64emu_t *emu, void* p) +void CallCleanup(x64emu_t *emu, elfheader_t* h) { - printf_log(LOG_DEBUG, "Calling atexit registered functions for %p mask\n", p); - for(int i=my_context->clean_sz-1; i>=0; --i) { - if(p==my_context->cleanups[i].dso) { - printf_log(LOG_DEBUG, "Call cleanup #%d\n", i); - RunFunctionWithEmu(emu, 0, (uintptr_t)(my_context->cleanups[i].f), my_context->cleanups[i].arg, my_context->cleanups[i].a ); - // now remove the cleanup - if(i!=my_context->clean_sz-1) - memmove(my_context->cleanups+i, my_context->cleanups+i+1, (my_context->clean_sz-i-1)*sizeof(cleanup_t)); - --my_context->clean_sz; - } + printf_log(LOG_DEBUG, "Calling atexit registered functions for elf: %p/%s\n", h, h?h->name:"(nil)"); + if(!h) + return; + for(int i=h->clean_sz-1; i>=0; --i) { + printf_log(LOG_DEBUG, "Call cleanup #%d\n", i); + RunFunctionWithEmu(emu, 0, (uintptr_t)(h->cleanups[i].f), h->cleanups[i].arg, h->cleanups[i].a ); + // now remove the cleanup + if(i!=h->clean_sz-1) + memmove(h->cleanups+i, h->cleanups+i+1, (h->clean_sz-i-1)*sizeof(cleanup_t)); + --h->clean_sz; } } diff --git a/src/include/x64emu.h b/src/include/x64emu.h index 51a27a18..e0adf686 100644 --- a/src/include/x64emu.h +++ b/src/include/x64emu.h @@ -3,6 +3,7 @@ typedef struct x64emu_s x64emu_t; typedef struct box64context_s box64context_t; +typedef struct elfheader_s elfheader_t; x64emu_t *NewX64Emu(box64context_t *context, uintptr_t start, uintptr_t stack, int stacksize, int ownstack); x64emu_t *NewX64EmuFromStack(x64emu_t* emu, box64context_t *context, uintptr_t start, uintptr_t stack, int stacksize, int ownstack); @@ -45,9 +46,9 @@ const char* DumpCPURegs(x64emu_t* emu, uintptr_t ip, int is32bits); void StopEmu(x64emu_t* emu, const char* reason, int is32bits); void EmuCall(x64emu_t* emu, uintptr_t addr); -void AddCleanup(x64emu_t *emu, void *p, void* dso_handle); -void AddCleanup1Arg(x64emu_t *emu, void *p, void* a, void* dso_handle); -void CallCleanup(x64emu_t *emu, void* p); +void AddCleanup(x64emu_t *emu, void *p); +void AddCleanup1Arg(x64emu_t *emu, void *p, void* a, elfheader_t* h); +void CallCleanup(x64emu_t *emu, elfheader_t* h); void CallAllCleanup(x64emu_t *emu); void UnimpOpcode(x64emu_t* emu, int is32bits); diff --git a/src/main.c b/src/main.c index cdc91fe0..9ed59359 100644 --- a/src/main.c +++ b/src/main.c @@ -1383,6 +1383,8 @@ void endBox64() box64_quit = 1; endMallocHook(); x64emu_t* emu = thread_get_emu(); + void startTimedExit(); + startTimedExit(); // atexit first printf_log(LOG_DEBUG, "Calling atexit registered functions (exiting box64)\n"); CallAllCleanup(emu); diff --git a/src/wrapped/wrappedlibc.c b/src/wrapped/wrappedlibc.c index 53c0e749..428946b9 100644 --- a/src/wrapped/wrappedlibc.c +++ b/src/wrapped/wrappedlibc.c @@ -485,7 +485,7 @@ void EXPORT my___gmon_start__(x64emu_t *emu) int EXPORT my___cxa_atexit(x64emu_t* emu, void* p, void* a, void* dso_handle) { - AddCleanup1Arg(emu, p, a, dso_handle); + AddCleanup1Arg(emu, p, a, FindElfAddress(my_context, (uintptr_t)dso_handle)); return 0; } void EXPORT my___cxa_finalize(x64emu_t* emu, void* p) @@ -495,11 +495,11 @@ void EXPORT my___cxa_finalize(x64emu_t* emu, void* p) CallAllCleanup(emu); return; } - CallCleanup(emu, p); + CallCleanup(emu, FindElfAddress(my_context, (uintptr_t)p)); } int EXPORT my_atexit(x64emu_t* emu, void *p) { - AddCleanup(emu, p, NULL); // should grab current dso_handle? + AddCleanup(emu, p); return 0; } @@ -2308,7 +2308,7 @@ EXPORT int32_t my___cxa_thread_atexit_impl(x64emu_t* emu, void* dtor, void* obj, { (void)emu; //printf_log(LOG_INFO, "Warning, call to __cxa_thread_atexit_impl(%p, %p, %p) ignored\n", dtor, obj, dso); - AddCleanup1Arg(emu, dtor, obj, dso); + AddCleanup1Arg(emu, dtor, obj, FindElfAddress(my_context, (uintptr_t)dso)); return 0; } @@ -3375,7 +3375,6 @@ EXPORT int my_register_printf_type(x64emu_t* emu, void* f) extern int box64_quit; extern int box64_exit_code; void endBox64(); -#if !defined(ANDROID) static void* timed_exit_thread(void* a) { // this is a workaround for some NVidia drivers on ARM64 that may freeze at exit @@ -3383,7 +3382,17 @@ static void* timed_exit_thread(void* a) usleep(500000); // wait 1/2 a second _exit(box64_exit_code); // force exit, something is wrong } -#endif + +void startTimedExit() +{ + static int started = 0; + if(started) + exit; + started = 1; + pthread_t exit_thread; + pthread_create(&exit_thread, NULL, timed_exit_thread, NULL); +} + EXPORT void my_exit(x64emu_t* emu, int code) { if(emu->flags.quitonexit) { @@ -3395,10 +3404,7 @@ EXPORT void my_exit(x64emu_t* emu, int code) emu->quit = 1; box64_exit_code = code; endBox64(); -#if !defined(ANDROID) - pthread_t exit_thread; - pthread_create(&exit_thread, NULL, timed_exit_thread, NULL); -#endif + startTimedExit(); exit(code); } |