about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rwxr-xr-xsrc/include/box64context.h1
-rwxr-xr-xsrc/include/librarian.h1
-rwxr-xr-xsrc/librarian/librarian.c23
-rwxr-xr-xsrc/librarian/library.c24
-rwxr-xr-xsrc/main.c19
-rwxr-xr-xsrc/wrapped/wrappedlibdl.c12
6 files changed, 53 insertions, 27 deletions
diff --git a/src/include/box64context.h b/src/include/box64context.h
index 2c0063e2..3fe285dc 100755
--- a/src/include/box64context.h
+++ b/src/include/box64context.h
@@ -59,6 +59,7 @@ void free_neededlib(needed_libs_t* needed);
 needed_libs_t* new_neededlib(int n);
 needed_libs_t* copy_neededlib(needed_libs_t* needed);
 void add1_neededlib(needed_libs_t* needed);
+void add1lib_neededlib(needed_libs_t* needed, library_t* lib, const char* name);
 
 typedef struct base_segment_s {
     uintptr_t       base;
diff --git a/src/include/librarian.h b/src/include/librarian.h
index b7a46880..2ff059df 100755
--- a/src/include/librarian.h
+++ b/src/include/librarian.h
@@ -22,6 +22,7 @@ void FreeDLPrivate(dlprivate_t **lib);
 box64context_t* GetLibrarianContext(lib_t* maplib);
 kh_mapsymbols_t* GetGlobalData(lib_t* maplib);
 int AddNeededLib(lib_t* maplib, int local, int bindnow, needed_libs_t* needed, box64context_t* box64, x64emu_t* emu); // 0=success, 1=error
+void RemoveNeededLib(lib_t* maplib, int local, needed_libs_t* needed, box64context_t* box64, x64emu_t* emu);
 library_t* GetLibMapLib(lib_t* maplib, const char* name);
 library_t* GetLibInternal(const char* name);
 uintptr_t FindGlobalSymbol(lib_t *maplib, const char* name, int version, const char* vername);
diff --git a/src/librarian/librarian.c b/src/librarian/librarian.c
index 6733c3af..e480f907 100755
--- a/src/librarian/librarian.c
+++ b/src/librarian/librarian.c
@@ -318,11 +318,6 @@ int AddNeededLib(lib_t* maplib, int local, int bindnow, needed_libs_t* needed, b
     }
     // error while loadind lib, unload...
     if(ret) {
-        for(int i=0; i<needed->size; ++i) {
-            if(box64_log>=LOG_DEBUG && needed->libs[i])
-                printf_log(LOG_DEBUG, "Will decref after failed load %s\n", needed->names[i]);
-            AddNeededLib_remove(maplib, local, &needed->libs[i], box64, emu);
-        }
         return ret;
     }
     // add dependant libs and init them
@@ -332,15 +327,19 @@ int AddNeededLib(lib_t* maplib, int local, int bindnow, needed_libs_t* needed, b
             if(!allow_missing_libs) ret = 1;
         }
     // error while loadind lib, unload...
-    if(ret) {
-        for(int i=0; i<needed->size; ++i) {
-            if(box64_log>=LOG_DEBUG && needed->libs[i])
-                printf_log(LOG_DEBUG, "Will remove after failed init %s\n", needed->names[i]);
-            AddNeededLib_remove(maplib, local, &needed->libs[i], box64, emu);
-        }
-    }
     return ret;
 }
+EXPORTDYN
+void RemoveNeededLib(lib_t* maplib, int local, needed_libs_t* needed, box64context_t* box64, x64emu_t* emu)
+{
+    if(!needed) // no needed libs, no problems
+        return;
+    for(int i=0; i<needed->size; ++i) {
+        if(box64_log>=LOG_DEBUG && needed->libs[i])
+            printf_log(LOG_DEBUG, "Will remove after failed init %s\n", needed->names[i]);
+        AddNeededLib_remove(maplib, local, &needed->libs[i], box64, emu);
+    }
+}
 
 library_t* GetLibMapLib(lib_t* maplib, const char* name)
 {
diff --git a/src/librarian/library.c b/src/librarian/library.c
index 9652fe7e..4c7995a7 100755
--- a/src/librarian/library.c
+++ b/src/librarian/library.c
@@ -1047,6 +1047,24 @@ void add1_neededlib(needed_libs_t* needed)
     needed->names = (char**)realloc(needed->names, needed->cap*sizeof(char*));
     needed->size++;
 }
