about summary refs log tree commit diff stats
path: root/src/librarian/library.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/librarian/library.c')
-rw-r--r--src/librarian/library.c57
1 files changed, 41 insertions, 16 deletions
diff --git a/src/librarian/library.c b/src/librarian/library.c
index 4f9c95c8..18fbe24f 100644
--- a/src/librarian/library.c
+++ b/src/librarian/library.c
@@ -217,7 +217,7 @@ static void initWrappedLib(library_t *lib, box64context_t* context) {
             lib->type = LIB_WRAPPED;
             lib->w.refcnt = 1;
             // Call librarian to load all dependant elf
-            if(AddNeededLib(context->maplib, 0, 0, lib->w.needed, context, thread_get_emu())) {
+            if(AddNeededLib(context->maplib, 0, 0, lib->w.needed, NULL, context, thread_get_emu())) {
                 printf_log(LOG_NONE, "Error: loading a needed libs in elf %s\n", lib->name);
                 return;
             }
@@ -240,7 +240,7 @@ static void initWrappedLib(library_t *lib, box64context_t* context) {
     }
 }
 
-static int loadEmulatedLib(const char* libname, library_t *lib, box64context_t* context)
+static int loadEmulatedLib(const char* libname, library_t *lib, box64context_t* context, elfheader_t* verneeded)
 {
     if(FileExist(libname, IS_FILE))
     {
@@ -255,28 +255,36 @@ static int loadEmulatedLib(const char* libname, library_t *lib, box64context_t*
             fclose(f);
             return 0;
         }
-        int mainelf = AddElfHeader(context, elf_header);
 
         if(CalcLoadAddr(elf_header)) {
             printf_log(LOG_NONE, "Error: reading elf header of %s\n", libname);
+            FreeElfHeader(&elf_header);
             fclose(f);
             return 0;
         }
         // allocate memory
         if(AllocElfMemory(context, elf_header, 0)) {
             printf_log(LOG_NONE, "Error: allocating memory for elf %s\n", libname);
+            FreeElfHeader(&elf_header);
             fclose(f);
             return 0;
         }
         // Load elf into memory
         if(LoadElfMemory(f, context, elf_header)) {
             printf_log(LOG_NONE, "Error: loading in memory elf %s\n", libname);
+            FreeElfHeader(&elf_header);
             fclose(f);
             return 0;
         }
         // can close the file now
         fclose(f);
+        if(verneeded && !isElfHasNeededVer(elf_header, lib->name, verneeded)) {
+            // incompatible, discard and continue the search
+            FreeElfHeader(&elf_header);
+            return 0;
+        }
 
+        int mainelf = AddElfHeader(context, elf_header);
         ElfAttachLib(elf_header, lib);
 
         lib->type = LIB_EMULATED;
@@ -301,6 +309,11 @@ static int loadEmulatedLib(const char* libname, library_t *lib, box64context_t*
             box64_dynarec_bigblock = 0;
             box64_dynarec_strongmem = 1;
         }
+        if(libname && box64_dynarec_jvm && strstr(libname, "libjvm.so")) {
+            printf_log(LOG_INFO, "libjvm detected, disable Dynarec BigBlock and enable Dynarec StrongMem\n");
+            box64_dynarec_bigblock = 0;
+            box64_dynarec_strongmem = 1;
+        }
         #endif
         if(libname && box64_libcef && strstr(libname, "libcef.so")) {
             printf_log(LOG_INFO, "libcef detected, using malloc_hack_2\n");
@@ -311,13 +324,13 @@ static int loadEmulatedLib(const char* libname, library_t *lib, box64context_t*
     return 0;
 }
 
-static void initEmulatedLib(const char* path, library_t *lib, box64context_t* context)
+static void initEmulatedLib(const char* path, library_t *lib, box64context_t* context, elfheader_t* verneeded)
 {
     char libname[MAX_PATH];
     strcpy(libname, path);
     int found = FileIsX64ELF(libname);
     if(found)
-        if(loadEmulatedLib(libname, lib, context))
+        if(loadEmulatedLib(libname, lib, context, verneeded))
             return;
     if(!strchr(path, '/'))
         for(int i=0; i<context->box64_ld_lib.size; ++i)
@@ -325,8 +338,15 @@ static void initEmulatedLib(const char* path, library_t *lib, box64context_t* co
             strcpy(libname, context->box64_ld_lib.paths[i]);
             strcat(libname, path);
             if(FileIsX64ELF(libname))
-                if(loadEmulatedLib(libname, lib, context))
+                if(loadEmulatedLib(libname, lib, context, verneeded))
                     return;
+            // also try x86_64 variant
+            strcpy(libname, context->box64_ld_lib.paths[i]);
+            strcat(libname, "x86_64/");
+            strcat(libname, path);
+            if(FileIsX64ELF(libname))
+                if(loadEmulatedLib(libname, lib, context, verneeded))
+                    return;            
         }
 }
 
@@ -348,7 +368,7 @@ static int isEssentialLib(const char* name) {
     return 0;
 }
 
-library_t *NewLibrary(const char* path, box64context_t* context)
+library_t *NewLibrary(const char* path, box64context_t* context, elfheader_t* verneeded)
 {
     printf_log(LOG_DEBUG, "Trying to load \"%s\"\n", path);
     library_t *lib = (library_t*)box_calloc(1, sizeof(library_t));
@@ -394,7 +414,7 @@ library_t *NewLibrary(const char* path, box64context_t* context)
         initWrappedLib(lib, context);
     // then look for a native one
     if(lib->type==LIB_UNNKNOW)
-        initEmulatedLib(path, lib, context);
+        initEmulatedLib(path, lib, context, verneeded);
     // still not loaded but notwrapped indicated: use wrapped...
     if(lib->type==LIB_UNNKNOW && notwrapped && !precise)
         initWrappedLib(lib, context);
@@ -610,11 +630,16 @@ int IsSameLib(library_t* lib, const char* path)
     if(!strchr(path, '/') || lib->type==LIB_WRAPPED || !lib->path) {
         if(strcmp(name, lib->name)==0)
             ret=1;
+        if(lib->type==LIB_EMULATED && lib->e.elf->soname && !strcmp(lib->e.elf->soname, path))
+            ret=1;
     } else {
         char rpath[PATH_MAX];
         box_realpath(path, rpath);
         if(!strcmp(rpath, lib->path))
             ret=1;
+        if(lib->type==LIB_EMULATED && lib->e.elf->path && !strcmp(lib->e.elf->path, rpath)) {
+            ret=1;
+        }
     }
     if(!ret) {
         int n = NbDot(name);
@@ -1104,21 +1129,21 @@ void setNeededLibs(library_t* lib, int n, ...)
 
 void IncRefCount(library_t* lib, x64emu_t* emu)
 {
-    if(lib->type==LIB_UNNKNOW)
+    if(!lib || lib->type==LIB_UNNKNOW)
         return;
     switch (lib->type) {
         case LIB_WRAPPED:
             ++lib->w.refcnt;
-            if(lib->w.needed)
+            /*if(lib->w.needed)
                 for(int i=0; i<lib->w.needed->size; ++i) {
                     IncRefCount(lib->w.needed->libs[i], emu);
-                }
+                }*/
             break;
         case LIB_EMULATED:
             ++lib->e.elf->refcnt;
-            if(lib->e.elf->needed)
-                for(int i=0; i<lib->e.elf->needed->size; ++i)
-                    IncRefCount(lib->e.elf->needed->libs[i], emu);
+            /*if(lib->e.elf->needed)
+                for(int i=0; i<lib->e.elf->needed->size; ++i)   // some libs may not be loaded yet
+                    IncRefCount(lib->e.elf->needed->libs[i], emu);*/
     }
 }
 
@@ -1155,9 +1180,9 @@ int DecRefCount(library_t** lib, x64emu_t* emu)
             }
             break;
     }
-    if(needed)
+    /*if(needed)
         for(int i=0; i<needed->size; ++i)
-            DecRefCount(&needed->libs[i], emu);
+            DecRefCount(&needed->libs[i], emu);*/
     if(freed)
         free_neededlib(needed);
     return ret;