about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2024-02-11 16:46:21 +0100
committerptitSeb <sebastien.chev@gmail.com>2024-02-11 16:46:21 +0100
commitc70581abc9380ab57deba3f8076e26191b5c2755 (patch)
tree267e6630695ffc7b618d58e0cb01117bd9975abc /src
parent5e6af3753292b8da43d4fbee186a78f3e5068141 (diff)
downloadbox64-c70581abc9380ab57deba3f8076e26191b5c2755.tar.gz
box64-c70581abc9380ab57deba3f8076e26191b5c2755.zip
Added support for RTLD_DEEPBIND flag on dlopen
Diffstat (limited to 'src')
-rw-r--r--src/elfs/elfloader.c72
-rw-r--r--src/include/elfloader.h6
-rw-r--r--src/include/librarian.h4
-rw-r--r--src/include/library.h3
-rw-r--r--src/librarian/librarian.c52
-rw-r--r--src/librarian/library.c16
-rw-r--r--src/librarian/library_private.h5
-rw-r--r--src/main.c8
-rw-r--r--src/wrapped/wrappedlibdl.c38
9 files changed, 119 insertions, 85 deletions
diff --git a/src/elfs/elfloader.c b/src/elfs/elfloader.c
index 4edd194b..8d8500d7 100644
--- a/src/elfs/elfloader.c
+++ b/src/elfs/elfloader.c
@@ -445,7 +445,7 @@ int FindR64COPYRel(elfheader_t* h, const char* name, uintptr_t *offs, uint64_t**
     return 0;
 }
 
