about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rwxr-xr-xsrc/box64context.c53
-rwxr-xr-xsrc/elfs/elfloader.c48
-rwxr-xr-xsrc/elfs/elfloader_private.h5
-rwxr-xr-xsrc/include/box64context.h6
-rwxr-xr-xsrc/include/elfloader.h4
-rwxr-xr-xsrc/include/librarian.h7
-rwxr-xr-xsrc/include/library.h14
-rw-r--r--src/include/symbols.h14
-rwxr-xr-xsrc/include/wrappedlibs.h4
-rwxr-xr-xsrc/librarian/librarian.c260
-rwxr-xr-xsrc/librarian/librarian_private.h5
-rwxr-xr-xsrc/librarian/library.c280
-rw-r--r--src/librarian/library_inner.h7
-rwxr-xr-xsrc/librarian/library_private.h34
-rw-r--r--src/librarian/symbols.c68
-rwxr-xr-xsrc/main.c10
-rwxr-xr-xsrc/wrapped/wrappedlib_init.h47
-rwxr-xr-xsrc/wrapped/wrappedlibdl.c54
18 files changed, 521 insertions, 399 deletions
diff --git a/src/box64context.c b/src/box64context.c
index 9a522748..1610c4e8 100755
--- a/src/box64context.c
+++ b/src/box64context.c
@@ -169,6 +169,8 @@ box64context_t *NewBox64Context(int argc)
     context->local_maplib = NewLibrarian(context, 1);
     context->versym = NewDictionnary();
     context->system = NewBridge();
+    context->globaldefver = NewDefaultVersion();
+    context->weakdefver = NewDefaultVersion();
     // create vsyscall
     context->vsyscall = AddBridge(context->system, vFEv, x64Syscall, 0, NULL);
     // create the vsyscalls
@@ -217,6 +219,8 @@ void FreeBox64Context(box64context_t** context)
     if(ctx->maplib)
         FreeLibrarian(&ctx->maplib, NULL);
     FreeDictionnary(&ctx->versym);
+    FreeDefaultVersion(&ctx->globaldefver);
+    FreeDefaultVersion(&ctx->weakdefver);
 
     for(int i=0; i<ctx->elfsize; ++i) {
         FreeElfHeader(&ctx->elfs[i]);
@@ -338,52 +342,3 @@ int AddTLSPartition(box64context_t* context, int tlssize) {
     return -context->tlssize;   // negative offset
 }
 
-void add_neededlib(needed_libs_t* needed, library_t* lib)
-{
-    if(!needed)
-        return;
-    for(int i=0; i<needed->size; ++i)
-        if(needed->libs[i] == lib)
-            return;
-    if(needed->size == needed->cap) {
-        needed->cap += 8;
-        needed->libs = (library_t**)box_realloc(needed->libs, needed->cap*sizeof(library_t*));
-    }
-    needed->libs[needed->size++] = lib;
-}
-
-void free_neededlib(needed_libs_t* needed)
-{
-    if(!needed)
-        return;
-    needed->cap = 0;
-    needed->size = 0;
-    if(needed->libs)
-        box_free(needed->libs);
-    needed->libs = NULL;
-}
-
-void add_dependedlib(needed_libs_t* depended, library_t* lib)
-{
-    if(!depended)
-        return;
-    for(int i=0; i<depended->size; ++i)
-        if(depended->libs[i] == lib)
-            return;
-    if(depended->size == depended->cap) {
-        depended->cap += 8;
-        depended->libs = (library_t**)box_realloc(depended->libs, depended->cap*sizeof(library_t*));
-    }
-    depended->libs[depended->size++] = lib;
-}
-
-void free_dependedlib(needed_libs_t* depended)
-{
-    if(!depended)
-        return;
-    depended->cap = 0;
-    depended->size = 0;
-    if(depended->libs)
-        box_free(depended->libs);
-    depended->libs = NULL;
-}
diff --git a/src/elfs/elfloader.c b/src/elfs/elfloader.c
index 43eb7157..f93ce1df 100755
--- a/src/elfs/elfloader.c
+++ b/src/elfs/elfloader.c
@@ -11,6 +11,7 @@
 #include <unistd.h>
 #include <errno.h>
 
+#include "custommem.h"
 #include "box64version.h"
 #include "elfloader.h"
 #include "debug.h"
@@ -26,7 +27,6 @@
 #include "box64stack.h"
 #include "callback.h"
 #include "box64stack.h"
-#include "custommem.h"
 #include "wine_tools.h"
 #include "dictionnary.h"
 #include "symbols.h"
@@ -58,6 +58,11 @@ elfheader_t* LoadAndCheckElfHeader(FILE* f, const char* name, int exec)
         h->path = (char*)box_malloc(1);
         h->path[0] = '\0';
     }
+    
+    h->mapsymbols = NewMapSymbols();
+    h->weaksymbols = NewMapSymbols();
+    h->localsymbols = NewMapSymbols();
+    
     return h;
 }
 
@@ -83,6 +88,10 @@ void FreeElfHeader(elfheader_t** head)
     box_free(h->SymTab);
     box_free(h->DynSym);
 
+    FreeMapSymbols(&h->mapsymbols);
+    FreeMapSymbols(&h->weaksymbols);
+    FreeMapSymbols(&h->localsymbols);
+    
     FreeElfMemory(h);
     box_free(h);
 
@@ -416,6 +425,7 @@ 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* defver = GetDefaultVersion((bind==STB_WEAK)?my_context->weakdefver:my_context->globaldefver, symname);
         if(bind==STB_LOCAL) {
             offs = sym->st_value + head->delta;
             end = offs + sym->st_size;
@@ -459,7 +469,7 @@ int RelocateElfREL(lib_t *maplib, lib_t *local_maplib, int bindnow, elfheader_t*
                     if(sym->st_size && offs) {
                         printf_dump(LOG_NEVER, "Apply %s R_X86_64_GLOB_DAT with R_X86_64_COPY @%p/%p (%p/%p -> %p/%p) size=%ld on sym=%s \n", (bind==STB_LOCAL)?"Local":"Global", p, globp, (void*)(p?(*p):0), (void*)(globp?(*globp):0), (void*)(offs + head->delta), (void*)globoffs, sym->st_size, symname);
                         memmove((void*)globoffs, (void*)offs, sym->st_size);   // preapply to copy part from lib to main elf
-                        AddWeakSymbol(GetGlobalData(maplib), symname, offs + head->delta, sym->st_size, version, vername);
+                        AddUniqueSymbol(GetGlobalData(maplib), symname, offs + head->delta, sym->st_size, version, vername);
                     } else {
                         printf_dump(LOG_NEVER, "Apply %s R_X86_64_GLOB_DAT with R_X86_64_COPY @%p/%p (%p/%p -> %p/%p) null sized on sym=%s \n", (bind==STB_LOCAL)?"Local":"Global", p, globp, (void*)(p?(*p):0), (void*)(globp?(*globp):0), (void*)offs, (void*)globoffs, symname);
                     }
@@ -484,7 +494,7 @@ int RelocateElfREL(lib_t *maplib, lib_t *local_maplib, int bindnow, elfheader_t*
                     uintptr_t old_offs = offs;
                     uintptr_t old_end = end;
                     offs = 0;
-                    GetSymbolStartEnd(GetGlobalData(maplib), symname, &offs, &end, version, vername, 1); // try globaldata symbols first
+                    GetSymbolStartEnd(GetGlobalData(maplib), symname, &offs, &end, version, vername, 1, defver); // try globaldata symbols first
                     if(offs==0) {
                         GetNoSelfSymbolStartEnd(maplib, symname, &offs, &end, head, version, vername);   // get original copy if any
                         if(!offs && local_maplib)
@@ -587,6 +597,7 @@ int RelocateElfRELA(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(rela[i].r_info)]:-1;
         if(version!=-1) version &=0x7fff;
         const char* vername = GetSymbolVersion(head, version);
+        const char* defver = GetDefaultVersion((bind==STB_WEAK)?my_context->weakdefver:my_context->globaldefver, symname);
         if(bind==STB_LOCAL) {
             offs = sym->st_value + head->delta;
             end = offs + sym->st_size;
@@ -632,7 +643,7 @@ int RelocateElfRELA(lib_t *maplib, lib_t *local_maplib, int bindnow, elfheader_t
                 globoffs = offs;
                 globend = end;
                 offs = end = 0;
-                GetSymbolStartEnd(GetGlobalData(maplib), symname, &offs, &end, version, vername, 1); // try globaldata symbols first
+                GetSymbolStartEnd(GetGlobalData(maplib), symname, &offs, &end, version, vername, 1, defver); // try globaldata symbols first
                 if(!offs && local_maplib)
                     GetNoSelfSymbolStartEnd(local_maplib, symname, &offs, &end, head, version, vername);
                 if(!offs)
@@ -657,7 +668,7 @@ int RelocateElfRELA(lib_t *maplib, lib_t *local_maplib, int bindnow, elfheader_t
                             (bind==STB_LOCAL)?"Local":"Global", p, globp, (void*)(p?(*p):0), 
                             (void*)(globp?(*globp):0), (void*)offs, (void*)globoffs, sym->st_size, symname, version, vername?vername:"(none)");
                         //memmove((void*)globoffs, (void*)offs, sym->st_size);   // preapply to copy part from lib to main elf
-                        AddWeakSymbol(GetGlobalData(maplib), symname, offs, sym->st_size, version, vername);
+                        AddUniqueSymbol(GetGlobalData(maplib), symname, offs, sym->st_size, version, vername);
                     } else {
                         printf_dump(LOG_NEVER, "Apply %s R_X86_64_GLOB_DAT with R_X86_64_COPY @%p/%p (%p/%p -> %p/%p) null sized on sym=%s (ver=%d/%s)\n", 
                             (bind==STB_LOCAL)?"Local":"Global", p, globp, (void*)(p?(*p):0), 
@@ -968,6 +979,7 @@ void AddSymbols(lib_t *maplib, kh_mapsymbols_t* mapsymbols, kh_mapsymbols_t* wea
                 p+=2;
                 symname = AddDictionnary(my_context->versym, symnameversionned);
                 const char* vername = AddDictionnary(my_context->versym, p);
+                AddDefaultVersion((bind==STB_WEAK)?my_context->weakdefver:my_context->globaldefver, symname, vername);
                 if((bind==STB_GNU_UNIQUE /*|| (bind==STB_GLOBAL && type==STT_FUNC)*/) && FindGlobalSymbol(maplib, symname, 2, p))
                     continue;
                 uintptr_t offs = (type==STT_TLS)?h->SymTab[i].st_value:(h->SymTab[i].st_value + h->delta);
@@ -1016,8 +1028,13 @@ 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) && !GetDefaultVersion((bind==STB_WEAK)?my_context->weakdefver:my_context->globaldefver, symname))?1:0;
             if(version!=-1) version &= 0x7fff;
             const char* vername = GetSymbolVersion(h, version);
+            if(add_default) {
+                AddDefaultVersion((bind==STB_WEAK)?my_context->weakdefver:my_context->globaldefver, symname, vername);
+                printf_dump(LOG_NEVER, "Adding Default Version \"%s\" for Symbol\"%s\"\n", vername, symname);
+            }
             int to_add = 1;
             if(libcef) {
                 if(strstr(symname, "_Zn")==symname || strstr(symname, "_Zd")==symname)
@@ -1035,7 +1052,7 @@ void AddSymbols(lib_t *maplib, kh_mapsymbols_t* mapsymbols, kh_mapsymbols_t* wea
                 if(bind==STB_WEAK) {
                     AddSymbol(weaksymbols, symname, offs, sz, version, vername);
                 } else {
-                    AddWeakSymbol(mapsymbols, symname, offs, sz, version?version:1, vername);
+                    AddSymbol(mapsymbols, symname, offs, sz, version?version:1, vername);
                 }
         }
     }
@@ -1591,6 +1608,25 @@ void ElfAttachLib(elfheader_t* head, library_t* lib)
     head->lib = lib;
 }
 
+kh_mapsymbols_t* GetMapSymbols(elfheader_t* h)
+{
+    if(!h)
+        return NULL;
+    return h->mapsymbols;
+}
+kh_mapsymbols_t* GetWeakSymbols(elfheader_t* h)
+{
+    if(!h)
+        return NULL;
+    return h->weaksymbols;
+}
+kh_mapsymbols_t* GetLocalSymbols(elfheader_t* h)
+{
+    if(!h)
+        return NULL;
+    return h->localsymbols;
+}
+
 typedef struct search_symbol_s{
     const char* name;
     void*       addr;
diff --git a/src/elfs/elfloader_private.h b/src/elfs/elfloader_private.h
index c1c34d0c..e75ba1ca 100755
--- a/src/elfs/elfloader_private.h
+++ b/src/elfs/elfloader_private.h
@@ -7,6 +7,7 @@ typedef struct dynablocklist_s dynablocklist_t;
 
 typedef struct library_s library_t;
 typedef struct needed_libs_s needed_libs_t;
+typedef struct kh_mapsymbols_s kh_mapsymbols_t;
 
 #include <elf.h>
 #include "elfloader.h"
@@ -95,6 +96,10 @@ struct elfheader_s {
 
     library_t   *lib;
     needed_libs_t *neededlibs;
+
+    kh_mapsymbols_t   *mapsymbols;
+    kh_mapsymbols_t   *weaksymbols;
+    kh_mapsymbols_t   *localsymbols;
 };
 
 #define R_X86_64_NONE           0       /* No reloc */
diff --git a/src/include/box64context.h b/src/include/box64context.h
index 036a2b6d..17f4a2a0 100755
--- a/src/include/box64context.h
+++ b/src/include/box64context.h
@@ -14,6 +14,7 @@ typedef struct lib_s lib_t;
 typedef struct bridge_s bridge_t;
 typedef struct dlprivate_s dlprivate_t;
 typedef struct kh_symbolmap_s kh_symbolmap_t;
+typedef struct kh_defaultversion_s kh_defaultversion_t;
 typedef struct library_s library_t;
 typedef struct linkmap_s linkmap_t;
 typedef struct kh_threadstack_s kh_threadstack_t;
@@ -52,10 +53,7 @@ typedef struct needed_libs_s {
     library_t   **libs;
 } needed_libs_t;
 
-void add_neededlib(needed_libs_t* needed, library_t* lib);
 void free_neededlib(needed_libs_t* needed);
-void add_dependedlib(needed_libs_t* depended, library_t* lib);
-void free_dependedlib(needed_libs_t* depended);
 
 typedef struct base_segment_s {
     uintptr_t       base;
@@ -120,6 +118,8 @@ typedef struct box64context_s {
     kh_symbolmap_t      *almymap;       // link to the mysymbolmap if libOpenAL
     kh_symbolmap_t      *vkwrappers;    // the map of wrapper for VulkanProcs (TODO: check SDL2)
     kh_symbolmap_t      *vkmymap;       // link to the mysymbolmap of libGL
+    kh_defaultversion_t *globaldefver;  // the global default version for symbols (the XXX@@vvvv of symbols)
+    kh_defaultversion_t *weakdefver;    // the weak default version for symbols (the XXX@@vvvv of symbols)
     vkprocaddess_t      vkprocaddress;
 
     pthread_mutex_t     mutex_once;
diff --git a/src/include/elfloader.h b/src/include/elfloader.h
index ca7a6621..6846dcd4 100755
--- a/src/include/elfloader.h
+++ b/src/include/elfloader.h
@@ -63,6 +63,10 @@ const char* GetParentSymbolVersion(elfheader_t* h, int index);
 const char* VersionnedName(const char* name, int ver, const char* vername);
 int SameVersionnedSymbol(const char* name1, int ver1, const char* vername1, const char* name2, int ver2, const char* vername2);
 
+kh_mapsymbols_t* GetMapSymbols(elfheader_t* h);
+kh_mapsymbols_t* GetWeakSymbols(elfheader_t* h);
+kh_mapsymbols_t* GetLocalSymbols(elfheader_t* h);
+
 void* GetNativeSymbolUnversionned(void* lib, const char* name);
 
 void AddMainElfToLinkmap(elfheader_t* lib);
diff --git a/src/include/librarian.h b/src/include/librarian.h
index d2f0740c..a3fdfb3d 100755
--- a/src/include/librarian.h
+++ b/src/include/librarian.h
@@ -20,20 +20,15 @@ dlprivate_t *NewDLPrivate();
 void FreeDLPrivate(dlprivate_t **lib);
 
 box64context_t* GetLibrarianContext(lib_t* maplib);
-kh_mapsymbols_t* GetMapSymbol(lib_t* maplib);
-kh_mapsymbols_t* GetWeakSymbol(lib_t* maplib);
-kh_mapsymbols_t* GetLocalSymbol(lib_t* maplib);
 kh_mapsymbols_t* GetGlobalData(lib_t* maplib);
-int AddNeededLib(lib_t* maplib, needed_libs_t* neededlibs, library_t *deplib, int local, int bindnow, const char** paths, int npath, box64context_t* box64, x64emu_t* emu); // 0=success, 1=error
+int AddNeededLib(lib_t* maplib, needed_libs_t* neededlibs, library_t* deplib, int local, int bindnow, const char** paths, int npath, box64context_t* box64, x64emu_t* emu); // 0=success, 1=error
 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);
 int GetNoSelfSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, elfheader_t* self, int version, const char* vername);
-int GetSelfSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, elfheader_t *self, int version, const char* vername);
 int GetGlobalSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, elfheader_t *self, int version, const char* vername);
 int GetGlobalNoWeakSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, int version, const char* vername);
 int GetLocalSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, elfheader_t *self, int version, const char* vername);
-int GetNoWeakSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, elfheader_t *self, int version, const char* vername);
 elfheader_t* GetGlobalSymbolElf(lib_t *maplib, const char* name, int version, const char* vername);
 int IsGlobalNoWeakSymbolInNative(lib_t *maplib, const char* name, int version, const char* vername);
 
diff --git a/src/include/library.h b/src/include/library.h
index 1bd9be3a..b62e122d 100755
--- a/src/include/library.h
+++ b/src/include/library.h
@@ -9,8 +9,9 @@ typedef struct kh_symbolmap_s  kh_symbolmap_t;
 typedef struct box64context_s  box64context_t;
 typedef struct x64emu_s        x64emu_t;
 typedef struct needed_libs_s   needed_libs_t;
+typedef struct elfheader_s     elfheader_t;
 
-#define LIB_NATIVE      0
+#define LIB_WRAPPED     0
 #define LIB_EMULATED    1
 #define LIB_UNNKNOW     -1
 
@@ -23,9 +24,9 @@ void Free1Library(library_t **lib, x64emu_t* emu);
 
 char* GetNameLib(library_t *lib);
 int IsSameLib(library_t* lib, const char* path);    // check if lib is same (path -> name)
-int GetLibSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start, uintptr_t* end, int version, const char* vername, int local);
-int GetLibNoWeakSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start, uintptr_t* end, int version, const char* vername, int local);
-int GetLibLocalSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start, uintptr_t* end, int version, const char* vername, int local);
+int GetLibGlobalSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start, uintptr_t* end, int* weak, int version, const char* vername, int local);
+int GetLibWeakSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start, uintptr_t* end, int* weak, int version, const char* vername, int local);
+int GetLibLocalSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start, uintptr_t* end, int* weak, int version, const char* vername, int local);
 void fillGLProcWrapper(box64context_t* context);
 void freeGLProcWrapper(box64context_t* context);
 void fillALProcWrapper(box64context_t* context);