+void add1lib_neededlib(needed_libs_t* needed, library_t* lib, const char* name)
+{
+    if(!needed || !lib)
+        return;
+    // check if lib is already present
+    for (int i=0; i<needed->size; ++i)
+        if(needed->libs[i]==lib)
+            return;
+    // add it
+    if(needed->size+1<=needed->cap)
+        return;
+    needed->cap = needed->size+1;
+    needed->libs = (library_t**)realloc(needed->libs, needed->cap*sizeof(library_t*));
+    needed->names = (char**)realloc(needed->names, needed->cap*sizeof(char*));
+    needed->libs[needed->size] = lib;
+    needed->names[needed->size] = name;
+    needed->size++;
+}
 needed_libs_t* copy_neededlib(needed_libs_t* needed)
 {
     if(!needed)
@@ -1098,8 +1116,10 @@ int DecRefCount(library_t** lib, x64emu_t* emu)
 {
     if(!lib || !*lib)
         return 1;
-    if((*lib)->type==LIB_UNNKNOW)
-        return 1;
+    if((*lib)->type==LIB_UNNKNOW) {
+        Free1Library(lib, emu);
+        return 0;
+    }
     int ret = 1;
     needed_libs_t* needed = NULL;
     int freed = 0;
diff --git a/src/main.c b/src/main.c
index b942f978..a8b0cff3 100755
--- a/src/main.c
+++ b/src/main.c
@@ -1701,12 +1701,19 @@ int main(int argc, const char **argv, char **env) {
     AddMainElfToLinkmap(elf_header);
     // pre-load lib if needed
     if(ld_preload.size) {
-        my_context->preload = new_neededlib(ld_preload.size);
-        for(int i=0; i<ld_preload.size; ++i)
-            my_context->preload->names[i] = ld_preload.paths[i];
-        if(AddNeededLib(my_context->maplib, 0, 0, my_context->preload, my_context, emu)) {
-            printf_log(LOG_INFO, "Warning, cannot pre-load of the libs\n");
-        }            
+        my_context->preload = new_neededlib(0);
+        for(int i=0; i<ld_preload.size; ++i) {
+            needed_libs_t* tmp = new_neededlib(1);
+            tmp->names[0] = ld_preload.paths[i];
+            if(AddNeededLib(my_context->maplib, 0, 0, tmp, my_context, emu)) {
+                printf_log(LOG_INFO, "Warning, cannot pre-load of %s\n", tmp->names[0]);
+                RemoveNeededLib(my_context->maplib, 0, tmp, my_context, emu);
+            } else {
+                for(int j=0; j<tmp->size; ++j)
+                    add1lib_neededlib(my_context->preload, tmp->libs[j], tmp->names[j]);
+                free_neededlib(tmp);
+            }
+        }
     }
     FreeCollection(&ld_preload);
     // Call librarian to load all dependant elf
diff --git a/src/wrapped/wrappedlibdl.c b/src/wrapped/wrappedlibdl.c
index 9267ee4b..34df9340 100755
--- a/src/wrapped/wrappedlibdl.c
+++ b/src/wrapped/wrappedlibdl.c
@@ -173,19 +173,17 @@ void* my_dlopen(x64emu_t* emu, void *filename, int flag)
         // Then open the lib
         my_context->deferredInit = 1;
         int bindnow = (!box64_musl && (flag&0x2))?1:0;
-        needed_libs_t tmp = {0};
-        char* names[] = {rfilename};
-        library_t* libs[] = { NULL };
-        tmp.size = tmp.cap = 1;
-        tmp.names = names;
-        tmp.libs = libs;
-        if(AddNeededLib(NULL, is_local, bindnow, &tmp, my_context, emu)) {
+        needed_libs_t *tmp = new_neededlib(1);
+        tmp->names[0] = rfilename;
+        if(AddNeededLib(NULL, is_local, bindnow, tmp, my_context, emu)) {
             printf_dlsym(strchr(rfilename,'/')?LOG_DEBUG:LOG_INFO, "Warning: Cannot dlopen(\"%s\"/%p, %X)\n", rfilename, filename, flag);
             if(!dl->last_error)
                 dl->last_error = box_malloc(129);
             snprintf(dl->last_error, 129, "Cannot dlopen(\"%s\"/%p, %X)\n", rfilename, filename, flag);
+            RemoveNeededLib(NULL, is_local, tmp, my_context, emu);
             return NULL;
         }
+        free_neededlib(tmp);
         lib = GetLibInternal(rfilename);
         RunDeferredElfInit(emu);
     } else {