-int RelocateElfREL(lib_t *maplib, lib_t *local_maplib, int bindnow, elfheader_t* head, int cnt, Elf64_Rel *rel)
+int RelocateElfREL(lib_t *maplib, lib_t *local_maplib, int bindnow, int deepbind, elfheader_t* head, int cnt, Elf64_Rel *rel)
 {
     int ret_ok = 0;
     for (int i=0; i<cnt; ++i) {
@@ -462,17 +462,19 @@ int RelocateElfREL(lib_t *maplib, lib_t *local_maplib, int bindnow, elfheader_t*
         int version = head->VerSym?((Elf64_Half*)((uintptr_t)head->VerSym+head->delta))[ELF64_R_SYM(rel[i].r_info)]:-1;
         if(version!=-1) version &=0x7fff;
         const char* vername = GetSymbolVersion(head, version);
-        const char* globdefver = (bind==STB_WEAK)?NULL:GetMaplibDefaultVersion(maplib, local_maplib, 0, symname);
-        const char* weakdefver = (bind==STB_WEAK || !globdefver)?GetMaplibDefaultVersion(maplib, local_maplib, 1, symname):NULL;
+        const char* globdefver = (bind==STB_WEAK)?NULL:GetMaplibDefaultVersion(maplib, local_maplib, 0, deepbind, symname);
+        const char* weakdefver = (bind==STB_WEAK || !globdefver)?GetMaplibDefaultVersion(maplib, local_maplib, 1, deepbind, symname):NULL;
         if(bind==STB_LOCAL) {
             if(!symname || !symname[0]) {
                 offs = sym->st_value + head->delta;
                 end = offs + sym->st_size;
             } else {
-                if(!offs && !end && local_maplib)
+                if(!offs && !end && local_maplib && deepbind)
                     GetLocalSymbolStartEnd(local_maplib, symname, &offs, &end, head, version, vername, globdefver, weakdefver);
                 if(!offs && !end)
                     GetLocalSymbolStartEnd(maplib, symname, &offs, &end, head, version, vername, globdefver, weakdefver);
+                if(!offs && !end && local_maplib && !deepbind)
+                    GetLocalSymbolStartEnd(local_maplib, symname, &offs, &end, head, version, vername, globdefver, weakdefver);
             }
         } else {
             // this is probably very very wrong. A proprer way to get reloc need to be written, but this hack seems ok for now
@@ -484,17 +486,21 @@ int RelocateElfREL(lib_t *maplib, lib_t *local_maplib, int bindnow, elfheader_t*
             // so weak symbol are the one left
             if(bind==STB_WEAK) {
                 if(!offs && !end) {
-                    if(!offs && !end && local_maplib)
+                    if(!offs && !end && local_maplib && deepbind)
                         GetGlobalWeakSymbolStartEnd(local_maplib, symname, &offs, &end, head, version, vername, globdefver, weakdefver);
                     if(!offs && !end)
                         GetGlobalWeakSymbolStartEnd(maplib, symname, &offs, &end, head, version, vername, globdefver, weakdefver);
+                    if(!offs && !end && local_maplib && !deepbind)
+                        GetGlobalWeakSymbolStartEnd(local_maplib, symname, &offs, &end, head, version, vername, globdefver, weakdefver);
                 }
             } else {
                 if(!offs && !end) {
-                    if(!offs && !end && local_maplib)
+                    if(!offs && !end && local_maplib && deepbind)
                         GetGlobalSymbolStartEnd(local_maplib, symname, &offs, &end, head, version, vername, globdefver, weakdefver);
                     if(!offs && !end)
                         GetGlobalSymbolStartEnd(maplib, symname, &offs, &end, head, version, vername, globdefver, weakdefver);
+                    if(!offs && !end && local_maplib && !deepbind)
+                        GetGlobalSymbolStartEnd(local_maplib, symname, &offs, &end, head, version, vername, globdefver, weakdefver);
                 }
             }
         }
@@ -635,7 +641,7 @@ EXPORT uintptr_t _dl_tlsdesc_undefweak(x64emu_t* emu)
 }
 
 
-int RelocateElfRELA(lib_t *maplib, lib_t *local_maplib, int bindnow, elfheader_t* head, int cnt, Elf64_Rela *rela, int* need_resolv)
+int RelocateElfRELA(lib_t *maplib, lib_t *local_maplib, int bindnow, int deepbind, elfheader_t* head, int cnt, Elf64_Rela *rela, int* need_resolv)
 {
     int ret_ok = 0;
     const char* old_globdefver = NULL;
@@ -665,8 +671,8 @@ int RelocateElfRELA(lib_t *maplib, lib_t *local_maplib, int bindnow, elfheader_t
             globdefver = old_globdefver;
             weakdefver = old_weakdefver;
         } else {
-            old_globdefver = globdefver = (bind==STB_WEAK)?NULL:GetMaplibDefaultVersion(maplib, local_maplib, 0, symname);
-            old_weakdefver = weakdefver = (bind==STB_WEAK || !globdefver)?GetMaplibDefaultVersion(maplib, local_maplib, 1, symname):NULL;
+            old_globdefver = globdefver = (bind==STB_WEAK)?NULL:GetMaplibDefaultVersion(maplib, local_maplib, 0, deepbind, symname);
+            old_weakdefver = weakdefver = (bind==STB_WEAK || !globdefver)?GetMaplibDefaultVersion(maplib, local_maplib, 1, deepbind, symname):NULL;
         }
         if(bind==STB_LOCAL) {
             if(!symname || !symname[0]) {
@@ -677,10 +683,12 @@ int RelocateElfRELA(lib_t *maplib, lib_t *local_maplib, int bindnow, elfheader_t
                     offs = old_offs;
                     end = old_end;
                 } else {
-                    if(local_maplib)
+                    if(local_maplib && deepbind)
                         GetLocalSymbolStartEnd(local_maplib, symname, &offs, &end, head, version, vername, globdefver, weakdefver);
                     if(!offs && !end)
                         GetLocalSymbolStartEnd(maplib, symname, &offs, &end, head, version, vername, globdefver, weakdefver);
+                    if(!offs && !end && local_maplib && !deepbind)
+                        GetLocalSymbolStartEnd(local_maplib, symname, &offs, &end, head, version, vername, globdefver, weakdefver);
                 }
             }
         } else {
@@ -696,8 +704,11 @@ int RelocateElfRELA(lib_t *maplib, lib_t *local_maplib, int bindnow, elfheader_t
                     offs = old_offs;
                     end = old_end;
                 } else {
-                    GetGlobalWeakSymbolStartEnd(maplib, symname, &offs, &end, head, version, vername, globdefver, weakdefver);
-                    if(!offs && !end && local_maplib)
+                    if(local_maplib && deepbind)
+                        GetGlobalWeakSymbolStartEnd(local_maplib, symname, &offs, &end, head, version, vername, globdefver, weakdefver);
+                    else
+                        GetGlobalWeakSymbolStartEnd(maplib, symname, &offs, &end, head, version, vername, globdefver, weakdefver);
+                    if(!offs && !end && local_maplib && !deepbind)
                         GetGlobalWeakSymbolStartEnd(local_maplib, symname, &offs, &end, head, version, vername, globdefver, weakdefver);
                 }
             } else {
@@ -705,10 +716,12 @@ int RelocateElfRELA(lib_t *maplib, lib_t *local_maplib, int bindnow, elfheader_t
                     offs = old_offs;
                     end = old_end;
                 } else {
-                    if(!offs && !end && local_maplib)
+                    if(!offs && !end && local_maplib && deepbind)
                         GetGlobalSymbolStartEnd(local_maplib, symname, &offs, &end, head, version, vername, globdefver, weakdefver);
                     if(!offs && !end)
                         GetGlobalSymbolStartEnd(maplib, symname, &offs, &end, head, version, vername, globdefver, weakdefver);
+                    if(!offs && !end && local_maplib && !deepbind)
+                        GetGlobalSymbolStartEnd(local_maplib, symname, &offs, &end, head, version, vername, globdefver, weakdefver);
                 }
             }
         }
@@ -921,7 +934,7 @@ int RelocateElfRELA(lib_t *maplib, lib_t *local_maplib, int bindnow, elfheader_t
     }
     return bindnow?ret_ok:0;
 }
-int RelocateElf(lib_t *maplib, lib_t *local_maplib, int bindnow, elfheader_t* head)
+int RelocateElf(lib_t *maplib, lib_t *local_maplib, int bindnow, int deepbind, elfheader_t* head)
 {
     if((head->flags&DF_BIND_NOW) && !bindnow) {
         bindnow = 1;
@@ -931,20 +944,20 @@ int RelocateElf(lib_t *maplib, lib_t *local_maplib, int bindnow, elfheader_t* he
         int cnt = head->relsz / head->relent;
         DumpRelTable(head, cnt, (Elf64_Rel *)(head->rel + head->delta), "Rel");
         printf_dump(LOG_DEBUG, "Applying %d Relocation(s) for %s\n", cnt, head->name);
-        if(RelocateElfREL(maplib, local_maplib, bindnow, head, cnt, (Elf64_Rel *)(head->rel + head->delta)))
+        if(RelocateElfREL(maplib, local_maplib, bindnow, deepbind, head, cnt, (Elf64_Rel *)(head->rel + head->delta)))
             return -1;
     }
     if(head->rela) {
         int cnt = head->relasz / head->relaent;
         DumpRelATable(head, cnt, (Elf64_Rela *)(head->rela + head->delta), "RelA");
         printf_dump(LOG_DEBUG, "Applying %d Relocation(s) with Addend for %s\n", cnt, head->name);
-        if(RelocateElfRELA(maplib, local_maplib, bindnow, head, cnt, (Elf64_Rela *)(head->rela + head->delta), NULL))
+        if(RelocateElfRELA(maplib, local_maplib, bindnow, deepbind, head, cnt, (Elf64_Rela *)(head->rela + head->delta), NULL))
             return -1;
     }
     return 0;
 }
 
-int RelocateElfPlt(lib_t *maplib, lib_t *local_maplib, int bindnow, elfheader_t* head)
+int RelocateElfPlt(lib_t *maplib, lib_t *local_maplib, int bindnow, int deepbind, elfheader_t* head)
 {
     int need_resolver = 0;
     if((head->flags&DF_BIND_NOW) && !bindnow) {
@@ -956,12 +969,12 @@ int RelocateElfPlt(lib_t *maplib, lib_t *local_maplib, int bindnow, elfheader_t*
         if(head->pltrel==DT_REL) {
             DumpRelTable(head, cnt, (Elf64_Rel *)(head->jmprel + head->delta), "PLT");
             printf_dump(LOG_DEBUG, "Applying %d PLT Relocation(s) for %s\n", cnt, head->name);
-            if(RelocateElfREL(maplib, local_maplib, bindnow, head, cnt, (Elf64_Rel *)(head->jmprel + head->delta)))
+            if(RelocateElfREL(maplib, local_maplib, bindnow, deepbind, head, cnt, (Elf64_Rel *)(head->jmprel + head->delta)))
                 return -1;
         } else if(head->pltrel==DT_RELA) {
             DumpRelATable(head, cnt, (Elf64_Rela *)(head->jmprel + head->delta), "PLT");
             printf_dump(LOG_DEBUG, "Applying %d PLT Relocation(s) with Addend for %s\n", cnt, head->name);
-            if(RelocateElfRELA(maplib, local_maplib, bindnow, head, cnt, (Elf64_Rela *)(head->jmprel + head->delta), &need_resolver))
+            if(RelocateElfRELA(maplib, local_maplib, bindnow, deepbind, head, cnt, (Elf64_Rela *)(head->jmprel + head->delta), &need_resolver))
                 return -1;
         }
         if(need_resolver) {
@@ -1106,6 +1119,9 @@ void AddSymbols(lib_t *maplib, kh_mapsymbols_t* mapsymbols, kh_mapsymbols_t* wea
         }
     }
     
+    int deepbind = 0;
+    if(h && h->lib)
+        deepbind = GetDeepBind(h->lib);
     printf_dump(LOG_NEVER, "Will look for Symbol to add in DynSym (%zu)\n", h->numDynSym);
     for (size_t i=0; i<h->numDynSym; ++i) {
         const char * symname = h->DynStr+h->DynSym[i].st_name;
@@ -1117,7 +1133,7 @@ void AddSymbols(lib_t *maplib, kh_mapsymbols_t* mapsymbols, kh_mapsymbols_t* wea
             uintptr_t offs = (type==STT_TLS)?h->DynSym[i].st_value:(h->DynSym[i].st_value + h->delta);
             size_t sz = h->DynSym[i].st_size;
             int version = h->VerSym?((Elf64_Half*)((uintptr_t)h->VerSym+h->delta))[i]:-1;
-            int add_default = (version!=-1 && (version&0x7fff)>1 && !(version&0x8000) && !GetMaplibDefaultVersion(my_context->maplib, (maplib==my_context->maplib)?NULL:maplib, (bind==STB_WEAK)?1:0, symname))?1:0;
+            int add_default = (version!=-1 && (version&0x7fff)>1 && !(version&0x8000) && !GetMaplibDefaultVersion(my_context->maplib, (maplib==my_context->maplib)?NULL:maplib, (bind==STB_WEAK)?1:0, deepbind, symname))?1:0;
             if(version!=-1) version &= 0x7fff;
             const char* vername = GetSymbolVersion(h, version);
             if(add_default) {
@@ -1155,7 +1171,7 @@ $PLATFORM – Expands to the processor type of the current machine (see the
 uname(1) man page description of the -i option). For more details of this token
 expansion, see “System Specific Shared Objects”
 */
-int LoadNeededLibs(elfheader_t* h, lib_t *maplib, int local, int bindnow, box64context_t *box64, x64emu_t* emu)
+int LoadNeededLibs(elfheader_t* h, lib_t *maplib, int local, int bindnow, int deepbind, box64context_t *box64, x64emu_t* emu)
 {
     if(h->needed)   // already done
         return 0;
@@ -1235,7 +1251,7 @@ int LoadNeededLibs(elfheader_t* h, lib_t *maplib, int local, int bindnow, box64c
             h->needed->names[j++] = h->DynStrTab+h->delta+h->Dynamic[i].d_un.d_val;
 
     // TODO: Add LD_LIBRARY_PATH and RPATH handling
-    if(AddNeededLib(maplib, local, bindnow, h->needed, h, box64, emu)) {
+    if(AddNeededLib(maplib, local, bindnow, deepbind, h->needed, h, box64, emu)) {
         printf_log(LOG_INFO, "Error loading one of needed lib\n");
         if(!allow_missing_libs)
             return 1;   //error...
@@ -1889,10 +1905,14 @@ EXPORT void PltResolver(x64emu_t* emu)
 
     library_t* lib = h->lib;
     lib_t* local_maplib = GetMaplib(lib);
-    const char* globdefver = (bind==STB_WEAK)?NULL:GetMaplibDefaultVersion(my_context->maplib, (my_context->maplib==local_maplib)?NULL:local_maplib, 0, symname);
-    const char* weakdefver = (bind==STB_WEAK)?GetMaplibDefaultVersion(my_context->maplib, (my_context->maplib==local_maplib)?NULL:local_maplib, 1, symname):NULL;
-    GetGlobalSymbolStartEnd(my_context->maplib, symname, &offs, &end, h, version, vername, globdefver, weakdefver);
-    if(!offs && !end && local_maplib) {
+    int deepbind = GetDeepBind(lib);
+    const char* globdefver = (bind==STB_WEAK)?NULL:GetMaplibDefaultVersion(my_context->maplib, (my_context->maplib==local_maplib)?NULL:local_maplib, 0, deepbind, symname);
+    const char* weakdefver = (bind==STB_WEAK)?GetMaplibDefaultVersion(my_context->maplib, (my_context->maplib==local_maplib)?NULL:local_maplib, 1, deepbind, symname):NULL;
+    if(!offs && !end && local_maplib && deepbind)
+        GetGlobalSymbolStartEnd(local_maplib, symname, &offs, &end, h, version, vername, globdefver, weakdefver);
+    else
+        GetGlobalSymbolStartEnd(my_context->maplib, symname, &offs, &end, h, version, vername, globdefver, weakdefver);
+    if(!offs && !end && local_maplib && !deepbind) {
         GetGlobalSymbolStartEnd(local_maplib, symname, &offs, &end, h, version, vername, globdefver, weakdefver);
     }
     if(!offs && !end && !version)
diff --git a/src/include/elfloader.h b/src/include/elfloader.h
index bc09ad31..80289c5c 100644
--- a/src/include/elfloader.h
+++ b/src/include/elfloader.h
@@ -26,13 +26,13 @@ int CalcLoadAddr(elfheader_t* head);
 int AllocLoadElfMemory(box64context_t* context, elfheader_t* head, int mainbin);
 void FreeElfMemory(elfheader_t* head);
 int isElfHasNeededVer(elfheader_t* head, const char* libname, elfheader_t* verneeded);
-int RelocateElf(lib_t *maplib, lib_t* local_maplib, int bindnow, elfheader_t* head);
-int RelocateElfPlt(lib_t *maplib, lib_t* local_maplib, int bindnow, elfheader_t* head);
+int RelocateElf(lib_t *maplib, lib_t* local_maplib, int bindnow, int deepbind, elfheader_t* head);
+int RelocateElfPlt(lib_t *maplib, lib_t* local_maplib, int bindnow, int deepbind, elfheader_t* head);
 void CalcStack(elfheader_t* h, uint64_t* stacksz, size_t* stackalign);
 uintptr_t GetEntryPoint(lib_t* maplib, elfheader_t* h);
 uintptr_t GetLastByte(elfheader_t* h);
 void AddSymbols(lib_t *maplib, kh_mapsymbols_t* mapsymbols, kh_mapsymbols_t* weaksymbols, kh_mapsymbols_t* localsymbols, elfheader_t* h);
-int LoadNeededLibs(elfheader_t* h, lib_t *maplib, int local, int bindnow, box64context_t *box64, x64emu_t* emu);
+int LoadNeededLibs(elfheader_t* h, lib_t *maplib, int local, int bindnow, int deepbind, box64context_t *box64, x64emu_t* emu);
 uintptr_t GetElfInit(elfheader_t* h);
 uintptr_t GetElfFini(elfheader_t* h);
 void RefreshElfTLS(elfheader_t* h);
diff --git a/src/include/librarian.h b/src/include/librarian.h
index 13cb3890..2864f246 100644
--- a/src/include/librarian.h
+++ b/src/include/librarian.h
@@ -21,7 +21,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, elfheader_t* verneeded, box64context_t* box64, x64emu_t* emu); // 0=success, 1=error
+int AddNeededLib(lib_t* maplib, int local, int bindnow, int deepbind, needed_libs_t* needed, elfheader_t* verneeded, 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);
@@ -39,7 +39,7 @@ int IsGlobalNoWeakSymbolInNative(lib_t *maplib, const char* name, int version, c
 void MapLibRemoveLib(lib_t* maplib, library_t* lib);
 void MapLibPrependLib(lib_t* maplib, library_t* lib, library_t* ref);
 
-const char* GetMaplibDefaultVersion(lib_t *maplib, lib_t *local_maplib, int isweak, const char* symname);
+const char* GetMaplibDefaultVersion(lib_t *maplib, lib_t *local_maplib, int isweak, int deepbind, const char* symname);
 
 const char* FindSymbolName(lib_t *maplib, void* p, void** start, uint64_t* sz, const char** libname, void** base, library_t** lib);
 
diff --git a/src/include/library.h b/src/include/library.h
index b08927e0..4cc1012f 100644
--- a/src/include/library.h
+++ b/src/include/library.h
@@ -17,7 +17,7 @@ typedef struct elfheader_s     elfheader_t;
 
 library_t *NewLibrary(const char* path, box64context_t* box64, elfheader_t* verneeded);
 int AddSymbolsLibrary(lib_t* maplib, library_t* lib, x64emu_t* emu);
-int FinalizeLibrary(library_t* lib, lib_t* local_maplib, int bindnow, x64emu_t* emu);
+int FinalizeLibrary(library_t* lib, lib_t* local_maplib, int bindnow, int deepbind, x64emu_t* emu);
 
 char* GetNameLib(library_t *lib);
 int IsSameLib(library_t* lib, const char* path);    // check if lib is same (path -> name)
@@ -28,6 +28,7 @@ char** GetNeededLibsNames(library_t* lib);
 int GetNeededLibsN(library_t* lib);
 library_t* GetNeededLib(library_t* lib, int idx);
 lib_t* GetMaplib(library_t* lib);
+int GetDeepBind(library_t* lib);
 
 int GetElfIndex(library_t* lib);    // -1 if no elf (i.e. wrapped)
 elfheader_t* GetElf(library_t* lib);    // NULL if no elf (i.e. wrapped)
diff --git a/src/librarian/librarian.c b/src/librarian/librarian.c
index 52e4def3..cc8c746c 100644
--- a/src/librarian/librarian.c
+++ b/src/librarian/librarian.c
@@ -269,7 +269,7 @@ static int AddNeededLib_add(lib_t** maplib, int local, needed_libs_t* needed, in
     return 0;
 }
 
-int AddNeededLib_init(lib_t* maplib, int local, int bindnow, library_t* lib, elfheader_t* verneeded, box64context_t* box64, x64emu_t* emu)
+int AddNeededLib_init(lib_t* maplib, int local, int bindnow, int deepbind, library_t* lib, elfheader_t* verneeded, box64context_t* box64, x64emu_t* emu)
 {
     if(!lib)    // no lib, error is already detected, no need to return a new one
         return 0;
@@ -283,7 +283,7 @@ int AddNeededLib_init(lib_t* maplib, int local, int bindnow, library_t* lib, elf
     } else {
         // it's an emulated lib, 
         // load dependancies and launch init sequence
-        if(LoadNeededLibs(mainelf, maplib, 0, bindnow, box64, emu)) {
+        if(LoadNeededLibs(mainelf, maplib, 0, bindnow, deepbind, box64, emu)) {
             printf_dump(LOG_DEBUG, "Failure to Add dependant lib => fail\n");
             return 1;
         }
@@ -295,7 +295,7 @@ int AddNeededLib_init(lib_t* maplib, int local, int bindnow, library_t* lib, elf
             tmp.size = tmp.cap = 1;
             tmp.names = names;
             tmp.libs = libs;
-            AddNeededLib(maplib, 0, 0, &tmp, verneeded, box64, emu);
+            AddNeededLib(maplib, 0, 0, deepbind, &tmp, verneeded, box64, emu);
         }
         if(!strcmp(GetNameLib(lib), "libmss.so.6")) {
             char* names[] = {"libSDL-1.2.so.0", "libdl.so.2"}; // TODO: they will never be uninit...
@@ -304,11 +304,11 @@ int AddNeededLib_init(lib_t* maplib, int local, int bindnow, library_t* lib, elf
             tmp.size = tmp.cap = 2;
             tmp.names = names;
             tmp.libs = libs;
-            AddNeededLib(maplib, 0, 0, &tmp, verneeded, box64, emu);
+            AddNeededLib(maplib, 0, 0, deepbind, &tmp, verneeded, box64, emu);
         }
 
         // finalize the lib
-        if(FinalizeLibrary(lib, local?maplib:NULL, bindnow, emu)) {
+        if(FinalizeLibrary(lib, local?maplib:NULL, bindnow, deepbind, emu)) {
             printf_dump(LOG_DEBUG, "Failure to finalizing lib => fail\n");
             return 1;
         }
@@ -330,7 +330,7 @@ void AddNeededLib_remove(lib_t* maplib, int local, library_t** lib, box64context
 }
 
 EXPORTDYN
-int AddNeededLib(lib_t* maplib, int local, int bindnow, needed_libs_t* needed, elfheader_t* verneeded, box64context_t* box64, x64emu_t* emu)
+int AddNeededLib(lib_t* maplib, int local, int bindnow, int deepbind, needed_libs_t* needed, elfheader_t* verneeded, box64context_t* box64, x64emu_t* emu)
 {
     if(!needed) // no needed libs, no problems
         return 0;
@@ -349,7 +349,7 @@ int AddNeededLib(lib_t* maplib, int local, int bindnow, needed_libs_t* needed, e
     }
     // add dependant libs and init them
     for (int i=0; i<needed->size; ++i)
-        if(AddNeededLib_init(maplib, local, bindnow, needed->libs[i], verneeded, box64, emu)) {
+        if(AddNeededLib_init(maplib, local, bindnow, deepbind, needed->libs[i], verneeded, box64, emu)) {
             printf_log(LOG_INFO, "Error initializing needed lib %s\n", needed->names[i]);
             if(!allow_missing_libs) ret = 1;
         }
@@ -386,8 +386,8 @@ EXPORTDYN
 uintptr_t FindGlobalSymbol(lib_t *maplib, const char* name, int version, const char* vername)
 {
     uintptr_t start = 0, end = 0;
-    const char *globdefver = GetMaplibDefaultVersion(my_context->maplib, (my_context->maplib==maplib)?NULL:maplib, 0, name);
-    const char *weakdefver = GetMaplibDefaultVersion(my_context->maplib, (my_context->maplib==maplib)?NULL:maplib, 1, name);
+    const char *globdefver = GetMaplibDefaultVersion(my_context->maplib, (my_context->maplib==maplib)?NULL:maplib, 0, 0, name);
+    const char *weakdefver = GetMaplibDefaultVersion(my_context->maplib, (my_context->maplib==maplib)?NULL:maplib, 1, 0, name);
     if(GetGlobalSymbolStartEnd(maplib, name, &start, &end, (void*)1, version, vername, globdefver, weakdefver))
         return start;
     return 0;
@@ -652,28 +652,28 @@ int GetGlobalWeakSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* star
     return 0;
 }
 
-const char* GetMaplibDefaultVersion(lib_t *maplib, lib_t* local_maplib, int isweak, const char* symname)
+static const char* internal_GetMaplibDefaultVersion(lib_t* maplib, int isweak, const char* symname)
 {
-    const char* ret = GetDefaultVersion(isweak?GetWeakDefaultVersion(my_context->elfs[0]):GetGlobalDefaultVersion(my_context->elfs[0]), symname);
-    if(ret)
-        return ret;
-    for(int i=0; i<maplib->libsz; ++i) {
+    const char* ret = NULL;
+    for(int i=0; maplib && i<maplib->libsz; ++i) {
         elfheader_t *h = GetElf(maplib->libraries[i]);
         if(h)
             ret = GetDefaultVersion(isweak?GetWeakDefaultVersion(h):GetGlobalDefaultVersion(h), symname);
         if(ret)
             return ret;
     }
-    if(local_maplib)
-        for(int i=0; i<local_maplib->libsz; ++i) {
-            elfheader_t *h = GetElf(local_maplib->libraries[i]);
-            if(h)
-                ret = GetDefaultVersion(isweak?GetWeakDefaultVersion(h):GetGlobalDefaultVersion(h), symname);
-            if(ret)
-                return ret;
-        }
-
-    return NULL;
+    return ret;
+}
+const char* GetMaplibDefaultVersion(lib_t *maplib, lib_t* local_maplib, int isweak, int deepbind, const char* symname)
+{
+    const char* ret = GetDefaultVersion(isweak?GetWeakDefaultVersion(my_context->elfs[0]):GetGlobalDefaultVersion(my_context->elfs[0]), symname);
+    if(ret)
+        return ret;
+    ret = internal_GetMaplibDefaultVersion(deepbind?local_maplib:maplib, isweak, symname);
+    if(ret)
+        return ret;
+    ret = internal_GetMaplibDefaultVersion(deepbind?maplib:local_maplib, isweak, symname);
+    return ret;
 }
 
 elfheader_t* GetGlobalSymbolElf(lib_t *maplib, const char* name, int version, const char* vername)
@@ -684,7 +684,7 @@ elfheader_t* GetGlobalSymbolElf(lib_t *maplib, const char* name, int version, co
     int weak = 0;
     elfheader_t* ret = NULL;
     // check with default version...
-    const char* defver = GetMaplibDefaultVersion(my_context->maplib, (my_context->maplib==maplib)?NULL:maplib, 0, name);
+    const char* defver = GetMaplibDefaultVersion(my_context->maplib, (my_context->maplib==maplib)?NULL:maplib, 0, 0, name);
 
     if(GetSymbolStartEnd(GetMapSymbols(my_context->elfs[0]), name, &start, &end, version, vername, 1, defver))
         return my_context->elfs[0];
@@ -702,7 +702,7 @@ elfheader_t* GetGlobalSymbolElf(lib_t *maplib, const char* name, int version, co
         }
     }
 
-    defver = GetMaplibDefaultVersion(my_context->maplib, (my_context->maplib==maplib)?NULL:maplib, 1, name);
+    defver = GetMaplibDefaultVersion(my_context->maplib, (my_context->maplib==maplib)?NULL:maplib, 1, 0, name);
     if(GetSymbolStartEnd(GetWeakSymbols(my_context->elfs[0]), name, &start, &end, version, vername, 1, defver))
         ret = my_context->elfs[0];
     for(int i=0; i<maplib->libsz; ++i) {
diff --git a/src/librarian/library.c b/src/librarian/library.c
index eb34ccbb..cb5862ee 100644
--- a/src/librarian/library.c
+++ b/src/librarian/library.c
@@ -238,7 +238,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, NULL, context, thread_get_emu())) {
+            if(AddNeededLib(context->maplib, 0, 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;
             }
@@ -500,21 +500,22 @@ int AddSymbolsLibrary(lib_t *maplib, library_t* lib, x64emu_t* emu)
     }
     return 0;
 }
-int FinalizeLibrary(library_t* lib, lib_t* local_maplib, int bindnow, x64emu_t* emu)
+int FinalizeLibrary(library_t* lib, lib_t* local_maplib, int bindnow, int deepbind, x64emu_t* emu)
 {
     if(!lib)
         return 0;
+    lib->deepbind = deepbind;
     if(lib->type==LIB_EMULATED) {
         if(lib->e.finalized)
             return 0;
         lib->e.finalized = 1;
         elfheader_t *elf_header = my_context->elfs[lib->e.elf_index];
         // finalize relocations
-        if(RelocateElf(my_context->maplib, local_maplib, bindnow, elf_header)) {
+        if(RelocateElf(my_context->maplib, local_maplib, bindnow, deepbind, elf_header)) {
             printf_log(LOG_NONE, "Error: relocating symbols in elf %s\n", lib->name);
             return 1;
         }
-        if(RelocateElfPlt(my_context->maplib, local_maplib, bindnow, elf_header)) {
+        if(RelocateElfPlt(my_context->maplib, local_maplib, bindnow, deepbind, elf_header)) {
             printf_log(LOG_NONE, "Error: relocating Plt symbols in elf %s\n", lib->name);
             return 1;
         }
@@ -1043,6 +1044,13 @@ lib_t* GetMaplib(library_t* lib)
     return lib->maplib;
 }
 
+int GetDeepBind(library_t* lib)
+{
+    if(!lib)
+        return 0;
+    return lib->deepbind;
+}
+
 linkmap_t* getLinkMapLib(library_t* lib)
 {
     linkmap_t* lm = my_context->linkmap;
diff --git a/src/librarian/library_private.h b/src/librarian/library_private.h
index 6bb291de..b7e1e45d 100644
--- a/src/librarian/library_private.h
+++ b/src/librarian/library_private.h
@@ -68,8 +68,9 @@ typedef struct elib_s {
 typedef struct library_s {
     char*               name;   // <> path
     char*               path;   // original path
-    int                 nbdot;  // nombre of "." after .so
-    int                 type;   // 0: native(wrapped) 1: emulated(elf) -1: undetermined
+    int8_t              nbdot;  // nombre of "." after .so
+    int8_t              type;   // 0: native(wrapped) 1: emulated(elf) -1: undetermined
+    uint8_t             deepbind;
     wrappedlib_fini_t   fini;
     wrappedlib_get_t    getglobal;  // get global (non-weak)
     wrappedlib_get_t    getweak;    // get weak symbol
diff --git a/src/main.c b/src/main.c
index 7c4f806b..7c74bc5a 100644
--- a/src/main.c
+++ b/src/main.c
@@ -2002,7 +2002,7 @@ int main(int argc, const char **argv, char **env) {
         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, elf_header, my_context, emu)) {
+            if(AddNeededLib(my_context->maplib, 0, 0, 0, tmp, elf_header, my_context, emu)) {
                 printf_log(LOG_INFO, "Warning, cannot pre-load %s\n", tmp->names[0]);
                 RemoveNeededLib(my_context->maplib, 0, tmp, my_context, emu);
             } else {
@@ -2014,20 +2014,20 @@ int main(int argc, const char **argv, char **env) {
     }
     FreeCollection(&ld_preload);
     // Call librarian to load all dependant elf
-    if(LoadNeededLibs(elf_header, my_context->maplib, 0, 0, my_context, emu)) {
+    if(LoadNeededLibs(elf_header, my_context->maplib, 0, 0, 0, my_context, emu)) {
         printf_log(LOG_NONE, "Error: Loading needed libs in elf %s\n", my_context->argv[0]);
         FreeBox64Context(&my_context);
         return -1;
     }
     // reloc...
     printf_log(LOG_DEBUG, "And now export symbols / relocation for %s...\n", ElfName(elf_header));
-    if(RelocateElf(my_context->maplib, NULL, 0, elf_header)) {
+    if(RelocateElf(my_context->maplib, NULL, 0, 0, elf_header)) {
         printf_log(LOG_NONE, "Error: Relocating symbols in elf %s\n", my_context->argv[0]);
         FreeBox64Context(&my_context);
         return -1;
     }
     // and handle PLT
-    RelocateElfPlt(my_context->maplib, NULL, 0, elf_header);
+    RelocateElfPlt(my_context->maplib, NULL, 0, 0, elf_header);
     // deferred init
     setupTraceInit();
     RunDeferredElfInit(emu);
diff --git a/src/wrapped/wrappedlibdl.c b/src/wrapped/wrappedlibdl.c
index 11278c1c..48b56e46 100644
--- a/src/wrapped/wrappedlibdl.c
+++ b/src/wrapped/wrappedlibdl.c
@@ -90,6 +90,7 @@ void* my_dlopen(x64emu_t* emu, void *filename, int flag)
     dlprivate_t *dl = my_context->dlprivate;
     size_t dlopened = 0;
     int is_local = (flag&0x100)?0:1;  // if not global, then local, and that means symbols are not put in the global "pot" for other libs
+    int deepbind = (flag&0x0008)?1:0;  // RTLD_DEEPBIND means LOCAL before GLOBAL scope during symbol resolution
     CLEARERR
     if(filename) {
         char* rfilename = (char*)alloca(MAX_PATH);
@@ -189,7 +190,7 @@ void* my_dlopen(x64emu_t* emu, void *filename, int flag)
         int bindnow = (!box64_musl && (flag&0x2))?1:0;
         needed_libs_t *tmp = new_neededlib(1);
         tmp->names[0] = rfilename;
-        if(AddNeededLib(NULL, is_local, bindnow, tmp, NULL, my_context, emu)) {
+        if(AddNeededLib(NULL, is_local, bindnow, deepbind, tmp, NULL, 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_calloc(1, 129);
@@ -256,6 +257,7 @@ char* my_dlerror(x64emu_t* emu)
 
 KHASH_SET_INIT_INT(libs);
 
+// TODO: deepbind is probably not followed correctly here
 int recursive_dlsym_lib(kh_libs_t* collection, library_t* lib, const char* rsymbol, uintptr_t *start, uintptr_t *end, int version, const char* vername, const char* globdefver, const char* weakdefver)
 {
     if(!lib)
@@ -304,8 +306,8 @@ void* my_dlsym(x64emu_t* emu, void *handle, void *symbol)
     printf_dlsym(LOG_DEBUG, "%04d|Call to dlsym(%p, \"%s\")%s", GetTID(), handle, rsymbol, dlsym_error?"":"\n");
     if(handle==NULL) {
         // special case, look globably
-        const char* globdefver = GetMaplibDefaultVersion(my_context->maplib, NULL, 0, rsymbol);
-        const char* weakdefver = GetMaplibDefaultVersion(my_context->maplib, NULL, 1, rsymbol);
+        const char* globdefver = GetMaplibDefaultVersion(my_context->maplib, NULL, 0, 0, rsymbol);
+        const char* weakdefver = GetMaplibDefaultVersion(my_context->maplib, NULL, 1, 0, rsymbol);
         if(GetGlobalSymbolStartEnd(my_context->maplib, rsymbol, &start, &end, NULL, -1, NULL, globdefver, weakdefver)) {
             printf_dlsym(LOG_NEVER, "%p\n", (void*)start);
             pthread_mutex_unlock(&mutex);
@@ -320,8 +322,8 @@ void* my_dlsym(x64emu_t* emu, void *handle, void *symbol)
     }
     if(handle==(void*)~0LL) {
         // special case, look globably but no self (RTLD_NEXT)
-        const char* globdefver = GetMaplibDefaultVersion(my_context->maplib, NULL, 0, rsymbol);
-        const char* weakdefver = GetMaplibDefaultVersion(my_context->maplib, NULL, 1, rsymbol);
+        const char* globdefver = GetMaplibDefaultVersion(my_context->maplib, NULL, 0, 0, rsymbol);
+        const char* weakdefver = GetMaplibDefaultVersion(my_context->maplib, NULL, 1, 0, rsymbol);
         elfheader_t *elf = FindElfAddress(my_context, *(uintptr_t*)R_RSP); // use return address to guess "self"
         if(GetNoSelfSymbolStartEnd(my_context->maplib, rsymbol, &start, &end, elf, 0, -1, NULL, globdefver, weakdefver)) {
             printf_dlsym(LOG_NEVER, "%p\n", (void*)start);
@@ -355,8 +357,9 @@ void* my_dlsym(x64emu_t* emu, void *handle, void *symbol)
         return NULL;
     }
     if(dl->dllibs[nlib].lib) {
-        const char* globdefver = GetMaplibDefaultVersion(my_context->maplib, (my_context->maplib==dl->dllibs[nlib].lib->maplib)?NULL:dl->dllibs[nlib].lib->maplib, 0, rsymbol);
-        const char* weakdefver = GetMaplibDefaultVersion(my_context->maplib, (my_context->maplib==dl->dllibs[nlib].lib->maplib)?NULL:dl->dllibs[nlib].lib->maplib, 1, rsymbol);
+        int deepbind = GetDeepBind(dl->dllibs[nlib].lib);
+        const char* globdefver = GetMaplibDefaultVersion(my_context->maplib, (my_context->maplib==dl->dllibs[nlib].lib->maplib)?NULL:dl->dllibs[nlib].lib->maplib, 0, deepbind, rsymbol);
+        const char* weakdefver = GetMaplibDefaultVersion(my_context->maplib, (my_context->maplib==dl->dllibs[nlib].lib->maplib)?NULL:dl->dllibs[nlib].lib->maplib, 1, deepbind, rsymbol);
         if(my_dlsym_lib(dl->dllibs[nlib].lib, rsymbol, &start, &end, -1, NULL, globdefver, weakdefver)==0) {
             // not found
             printf_dlsym(LOG_NEVER, "%p\nCall to dlsym(%s, \"%s\") Symbol not found\n", NULL, GetNameLib(dl->dllibs[nlib].lib), rsymbol);
@@ -370,8 +373,8 @@ void* my_dlsym(x64emu_t* emu, void *handle, void *symbol)
     } else {
         // still usefull?
         //  => look globably
-        const char* globdefver = GetMaplibDefaultVersion(my_context->maplib, NULL, 0, rsymbol);
-        const char* weakdefver = GetMaplibDefaultVersion(my_context->maplib, NULL, 1, rsymbol);
+        const char* globdefver = GetMaplibDefaultVersion(my_context->maplib, NULL, 0, 0, rsymbol);
+        const char* weakdefver = GetMaplibDefaultVersion(my_context->maplib, NULL, 1, 0, rsymbol);
         if(GetGlobalSymbolStartEnd(my_context->maplib, rsymbol, &start, &end, NULL, -1, NULL, globdefver, weakdefver)) {
             printf_dlsym(LOG_NEVER, "%p\n", (void*)start);
             pthread_mutex_unlock(&mutex);
@@ -460,8 +463,8 @@ void* my_dlvsym(x64emu_t* emu, void *handle, void *symbol, const char *vername)
     printf_dlsym(LOG_DEBUG, "Call to dlvsym(%p, \"%s\", %s)%s", handle, rsymbol, vername?vername:"(nil)", dlsym_error?"":"\n");
     if(handle==NULL) {
         // special case, look globably
-        const char* globdefver = GetMaplibDefaultVersion(my_context->maplib, NULL, 0, rsymbol);
-        const char* weakdefver = GetMaplibDefaultVersion(my_context->maplib, NULL, 1, rsymbol);
+        const char* globdefver = GetMaplibDefaultVersion(my_context->maplib, NULL, 0, 0, rsymbol);
+        const char* weakdefver = GetMaplibDefaultVersion(my_context->maplib, NULL, 1, 0, rsymbol);
         if(GetGlobalSymbolStartEnd(my_context->maplib, rsymbol, &start, &end, NULL, version, vername, globdefver, weakdefver)) {
             printf_dlsym(LOG_NEVER, "%p\n", (void*)start);
             return (void*)start;
@@ -474,8 +477,8 @@ void* my_dlvsym(x64emu_t* emu, void *handle, void *symbol, const char *vername)
     }
     if(handle==(void*)~0LL) {
         // special case, look globably but no self (RTLD_NEXT)
-        const char* globdefver = GetMaplibDefaultVersion(my_context->maplib, NULL, 0, rsymbol);
-        const char* weakdefver = GetMaplibDefaultVersion(my_context->maplib, NULL, 1, rsymbol);
+        const char* globdefver = GetMaplibDefaultVersion(my_context->maplib, NULL, 0, 0, rsymbol);
+        const char* weakdefver = GetMaplibDefaultVersion(my_context->maplib, NULL, 1, 0, rsymbol);
         elfheader_t *elf = FindElfAddress(my_context, *(uintptr_t*)R_RSP); // use return address to guess "self"
         if(GetNoSelfSymbolStartEnd(my_context->maplib, rsymbol, &start, &end, elf, 0, version, vername, globdefver, weakdefver)) {
                 printf_dlsym(LOG_NEVER, "%p\n", (void*)start);
@@ -505,8 +508,9 @@ void* my_dlvsym(x64emu_t* emu, void *handle, void *symbol, const char *vername)
         return NULL;
     }
     if(dl->dllibs[nlib].lib) {
-        const char* globdefver = GetMaplibDefaultVersion(my_context->maplib, (my_context->maplib==dl->dllibs[nlib].lib->maplib)?NULL:dl->dllibs[nlib].lib->maplib, 0, rsymbol);
-        const char* weakdefver = GetMaplibDefaultVersion(my_context->maplib, (my_context->maplib==dl->dllibs[nlib].lib->maplib)?NULL:dl->dllibs[nlib].lib->maplib, 1, rsymbol);
+        int deepbind = GetDeepBind(dl->dllibs[nlib].lib);
+        const char* globdefver = GetMaplibDefaultVersion(my_context->maplib, (my_context->maplib==dl->dllibs[nlib].lib->maplib)?NULL:dl->dllibs[nlib].lib->maplib, 0, deepbind, rsymbol);
+        const char* weakdefver = GetMaplibDefaultVersion(my_context->maplib, (my_context->maplib==dl->dllibs[nlib].lib->maplib)?NULL:dl->dllibs[nlib].lib->maplib, 1, deepbind, rsymbol);
         if(my_dlsym_lib(dl->dllibs[nlib].lib, rsymbol, &start, &end, version, vername, globdefver, weakdefver)==0) {
             // not found
                 printf_dlsym(LOG_NEVER, "%p\nCall to dlvsym(%s, \"%s\", %s) Symbol not found\n", NULL, GetNameLib(dl->dllibs[nlib].lib), rsymbol, vername?vername:"(nil)");
@@ -518,8 +522,8 @@ void* my_dlvsym(x64emu_t* emu, void *handle, void *symbol, const char *vername)
         }
     } else {
         // still usefull?
-        const char* globdefver = GetMaplibDefaultVersion(my_context->maplib, NULL, 0, rsymbol);
-        const char* weakdefver = GetMaplibDefaultVersion(my_context->maplib, NULL, 1, rsymbol);
+        const char* globdefver = GetMaplibDefaultVersion(my_context->maplib, NULL, 0, 0, rsymbol);
+        const char* weakdefver = GetMaplibDefaultVersion(my_context->maplib, NULL, 1, 0, rsymbol);
         if(GetGlobalSymbolStartEnd(my_context->maplib, rsymbol, &start, &end, NULL, -1, NULL, globdefver, weakdefver)) {
             printf_dlsym(LOG_NEVER, "%p\n", (void*)start);
             return (void*)start;