@@ -35,7 +36,8 @@ int GetNeededLibN(library_t* lib);
 library_t* GetNeededLib(library_t* lib, int idx);
 lib_t* GetMaplib(library_t* lib);
 
-int GetElfIndex(library_t* lib);    // -1 if no elf (i.e. native)
-void* GetHandle(library_t* lib);    // NULL if not native
+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)
+void* GetHandle(library_t* lib);    // NULL if not wrapped
 
 #endif //__LIBRARY_H_
diff --git a/src/include/symbols.h b/src/include/symbols.h
index 49cd40f0..98eb9db7 100644
--- a/src/include/symbols.h
+++ b/src/include/symbols.h
@@ -14,11 +14,19 @@ void FreeMapSymbols(kh_mapsymbols_t** map);
 
 // replace if already there
 void AddSymbol(kh_mapsymbols_t *mapsymbols, const char* name, uintptr_t addr, uint32_t sz, int ver, const char* vername);
-uintptr_t FindSymbol(kh_mapsymbols_t *mapsymbols, const char* name, int ver, const char* vername, int local);
+uintptr_t FindSymbol(kh_mapsymbols_t *mapsymbols, const char* name, int ver, const char* vername, int local, const char* defver);
 // don't add if already there
 
-void AddWeakSymbol(kh_mapsymbols_t *mapsymbols, const char* name, uintptr_t addr, uint32_t sz, int ver, const char* vername);
-int GetSymbolStartEnd(kh_mapsymbols_t* mapsymbols, const char* name, uintptr_t* start, uintptr_t* end, int ver, const char* vername, int local);
+void AddUniqueSymbol(kh_mapsymbols_t *mapsymbols, const char* name, uintptr_t addr, uint32_t sz, int ver, const char* vername);
+int GetSymbolStartEnd(kh_mapsymbols_t* mapsymbols, const char* name, uintptr_t* start, uintptr_t* end, int ver, const char* vername, int local, const char* defver);
 const char* GetSymbolName(kh_mapsymbols_t* mapsymbols, void* p, uintptr_t* offs, uint32_t* sz, const char** vername);
 
+// default version handling
+KHASH_MAP_DECLARE_STR(defaultversion, const char*)
+kh_defaultversion_t* NewDefaultVersion();
+void FreeDefaultVersion(kh_defaultversion_t** def);
+
+void AddDefaultVersion(kh_defaultversion_t* def, const char* symname, const char* vername);
+const char* GetDefaultVersion(kh_defaultversion_t* def, const char* symname);
+
 #endif //__SYMBOLS_PRIVATE_H_
\ No newline at end of file
diff --git a/src/include/wrappedlibs.h b/src/include/wrappedlibs.h
index 5ff61939..871f7af0 100755
--- a/src/include/wrappedlibs.h
+++ b/src/include/wrappedlibs.h
@@ -7,7 +7,7 @@ typedef struct box64context_s  box64context_t;
 
 typedef int (*wrappedlib_init_t)(library_t * lib, box64context_t* box64);  // 0 = success
 typedef void (*wrappedlib_fini_t)(library_t * lib);
-typedef int (*wrappedlib_get_t)(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, int version, const char* vername, int local);
+typedef int (*wrappedlib_get_t)(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, int* weak, int version, const char* vername, int local);
 
 void setNeededLibs(library_t* lib, int n, ...);
 #define SETALT(A)       lib->w.altmy = strdup(#A)
@@ -17,8 +17,6 @@ typedef struct wrappedlib_s {
     const char*         name;
     wrappedlib_init_t   init;
     wrappedlib_fini_t   fini;
-    wrappedlib_get_t    get;
-    wrappedlib_get_t    getnoweak;
 } wrappedlib_t;
 
 #endif //__WRAPPEDLIBS_H__
