about summary refs log tree commit diff stats
path: root/src/wrapped
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2024-01-19 15:09:20 +0100
committerptitSeb <sebastien.chev@gmail.com>2024-01-19 15:09:20 +0100
commite4c64073c5b433d8a59f1a456518a45037a414dc (patch)
tree87a3f5509fdfaa76f91a26f8eb97a7c0144a4664 /src/wrapped
parent0ff15e91d94e82fdb3d1a7de4529c58774550c07 (diff)
downloadbox64-e4c64073c5b433d8a59f1a456518a45037a414dc.tar.gz
box64-e4c64073c5b433d8a59f1a456518a45037a414dc.zip
Reworked exit, unloading libs and running Fini as it should (plus a workaround for nvidia driver not unloading)
Diffstat (limited to 'src/wrapped')
-rw-r--r--src/wrapped/wrappedlibc.c23
-rw-r--r--src/wrapped/wrappedlibdl.c35
2 files changed, 54 insertions, 4 deletions
diff --git a/src/wrapped/wrappedlibc.c b/src/wrapped/wrappedlibc.c
index 347a38e6..583f9b2e 100644
--- a/src/wrapped/wrappedlibc.c
+++ b/src/wrapped/wrappedlibc.c
@@ -522,7 +522,7 @@ pid_t EXPORT my_fork(x64emu_t* emu)
 {
     #if 1
     emu->quit = 1;
-    emu->fork = 3;  // use regular fork...
+    emu->fork = 1;  // use regular fork...
     return 0;
     #else
     // execute atforks prepare functions, in reverse order
@@ -3372,6 +3372,17 @@ 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*)
+{
+    // this is a workaround for some NVidia drivers on ARM64 that may freeze at exit
+    // waiting on a pthread_cond_destroy
+    usleep(500000); // wait 1/2 a second
+    _exit(box64_exit_code); // force exit, something is wrong
+}
+#endif
 EXPORT void my_exit(x64emu_t* emu, int code)
 {
     if(emu->flags.quitonexit) {
@@ -3381,7 +3392,12 @@ EXPORT void my_exit(x64emu_t* emu, int code)
         return;
     }
     emu->quit = 1;
-    box64_quit = 1;
+    box64_exit_code = code;
+    endBox64();
+#if !defined(ANDROID)
+    pthread_t exit_thread;
+    pthread_create(&exit_thread, NULL, timed_exit_thread, NULL);
+#endif
     exit(code);
 }
 
@@ -3472,6 +3488,7 @@ EXPORT char my___libc_single_threaded = 0;
         setNeededLibs(lib, NEEDED_LIBS);
 
 #define CUSTOM_FINI \
-    freeMy();
+    freeMy();       \
+    return;     // do not unload...
 
 #include "wrappedlib_init.h"
diff --git a/src/wrapped/wrappedlibdl.c b/src/wrapped/wrappedlibdl.c
index 7ccf0e1c..11278c1c 100644
--- a/src/wrapped/wrappedlibdl.c
+++ b/src/wrapped/wrappedlibdl.c
@@ -176,8 +176,16 @@ void* my_dlopen(x64emu_t* emu, void *filename, int flag)
             return NULL;
         }
         dlopened = (lib==NULL);
-        // Then open the lib
+        // cleanup the old deferredInit state
+        int old_deferredInit = my_context->deferredInit;
         my_context->deferredInit = 1;
+        elfheader_t** old_deferredInitList = my_context->deferredInitList;
+        my_context->deferredInitList = NULL;
+        int old_deferredInitSz = my_context->deferredInitSz;
+        int old_deferredInitCap = my_context->deferredInitCap;
+        my_context->deferredInitSz = my_context->deferredInitCap = 0;
+
+        // Then open the lib
         int bindnow = (!box64_musl && (flag&0x2))?1:0;
         needed_libs_t *tmp = new_neededlib(1);
         tmp->names[0] = rfilename;
@@ -187,11 +195,21 @@ void* my_dlopen(x64emu_t* emu, void *filename, int flag)
                 dl->last_error = box_calloc(1, 129);
             snprintf(dl->last_error, 129, "Cannot dlopen(\"%s\"/%p, %X)\n", rfilename, filename, flag);
             RemoveNeededLib(NULL, is_local, tmp, my_context, emu);
+            if(my_context->deferredInitList)
+                box_free(my_context->deferredInitList);
+            my_context->deferredInit = old_deferredInit;
+            my_context->deferredInitList = old_deferredInitList;
+            my_context->deferredInitSz = old_deferredInitSz;
+            my_context->deferredInitCap = old_deferredInitCap;
             return NULL;
         }
         free_neededlib(tmp);
         lib = GetLibInternal(rfilename);
         RunDeferredElfInit(emu);
+        my_context->deferredInit = old_deferredInit;
+        my_context->deferredInitList = old_deferredInitList;
+        my_context->deferredInitSz = old_deferredInitSz;
+        my_context->deferredInitCap = old_deferredInitCap;
     } else {
         // check if already dlopenned...
         for (size_t i=MIN_NLIB; i<dl->lib_sz; ++i) {
@@ -585,6 +603,21 @@ EXPORT int my__dl_find_object(x64emu_t* emu, void* addr, my_dl_find_object_t* re
     return -1;
 }
 
+void closeAllDLOpenned()
+{
+    dlprivate_t *dl = my_context->dlprivate;
+    if(dl) {
+        x64emu_t* emu = thread_get_emu();
+        for(size_t i=0; i<dl->lib_sz; ++i)
+            while(dl->dllibs[i].count) {
+                printf_log(LOG_DEBUG, "  closing %s\n", dl->dllibs[i].lib->name);
+                my_dlclose(emu, (void*)(i+1));
+            }
+    }
+}
+
+#define CUSTOM_FINI \
+    closeAllDLOpenned();
 
 // define all standard library functions
 #include "wrappedlib_init.h"