about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2024-02-06 18:20:11 +0100
committerptitSeb <sebastien.chev@gmail.com>2024-02-06 18:20:11 +0100
commitee2580a57fae19e1c47a1af03dcfb3edffe697b3 (patch)
tree702dfb0ae7170c0a33c1761fb17cb801d73102f8
parent255d5c661e0cf1a4d2bd2664b2cc8cc7587b6226 (diff)
downloadbox64-ee2580a57fae19e1c47a1af03dcfb3edffe697b3.tar.gz
box64-ee2580a57fae19e1c47a1af03dcfb3edffe697b3.zip
Reworked, again, exit process
-rw-r--r--src/elfs/elfloader.c2
-rw-r--r--src/elfs/elfloader_private.h5
-rw-r--r--src/emu/x64emu.c44
-rw-r--r--src/include/x64emu.h7
-rw-r--r--src/main.c2
-rw-r--r--src/wrapped/wrappedlibc.c26
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);
 }