diff --git a/src/librarian/librarian.c b/src/librarian/librarian.c
index e871b68e..170ff329 100755
--- a/src/librarian/librarian.c
+++ b/src/librarian/librarian.c
@@ -19,17 +19,12 @@ KHASH_MAP_IMPL_INT(mapoffsets, cstr_t);
 
 lib_t *NewLibrarian(box64context_t* context, int ownlibs)
 {
-    lib_t *maplib = (lib_t*)box_calloc(1, sizeof(lib_t));
+    lib_t *maplib = (lib_t*)calloc(1, sizeof(lib_t));
     
-    maplib->mapsymbols = NewMapSymbols();
-    maplib->weaksymbols = NewMapSymbols();
-    maplib->localsymbols = NewMapSymbols();
     maplib->mapoffsets = kh_init(mapoffsets);
     maplib->globaldata = NewMapSymbols();
     maplib->bridge = NewBridge();
 
-    maplib->context = context;
-
     maplib->ownlibs = ownlibs;
 
     return maplib;
@@ -38,43 +33,47 @@ static void freeLibraryRecurse(lib_t *maplib, x64emu_t *emu, int idx, char *free
     if (freed[idx]) return; // Already freed
     
     library_t *lib = maplib->libraries[idx];
-    if(lib==owner) return; // don't free owner of maplib
+    if(lib==owner) return;  // don't free owner of maplib
     freed[idx] = 1; // Avoid infinite loops
-    printf_log(LOG_DEBUG, "Free %s\n", lib->name);
-    for (int i = lib->depended.size - 1; i >= 0; --i) {
+    printf_log(LOG_DEBUG, "Unloading %s\n", lib->name);
+    for (int i = lib->dependedby.size - 1; i >= 0; --i) {
         int j;
         for (j = 0; j < maplib->libsz; ++j) {
-            if (lib->depended.libs[i] == maplib->libraries[j]) break;
+            if (lib->dependedby.libs[i] == maplib->libraries[j]) break;
         }
         if (j == maplib->libsz) {
             // dependant lib already freed
+            // library as been freed already
             continue;
         }
         if (freed[j] == 1) {
-            printf_log(LOG_DEBUG, "Cyclic dependancy detected (cycle is between %s and %s)\n", lib->name, lib->depended.libs[i]->name);
+            printf_log(LOG_DEBUG, "Cyclic dependancy detected (cycle is between %s and %s)\n", lib->name, lib->dependedby.libs[i]->name);
             continue;
         }
         freeLibraryRecurse(maplib, emu, j, freed, owner);
         if (freed[idx] != 1) {
-            printf_log(LOG_DEBUG, "Library cleared (cyclic dependancy break)\n");
+            printf_log(LOG_DEBUG, "Note: library already freed (cyclic dependancy break)\n");
             return;
         }
     }
+    
     library_t *ptr = maplib->libraries[idx];
-    if(maplib->ownlibs)
+    if(maplib->ownlibs/* && (!maplib->owner || ptr->maplib==maplib)*/)
         Free1Library(&ptr, emu);
     freed[idx] = 2;
 }
 void FreeLibrarian(lib_t **maplib, x64emu_t *emu)
 {
+    // should that be in reverse order?
     if(!maplib || !*maplib)
         return;
-    
+
     library_t* owner = (*maplib)->owner;
-    (*maplib)->owner = NULL;    // to avoid recursive free
+    (*maplib)->owner = NULL;    // to avoid recursive free...
+    
     if((*maplib)->ownlibs && (*maplib)->libsz) {
         printf_log(LOG_DEBUG, "Closing %d libs from maplib %p\n", (*maplib)->libsz, *maplib);
-        char *freed = (char*)box_calloc((*maplib)->libsz, sizeof(char));
+        char *freed = (char*)calloc((*maplib)->libsz, sizeof(char));
         if (!freed) {
             printf_log(LOG_INFO, "Failed to malloc freed table, using old algorithm (a crash is likely)\n");
             for (int i=(*maplib)->libsz-1; i>=0; --i) 
@@ -88,15 +87,12 @@ void FreeLibrarian(lib_t **maplib, x64emu_t *emu)
             }
             memset((*maplib)->libraries, 0, (*maplib)->libsz*sizeof(library_t*)); // NULL = 0 anyway
             (*maplib)->libsz = 0;
-            box_free(freed);
+            free(freed);
         }
     }
-    box_free((*maplib)->libraries);
+    free((*maplib)->libraries);
     (*maplib)->libraries = NULL;
 
-    FreeMapSymbols(&(*maplib)->mapsymbols);
-    FreeMapSymbols(&(*maplib)->weaksymbols);
-    FreeMapSymbols(&(*maplib)->localsymbols);
     if((*maplib)->mapoffsets) {
         kh_destroy(mapoffsets, (*maplib)->mapoffsets);
     }
@@ -106,29 +102,14 @@ void FreeLibrarian(lib_t **maplib, x64emu_t *emu)
     if((*maplib)->bridge)
         FreeBridge(&(*maplib)->bridge);
 
-    box_free(*maplib);
+    free(*maplib);
     *maplib = NULL;
 
 }
 
 box64context_t* GetLibrarianContext(lib_t* maplib)
 {
-    return maplib->context;
-}
-
-kh_mapsymbols_t* GetMapSymbol(lib_t* maplib)
-{
-    return maplib->mapsymbols;
-}
-
-kh_mapsymbols_t* GetWeakSymbol(lib_t* maplib)
-{
-    return maplib->weaksymbols;
-}
-
-kh_mapsymbols_t* GetLocalSymbol(lib_t* maplib)
-{
-    return maplib->localsymbols;
+    return my_context;
 }
 
 kh_mapsymbols_t* GetGlobalData(lib_t* maplib)
@@ -163,29 +144,35 @@ void MapLibAddLib(lib_t* maplib, library_t* lib)
         return;
     if (maplib->libsz == maplib->libcap) {
         maplib->libcap += 8;
-        maplib->libraries = (library_t**)box_realloc(maplib->libraries, maplib->libcap*sizeof(library_t*));
+        maplib->libraries = (library_t**)realloc(maplib->libraries, maplib->libcap*sizeof(library_t*));
     }
     maplib->libraries[maplib->libsz] = lib;
     ++maplib->libsz;
 }
 
-void MapLibAddMapLib(lib_t* dest, lib_t* src)
+static void MapLibRemoveLib(lib_t* maplib, library_t* lib);
+
+static void MapLibAddMapLib(lib_t* dest, library_t* lib_src, lib_t* src)
 {
     if(!src)
         return;
+    library_t *owner = src->owner;
     for(int i=0; i<src->libsz; ++i) {
         library_t* lib = src->libraries[i];
         if(!lib || libraryInMapLib(dest, lib)) continue;
         MapLibAddLib(dest, lib);
-        if(lib->maplib && src!=lib->maplib) {   //TODO: find why is src!=lib->maplib needed
-            MapLibAddMapLib(dest, lib->maplib);
-            box_free(lib->maplib);
-            lib->maplib = NULL;
+        if(lib->maplib && src!=lib->maplib && dest!=lib->maplib) {
+            MapLibAddMapLib(dest, lib, lib->maplib);
+            MapLibRemoveLib(src, lib);
+            if(lib->maplib)
+                lib->maplib = (dest==my_context->maplib)?NULL:dest;
         }
     }
+    if(lib_src == owner)
+        FreeLibrarian(&src, NULL);
 }
 
-void MapLibRemoveLib(lib_t* maplib, library_t* lib)
+static void MapLibRemoveLib(lib_t* maplib, library_t* lib)
 {
     if(!maplib || !lib)
         return;
@@ -196,6 +183,7 @@ void MapLibRemoveLib(lib_t* maplib, library_t* lib)
     --maplib->libsz;
     if(idx!=(maplib->libsz))
         memmove(&maplib->libraries[idx], &maplib->libraries[idx+1], sizeof(library_t*)*(maplib->libsz-idx));
+    maplib->libraries[maplib->libsz] = NULL;
 }
 
 static void MapLibRemoveMapLib(lib_t* dest, lib_t* src)
@@ -222,7 +210,7 @@ int AddNeededLib_add(lib_t* maplib, needed_libs_t* neededlibs, library_t* deplib
     library_t *lib = getLib(my_context->maplib, path);
     if(lib) {
         add_neededlib(neededlibs, lib);
-        if (lib && deplib) add_dependedlib(&lib->depended, deplib);
+        if (lib && deplib) add_dependedbylib(&lib->dependedby, deplib);
         printf_log(LOG_DEBUG, "Already present in maplib => success\n");
         return 0;
     }
@@ -234,7 +222,7 @@ int AddNeededLib_add(lib_t* maplib, needed_libs_t* neededlibs, library_t* deplib
             // add lib to maplib...
             if(maplib) {
                 if(lib->maplib) {
-                    MapLibAddMapLib(maplib, lib->maplib);
+                    MapLibAddMapLib(maplib, lib, lib->maplib);
                 }
                 if(!libraryInMapLib(maplib, lib))
                     MapLibAddLib(maplib, lib);
@@ -245,16 +233,14 @@ int AddNeededLib_add(lib_t* maplib, needed_libs_t* neededlibs, library_t* deplib
             // promote lib from local to global...
             // for add the depending local libs...
             if(lib->maplib) {
-                MapLibAddMapLib(my_context->maplib, lib->maplib);
-                box_free(lib->maplib);
-                lib->maplib = NULL;
+                MapLibAddMapLib(my_context->maplib, lib, lib->maplib);
             }
             if(!libraryInMapLib(my_context->maplib, lib))
                 MapLibAddLib(my_context->maplib, lib);
             MapLibRemoveMapLib(my_context->local_maplib, my_context->maplib);
         }
         add_neededlib(neededlibs, lib);
-        if (lib && deplib) add_dependedlib(&lib->depended, deplib);
+        if (lib && deplib) add_dependedbylib(&lib->dependedby, deplib);
         return 0;
     }
     // load a new one
@@ -265,15 +251,19 @@ int AddNeededLib_add(lib_t* maplib, needed_libs_t* neededlibs, library_t* deplib
     }
 
     add_neededlib(neededlibs, lib);
-    if (lib && deplib) add_dependedlib(&lib->depended, deplib);
+    if (lib && deplib) add_dependedbylib(&lib->dependedby, deplib);
 
     // add lib now
     if(local) {
         MapLibAddLib(my_context->local_maplib, lib);
-        if(maplib)
+        if(maplib) {
             MapLibAddLib(maplib, lib);
-        lib->maplib = NewLibrarian(box64, 0);
-        MapLibAddLib(lib->maplib, lib);
+            if(!lib->maplib)
+                lib->maplib = maplib;
+        } else {
+            lib->maplib = NewLibrarian(box64, 0);
+            MapLibAddLib(lib->maplib, lib);
+        }
     } else {
         MapLibAddLib(my_context->maplib, lib);
     }
@@ -281,7 +271,6 @@ int AddNeededLib_add(lib_t* maplib, needed_libs_t* neededlibs, library_t* deplib
     if(!maplib)
         maplib = (local)?lib->maplib:my_context->maplib;
 
-
     if(AddSymbolsLibrary(maplib, lib, emu)) {   // also add needed libs
         printf_log(LOG_DEBUG, "Failure to Add lib => fail\n");
         return 1;
@@ -345,7 +334,7 @@ int AddNeededLib(lib_t* maplib, needed_libs_t* neededlibs, library_t* deplib, in
 {
     box64_mapclean = 0;
     if(!neededlibs) {
-        neededlibs = box_calloc(1, sizeof(needed_libs_t));
+        neededlibs = calloc(1, sizeof(needed_libs_t));
     }
     int idx = neededlibs->size;
     // Add libs and symbol
@@ -390,9 +379,7 @@ uintptr_t FindGlobalSymbol(lib_t *maplib, const char* name, int version, const c
 
 static int isLocal(elfheader_t* self, library_t* l)
 {
-    if(GetElfIndex(l)==-1)
-        return 1;
-    if(my_context->elfs[GetElfIndex(l)]==self)
+    if(GetElf(l)==self)
         return 1;
     return 0;
 }
@@ -402,31 +389,41 @@ int GetNoSelfSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, u
     assert(self);   // need self for this one
     //search for the self, to start "next"
     int go = -1;
+    int weak = 0;
+    const char* defver = GetDefaultVersion(my_context->globaldefver, name);
     for(int i=0; i<maplib->libsz && (go==-1); ++i) {
-        if(GetElfIndex(maplib->libraries[i])!=-1 && (maplib->context->elfs[GetElfIndex(maplib->libraries[i])]==self))
+        if(GetElfIndex(maplib->libraries[i])!=-1 && (GetElf(maplib->libraries[i])==self))
             go = i+1;
     }
     if(go<0)
         go = 0; // not found...
     for(int i=go; i<maplib->libsz; ++i) {
-        if(GetElfIndex(maplib->libraries[i])==-1 || (maplib->context->elfs[GetElfIndex(maplib->libraries[i])]!=self))
-            if(GetLibSymbolStartEnd(maplib->libraries[i], name, start, end, version, vername, 0))
+        if(GetElfIndex(maplib->libraries[i])==-1 || (my_context->elfs[GetElfIndex(maplib->libraries[i])]!=self))
+            if(GetLibGlobalSymbolStartEnd(maplib->libraries[i], name, start, end, &weak, version, vername, 0))
                 if(*start)
                     return 1;
     }
+    for(int i=go; i<maplib->libsz; ++i)
+        if(GetElfIndex(maplib->libraries[i])==-1 || (my_context->elfs[GetElfIndex(maplib->libraries[i])]!=self))
+            GetLibWeakSymbolStartEnd(maplib->libraries[i], name, start, end, &weak, version, vername, 0);
+    // loop done, weak symbol found
+    if(weak && *start)
+        return 1;
     // if self defined, give it another chance with self...
+    defver = GetDefaultVersion(my_context->weakdefver, name);
     if(self) {
-        if(maplib->context->elfs[0]==self) {
-            if(GetSymbolStartEnd(maplib->mapsymbols, name, start, end, version, vername, 1))
+        if(my_context->elfs[0]==self) {
+            if(GetSymbolStartEnd(GetMapSymbols(my_context->elfs[0]), name, start, end, version, vername, 1, defver))
                 if(*start)
                     return 1;
-            if(GetSymbolStartEnd(maplib->weaksymbols, name, start, end, version, vername, 1))
+            if(GetSymbolStartEnd(GetWeakSymbols(my_context->elfs[0]), name, start, end, version, vername, 1, defver))
                 if(*start)
                     return 1;
         }
+        // should check weak here?
         for(int i=0; i<go; ++i) {
-            if(GetElfIndex(maplib->libraries[i])==-1 || (maplib->context->elfs[GetElfIndex(maplib->libraries[i])]==self))
-                if(GetLibSymbolStartEnd(maplib->libraries[i], name, start, end, version, vername, 1))
+            if(GetElfIndex(maplib->libraries[i])==-1 || (my_context->elfs[GetElfIndex(maplib->libraries[i])]==self))
+                if(GetLibWeakSymbolStartEnd(maplib->libraries[i], name, start, end, &weak, version, vername, 1))
                     if(*start)
                         return 1;
         }
@@ -436,52 +433,57 @@ int GetNoSelfSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, u
 }
 static int GetGlobalSymbolStartEnd_internal(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, elfheader_t* self, int version, const char* vername)
 {
+    int weak = 0;
+    // check with default version...
+    const char* defver = GetDefaultVersion(my_context->globaldefver, name);
     // search non-weak symbol, from older to newer (first GLOBAL object wins)
-    if(GetSymbolStartEnd(maplib->mapsymbols, name, start, end, version, vername, (maplib->context->elfs[0]==self || !self)?1:0))
+    if(GetSymbolStartEnd(GetMapSymbols(my_context->elfs[0]), name, start, end, version, vername, (my_context->elfs[0]==self || !self)?1:0, defver))
         if(*start)
             return 1;
     // TODO: create a temporary map to search lib only 1 time, and in order of needed...
     // search in needed libs from neededlibs first, in order
     for(int i=0; i<my_context->neededlibs.size; ++i)
-        if(GetLibNoWeakSymbolStartEnd(my_context->neededlibs.libs[i], name, start, end, version, vername, isLocal(self, my_context->neededlibs.libs[i])))
+        if(GetLibGlobalSymbolStartEnd(my_context->neededlibs.libs[i], name, start, end, &weak, version, vername, isLocal(self, my_context->neededlibs.libs[i])))
             if(*start)
                 return 1;
     // search in global symbols
     for(int i=0; i<maplib->libsz; ++i) {
-        if(GetLibNoWeakSymbolStartEnd(maplib->libraries[i], name, start, end, version, vername, isLocal(self, maplib->libraries[i])))
+        if(GetLibGlobalSymbolStartEnd(maplib->libraries[i], name, start, end, &weak, version, vername, isLocal(self, maplib->libraries[i])))
             if(*start)
                 return 1;
     }
 
-    if(GetSymbolStartEnd(maplib->weaksymbols, name, start, end, version, vername, (maplib->context->elfs[0]==self || !self)?1:0))
+    // check with default version...
+    defver = GetDefaultVersion(my_context->weakdefver, name);
+    int ok = 0;
+    // GetSymbolStartEnd should not change start/end if symbol is not found
+    if(GetSymbolStartEnd(GetWeakSymbols(my_context->elfs[0]), name, start, end, version, vername, (my_context->elfs[0]==self || !self)?1:0, defver))
         if(*start)
-            return 1;
-            
+            ok = 1;
+
     for(int i=0; i<maplib->libsz; ++i) {
-        if(GetLibSymbolStartEnd(maplib->libraries[i], name, start, end, version, vername, isLocal(self, maplib->libraries[i])))    // only weak symbol haven't been found yet
+        if(GetLibWeakSymbolStartEnd(maplib->libraries[i], name, start, end, &weak, version, vername, isLocal(self, maplib->libraries[i])))
             if(*start)
-                return 1;
+                ok = 1;
     }
     // nope, not found
-    return 0;
+    return (ok && *start)?1:0;
 }
 void** my_GetGTKDisplay();
 void** my_GetGthreadsGotInitialized();
 int GetGlobalSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, elfheader_t* self, int version, const char* vername)
 {
-    if(!maplib)
-        return 0;
     if(GetGlobalSymbolStartEnd_internal(maplib, name, start, end, self, version, vername)) {
         if(start && end && *end==*start) {  // object is of 0 sized, try to see an "_END" object of null size
             uintptr_t start2, end2;
-            char* buff = (char*)box_malloc(strlen(name) + strlen("_END") + 1);
+            char* buff = (char*)malloc(strlen(name) + strlen("_END") + 1);
             strcpy(buff, name);
             strcat(buff, "_END");
             if(GetGlobalSymbolStartEnd_internal(maplib, buff, &start2, &end2, self, version, vername)) {
                 if(end2>*end && start2==end2)
                     *end = end2;
             }
-            box_free(buff);
+            free(buff);
         }
         return 1;
     }
@@ -506,31 +508,58 @@ elfheader_t* GetGlobalSymbolElf(lib_t *maplib, const char* name, int version, co
 {
     uintptr_t start = 0;
     uintptr_t end = 0;
-    if(GetSymbolStartEnd(maplib->mapsymbols, name, &start, &end, version, vername, 1))
-        return maplib->context->elfs[0];
-    if(GetSymbolStartEnd(maplib->weaksymbols, name, &start, &end, version, vername, 1))
-        return maplib->context->elfs[0];
+    int weak = 0;
+    elfheader_t* ret = NULL;
+    // check with default version...
+    const char* defver = GetDefaultVersion(my_context->globaldefver, name);
+
+    if(GetSymbolStartEnd(GetMapSymbols(my_context->elfs[0]), name, &start, &end, version, vername, 1, defver))
+        return my_context->elfs[0];
     for(int i=0; i<maplib->libsz; ++i) {
-        if(GetLibSymbolStartEnd(maplib->libraries[i], name, &start, &end, version, vername, 1)) {
+        if(GetLibGlobalSymbolStartEnd(maplib->libraries[i], name, &start, &end, &weak, version, vername, 1)) {
             int idx = GetElfIndex(maplib->libraries[i]);
             if(idx==-1) {
                 printf_log(LOG_NONE, "Warning, getting Elf info for a native symbol \"%s\" from lib \"%s\"\n", name, GetNameLib(maplib->libraries[i]));
                 return NULL;
             }
-            return maplib->context->elfs[idx];
+            if(weak)
+                ret = my_context->elfs[idx];
+            else
+                return my_context->elfs[idx];
         }
     }
-    // nope, not found
-    return NULL;
+
+    defver = GetDefaultVersion(my_context->weakdefver, 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) {
+        if(GetLibWeakSymbolStartEnd(maplib->libraries[i], name, &start, &end, &weak, version, vername, 1)) {
+            int idx = GetElfIndex(maplib->libraries[i]);
+            if(idx==-1) {
+                printf_log(LOG_NONE, "Warning, getting Elf info for a native symbol \"%s\" from lib \"%s\"\n", name, GetNameLib(maplib->libraries[i]));
+                return NULL;
+            }
+            if(weak)
+                ret = my_context->elfs[idx];
+            else
+                return my_context->elfs[idx];
+        }
+    }
+    // return what has been found (maybe nothing)
+    return ret;
 }
 
 int GetGlobalNoWeakSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, int version, const char* vername)
 {
-    if(GetSymbolStartEnd(maplib->mapsymbols, name, start, end, version, vername, 1))
+    int weak = 0;
+    // check with default version...
+    const char* defver = GetDefaultVersion(my_context->globaldefver, name);
+
+    if(GetSymbolStartEnd(GetMapSymbols(my_context->elfs[0]), name, start, end, version, vername, 1, defver))
         if(*start || *end)
             return 1;
     for(int i=0; i<maplib->libsz; ++i)
-        if(GetLibNoWeakSymbolStartEnd(maplib->libraries[i], name, start, end, version, vername, 1))
+        if(GetLibGlobalSymbolStartEnd(maplib->libraries[i], name, start, end, &weak, version, vername, 1))
             if(*start || *end)
                 return 1;
     // nope, not found
@@ -540,9 +569,11 @@ int GetGlobalNoWeakSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* st
 int IsGlobalNoWeakSymbolInNative(lib_t *maplib, const char* name, int version, const char* vername)
 {
     uintptr_t start, end;
+    int weak;
+    // check with default version...
     for(int i=0; i<maplib->libsz; ++i)
         if(GetElfIndex(maplib->libraries[i])==-1)
-            if(GetLibNoWeakSymbolStartEnd(maplib->libraries[i], name, &start, &end, version, vername, 1))
+            if(GetLibGlobalSymbolStartEnd(maplib->libraries[i], name, &start, &end, &weak, version, vername, 1))
                 if(start || end)
                     return 1;
     // nope, not found
@@ -552,58 +583,30 @@ int IsGlobalNoWeakSymbolInNative(lib_t *maplib, const char* name, int version, c
 
 int GetLocalSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, elfheader_t *self, int version, const char* vername)
 {
-    if(maplib->context->elfs[0]==self || !self) {
-        if(GetSymbolStartEnd(maplib->localsymbols, name, start, end, version, vername, 1))
+    // check with default version...
+    int weak;
+
+    if(my_context->elfs[0]==self || !self) {
+        if(GetSymbolStartEnd(GetLocalSymbols(my_context->elfs[0]), name, start, end, version, vername, 1, NULL))
             if(*start || *end)
                 return 1;
         if(self)
             return 0;
     }
     for(int i=0; i<maplib->libsz; ++i) {
-        if(GetElfIndex(maplib->libraries[i])!=-1 && (!self || maplib->context->elfs[GetElfIndex(maplib->libraries[i])]==self)) {
-            if(GetLibLocalSymbolStartEnd(maplib->libraries[i], name, start, end, version, vername, 1))
+        if(GetElfIndex(maplib->libraries[i])!=-1 && (!self || my_context->elfs[GetElfIndex(maplib->libraries[i])]==self)) {
+            if(GetLibLocalSymbolStartEnd(maplib->libraries[i], name, start, end, &weak, version, vername, 1))
                 if(*start)
                     return 1;
             if(self)
                 return 0;
         }
     }
-    return 0;
-}
 
-int GetSelfSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, elfheader_t *self, int version, const char* vername)
-{
-    if(maplib->context->elfs[0]==self) {
-        if(GetSymbolStartEnd(maplib->localsymbols, name, start, end, version, vername, 1))
-            if(*start || *end)
-                return 1;
-    } else {
-        for(int i=0; i<maplib->libsz; ++i) {
-            if(GetElfIndex(maplib->libraries[i])!=-1 && (maplib->context->elfs[GetElfIndex(maplib->libraries[i])]==self))
-                if(GetLibSymbolStartEnd(maplib->libraries[i], name, start, end, version, vername, 1))
-                    if(*start || *end)
-                        return 1;
-        }
-    }
     return 0;
 }
 
-int GetNoWeakSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, elfheader_t *self, int version, const char* vername)
-{
-    if(maplib->context->elfs[0]==self) {
-        if(GetSymbolStartEnd(maplib->mapsymbols, name, start, end, version, vername, 1))
-            if(*start || *end)
-                return 1;
-    } else {
-        for(int i=0; i<maplib->libsz; ++i) {
-            if(GetElfIndex(maplib->libraries[i])!=-1 && (maplib->context->elfs[GetElfIndex(maplib->libraries[i])]==self))
-                if(GetLibNoWeakSymbolStartEnd(maplib->libraries[i], name, start, end, version, vername, 1))
-                    if(*start || *end)
-                        return 1;
-        }
-    }
-    return 0;
-}
+
 const char* FindSymbolName(lib_t *maplib, void* p, void** start, uint64_t* sz, const char** libname, void** base, library_t** lib)
 {
     // first, search in self...
@@ -645,7 +648,6 @@ const char* FindSymbolName(lib_t *maplib, void* p, void** start, uint64_t* sz, c
         return ret;
     }
     // TODO: find if cyclic references exists (should also fix MapLibAddMapLib)
-    (void)maplib;
     /* for (int i = 0; i < maplib->libsz; ++i) {
         // if (maplib == maplib->libraries[i]->maplib) continue;
         const char *nameInLib = FindSymbolName(maplib->libraries[i]->maplib, p, start, sz, libname, base);
diff --git a/src/librarian/librarian_private.h b/src/librarian/librarian_private.h
index da2b1f0f..b7ff5c0c 100755
--- a/src/librarian/librarian_private.h
+++ b/src/librarian/librarian_private.h
@@ -13,9 +13,6 @@ typedef char* cstr_t;
 KHASH_MAP_DECLARE_INT(mapoffsets, cstr_t);
 
 typedef struct lib_s {
-    khash_t(mapsymbols)   *mapsymbols;
-    khash_t(mapsymbols)   *weaksymbols;
-    khash_t(mapsymbols)   *localsymbols;
     khash_t(mapoffsets)   *mapoffsets;
     khash_t(mapsymbols)   *globaldata;
     library_t             **libraries;
@@ -24,8 +21,6 @@ typedef struct lib_s {
     int                   ownlibs;
     library_t             *owner;       // in case that maplib is owned by a lib
 
-    box64context_t*       context;
-    
     bridge_t              *bridge;        // all x86 -> arm bridge
 } lib_t;
 
diff --git a/src/librarian/library.c b/src/librarian/library.c
index 50fd6df2..77a8d3a9 100755
--- a/src/librarian/library.c
+++ b/src/librarian/library.c
@@ -24,17 +24,20 @@
 #include "librarian_private.h"
 #include "pathcoll.h"
 #include "x64emu.h"
+#include "symbols.h"
+#include "elfs/elfloader_private.h"
+#include "library_inner.h"
 
 #include "wrappedlibs.h"
 // create the native lib list
 #define GO(P, N) int wrapped##N##_init(library_t* lib, box64context_t *box64); \
-                 void wrapped##N##_fini(library_t* lib); \
-                 int wrapped##N##_get(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, int version, const char* vername, int local); \
-                 int wrapped##N##_getnoweak(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, int version, const char* vername, int local);
+                 void wrapped##N##_fini(library_t* lib);
+
 #include "library_list.h"
+
 #undef GO
 
-#define GO(P, N) {P, wrapped##N##_init, wrapped##N##_fini, wrapped##N##_get, wrapped##N##_getnoweak},
+#define GO(P, N) {P, wrapped##N##_init, wrapped##N##_fini},
 wrappedlib_t wrappedlibs[] = {
 #include "library_list.h"
 };
@@ -81,7 +84,7 @@ int NbDot(const char* name)
     return ret;
 }
 
-void NativeLib_CommonInit(library_t *lib) {
+void WrappedLib_CommonInit(library_t *lib) {
     lib->w.bridge = NewBridge();
     
     lib->w.symbolmap = kh_init(symbolmap);
@@ -97,10 +100,8 @@ void NativeLib_CommonInit(library_t *lib) {
 
 void EmuLib_Fini(library_t* lib)
 {
-    kh_destroy(mapsymbols, lib->e.mapsymbols);
-    kh_destroy(mapsymbols, lib->e.localsymbols);
 }
-void NativeLib_FinishFini(library_t* lib)
+void WrappedLib_FinishFini(library_t* lib)
 {
     if(lib->w.lib)
         dlclose(lib->w.lib);
@@ -117,79 +118,88 @@ void NativeLib_FinishFini(library_t* lib)
     FreeBridge(&lib->w.bridge);
 }
 
-int WrappedLib_defget(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, int version, const char* vername, int local) {
+int WrappedLib_GetWeak(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, int* weak, int version, const char* vername, int local) {
     uintptr_t addr = 0;
     uintptr_t size = 0;
-    if (!getSymbolInMaps(lib, name, 0, &addr, &size, version, vername, local)) {
+    int wk = 0;
+    if (!getSymbolInMaps(lib, name, 0, &addr, &size, &wk, version, vername, local)) {
         return 0;
     }
     if(!addr && !size)
         return 0;
+    if(!wk) // found a global symbol
+        return 0;
     *offs = addr;
     *sz = size;
+    *weak = wk;
     return 1;
 }
-int EmuLib_Get(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, int version, const char* vername, int local)
+int EmuLib_GetWeak(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, int*weak, int version, const char* vername, int local)
 {
     // symbols...
     uintptr_t start, end;
-    if(GetSymbolStartEnd(lib->e.mapsymbols, name, &start, &end, version, vername, local))
-    {
-        *offs = start;
-        *sz = end-start;
-        return 1;
-    }
+    const char* defver = GetDefaultVersion(my_context->weakdefver, name);
     // weak symbols...
-    if(GetSymbolStartEnd(lib->e.weaksymbols, name, &start, &end, version, vername, local))
+    if(GetSymbolStartEnd(GetWeakSymbols(lib->e.elf), name, &start, &end, version, vername, local, defver))
     {
         *offs = start;
         *sz = end-start;
+        *weak = 1;
         return 1;
     }
     return 0;
 }
-int WrappedLib_defgetnoweak(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, int version, const char* vername, int local) {
+int WrappedLib_GetGlobal(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, int* weak, int version, const char* vername, int local) {
     uintptr_t addr = 0;
     uintptr_t size = 0;
-    if (!getSymbolInMaps(lib, name, 1, &addr, &size, version, vername, local)) {
+    int wk = 0;
+    if (!getSymbolInMaps(lib, name, 1, &addr, &size, &wk, version, vername, local)) {
         return 0;
     }
     if(!addr && !size)
         return 0;
+    if(wk)
+        return 0;   //found a weak symbol
     *offs = addr;
     *sz = size;
+    *weak = 0;
     return 1;
 }
-int EmuLib_GetNoWeak(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, int version, const char* vername, int local)
+int EmuLib_GetGlobal(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, int* weak, int version, const char* vername, int local)
 {
     uintptr_t start, end;
-    if(GetSymbolStartEnd(lib->e.mapsymbols, name, &start, &end, version, vername, local))
+    const char* defver = GetDefaultVersion(my_context->globaldefver, name);
+    if(GetSymbolStartEnd(GetMapSymbols(lib->e.elf), name, &start, &end, version, vername, local, defver))
     {
         *offs = start;
         *sz = end-start;
+        *weak = 0;
         return 1;
     }
     return 0;
 }
-int EmuLib_GetLocal(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, int version, const char* vername, int local)
+int EmuLib_GetLocal(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, int* weak, int version, const char* vername, int local)
 {
     uintptr_t start, end;
-    if(GetSymbolStartEnd(lib->e.localsymbols, name, &start, &end, version, vername, local))
+    const char* defver = GetDefaultVersion(my_context->globaldefver, name);
+    if(!defver) defver = GetDefaultVersion(my_context->weakdefver, name);
+    if(GetSymbolStartEnd(GetLocalSymbols(lib->e.elf), name, &start, &end, version, vername, local, defver))
     {
         *offs = start;
         *sz = end-start;
+        *weak = 0;
         return 1;
     }
     return 0;
 }
 
-int NativeLib_GetLocal(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, int version, const char* vername, int local)
+int WrappedLib_GetLocal(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, int* weak, int version, const char* vername, int local)
 {
     (void)lib; (void)name; (void)offs; (void)sz; (void)version; (void)vername; (void)local;
     return 0;
 }
 
-static void initNativeLib(library_t *lib, box64context_t* context) {
+static void initWrappedLib(library_t *lib, box64context_t* context) {
     int nb = sizeof(wrappedlibs) / sizeof(wrappedlib_t);
     for (int i=0; i<nb; ++i) {
         if(strcmp(lib->name, wrappedlibs[i].name)==0) {
@@ -202,10 +212,10 @@ static void initNativeLib(library_t *lib, box64context_t* context) {
             }
             printf_log(LOG_INFO, "Using native(wrapped) %s\n", lib->name);
             lib->fini = wrappedlibs[i].fini;
-            lib->get = wrappedlibs[i].get;
-            lib->getnoweak = wrappedlibs[i].getnoweak;
-            lib->getlocal = NativeLib_GetLocal;
-            lib->type = LIB_NATIVE;
+            lib->getglobal = WrappedLib_GetGlobal;
+            lib->getweak = WrappedLib_GetWeak;
+            lib->getlocal = WrappedLib_GetLocal;
+            lib->type = LIB_WRAPPED;
             // Call librarian to load all dependant elf
             if(AddNeededLib(context->maplib, &lib->needed, lib, 0, 0, (const char**)lib->w.neededlibs, lib->w.needed, context, thread_get_emu())) {
                 printf_log(LOG_NONE, "Error: loading a needed libs in elf %s\n", lib->name);
@@ -271,14 +281,11 @@ static int loadEmulatedLib(const char* libname, library_t *lib, box64context_t*
 
         lib->type = LIB_EMULATED;
         lib->fini = EmuLib_Fini;
-        lib->get = EmuLib_Get;
-        lib->getnoweak = EmuLib_GetNoWeak;
+        lib->getglobal = EmuLib_GetGlobal;
+        lib->getweak = EmuLib_GetWeak;
         lib->getlocal = EmuLib_GetLocal;
         lib->e.elf_index = mainelf;
         lib->e.elf = elf_header;
-        lib->e.mapsymbols = kh_init(mapsymbols);
-        lib->e.weaksymbols = kh_init(mapsymbols);
-        lib->e.localsymbols = kh_init(mapsymbols);
 
         if(lib->path && strcmp(lib->path, libname)) {
             box_free(lib->path);
@@ -381,13 +388,13 @@ library_t *NewLibrary(const char* path, box64context_t* context)
     // And now, actually loading a library
     // look for native(wrapped) libs first
     if(!notwrapped && !precise)
-        initNativeLib(lib, context);
+        initWrappedLib(lib, context);
     // then look for a native one
     if(lib->type==LIB_UNNKNOW)
         initEmulatedLib(path, lib, context);
     // still not loaded but notwrapped indicated: use wrapped...
     if(lib->type==LIB_UNNKNOW && notwrapped && !precise)
-        initNativeLib(lib, context);
+        initWrappedLib(lib, context);
     // nothing loaded, so error...
     if(lib->type==LIB_UNNKNOW)
     {
@@ -396,7 +403,9 @@ library_t *NewLibrary(const char* path, box64context_t* context)
         box_free(lib);
         return NULL;
     }
-    lib->bridgemap = kh_init(bridgemap);
+    lib->gbridgemap = kh_init(bridgemap);
+    lib->wbridgemap = kh_init(bridgemap);
+    lib->lbridgemap = kh_init(bridgemap);
 
     return lib;
 }
@@ -408,7 +417,7 @@ int AddSymbolsLibrary(lib_t *maplib, library_t* lib, x64emu_t* emu)
     if(lib->type==LIB_EMULATED) {
         elfheader_t *elf_header = lib->e.elf;
         // add symbols
-        AddSymbols(maplib, lib->e.mapsymbols, lib->e.weaksymbols, lib->e.localsymbols, elf_header);
+        AddSymbols(maplib, GetMapSymbols(lib->e.elf), GetWeakSymbols(lib->e.elf), GetLocalSymbols(lib->e.elf), elf_header);
     }
     return 0;
 }
@@ -432,12 +441,13 @@ int FinalizeLibrary(library_t* lib, lib_t* local_maplib, int bindnow, x64emu_t*
         }
 #ifdef HAVE_TRACE
         if(trace_func) {
+            int weak;
             if (GetGlobalSymbolStartEnd(local_maplib, trace_func, &trace_start, &trace_end, elf_header, -1, NULL)) {
                 SetTraceEmu(trace_start, trace_end);
                 printf_log(LOG_INFO, "TRACE on %s only (%p-%p)\n", trace_func, (void*)trace_start, (void*)trace_end);
                 box_free(trace_func);
                 trace_func = NULL;
-            } else if(GetLibLocalSymbolStartEnd(lib, trace_func, &trace_start, &trace_end, -1, NULL, 0)) {
+            } else if(GetLibLocalSymbolStartEnd(lib, trace_func, &trace_start, &trace_end, &weak, -1, NULL, 0)) {
                 SetTraceEmu(trace_start, trace_end);
                 printf_log(LOG_INFO, "TRACE on %s only (%p-%p)\n", trace_func, (void*)trace_start, (void*)trace_end);
                 box_free(trace_func);
@@ -518,14 +528,28 @@ void Free1Library(library_t **lib, x64emu_t* emu)
     box_free((*lib)->name);
     box_free((*lib)->path);
 
-    if((*lib)->bridgemap) {
+    if((*lib)->gbridgemap) {
+        bridged_t *br;
+        kh_foreach_value_ref((*lib)->gbridgemap, br,
+            free(br->name);
+        );
+        kh_destroy(bridgemap, (*lib)->gbridgemap);
+    }
+    if((*lib)->wbridgemap) {
         bridged_t *br;
-        kh_foreach_value_ref((*lib)->bridgemap, br,
-            box_free(br->name);
+        kh_foreach_value_ref((*lib)->wbridgemap, br,
+            free(br->name);
         );
-        kh_destroy(bridgemap, (*lib)->bridgemap);
+        kh_destroy(bridgemap, (*lib)->wbridgemap);
     }
-    if((*lib)->type == LIB_NATIVE) {
+    if((*lib)->lbridgemap) {
+        bridged_t *br;
+        kh_foreach_value_ref((*lib)->lbridgemap, br,
+            free(br->name);
+        );
+        kh_destroy(bridgemap, (*lib)->lbridgemap);
+    }
+    if((*lib)->type == LIB_WRAPPED) {
         if((*lib)->w.symbolmap)
             kh_destroy(symbolmap, (*lib)->w.symbolmap);
         if((*lib)->w.wsymbolmap)
@@ -546,7 +570,7 @@ void Free1Library(library_t **lib, x64emu_t* emu)
             kh_destroy(symbol2map, (*lib)->w.symbol2map);
     }
     free_neededlib(&(*lib)->needed);
-    free_neededlib(&(*lib)->depended);
+    free_neededlib(&(*lib)->dependedby);
 
     box_free(*lib);
     *lib = NULL;
@@ -562,7 +586,7 @@ int IsSameLib(library_t* lib, const char* path)
     if(!lib) 
         return 0;
     char* name = Path2Name(path);
-    if(!strchr(path, '/') || lib->type==LIB_NATIVE || !lib->path) {
+    if(!strchr(path, '/') || lib->type==LIB_WRAPPED || !lib->path) {
         if(strcmp(name, lib->name)==0)
             ret=1;
     } else {
@@ -581,79 +605,91 @@ int IsSameLib(library_t* lib, const char* path)
     box_free(name);
     return ret;
 }
-int GetLibSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start, uintptr_t* end, int version, const char* vername, int local)
+int GetLibWeakSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start, uintptr_t* end, int* weak, int version, const char* vername, int local)
 {
     if(!name[0] || !lib->active)
         return 0;
     khint_t k;
     // check first if already in the map
-    k = kh_get(bridgemap, lib->bridgemap, VersionnedName(name, version, vername));
-    if(k!=kh_end(lib->bridgemap)) {
-        *start = kh_value(lib->bridgemap, k).start;
-        *end = kh_value(lib->bridgemap, k).end;
+    k = kh_get(bridgemap, lib->wbridgemap, VersionnedName(name, version, vername));
+    if(k!=kh_end(lib->wbridgemap)) {
+        *start = kh_value(lib->wbridgemap, k).start;
+        *end = kh_value(lib->wbridgemap, k).end;
+        *weak = 1;
         return 1;
     }
+    if(local) {
+        k = kh_get(bridgemap, lib->lbridgemap, VersionnedName(name, version, vername));
+        if(k!=kh_end(lib->lbridgemap)) {
+            *start = kh_value(lib->lbridgemap, k).start;
+            *end = kh_value(lib->lbridgemap, k).end;
+            *weak = 0;
+            return 1;
+        }
+    }
     // get a new symbol
-    if(lib->get(lib, name, start, end, version, vername, local)) {
+    if(lib->getweak(lib, name, start, end, weak, version, vername, local)) {
         *end += *start;     // lib->get(...) gives size, not end
         char* symbol = box_strdup(VersionnedName(name, version, vername));
         int ret;
-        k = kh_put(bridgemap, lib->bridgemap, symbol, &ret);
-        kh_value(lib->bridgemap, k).name = symbol;
-        kh_value(lib->bridgemap, k).start = *start;
-        kh_value(lib->bridgemap, k).end = *end;
+        kh_bridgemap_t *map = local?lib->lbridgemap:((*weak)?lib->wbridgemap:lib->gbridgemap);
+        k = kh_put(bridgemap, map, symbol, &ret);
+        kh_value(map, k).name = symbol;
+        kh_value(map, k).start = *start;
+        kh_value(map, k).end = *end;
         return 1;
     }
     // nope
     return 0;
 }
-int GetLibNoWeakSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start, uintptr_t* end, int version, const char* vername, int local)
+int GetLibGlobalSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start, uintptr_t* end, int* weak, int version, const char* vername, int local)
 {
     if(!name[0] || !lib->active)
         return 0;
     khint_t k;
     // get a new symbol
-    if(lib->getnoweak(lib, name, start, end, version, vername, local)) {
+    if(lib->getglobal(lib, name, start, end, weak, version, vername, local)) {
         *end += *start;     // lib->get(...) gives size, not end
+        kh_bridgemap_t *map = local?lib->lbridgemap:((*weak)?lib->wbridgemap:lib->gbridgemap);
         // check if already in the map
-        k = kh_get(bridgemap, lib->bridgemap, VersionnedName(name, version, vername));
-        if(k!=kh_end(lib->bridgemap)) {
-            *start = kh_value(lib->bridgemap, k).start;
-            *end = kh_value(lib->bridgemap, k).end;
+        k = kh_get(bridgemap, map, VersionnedName(name, version, vername));
+        if(k!=kh_end(map)) {
+            *start = kh_value(map, k).start;
+            *end = kh_value(map, k).end;
             return 1;
         }
         char* symbol = box_strdup(VersionnedName(name, version, vername));
         int ret;
-        k = kh_put(bridgemap, lib->bridgemap, symbol, &ret);
-        kh_value(lib->bridgemap, k).name = symbol;
-        kh_value(lib->bridgemap, k).start = *start;
-        kh_value(lib->bridgemap, k).end = *end;
+        k = kh_put(bridgemap, map, symbol, &ret);
+        kh_value(map, k).name = symbol;
+        kh_value(map, k).start = *start;
+        kh_value(map, k).end = *end;
         return 1;
     }
     // nope
     return 0;
 }
-int GetLibLocalSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start, uintptr_t* end, int version, const char* vername, int local)
+int GetLibLocalSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start, uintptr_t* end, int* weak, int version, const char* vername, int local)
 {
     if(!name[0] || !lib->active)
         return 0;
     khint_t k;
     // check first if already in the map
-    k = kh_get(bridgemap, lib->bridgemap, VersionnedName(name, version, vername));
-    if(k!=kh_end(lib->bridgemap)) {
-        *start = kh_value(lib->bridgemap, k).start;
-        *end = kh_value(lib->bridgemap, k).end;
+    k = kh_get(bridgemap, lib->lbridgemap, VersionnedName(name, version, vername));
+    if(k!=kh_end(lib->lbridgemap)) {
+        *start = kh_value(lib->lbridgemap, k).start;
+        *end = kh_value(lib->lbridgemap, k).end;
         return 1;
     }
     // get a new symbol
-    if(lib->getlocal(lib, name, start, end, version, vername, local)) {
+    if(lib->getlocal(lib, name, start, end, weak, version, vername, local)) {
         *end += *start;     // lib->get(...) gives size, not end
         char* symbol = box_strdup(VersionnedName(name, version, vername));
         int ret;
-        k = kh_put(bridgemap, lib->bridgemap, symbol, &ret);
-        kh_value(lib->bridgemap, k).name = symbol;
-        kh_value(lib->bridgemap, k).start = *start;
-        kh_value(lib->bridgemap, k).end = *end;
+        k = kh_put(bridgemap, lib->lbridgemap, symbol, &ret);
+        kh_value(lib->lbridgemap, k).name = symbol;
+        kh_value(lib->lbridgemap, k).start = *start;
+        kh_value(lib->lbridgemap, k).end = *end;
         return 1;
     }
     // nope
@@ -665,8 +701,14 @@ int GetElfIndex(library_t* lib)
         return -1;
     return lib->e.elf_index;
 }
+elfheader_t* GetElf(library_t* lib)
+{
+    if(!lib || lib->type!=LIB_EMULATED)
+        return NULL;
+    return lib->e.elf;
+}
 
-static int getSymbolInDataMaps(library_t*lib, const char* name, int noweak, uintptr_t *addr, uintptr_t *size)
+static int getSymbolInDataMaps(library_t*lib, const char* name, int noweak, uintptr_t *addr, uintptr_t *size, int* weak)
 {
     void* symbol;
     khint_t k = kh_get(datamap, lib->w.datamap, name);
@@ -676,6 +718,7 @@ static int getSymbolInDataMaps(library_t*lib, const char* name, int noweak, uint
             // found!
             *addr = (uintptr_t)symbol;
             *size = kh_value(lib->w.datamap, k);
+            *weak = 0;
             return 1;
         }
     }
@@ -687,6 +730,7 @@ static int getSymbolInDataMaps(library_t*lib, const char* name, int noweak, uint
                 // found!
                 *addr = (uintptr_t)symbol;
                 *size = kh_value(lib->w.wdatamap, k);
+                *weak = 1;
                 return 1;
             }
         }
@@ -707,12 +751,13 @@ static int getSymbolInDataMaps(library_t*lib, const char* name, int noweak, uint
             // found!
             *addr = (uintptr_t)symbol;
             *size = kh_value(lib->w.mydatamap, k);
+            *weak = 0;
             return 1;
         }
     }
     return 0;
 }
-static int getSymbolInSymbolMaps(library_t*lib, const char* name, int noweak, uintptr_t *addr, uintptr_t *size)
+static int getSymbolInSymbolMaps(library_t*lib, const char* name, int noweak, uintptr_t *addr, uintptr_t *size, int* weak)
 {
     void* symbol;
     // check in mysymbolmap
@@ -731,6 +776,7 @@ static int getSymbolInSymbolMaps(library_t*lib, const char* name, int noweak, ui
             AddOffsetSymbol(my_context->maplib, symbol, name);
         *addr = AddBridge(lib->w.bridge, kh_value(lib->w.mysymbolmap, k), symbol, 0, name);
         *size = sizeof(void*);
+        *weak = 0;
         return 1;
     }
     // check in stsymbolmap (return struct...)
@@ -749,6 +795,7 @@ static int getSymbolInSymbolMaps(library_t*lib, const char* name, int noweak, ui
             AddOffsetSymbol(my_context->maplib, symbol, name);
         *addr = AddBridge(lib->w.bridge, kh_value(lib->w.stsymbolmap, k), symbol, sizeof(void*), name);
         *size = sizeof(void*);
+        *weak = 0;
         return 1;
     }
     // check in symbolmap
@@ -776,6 +823,7 @@ static int getSymbolInSymbolMaps(library_t*lib, const char* name, int noweak, ui
             AddOffsetSymbol(my_context->maplib, symbol, name);
         *addr = AddBridge(lib->w.bridge, kh_value(lib->w.symbolmap, k), symbol, 0, name);
         *size = sizeof(void*);
+        *weak = 0;
         return 1;
     }
     if(!noweak) {
@@ -795,6 +843,7 @@ static int getSymbolInSymbolMaps(library_t*lib, const char* name, int noweak, ui
                 AddOffsetSymbol(my_context->maplib, symbol, name);
             *addr = AddBridge(lib->w.bridge, kh_value(lib->w.wmysymbolmap, k), symbol, 0, name);
             *size = sizeof(void*);
+            *weak = 1;
             return 1;
         }
         k = kh_get(symbolmap, lib->w.wsymbolmap, name);
@@ -821,6 +870,7 @@ static int getSymbolInSymbolMaps(library_t*lib, const char* name, int noweak, ui
                 AddOffsetSymbol(my_context->maplib, symbol, name);
             *addr = AddBridge(lib->w.bridge, kh_value(lib->w.wsymbolmap, k), symbol, 0, name);
             *size = sizeof(void*);
+            *weak = 1;
             return 1;
         }
     }
@@ -841,26 +891,27 @@ static int getSymbolInSymbolMaps(library_t*lib, const char* name, int noweak, ui
                 AddOffsetSymbol(my_context->maplib, symbol, name);
             *addr = AddBridge(lib->w.bridge, kh_value(lib->w.symbol2map, k).w, symbol, 0, name);
             *size = sizeof(void*);
+            *weak = kh_value(lib->w.symbol2map, k).weak;
             return 1;
         }
 
     return 0;
 }
 
-int getSymbolInMaps(library_t *lib, const char* name, int noweak, uintptr_t *addr, uintptr_t *size, int version, const char* vername, int local)
+int getSymbolInMaps(library_t *lib, const char* name, int noweak, uintptr_t *addr, uintptr_t *size, int* weak, int version, const char* vername, int local)
 {
     if(!lib->active)
         return 0;
     if(version==-2) // don't send global native symbol for a version==-2 search
         return 0;
     // check in datamaps (but no version, it's not handled there)
-    if(getSymbolInDataMaps(lib, name, noweak, addr, size))
+    if(getSymbolInDataMaps(lib, name, noweak, addr, size, weak))
         return 1;
 
-    if(getSymbolInSymbolMaps(lib, VersionnedName(name, version, vername), noweak, addr, size))
+    if(getSymbolInSymbolMaps(lib, VersionnedName(name, version, vername), noweak, addr, size, weak))
         return 1;
 
-    if(getSymbolInSymbolMaps(lib, name, noweak, addr, size))
+    if(getSymbolInSymbolMaps(lib, name, noweak, addr, size, weak))
         return 1;
 
     return 0;
@@ -884,7 +935,7 @@ void* GetHandle(library_t* lib)
 {
     if(!lib)
         return NULL;
-    if(lib->type!=LIB_NATIVE)
+    if(lib->type!=LIB_WRAPPED)
         return NULL;
     return lib->w.lib;
 }
@@ -941,9 +992,66 @@ void AddMainElfToLinkmap(elfheader_t* elf)
     lm->l_ld = GetDynamicSection(elf);
 }
 
+static int is_neededlib_present(needed_libs_t* needed, library_t* lib)
+{
+    if(!needed || !lib)
+        return 0;
+    if(!needed->size)
+        return 0;
+    for(int i=0; i<needed->size; ++i)
+        if(needed->libs[i] == lib)
+            return 1;
+    return 0;
+}
+
+void add_neededlib(needed_libs_t* needed, library_t* lib)
+{
+    if(!needed)
+        return;
+    if(is_neededlib_present(needed, lib))
+        return;
+    if(needed->size == needed->cap) {
+        needed->cap += 8;
+        needed->libs = (library_t**)realloc(needed->libs, needed->cap*sizeof(library_t*));
+    }
+    needed->libs[needed->size++] = lib;
+}
+void free_neededlib(needed_libs_t* needed)
+{
+    if(!needed)
+        return;
+    needed->cap = 0;
+    needed->size = 0;
+    if(needed->libs)
+        free(needed->libs);
+    needed->libs = NULL;
+}
+void add_dependedbylib(needed_libs_t* dependedby, library_t* lib)
+{
+    if(!dependedby)
+        return;
+    if(is_neededlib_present(dependedby, lib))
+        return;
+    if(dependedby->size == dependedby->cap) {
+        dependedby->cap += 8;
+        dependedby->libs = (library_t**)realloc(dependedby->libs, dependedby->cap*sizeof(library_t*));
+    }
+    dependedby->libs[dependedby->size++] = lib;
+}
+void free_dependedbylib(needed_libs_t* dependedby)
+{
+    if(!dependedby)
+        return;
+    dependedby->cap = 0;
+    dependedby->size = 0;
+    if(dependedby->libs)
+        free(dependedby->libs);
+    dependedby->libs = NULL;
+}
+
 void setNeededLibs(library_t* lib, int n, ...)
 {
-    if(lib->type!=LIB_NATIVE && lib->type!=LIB_UNNKNOW)
+    if(lib->type!=LIB_WRAPPED && lib->type!=LIB_UNNKNOW)
         return;
     lib->w.needed = n;
     lib->w.neededlibs = (char**)box_calloc(n, sizeof(char*));
@@ -953,4 +1061,4 @@ void setNeededLibs(library_t* lib, int n, ...)
         lib->w.neededlibs[i] = box_strdup(va_arg(va, char*));
     }
     va_end (va);
-}
\ No newline at end of file
+}
diff --git a/src/librarian/library_inner.h b/src/librarian/library_inner.h
new file mode 100644
index 00000000..68598b32
--- /dev/null
+++ b/src/librarian/library_inner.h
@@ -0,0 +1,7 @@
+#ifndef __LIBRARY_INNER_H__
+#define __LIBRARY_INNER_H__
+
+void WrappedLib_CommonInit(library_t* lib);
+void WrappedLib_FinishFini(library_t* lib);
+
+#endif
\ No newline at end of file
diff --git a/src/librarian/library_private.h b/src/librarian/library_private.h
index 34810f86..3015c55e 100755
--- a/src/librarian/library_private.h
+++ b/src/librarian/library_private.h
@@ -8,12 +8,13 @@
 #include "wrappedlibs.h"
 #include "box64context.h"
 
-typedef struct lib_s    lib_t;
-typedef struct bridge_s bridge_t;
-typedef struct kh_bridgemap_s kh_bridgemap_t;
-typedef struct kh_mapsymbols_s kh_mapsymbols_t;
+typedef struct lib_s            lib_t;
+typedef struct bridge_s         bridge_t;
+typedef struct elfheader_s      elfheader_t;
+typedef struct kh_bridgemap_s   kh_bridgemap_t;
+typedef struct kh_mapsymbols_s  kh_mapsymbols_t;
+typedef struct x64emu_s         x64emu_t;
 
-typedef struct x64emu_s x64emu_t;
 typedef void (*wrapper_t)(x64emu_t* emu, uintptr_t fnc);
 
 typedef struct symbol2_s {
@@ -54,9 +55,6 @@ typedef struct elib_s {
     int             elf_index;
     elfheader_t     *elf;
     int             finalized;
-    kh_mapsymbols_t *mapsymbols;
-    kh_mapsymbols_t *weaksymbols;
-    kh_mapsymbols_t *localsymbols;
 } elib_t;
 
 typedef struct library_s {
@@ -66,18 +64,24 @@ typedef struct library_s {
     int                 type;   // 0: native(wrapped) 1: emulated(elf) -1: undetermined
     int                 active;
     wrappedlib_fini_t   fini;
-    wrappedlib_get_t    get;        // get weak and no weak
-    wrappedlib_get_t    getnoweak;  // get only non weak symbol
-    wrappedlib_get_t    getlocal;
+    wrappedlib_get_t    getglobal;  // get global (non-weak)
+    wrappedlib_get_t    getweak;    // get weak symbol
+    wrappedlib_get_t    getlocal;   // get local symbol
     union {
         wlib_t  w;     
         elib_t  e;
     };                              // private lib data
     needed_libs_t       needed;
-    needed_libs_t       depended;   // used to free library
-    lib_t               *maplib;    // local maplib, for dlopen'd library with LOCAL binding (most of the dlopen)
-    kh_bridgemap_t  *bridgemap;
+    needed_libs_t       dependedby;     // used to free library
+    lib_t               *maplib;        // local maplib, for dlopen'd library with LOCAL binding (most of the dlopen)
+    kh_bridgemap_t      *gbridgemap;    // global symbol bridgemap
+    kh_bridgemap_t      *wbridgemap;    // weak symbol bridgemap
+    kh_bridgemap_t      *lbridgemap;    // local symbol bridgemap
 } library_t;
+void add_neededlib(needed_libs_t* needed, library_t* lib);
+void free_neededlib(needed_libs_t* needed);
+void add_dependedbylib(needed_libs_t* dependedby, library_t* lib);
+void free_dependedbylib(needed_libs_t* dependedby);
 
 // type for map elements
 typedef struct map_onesymbol_s {
@@ -97,7 +101,7 @@ typedef struct map_onedata_s {
     int         weak;
 } map_onedata_t;
 
-int getSymbolInMaps(library_t *lib, const char* name, int noweak, uintptr_t *addr, uintptr_t *size, int version, const char* vername, int local);  // Add bridges to functions
+int getSymbolInMaps(library_t *lib, const char* name, int noweak, uintptr_t *addr, uintptr_t *size, int *weak, int version, const char* vername, int local);  // Add bridges to functions
 
 typedef struct linkmap_s {
     // actual struct link_map
diff --git a/src/librarian/symbols.c b/src/librarian/symbols.c
index 8042c860..3f5bc657 100644
--- a/src/librarian/symbols.c
+++ b/src/librarian/symbols.c
@@ -41,7 +41,7 @@ void FreeMapSymbols(kh_mapsymbols_t** map)
     if(!map || !(*map))
         return;
     versymbols_t *v;
-    kh_foreach_value_ref(*map, v, box_free(v->syms););
+    kh_foreach_value_ref(*map, v, free(v->syms););
 
     kh_destroy(mapsymbols, *map);
     *map = NULL;
@@ -105,7 +105,7 @@ static versymbol_t* FindFirstVersion(versymbols_t* s)
 }
 
 // Match version (so ver=0:0, ver=1:-1/1/X, ver=-1:any, ver=X:1/"name")
-static versymbol_t* MatchVersion(versymbols_t* s, int ver, const char* vername, int local)
+static versymbol_t* MatchVersion(versymbols_t* s, int ver, const char* vername, int local, const char* defver)
 {
     if(!s || !s->sz)
         return NULL;
@@ -120,19 +120,27 @@ static versymbol_t* MatchVersion(versymbols_t* s, int ver, const char* vername,
         if(local) ret = FindVersionLocal(s);
         if(!ret) ret = FindNoVersion(s);
         if(!ret) ret = FindVersionGlobal(s);
-        if(!ret) ret = FindFirstVersion(s);
+        if(!ret && defver) ret = FindVersion(s, defver);
+        //if(!ret) ret = FindFirstVersion(s);
+        return ret;
+    }
+    if(ver==-2) {
+        if(local) ret = FindVersionLocal(s);
+        if(!ret) ret = FindVersionGlobal(s);
         return ret;
     }
     if(ver==1) {
         if(local) ret = FindVersionLocal(s);
         if(!ret) ret = FindVersionGlobal(s);
         if(!ret) ret = FindNoVersion(s);
-        if(!ret) ret = FindFirstVersion(s);
+        if(!ret && defver) ret = FindVersion(s, defver);
+        //if(!ret) ret = FindFirstVersion(s);
         return ret;
     }
     ret = FindVersion(s, vername);
-    if(local && !ret) FindVersionLocal(s);
-    if(!ret) return FindVersionGlobal(s);
+    if(local && !ret) ret = FindVersionLocal(s);
+    if(!ret && defver && vername && !strcmp(defver, vername)) ret = FindVersionGlobal(s);
+    //if(!ret) return FindVersionGlobal(s);
     return ret;
 }
 
@@ -152,7 +160,7 @@ void AddSymbol(kh_mapsymbols_t *mapsymbols, const char* name, uintptr_t addr, ui
     // add a new record
     if(v->sz == v->cap) {
         v->cap+=4;
-        v->syms = (versymbol_t*)box_realloc(v->syms, v->cap*sizeof(versymbol_t));
+        v->syms = (versymbol_t*)realloc(v->syms, v->cap*sizeof(versymbol_t));
     }
     int idx = v->sz++;
     v->syms[idx].version = ver;
@@ -161,7 +169,7 @@ void AddSymbol(kh_mapsymbols_t *mapsymbols, const char* name, uintptr_t addr, ui
     v->syms[idx].sym.sz = sz;
 }
 
-uintptr_t FindSymbol(kh_mapsymbols_t *mapsymbols, const char* name, int ver, const char* vername, int local)
+uintptr_t FindSymbol(kh_mapsymbols_t *mapsymbols, const char* name, int ver, const char* vername, int local, const char* defver)
 {
     if(!mapsymbols)
         return 0;
@@ -169,13 +177,13 @@ uintptr_t FindSymbol(kh_mapsymbols_t *mapsymbols, const char* name, int ver, con
     if(k==kh_end(mapsymbols))
         return 0;
     versymbols_t * v = &kh_val(mapsymbols, k);
-    versymbol_t * s = MatchVersion(v, ver, vername, local);
+    versymbol_t * s = MatchVersion(v, ver, vername, local, defver);
     if(s)
         return s->sym.offs;
     return 0;
 }
 
-void AddWeakSymbol(kh_mapsymbols_t *mapsymbols, const char* name, uintptr_t addr, uint32_t sz, int ver, const char* vername)
+void AddUniqueSymbol(kh_mapsymbols_t *mapsymbols, const char* name, uintptr_t addr, uint32_t sz, int ver, const char* vername)
 {
     int ret;
     khint_t k = kh_put(mapsymbols, mapsymbols, name, &ret);
@@ -189,7 +197,7 @@ void AddWeakSymbol(kh_mapsymbols_t *mapsymbols, const char* name, uintptr_t addr
     // add a new record
     if(v->sz == v->cap) {
         v->cap+=4;
-        v->syms = (versymbol_t*)box_realloc(v->syms, v->cap*sizeof(versymbol_t));
+        v->syms = (versymbol_t*)realloc(v->syms, v->cap*sizeof(versymbol_t));
     }
     int idx = v->sz++;
     v->syms[idx].version = ver;
@@ -198,7 +206,7 @@ void AddWeakSymbol(kh_mapsymbols_t *mapsymbols, const char* name, uintptr_t addr
     v->syms[idx].sym.sz = sz;
 }
 
-int GetSymbolStartEnd(kh_mapsymbols_t* mapsymbols, const char* name, uintptr_t* start, uintptr_t* end, int ver, const char* vername, int local)
+int GetSymbolStartEnd(kh_mapsymbols_t* mapsymbols, const char* name, uintptr_t* start, uintptr_t* end, int ver, const char* vername, int local, const char* defver)
 {
     if(!mapsymbols)
         return 0;
@@ -206,7 +214,7 @@ int GetSymbolStartEnd(kh_mapsymbols_t* mapsymbols, const char* name, uintptr_t*
     if(k==kh_end(mapsymbols))
         return 0;
     versymbols_t * v = &kh_val(mapsymbols, k);
-    versymbol_t* s = MatchVersion(v, ver, vername, local);
+    versymbol_t* s = MatchVersion(v, ver, vername, local, defver);
     if(s) {
         *start = s->sym.offs;
         *end = *start + s->sym.sz;
@@ -231,3 +239,37 @@ const char* GetSymbolName(kh_mapsymbols_t* mapsymbols, void* p, uintptr_t* start
     );
     return NULL;
 }
+
+
+KHASH_MAP_IMPL_STR(defaultversion, const char*)
+kh_defaultversion_t* NewDefaultVersion()
+{
+    kh_defaultversion_t* ret = kh_init(defaultversion);
+    return ret;
+}
+
+void FreeDefaultVersion(kh_defaultversion_t** def)
+{
+    if(!def || !*def)
+        return;
+    const char* v;
+    kh_foreach_value(*def, v, free((char*)v););
+
+    kh_destroy(defaultversion, *def);
+    *def = NULL;
+}
+
+void AddDefaultVersion(kh_defaultversion_t* def, const char* symname, const char* vername)
+{
+    int ret;
+    khint_t k = kh_put(defaultversion, def, symname, &ret);
+    if(!ret) return;    // already set!
+    kh_value(def, k) = strdup(vername);
+}
+const char* GetDefaultVersion(kh_defaultversion_t* def, const char* symname)
+{
+    khint_t k = kh_get(defaultversion, def, symname);
+    if(k==kh_end(def))
+        return NULL;
+    return kh_value(def, k);
+}
diff --git a/src/main.c b/src/main.c
index 9e1bb0bd..b522f635 100755
--- a/src/main.c
+++ b/src/main.c
@@ -900,7 +900,7 @@ void setupTraceInit()
             if(s_trace_start || s_trace_end)
                 SetTraceEmu(s_trace_start, s_trace_end);
         } else {
-            if (GetSymbolStartEnd(GetMapSymbol(my_context->maplib), p, &s_trace_start, &s_trace_end, -1, NULL, -1)) {
+            if (GetGlobalSymbolStartEnd(my_context->maplib, p, &trace_start, &trace_end, NULL, -1, NULL)) {
                 SetTraceEmu(s_trace_start, s_trace_end);
                 printf_log(LOG_INFO, "TRACE on %s only (%p-%p)\n", p, (void*)s_trace_start, (void*)s_trace_end);
             } else {
@@ -1479,11 +1479,11 @@ int main(int argc, const char **argv, char **env) {
 
     setupTraceInit();
     // export symbols
-    AddSymbols(my_context->maplib, GetMapSymbol(my_context->maplib), GetWeakSymbol(my_context->maplib), GetLocalSymbol(my_context->maplib), elf_header);
+    AddSymbols(my_context->maplib, GetMapSymbols(elf_header), GetWeakSymbols(elf_header), GetLocalSymbols(elf_header), elf_header);
     if(wine_preloaded) {
-        uintptr_t wineinfo = FindSymbol(GetMapSymbol(my_context->maplib), "wine_main_preload_info", -1, NULL, 1);
-        if(!wineinfo) wineinfo = FindSymbol(GetWeakSymbol(my_context->maplib), "wine_main_preload_info", -1, NULL, 1);
-        if(!wineinfo) wineinfo = FindSymbol(GetLocalSymbol(my_context->maplib), "wine_main_preload_info", -1, NULL, 1);
+        uintptr_t wineinfo = FindSymbol(GetMapSymbols(elf_header), "wine_main_preload_info", -1, NULL, 1, NULL);
+        if(!wineinfo) wineinfo = FindSymbol(GetWeakSymbols(elf_header), "wine_main_preload_info", -1, NULL, 1, NULL);
+        if(!wineinfo) wineinfo = FindSymbol(GetLocalSymbols(elf_header), "wine_main_preload_info", -1, NULL, 1, NULL);
         if(!wineinfo) {printf_log(LOG_NONE, "Warning, Symbol wine_main_preload_info not found\n");}
         else {
             *(void**)wineinfo = get_wine_prereserve();
diff --git a/src/wrapped/wrappedlib_init.h b/src/wrapped/wrappedlib_init.h
index b61989b0..2b34acab 100755
--- a/src/wrapped/wrappedlib_init.h
+++ b/src/wrapped/wrappedlib_init.h
@@ -2,6 +2,8 @@
 #error Meh
 #endif
 
+#include "librarian/library_inner.h"
+
 #define FUNC3(M,N) wrapped##M##N
 #define FUNC2(M,N) FUNC3(M,N)
 #define FUNC(N) FUNC2(LIBNAME,N)
@@ -111,7 +113,6 @@ static const map_onedata_t MAPNAME(mydatamap)[] = {
 #undef DOIT
 #undef _DOIT
 
-void NativeLib_CommonInit(library_t *lib);
 int FUNC(_init)(library_t* lib, box64context_t* box64)
 {
     (void)box64;
@@ -140,7 +141,7 @@ int FUNC(_init)(library_t* lib, box64context_t* box64)
 #endif
         } else lib->path = strdup(MAPNAME(Name));
     }
-    NativeLib_CommonInit(lib);
+    WrappedLib_CommonInit(lib);
 
     khint_t k;
     int ret;
@@ -201,51 +202,11 @@ int FUNC(_init)(library_t* lib, box64context_t* box64)
     return 0;
 }
 
-void NativeLib_FinishFini(library_t* lib);
 void FUNC(_fini)(library_t* lib)
 {
 #ifdef CUSTOM_FINI
     CUSTOM_FINI
 #endif
-    NativeLib_FinishFini(lib);
-}
-
-int WrappedLib_defget(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, int version, const char* vername, int local);
-int FUNC(_get)(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, int version, const char* vername, int local)
-{
-#ifdef CUSTOM_FAIL
-    uintptr_t addr = 0;
-    uintptr_t size = 0;
-    void* symbol = NULL;
-    if (!getSymbolInMaps(lib, name, 0, &addr, &size, version, vername, local)) {
-        CUSTOM_FAIL
-    }
-    if(!addr && !size)
-        return 0;
-    *offs = addr;
-    *sz = size;
-    return 1;
-#else
-    return WrappedLib_defget(lib, name, offs, sz, version, vername, local);
-#endif
+    WrappedLib_FinishFini(lib);
 }
 
-int WrappedLib_defgetnoweak(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, int version, const char* vername, int local);
-int FUNC(_getnoweak)(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, int version, const char* vername, int local)
-{
-#ifdef CUSTOM_FAIL
-    uintptr_t addr = 0;
-    uintptr_t size = 0;
-    void* symbol = NULL;
-    if (!getSymbolInMaps(lib, name, 1, &addr, &size, version, vername, local)) {
-        CUSTOM_FAIL
-    }
-    if(!addr && !size)
-        return 0;
-    *offs = addr;
-    *sz = size;
-    return 1;
-#else
-    return WrappedLib_defgetnoweak(lib, name, offs, sz, version, vername, local);
-#endif
-}
diff --git a/src/wrapped/wrappedlibdl.c b/src/wrapped/wrappedlibdl.c
index 6360cf34..d452a8d8 100755
--- a/src/wrapped/wrappedlibdl.c
+++ b/src/wrapped/wrappedlibdl.c
@@ -129,7 +129,7 @@ void* my_dlopen(x64emu_t* emu, void *filename, int flag)
         const char* libs[] = {rfilename};
         my_context->deferedInit = 1;
         int bindnow = (!box64_musl && (flag&0x2))?1:0;
-        if(AddNeededLib(NULL, NULL, NULL, is_local, bindnow, libs, 1, emu->context, emu)) {
+        if(AddNeededLib(NULL, NULL, NULL, is_local, bindnow, libs, 1, 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);
@@ -175,7 +175,7 @@ void* my_dlmopen(x64emu_t* emu, void* lmid, void *filename, int flag)
 }
 char* my_dlerror(x64emu_t* emu)
 {
-    dlprivate_t *dl = emu->context->dlprivate;
+    dlprivate_t *dl = my_context->dlprivate;
     return dl->last_error;
 }
 
@@ -190,8 +190,12 @@ int recursive_dlsym_lib(kh_libs_t* collection, library_t* lib, const char* rsymb
         return 0;
     int ret;
     kh_put(libs, collection, (uintptr_t)lib, &ret);
+    // TODO: should use librarian functions instead!
+    int weak;
     // look in the library itself
-    if(lib->get(lib, rsymbol, start, end, version, vername, 1))
+    if(lib->getglobal(lib, rsymbol, start, end, &weak, version, vername, 1))
+        return 1;
+    if(lib->getweak(lib, rsymbol, start, end, &weak, version, vername, 1))
         return 1;
     // look in other libs
     int n = GetNeededLibN(lib);
@@ -215,14 +219,14 @@ int my_dlsym_lib(library_t* lib, const char* rsymbol, uintptr_t *start, uintptr_
 void* my_dlsym(x64emu_t* emu, void *handle, void *symbol)
 {
     (void)emu;
-    dlprivate_t *dl = emu->context->dlprivate;
+    dlprivate_t *dl = my_context->dlprivate;
     uintptr_t start = 0, end = 0;
     char* rsymbol = (char*)symbol;
     CLEARERR
     printf_dlsym(LOG_DEBUG, "Call to dlsym(%p, \"%s\")%s", handle, rsymbol, dlsym_error?"":"\n");
     if(handle==NULL) {
         // special case, look globably
-        if(GetGlobalSymbolStartEnd(emu->context->maplib, rsymbol, &start, &end, NULL, -1, NULL)) {
+        if(GetGlobalSymbolStartEnd(my_context->maplib, rsymbol, &start, &end, NULL, -1, NULL)) {
             printf_dlsym(LOG_NEVER, "%p\n", (void*)start);
             return (void*)start;
         }
@@ -234,8 +238,8 @@ void* my_dlsym(x64emu_t* emu, void *handle, void *symbol)
     }
     if(handle==(void*)~0LL) {
         // special case, look globably but no self (RTLD_NEXT)
-        elfheader_t *elf = FindElfAddress(emu->context, *(uintptr_t*)R_RSP); // use return address to guess "self"
-        if(GetNoSelfSymbolStartEnd(emu->context->maplib, rsymbol, &start, &end, elf, -1, NULL)) {
+        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, -1, NULL)) {
             printf_dlsym(LOG_NEVER, "%p\n", (void*)start);
             return (void*)start;
         }
@@ -275,7 +279,9 @@ void* my_dlsym(x64emu_t* emu, void *handle, void *symbol)
     } else {
         // still usefull?
         //  => look globably
-        if(GetGlobalSymbolStartEnd(emu->context->maplib, rsymbol, &start, &end, NULL, -1, NULL)) {
+        const char* defver = GetDefaultVersion(my_context->globaldefver, rsymbol);
+        if(!defver) defver = GetDefaultVersion(my_context->weakdefver, rsymbol);
+        if(GetGlobalSymbolStartEnd(my_context->maplib, rsymbol, &start, &end, NULL, -1, defver)) {
             printf_dlsym(LOG_NEVER, "%p\n", (void*)start);
             return (void*)start;
         }
@@ -292,7 +298,7 @@ int my_dlclose(x64emu_t* emu, void *handle)
 {
     (void)emu;
     printf_dlsym(LOG_DEBUG, "Call to dlclose(%p)\n", handle);
-    dlprivate_t *dl = emu->context->dlprivate;
+    dlprivate_t *dl = my_context->dlprivate;
     CLEARERR
     size_t nlib = (size_t)handle;
     --nlib;
@@ -316,7 +322,7 @@ int my_dlclose(x64emu_t* emu, void *handle)
         int idx = GetElfIndex(dl->libs[nlib]);
         if(idx!=-1) {
             printf_dlsym(LOG_DEBUG, "dlclose: Call to Fini for %p\n", handle);
-            RunElfFini(emu->context->elfs[idx], emu);
+            RunElfFini(my_context->elfs[idx], emu);
             InactiveLibrary(dl->libs[nlib]);
         }
     }
@@ -325,7 +331,7 @@ int my_dlclose(x64emu_t* emu, void *handle)
 int my_dladdr1(x64emu_t* emu, void *addr, void *i, void** extra_info, int flags)
 {
     //int dladdr(void *addr, Dl_info *info);
-    dlprivate_t *dl = emu->context->dlprivate;
+    dlprivate_t *dl = my_context->dlprivate;
     CLEARERR
     Dl_info *info = (Dl_info*)i;
     printf_log(LOG_DEBUG, "Warning: partially unimplement call to dladdr/dladdr1(%p, %p, %p, %d)\n", addr, info, extra_info, flags);
@@ -334,7 +340,7 @@ int my_dladdr1(x64emu_t* emu, void *addr, void *i, void** extra_info, int flags)
     library_t* lib = NULL;
     info->dli_saddr = NULL;
     info->dli_fname = NULL;
-    info->dli_sname = FindSymbolName(emu->context->maplib, addr, &info->dli_saddr, NULL, &info->dli_fname, &info->dli_fbase, &lib);
+    info->dli_sname = FindSymbolName(my_context->maplib, addr, &info->dli_saddr, NULL, &info->dli_fname, &info->dli_fbase, &lib);
     printf_log(LOG_DEBUG, "     dladdr return saddr=%p, fname=\"%s\", sname=\"%s\"\n", info->dli_saddr, info->dli_sname?info->dli_sname:"", info->dli_fname?info->dli_fname:"");
     if(flags==RTLD_DL_SYMENT) {
         printf_log(LOG_INFO, "Warning, unimplement call to dladdr1 with RTLD_DL_SYMENT flags\n");
@@ -350,7 +356,7 @@ int my_dladdr(x64emu_t* emu, void *addr, void *i)
 }
 void* my_dlvsym(x64emu_t* emu, void *handle, void *symbol, const char *vername)
 {
-    dlprivate_t *dl = emu->context->dlprivate;
+    dlprivate_t *dl = my_context->dlprivate;
     int version = (vername)?2:-1;
     uintptr_t start, end;
     char* rsymbol = (char*)symbol;
@@ -358,7 +364,7 @@ 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
-        if(GetGlobalSymbolStartEnd(emu->context->maplib, rsymbol, &start, &end, NULL, version, vername)) {
+        if(GetGlobalSymbolStartEnd(my_context->maplib, rsymbol, &start, &end, NULL, version, vername)) {
             printf_dlsym(LOG_NEVER, "%p\n", (void*)start);
             return (void*)start;
         }
@@ -370,8 +376,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)
-        elfheader_t *elf = FindElfAddress(emu->context, *(uintptr_t*)R_RSP); // use return address to guess "self"
-        if(GetNoSelfSymbolStartEnd(emu->context->maplib, rsymbol, &start, &end, elf, version, vername)) {
+        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, version, vername)) {
                 printf_dlsym(LOG_NEVER, "%p\n", (void*)start);
             return (void*)start;
         }
@@ -410,16 +416,10 @@ void* my_dlvsym(x64emu_t* emu, void *handle, void *symbol, const char *vername)
         }
     } else {
         // still usefull?
-        if(GetSymbolStartEnd(GetLocalSymbol(emu->context->maplib), rsymbol, &start, &end, version, vername, 1)) {
-                printf_dlsym(LOG_NEVER, "%p\n", (void*)start);
-            return (void*)start;
-        }
-        if(GetSymbolStartEnd(GetWeakSymbol(emu->context->maplib), rsymbol, &start, &end, version, vername, 1)) {
-                printf_dlsym(LOG_NEVER, "%p\n", (void*)start);
-            return (void*)start;
-        }
-        if(GetSymbolStartEnd(GetMapSymbol(emu->context->maplib), rsymbol, &start, &end, version, vername, 1)) {
-                printf_dlsym(LOG_NEVER, "%p\n", (void*)start);
+         const char* defver = GetDefaultVersion(my_context->globaldefver, rsymbol);
+        if(!defver) defver = GetDefaultVersion(my_context->weakdefver, rsymbol);
+        if(GetGlobalSymbolStartEnd(my_context->maplib, rsymbol, &start, &end, NULL, -1, defver)) {
+            printf_dlsym(LOG_NEVER, "%p\n", (void*)start);
             return (void*)start;
         }
         // not found
@@ -438,7 +438,7 @@ int my_dlinfo(x64emu_t* emu, void* handle, int request, void* info)
 {
     (void)emu;
     printf_dlsym(LOG_DEBUG, "Call to dlinfo(%p, %d, %p)\n", handle, request, info);
-    dlprivate_t *dl = emu->context->dlprivate;
+    dlprivate_t *dl = my_context->dlprivate;
     CLEARERR
     size_t nlib = (size_t)handle;
     --nlib;