about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/box64context.c6
-rw-r--r--src/elfs/elfhash.c354
-rw-r--r--src/elfs/elfload_dump.c5
-rw-r--r--src/elfs/elfloader.c706
-rw-r--r--src/elfs/elfloader_private.h24
-rw-r--r--src/elfs/elfparser.c128
-rw-r--r--src/emu/x64run_private.c2
-rw-r--r--src/include/box64context.h1
-rw-r--r--src/include/elfloader.h14
-rw-r--r--src/include/librarian.h22
-rw-r--r--src/include/library.h6
-rw-r--r--src/include/symbols.h18
-rw-r--r--src/include/wrappedlibs.h2
-rw-r--r--src/librarian/globalsymbols.c10
-rw-r--r--src/librarian/librarian.c369
-rw-r--r--src/librarian/librarian_private.h1
-rw-r--r--src/librarian/library.c189
-rw-r--r--src/librarian/library_private.h7
-rw-r--r--src/librarian/symbols.c78
-rw-r--r--src/libtools/sdl2rwops.c4
-rw-r--r--src/libtools/signals.c9
-rw-r--r--src/main.c68
-rw-r--r--src/mallochook.c7
-rw-r--r--src/tools/bridge.c2
-rw-r--r--src/wrapped/wrappedgtk3.c2
-rw-r--r--src/wrapped/wrappedgtkx112.c2
-rw-r--r--src/wrapped/wrappedlibdl.c47
27 files changed, 981 insertions, 1102 deletions
diff --git a/src/box64context.c b/src/box64context.c
index 679ee108..208a9fa2 100644
--- a/src/box64context.c
+++ b/src/box64context.c
@@ -212,8 +212,8 @@ box64context_t *NewBox64Context(int argc)
 
     init_custommem_helper(context);
 
-    context->maplib = NewLibrarian(context, 1);
-    context->local_maplib = NewLibrarian(context, 1);
+    context->maplib = NewLibrarian(context);
+    context->local_maplib = NewLibrarian(context);
     context->versym = NewDictionnary();
     context->system = NewBridge();
     // Cannot use Bridge name as the map is not initialized yet
@@ -263,6 +263,7 @@ box64context_t *NewBox64Context(int argc)
     context->segtls[4].is32bits = 1;
 
     context->globdata = NewMapSymbols();
+    context->uniques = NewMapSymbols();
 
     initAllHelpers(context);
     
@@ -363,6 +364,7 @@ void FreeBox64Context(box64context_t** context)
         FreeX64Emu(&ctx->emu_sig);
 
     FreeMapSymbols(&ctx->globdata);
+    FreeMapSymbols(&ctx->uniques);
 
 #ifdef DYNAREC
     //dynarec_log(LOG_INFO, "BOX64 Dynarec at exit: Max DB=%d, righter=%d\n", ctx->max_db_size, rb_get_righter(ctx->db_sizes));
diff --git a/src/elfs/elfhash.c b/src/elfs/elfhash.c
new file mode 100644
index 00000000..6c602617
--- /dev/null
+++ b/src/elfs/elfhash.c
@@ -0,0 +1,354 @@
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <elf.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/sysmacros.h>
+#include <sys/types.h>
+#include <link.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include "custommem.h"
+#include "box64version.h"
+#include "elfloader.h"
+#include "debug.h"
+#include "elfload_dump.h"
+#include "elfloader_private.h"
+
+const char* GetSymbolVersion(elfheader_t* h, int version)
+{
+    if(version<2)
+        return NULL;
+    /*if(version==1)
+        return "*";*/
+    if(h->VerNeed) {
+        Elf64_Verneed *ver = (Elf64_Verneed*)((uintptr_t)h->VerNeed + h->delta);
+        while(ver) {
+            Elf64_Vernaux *aux = (Elf64_Vernaux*)((uintptr_t)ver + ver->vn_aux);
+            for(int j=0; j<ver->vn_cnt; ++j) {
+                if(aux->vna_other==version) 
+                    return h->DynStr+aux->vna_name;
+                aux = (Elf64_Vernaux*)((uintptr_t)aux + aux->vna_next);
+            }
+            ver = ver->vn_next?((Elf64_Verneed*)((uintptr_t)ver + ver->vn_next)):NULL;
+        }
+    }
+    return GetParentSymbolVersion(h, version);  // if symbol is "internal", use Def table instead
+}
+
+const char* GetParentSymbolVersion(elfheader_t* h, int index)
+{
+    if(!h->VerDef || (index<1))
+        return NULL;
+    Elf64_Verdef *def = (Elf64_Verdef*)((uintptr_t)h->VerDef + h->delta);
+    while(def) {
+        if(def->vd_ndx==index) {
+            if(def->vd_cnt<1)
+                return NULL;
+            /*if(def->vd_flags&VER_FLG_BASE)
+                return NULL;*/
+            Elf64_Verdaux *aux = (Elf64_Verdaux*)((uintptr_t)def + def->vd_aux);
+            return h->DynStr+aux->vda_name; // return Parent, so 1st aux
+        }
+        def = def->vd_next?((Elf64_Verdef*)((uintptr_t)def + def->vd_next)):NULL;
+    }
+    return NULL;
+}
+
+Elf64_Half GetParentSymbolVersionFlag(elfheader_t* h, int index)
+{
+    if(!h->VerDef || (index<1))
+        return (Elf64_Half)-1;
+    Elf64_Verdef *def = (Elf64_Verdef*)((uintptr_t)h->VerDef + h->delta);
+    while(def) {
+        if(def->vd_ndx==index) {
+            return def->vd_flags;
+        }
+        def = def->vd_next?((Elf64_Verdef*)((uintptr_t)def + def->vd_next)):NULL;
+    }
+    return (Elf64_Half)-1;
+}
+Elf64_Half GetSymbolVersionFlag(elfheader_t* h, int version)
+{
+    if(version<2)
+        return (Elf64_Half)-1;
+    if(h->VerNeed) {
+        Elf64_Verneed *ver = (Elf64_Verneed*)((uintptr_t)h->VerNeed + h->delta);
+        while(ver) {
+            Elf64_Vernaux *aux = (Elf64_Vernaux*)((uintptr_t)ver + ver->vn_aux);
+            for(int j=0; j<ver->vn_cnt; ++j) {
+                if(aux->vna_other==version) 
+                    return aux->vna_flags;
+                aux = (Elf64_Vernaux*)((uintptr_t)aux + aux->vna_next);
+            }
+            ver = ver->vn_next?((Elf64_Verneed*)((uintptr_t)ver + ver->vn_next)):NULL;
+        }
+    }
+    return GetParentSymbolVersionFlag(h, version);  // if symbol is "internal", use Def table instead
+}
+
+
+int GetVersionIndice(elfheader_t* h, const char* vername)
+{
+    if(!vername)
+        return 0;
+    if(h->VerDef) {
+        Elf64_Verdef *def = (Elf64_Verdef*)((uintptr_t)h->VerDef + h->delta);
+        while(def) {
+            Elf64_Verdaux *aux = (Elf64_Verdaux*)((uintptr_t)def + def->vd_aux);
+            if(!strcmp(h->DynStr+aux->vda_name, vername))
+                return def->vd_ndx;
+            def = def->vd_next?((Elf64_Verdef*)((uintptr_t)def + def->vd_next)):NULL;
+        }
+    }
+    return 0;
+}
+
+int GetNeededVersionCnt(elfheader_t* h, const char* libname)
+{
+    if(!libname)
+        return 0;
+    if(h->VerNeed) {
+        Elf64_Verneed *ver = (Elf64_Verneed*)((uintptr_t)h->VerNeed + h->delta);
+        while(ver) {
+            char *filename = h->DynStr + ver->vn_file;
+            if(!strcmp(filename, libname))
+                return ver->vn_cnt;
+            ver = ver->vn_next?((Elf64_Verneed*)((uintptr_t)ver + ver->vn_next)):NULL;
+        }
+    }
+    return 0;
+}
+
+const char* GetNeededVersionString(elfheader_t* h, const char* libname, int idx)
+{
+    if(!libname)
+        return 0;
+    if(h->VerNeed) {
+        Elf64_Verneed *ver = (Elf64_Verneed*)((uintptr_t)h->VerNeed + h->delta);
+        while(ver) {
+            char *filename = h->DynStr + ver->vn_file;
+            Elf64_Vernaux *aux = (Elf64_Vernaux*)((uintptr_t)ver + ver->vn_aux);
+            if(!strcmp(filename, libname)) {
+                for(int j=0; j<ver->vn_cnt; ++j) {
+                    if(j==idx) 
+                        return h->DynStr+aux->vna_name;
+                    aux = (Elf64_Vernaux*)((uintptr_t)aux + aux->vna_next);
+                }
+                return NULL;    // idx out of bound, return NULL...
+           }
+            ver = ver->vn_next?((Elf64_Verneed*)((uintptr_t)ver + ver->vn_next)):NULL;
+        }
+    }
+    return NULL;
+}
+
+int GetNeededVersionForLib(elfheader_t* h, const char* libname, const char* ver)
+{
+    if(!libname || !ver)
+        return 0;
+    int n = GetNeededVersionCnt(h, libname);
+    if(!n)
+        return 0;
+    for(int i=0; i<n; ++i) {
+        const char* vername = GetNeededVersionString(h, libname, i);
+        if(vername && !strcmp(ver, vername))
+            return 1;
+    }
+    return 0;
+}
+
+static int SymbolMatch(elfheader_t* h, uint32_t i, int ver, const char* vername, int local, int veropt)
+{
+    int version = h->VerSym?((Elf64_Half*)((uintptr_t)h->VerSym+h->delta))[i]:-1;
+    if(version!=-1) version &=0x7fff;
+    const char* symvername = GetSymbolVersion(h, version);
+    Elf64_Half flags = GetSymbolVersionFlag(h, version);
+    if(ver==-1 || version==-1)
+        return 1;
+    if(version==0 && !local)
+        return 0;
+    if(version<2 && ver>1 && veropt)
+        return 1;
+    if(ver==0 && version<2)
+        return 1;
+    if(ver==1 && version<2)
+        return 1;
+    if(ver<2 && version>2 && flags==0)  // flag is not WEAK, so global works
+        return 1;
+    if(ver<2 || !symvername)
+        return 0;
+    return strcmp(vername, symvername)?0:1;
+}
+
+uint32_t old_elf_hash(const char* name)
+{
+    uint32_t h = 0, g;
+    for (unsigned char c = *name; c; c = *++name) {
+        h = (h << 4) + c;
+        if (g = h & 0xf0000000) {
+            h ^= g >> 24;
+        }
+        h &= ~g;
+    }
+    return h;
+}
+
+Elf64_Sym* old_elf_lookup(elfheader_t* h, const char* symname, int ver, const char* vername, int local, int veropt)
+{
+    // Prepare hash table
+    const uint32_t *hashtab = (uint32_t*)(h->hash + h->delta);
+    const uint32_t nbuckets = hashtab[0];
+    const uint32_t nchains = hashtab[1];
+    const uint32_t *buckets = &hashtab[2];
+    const uint32_t *chains = &buckets[nbuckets];
+    // get hash from symname to lookup
+    const uint32_t hash = old_elf_hash(symname);
+    // Search for it
+    for (uint32_t i = buckets[hash % nbuckets]; i; i = chains[i]) {
+        const char* name = h->DynStr + h->DynSym[i].st_name;
+        if (!strcmp(symname, name) && SymbolMatch(h, i, ver, vername, local, veropt)) {
+            return &h->DynSym[i];
+        }
+    }
+    return NULL;
+}
+
+
+void old_elf_hash_dump(elfheader_t* h)
+{
+    // Prepare hash table
+    const uint32_t *hashtab = (uint32_t*)(h->hash + h->delta);
+    const uint32_t nbuckets = hashtab[0];
+    const uint32_t nchains = hashtab[1];
+    const uint32_t *buckets = &hashtab[2];
+    const uint32_t *chains = &buckets[nbuckets];
+    printf_log(LOG_NONE, "------------ Dump HASH from %s\n", h->name);
+    printf_log(LOG_NONE, "Buckets[%d] = \n", nbuckets);
+    for(uint32_t i=0; i<nbuckets; ++i) {
+        const char* name = h->DynStr + h->DynSym[buckets[i]].st_name;
+        printf_log(LOG_NONE, "%d: %s\n", buckets[i], name);
+    }
+    printf_log(LOG_NONE,"Chains[%d] = ", nchains);
+    for (uint32_t i = 0; i<nchains; ++i)
+        printf_log(LOG_NONE, "%d ", chains[i]);
+    printf_log(LOG_NONE, "\n------------\n");
+}
+
+uint32_t new_elf_hash(const char *name)
+{
+    uint32_t h = 5381;
+    for (unsigned char c = *name; c; c = *++name)
+            h = h * 33 + c;
+    return h;
+}
+
+Elf64_Sym* new_elf_lookup(elfheader_t* h, const char* symname, int ver, const char* vername, int local, int veropt)
+{
+    // Prepare hash table
+    const uint32_t *hashtab = (uint32_t*)(h->gnu_hash + h->delta);
+    const uint32_t nbuckets = hashtab[0];
+    const uint32_t symoffset = hashtab[1];
+    const uint32_t bloom_size = hashtab[2];
+    const uint32_t bloom_shift = hashtab[3];
+    const uint64_t *blooms = (uint64_t*)&hashtab[4];
+    const uint32_t *buckets = (uint32_t*)&blooms[bloom_size];
+    const uint32_t *chains = &buckets[nbuckets];
+    // get hash from symname to lookup
+    const uint32_t hash = new_elf_hash(symname);
+    // early check with bloom: if at least one bit is not set, a symbol is surely missing.
+    uint64_t word = blooms[(hash/64)%bloom_size];
+    uint64_t mask = 0
+        | 1LL << (hash%64)
+        | 1LL << ((hash>>bloom_shift)%64);
+    if ((word & mask) != mask) {
+        return NULL;
+    }
+    // now look at the bucket chain for the symbol
+    uint32_t symidx = buckets[hash%nbuckets];
+    if (symidx < symoffset)
+        return NULL;
+    while(1) {
+        const char* name = h->DynStr + h->DynSym[symidx].st_name;
+        const uint32_t symhash = chains[symidx-symoffset];
+        if ((hash|1) == (symhash|1) && !strcmp(name, symname) && SymbolMatch(h, symidx, ver, vername, local, veropt)) {
+            return &h->DynSym[symidx];
+        }
+        if(symhash&1)
+            return NULL;
+        symidx++;
+    }
+}
+
+void new_elf_hash_dump(elfheader_t* h)
+{
+    // Prepare hash table
+    const uint32_t *hashtab = (uint32_t*)(h->gnu_hash + h->delta);
+    const uint32_t nbuckets = hashtab[0];
+    const uint32_t symoffset = hashtab[1];
+    const uint32_t bloom_size = hashtab[2];
+    const uint32_t bloom_shift = hashtab[3];
+    const uint64_t *blooms = (uint64_t*)&hashtab[4];
+    const uint32_t *buckets = (uint32_t*)&blooms[bloom_size];
+    const uint32_t *chains = &buckets[nbuckets];
+    printf_log(LOG_NONE, "===============Dump GNU_HASH from %s\n", h->name);
+    printf_log(LOG_NONE, "Bloom: size=%d, shift=%d\n", bloom_size, bloom_shift);
+    printf_log(LOG_NONE, "Buckets[%d] offset=%d = \n", nbuckets, symoffset);
+    for(uint32_t i=0; i<nbuckets; ++i) {
+        uint32_t symidx = buckets[i];
+        printf_log(LOG_NONE, "%d:", symidx);
+        while(symidx>=symoffset) {
+            const char* name = h->DynStr + h->DynSym[symidx].st_name;
+            const uint32_t hash = chains[symidx-symoffset];
+            if(hash&1)
+                symidx=0;
+            else
+                symidx++;
+            printf_log(LOG_NONE, " %s (%x) -> %d", name, hash, symidx);
+        }
+        printf_log(LOG_NONE, "\n");
+    }
+    printf_log(LOG_NONE, "\n===============\n");
+}
+
+Elf64_Sym* ElfLookup(elfheader_t* h, const char* symname, int ver, const char* vername, int local, int veropt)
+{
+    if(h->gnu_hash)
+        return new_elf_lookup(h, symname, ver, vername, local, veropt);
+    return old_elf_lookup(h, symname, ver, vername, local, veropt);
+}
+
+Elf64_Sym* ElfSymTabLookup(elfheader_t* h, const char* symname)
+{
+    if(!h->SymTab)
+        return 0;
+    for(int i=0; i<h->numSymTab; ++i) {
+        Elf64_Sym* sym = &h->SymTab[i];
+        int type = ELF64_ST_TYPE(sym->st_info);
+        if(type==STT_FUNC || type==STT_TLS || type==STT_OBJECT) {
+            const char * name = h->StrTab+sym->st_name;
+            if(name && !strcmp(symname, name))
+                return sym;
+        }
+    }
+    return NULL;
+}
+
+Elf64_Sym* ElfDynSymLookup(elfheader_t* h, const char* symname)
+{
+    if(!h->DynSym)
+        return 0;
+    for(int i=0; i<h->numDynSym; ++i) {
+        Elf64_Sym* sym = &h->DynSym[i];
+        int type = ELF64_ST_TYPE(sym->st_info);
+        if(type==STT_FUNC || type==STT_TLS || type==STT_OBJECT) {
+            const char * name = h->DynStr+sym->st_name;
+            if(name && !strcmp(symname, name))
+                return sym;
+        }
+    }
+    return NULL;
+}
diff --git a/src/elfs/elfload_dump.c b/src/elfs/elfload_dump.c
index 1730967f..4c9cf228 100644
--- a/src/elfs/elfload_dump.c
+++ b/src/elfs/elfload_dump.c
@@ -231,10 +231,11 @@ const char* DumpSym(elfheader_t *h, Elf64_Sym* sym, int version)
 {
     static char buff[4096];
     const char* vername = (version==-1)?"(none)":((version==0)?"*local*":((version==1)?"*global*":GetSymbolVersion(h, version)));
+    int veropt = GetSymbolVersionFlag(h, version)?0:1;
     memset(buff, 0, sizeof(buff));
-    sprintf(buff, "\"%s\", value=%p, size=%ld, info/other=%d/%d index=%d (ver=%d/%s)", 
+    sprintf(buff, "\"%s\", value=%p, size=%ld, info/other=%d/%d index=%d (%sver=%d/%s)", 
         h->DynStr+sym->st_name, (void*)sym->st_value, sym->st_size,
-        sym->st_info, sym->st_other, sym->st_shndx, version, vername);
+        sym->st_info, sym->st_other, sym->st_shndx, veropt?"opt":"", version, vername);
     return buff;
 }
 
diff --git a/src/elfs/elfloader.c b/src/elfs/elfloader.c
index 8d8500d7..8845444a 100644
--- a/src/elfs/elfloader.c
+++ b/src/elfs/elfloader.c
@@ -64,11 +64,6 @@ elfheader_t* LoadAndCheckElfHeader(FILE* f, const char* name, int exec)
         h->path[0] = '\0';
     }
     
-    h->mapsymbols = NewMapSymbols();
-    h->weaksymbols = NewMapSymbols();
-    h->localsymbols = NewMapSymbols();
-    h->globaldefver = NewDefaultVersion();
-    h->weakdefver = NewDefaultVersion();
     h->refcnt = 1;
 
     h->file = f;
@@ -94,12 +89,6 @@ void FreeElfHeader(elfheader_t** head)
     box_free(h->SymTab);
     box_free(h->DynSym);
 
-    FreeMapSymbols(&h->mapsymbols);
-    FreeMapSymbols(&h->weaksymbols);
-    FreeMapSymbols(&h->localsymbols);
-    FreeDefaultVersion(&h->globaldefver);
-    FreeDefaultVersion(&h->weakdefver);
-    
     FreeElfMemory(h);
 
     box_free(h->name);
@@ -259,7 +248,7 @@ int AllocLoadElfMemory(box64context_t* context, elfheader_t* head, int mainbin)
                 try_mmap = 0;
             if(e->p_offset&(box64_pagesize-1))
                 try_mmap = 0;
-            if(e->p_memsz-e->p_filesz>(box64_pagesize-1))
+            if(ALIGN(e->p_memsz)!=ALIGN(e->p_filesz))
                 try_mmap = 0;
             if(!e->p_filesz)
                 try_mmap = 0;
@@ -279,8 +268,8 @@ int AllocLoadElfMemory(box64context_t* context, elfheader_t* head, int mainbin)
                     try_mmap = 0;
                     printf_dump(log_level, "Mapping failed, using regular mmap+read");
                 } else {
-                    /*if(e->p_memsz>e->p_filesz)
-                        memset((void*)((uintptr_t)p + e->p_filesz), 0, e->p_memsz-e->p_filesz);*/ // already zero'd by the mmap
+                    if(e->p_memsz>e->p_filesz && (prot&PROT_WRITE))
+                        memset((void*)((uintptr_t)p + e->p_filesz), 0, e->p_memsz-e->p_filesz);
                     setProtection_elf((uintptr_t)p, head->multiblocks[n].asize, prot);
                     head->multiblocks[n].p = p;
 
@@ -418,7 +407,29 @@ int isElfHasNeededVer(elfheader_t* head, const char* libname, elfheader_t* verne
     return 1;
 }
 
-int FindR64COPYRel(elfheader_t* h, const char* name, uintptr_t *offs, uint64_t** p, size_t size, int version, const char* vername)
+static int IsSymInElfSpace(const elfheader_t* h, Elf64_Sym* sym)
+{
+    if(!h || !sym)
+        return 0;
+    uintptr_t addr = (uintptr_t)sym;
+    if(h->SymTab && addr>=(uintptr_t)h->SymTab && addr<(uintptr_t)&h->SymTab[h->numSymTab])
+        return 1;
+    if(h->DynSym && addr>=(uintptr_t)h->DynSym && addr<(uintptr_t)&h->DynSym[h->numDynSym])
+        return 1;
+    return 0;
+}
+static elfheader_t* FindElfSymbol(box64context_t *context, Elf64_Sym* sym)
+{
+    if(!sym)
+        return NULL;
+    for (int i=0; i<context->elfsize; ++i)
+        if(IsSymInElfSpace(context->elfs[i], sym))
+            return context->elfs[i];
+    
+    return NULL;
+}
+
+int FindR64COPYRel(elfheader_t* h, const char* name, uintptr_t *offs, uint64_t** p, size_t size, int version, const char* vername, int veropt)
 {
     if(!h)
         return 0;
@@ -435,7 +446,9 @@ int FindR64COPYRel(elfheader_t* h, const char* name, uintptr_t *offs, uint64_t**
             if(version2!=-1) version2 &= 0x7fff;
             if(version && !version2) version2=-1;   // match a versioned symbol against a global "local" symbol
             const char* vername2 = GetSymbolVersion(h, version2);
-            if(SameVersionedSymbol(name, version, vername, symname, version2, vername2)) {
+            Elf64_Half flags = GetSymbolVersionFlag(h, version2);
+            int veropt2 = flags?0:1;
+            if(SameVersionedSymbol(name, version, vername, veropt, symname, version2, vername2, veropt2)) {
                 if(offs) *offs = sym->st_value + h->delta;
                 if(p) *p = (uint64_t*)(rela[i].r_offset + h->delta + rela[i].r_addend);
                 return 1;
@@ -447,184 +460,8 @@ int FindR64COPYRel(elfheader_t* h, const char* name, uintptr_t *offs, uint64_t**
 
 int RelocateElfREL(lib_t *maplib, lib_t *local_maplib, int bindnow, int deepbind, elfheader_t* head, int cnt, Elf64_Rel *rel)
 {
-    int ret_ok = 0;
-    for (int i=0; i<cnt; ++i) {
-        int t = ELF64_R_TYPE(rel[i].r_info);
-        Elf64_Sym *sym = &head->DynSym[ELF64_R_SYM(rel[i].r_info)];
-        int bind = ELF64_ST_BIND(sym->st_info);
-        const char* symname = SymName(head, sym);
-        //uint64_t ndx = sym->st_shndx;
-        uint64_t *p = (uint64_t*)(rel[i].r_offset + head->delta);
-        uintptr_t offs = 0;
-        uintptr_t end = 0;
-        size_t size = sym->st_size;
-        //uintptr_t tmp = 0;
-        int version = head->VerSym?((Elf64_Half*)((uintptr_t)head->VerSym+head->delta))[ELF64_R_SYM(rel[i].r_info)]:-1;
-        if(version!=-1) version &=0x7fff;
-        const char* vername = GetSymbolVersion(head, version);
-        const char* globdefver = (bind==STB_WEAK)?NULL:GetMaplibDefaultVersion(maplib, local_maplib, 0, deepbind, symname);
-        const char* weakdefver = (bind==STB_WEAK || !globdefver)?GetMaplibDefaultVersion(maplib, local_maplib, 1, deepbind, symname):NULL;
-        if(bind==STB_LOCAL) {
-            if(!symname || !symname[0]) {
-                offs = sym->st_value + head->delta;
-                end = offs + sym->st_size;
-            } else {
-                if(!offs && !end && local_maplib && deepbind)
-                    GetLocalSymbolStartEnd(local_maplib, symname, &offs, &end, head, version, vername, globdefver, weakdefver);
-                if(!offs && !end)
-                    GetLocalSymbolStartEnd(maplib, symname, &offs, &end, head, version, vername, globdefver, weakdefver);
-                if(!offs && !end && local_maplib && !deepbind)
-                    GetLocalSymbolStartEnd(local_maplib, symname, &offs, &end, head, version, vername, globdefver, weakdefver);
-            }
-        } else {
-            // this is probably very very wrong. A proprer way to get reloc need to be written, but this hack seems ok for now
-            // at least it work for half-life, unreal, ut99, zsnes, Undertale, ColinMcRae Remake, FTL, ShovelKnight...
-            /*if(bind==STB_GLOBAL && (ndx==10 || ndx==19) && t!=R_X86_64_GLOB_DAT) {
-                offs = sym->st_value + head->delta;
-                end = offs + sym->st_size;
-            }*/
-            // so weak symbol are the one left
-            if(bind==STB_WEAK) {
-                if(!offs && !end) {
-                    if(!offs && !end && local_maplib && deepbind)
-                        GetGlobalWeakSymbolStartEnd(local_maplib, symname, &offs, &end, head, version, vername, globdefver, weakdefver);
-                    if(!offs && !end)
-                        GetGlobalWeakSymbolStartEnd(maplib, symname, &offs, &end, head, version, vername, globdefver, weakdefver);
-                    if(!offs && !end && local_maplib && !deepbind)
-                        GetGlobalWeakSymbolStartEnd(local_maplib, symname, &offs, &end, head, version, vername, globdefver, weakdefver);
-                }
-            } else {
-                if(!offs && !end) {
-                    if(!offs && !end && local_maplib && deepbind)
-                        GetGlobalSymbolStartEnd(local_maplib, symname, &offs, &end, head, version, vername, globdefver, weakdefver);
-                    if(!offs && !end)
-                        GetGlobalSymbolStartEnd(maplib, symname, &offs, &end, head, version, vername, globdefver, weakdefver);
-                    if(!offs && !end && local_maplib && !deepbind)
-                        GetGlobalSymbolStartEnd(local_maplib, symname, &offs, &end, head, version, vername, globdefver, weakdefver);
-                }
-            }
-        }
-        uintptr_t globoffs, globend;
-        uint64_t* globp;
-        switch(t) {
-            case R_X86_64_NONE:
-                // can be ignored
-                printf_dump(LOG_NEVER, "Ignoring %s @%p (%p)\n", DumpRelType(t), p, (void*)(p?(*p):0));
-                break;
-            case R_X86_64_PC32:
-                    if (!offs) {
-                        printf_log(LOG_NONE, "Error: Global Symbol %s not found, cannot apply R_X86_64_PC32 @%p (%p) in %s\n", symname, p, *(void**)p, head->name);
-                        ret_ok = 1;
-                    }
-                    offs = (offs - (uintptr_t)p);
-                    if(!offs)
-                        printf_dump(LOG_NEVER, "Apply %s R_X86_64_PC32 @%p with sym=%s (%p -> %p)\n", (bind==STB_LOCAL)?"Local":"Global", p, symname, *(void**)p, (void*)(*(uintptr_t*)p+offs));
-                    *p += offs;
-                break;
-            case R_X86_64_GLOB_DAT:
-                if(head!=my_context->elfs[0] && !IsGlobalNoWeakSymbolInNative(maplib, symname, version, vername, globdefver) && FindR64COPYRel(my_context->elfs[0], symname, &globoffs, &globp, size, version, vername)) {
-                    // set global offs / size for the symbol
-                    offs = sym->st_value;
-                    end = offs + sym->st_size;
-                    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
-                        AddUniqueSymbol(GetGlobalData(maplib), symname, globoffs, sym->st_size, version, vername);
-                        AddUniqueSymbol(my_context->globdata, 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);
-                    }
-                    *p = globoffs;
-                } else {
-                    if((size==0) && GetSymbolStartEnd(GetGlobalData(maplib), symname, &globoffs, &globend, version, vername, 0, globdefver)) {
-                        offs = globoffs;
-                    }
-                    if (!offs) {
-                        if(strcmp(symname, "__gmon_start__") && strcmp(symname, "data_start") && strcmp(symname, "__data_start") && strcmp(symname, "collector_func_load"))
-                            printf_log(LOG_NONE, "%s: Global Symbol %s (ver=%d/%s) not found, cannot apply R_X86_64_GLOB_DAT @%p (%p) in %s\n", (bind==STB_WEAK)?"Warning":"Error", symname, version, vername?vername:"(none)", p, *(void**)p, head->name);
-                    } else {
-                        printf_dump(LOG_NEVER, "Apply %s R_X86_64_GLOB_DAT @%p (%p -> %p) on sym=%s (ver=%d/%s)\n", (bind==STB_LOCAL)?"Local":"Global", p, (void*)(p?(*p):0), (void*)offs, symname, version, vername?vername:"(none)");
-                        *p = offs;
-                    }
-                }
-                break;
-            case R_X86_64_COPY:
-                if(offs) {
-                    uintptr_t old_offs = offs;
-                    uintptr_t old_end = end;
-                    offs = 0;
-                    GetSizedSymbolStartEnd(my_context->globdata, symname, &offs, &end, size, version, vername, 1, globdefver); // try globaldata symbols first
-                    if(offs==0) {
-                        GetNoSelfSymbolStartEnd(maplib, symname, &offs, &end, head, size, version, vername, globdefver, weakdefver);   // get original copy if any
-                        if(!offs && local_maplib)
-                            GetNoSelfSymbolStartEnd(local_maplib, symname, &offs, &end, head, size, version, vername, globdefver, weakdefver);
-                    }
-                    if(!offs) {
-                        offs = old_offs;
-                        end = old_end;
-                    }
-                    printf_dump(LOG_NEVER, "Apply %s R_X86_64_COPY @%p with sym=%s, @%p size=%ld (", (bind==STB_LOCAL)?"Local":"Global", p, symname, (void*)offs, sym->st_size);
-                    memmove(p, (void*)offs, sym->st_size);
-                    if(box64_dump) {
-                        uint64_t *k = (uint64_t*)p;
-                        for (unsigned j=0; j<((sym->st_size>128u)?128u:sym->st_size); j+=8, ++k)
-                            printf_dump(LOG_NEVER, "%s0x%016lX", j?" ":"", *k);
-                        printf_dump(LOG_NEVER, "%s)\n", (sym->st_size>128u)?" ...":"");
-                    }
-                } else {
-                    printf_log(LOG_NONE, "Error: Symbol %s not found, cannot apply R_X86_64_COPY @%p (%p) in %s\n", symname, p, *(void**)p, head->name);
-                }
-                break;
-            case R_X86_64_RELATIVE:
-                printf_dump(LOG_NEVER, "Apply %s R_X86_64_RELATIVE @%p (%p -> %p)\n", (bind==STB_LOCAL)?"Local":"Global", p, *(void**)p, (void*)((*p)+head->delta));
-                *p += head->delta;
-                break;
-            case R_X86_64_64:
-                if (!offs) {
-                    printf_log(LOG_NONE, "%s: Symbol %s not found, cannot apply R_X86_64_64 @%p (%p) in %s\n", (bind==STB_GLOBAL)?"Error":"Warning", symname, p, *(void**)p, head->name);
-                    if(bind==STB_GLOBAL)
-                        ret_ok = 1;
-                    // return -1;
-                } else {
-                    printf_dump(LOG_NEVER, "Apply %s R_X86_64_64 @%p with sym=%s (%p -> %p)\n", (bind==STB_LOCAL)?"Local":"Global", p, symname, *(void**)p, (void*)(offs+*(uint64_t*)p));
-                    *p += offs;
-                }
-                break;
-            #if 0
-            case R_X86_64_JUMP_SLOT:
-                // apply immediatly for gobject closure marshal or for LOCAL binding. Also, apply immediatly if it doesn't jump in the got
-                tmp = (uintptr_t)(*p);
-                if (bind==STB_LOCAL 
-                  || ((symname && strstr(symname, "g_cclosure_marshal_")==symname)) 
-                  || !tmp
-                  || !((tmp>=head->plt && tmp<head->plt_end) || (tmp>=head->gotplt && tmp<head->gotplt_end))
-                  ) {
-                    if (!offs) {
-                        if(bind==STB_WEAK) {
-                            printf_log(LOG_INFO, "Warning: Weak Symbol %s not found, cannot apply R_X86_64_JUMP_SLOT @%p (%p)\n", symname, p, *(void**)p);
-                        } else {
-                            printf_log(LOG_NONE, "Error: Symbol %s not found, cannot apply R_X86_64_JUMP_SLOT @%p (%p) in %s\n", symname, p, *(void**)p, head->name);
-                        }
-                        // return -1;
-                    } else {
-                        if(p) {
-                            printf_dump(LOG_NEVER, "Apply %s R_X86_64_JUMP_SLOT @%p with sym=%s (%p -> %p)\n", (bind==STB_LOCAL)?"Local":"Global", p, symname, *(void**)p, (void*)offs);
-                            *p = offs;
-                        } else {
-                            printf_log(LOG_NONE, "Warning, Symbol %s found, but Jump Slot Offset is NULL \n", symname);
-                        }
-                    }
-                } else {
-                    printf_dump(LOG_NEVER, "Preparing (if needed) %s R_X86_64_JUMP_SLOT @%p (0x%lx->0x%0lx) with sym=%s to be apply later\n", (bind==STB_LOCAL)?"Local":"Global", p, *p, *p+head->delta, symname);
-                    *p += head->delta;
-                }
-                break;
-            #endif
-            default:
-                printf_log(LOG_INFO, "Warning, don't know how to handle rel #%d %s (%p)\n", i, DumpRelType(ELF64_R_TYPE(rel[i].r_info)), p);
-        }
-    }
-    return bindnow?ret_ok:0;
+    printf_log(LOG_NONE, "Error: REL type of Relocation unsupported (only RELA)\n");
+    return 1;
 }
 
 struct tlsdesc
@@ -640,17 +477,32 @@ EXPORT uintptr_t _dl_tlsdesc_undefweak(x64emu_t* emu)
     return td->arg;
 }
 
+void GrabX64CopyMainElfReloc(elfheader_t* head)
+{
+    if(head->rela) {
+        int cnt = head->relasz / head->relaent;
+        Elf64_Rela* rela = (Elf64_Rela *)(head->rela + head->delta);
+        printf_dump(LOG_DEBUG, "Grabbing R_X86_64_COPY Relocation(s) in advance for %s\n", head->name);
+        for (int i=0; i<cnt; ++i) {
+            int t = ELF64_R_TYPE(rela[i].r_info);
+            if(t == R_X86_64_COPY) {
+                Elf64_Sym *sym = &head->DynSym[ELF64_R_SYM(rela[i].r_info)];
+                const char* symname = SymName(head, sym);
+                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);
+                Elf64_Half flags = GetSymbolVersionFlag(head, version);
+                int veropt = flags?0:1;
+                uintptr_t offs = sym->st_value + head->delta;
+                AddUniqueSymbol(my_context->globdata, symname, offs, sym->st_size, version, vername, veropt);
+            }
+        }
+    }
+}
 
 int RelocateElfRELA(lib_t *maplib, lib_t *local_maplib, int bindnow, int deepbind, elfheader_t* head, int cnt, Elf64_Rela *rela, int* need_resolv)
 {
     int ret_ok = 0;
-    const char* old_globdefver = NULL;
-    const char* old_weakdefver = NULL;
-    int old_bind = -1;
-    const char* old_symname = NULL;
-    uintptr_t old_offs = 0;
-    uintptr_t old_end = 0;
-    int old_version = -1;
     for (int i=0; i<cnt; ++i) {
         int t = ELF64_R_TYPE(rela[i].r_info);
         Elf64_Sym *sym = &head->DynSym[ELF64_R_SYM(rela[i].r_info)];
@@ -661,74 +513,51 @@ int RelocateElfRELA(lib_t *maplib, lib_t *local_maplib, int bindnow, int deepbin
         uintptr_t offs = 0;
         uintptr_t end = 0;
         size_t size = sym->st_size;
-        elfheader_t* h_tls = NULL;//head;
+        elfheader_t* sym_elf = NULL;
         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* globdefver = NULL;
-        const char* weakdefver = NULL;
-        if(old_bind==bind && old_symname==symname) {
-            globdefver = old_globdefver;
-            weakdefver = old_weakdefver;
+        Elf64_Half flags = GetSymbolVersionFlag(head, version);
+        int veropt = flags?0:1;
+        Elf64_Sym* elfsym = NULL;
+        int vis = ELF64_ST_VISIBILITY(sym->st_other);
+        if(vis==STV_PROTECTED) {
+            elfsym = ElfDynSymLookup(head, symname);
+            printf_log(LOG_INFO, "Symbol %s from %s is PROTECTED\n", symname, head);
         } else {
-            old_globdefver = globdefver = (bind==STB_WEAK)?NULL:GetMaplibDefaultVersion(maplib, local_maplib, 0, deepbind, symname);
-            old_weakdefver = weakdefver = (bind==STB_WEAK || !globdefver)?GetMaplibDefaultVersion(maplib, local_maplib, 1, deepbind, symname):NULL;
-        }
-        if(bind==STB_LOCAL) {
-            if(!symname || !symname[0]) {
-                offs = sym->st_value + head->delta;
-                end = offs + sym->st_size;
-            } else {
-                if(old_version==version && old_bind==bind && old_symname==symname) {
-                    offs = old_offs;
-                    end = old_end;
-                } else {
-                    if(local_maplib && deepbind)
-                        GetLocalSymbolStartEnd(local_maplib, symname, &offs, &end, head, version, vername, globdefver, weakdefver);
-                    if(!offs && !end)
-                        GetLocalSymbolStartEnd(maplib, symname, &offs, &end, head, version, vername, globdefver, weakdefver);
-                    if(!offs && !end && local_maplib && !deepbind)
-                        GetLocalSymbolStartEnd(local_maplib, symname, &offs, &end, head, version, vername, globdefver, weakdefver);
-                }
-            }
-        } else {
-            // this is probably very very wrong. A proprer way to get reloc need to be written, but this hack seems ok for now
-            // at least it work for half-life, unreal, ut99, zsnes, Undertale, ColinMcRae Remake, FTL, ShovelKnight...
-            /*if(bind==STB_GLOBAL && (ndx==10 || ndx==19) && t!=R_X86_64_GLOB_DAT) {
-                offs = sym->st_value + head->delta;
-                end = offs + sym->st_size;
-            }*/
-            // so weak symbol are the one left
-            if(bind==STB_WEAK) {
-                if(old_version==version && old_bind==bind && old_symname==symname) {
-                    offs = old_offs;
-                    end = old_end;
-                } else {
-                    if(local_maplib && deepbind)
-                        GetGlobalWeakSymbolStartEnd(local_maplib, symname, &offs, &end, head, version, vername, globdefver, weakdefver);
-                    else
-                        GetGlobalWeakSymbolStartEnd(maplib, symname, &offs, &end, head, version, vername, globdefver, weakdefver);
-                    if(!offs && !end && local_maplib && !deepbind)
-                        GetGlobalWeakSymbolStartEnd(local_maplib, symname, &offs, &end, head, version, vername, globdefver, weakdefver);
-                }
-            } else {
-                if(old_version==version && old_bind==bind && old_symname==symname) {
-                    offs = old_offs;
-                    end = old_end;
+            if(bind==STB_GNU_UNIQUE) {
+                GetGlobalSymbolStartEnd(maplib, symname, &offs, &end, head, version, vername, veropt, (void**)&elfsym);
+                if(!offs && !end && local_maplib)
+                    GetGlobalSymbolStartEnd(local_maplib, symname, &offs, &end, head, version, vername, veropt, (void**)&elfsym);
+            } else if(bind==STB_LOCAL) {
+                if(!symname || !symname[0]) {
+                    offs = sym->st_value + head->delta;
+                    end = offs + sym->st_size;
                 } else {
+                    elfsym = ElfDynSymLookup(head, symname);
+                    if(elfsym && elfsym->st_shndx) {
+                        offs = elfsym->st_value + head->delta;
+                        end = offs + elfsym->st_size;
+                    }
                     if(!offs && !end && local_maplib && deepbind)
-                        GetGlobalSymbolStartEnd(local_maplib, symname, &offs, &end, head, version, vername, globdefver, weakdefver);
+                        GetLocalSymbolStartEnd(local_maplib, symname, &offs, &end, head, version, vername, veropt, (void**)&elfsym);
                     if(!offs && !end)
-                        GetGlobalSymbolStartEnd(maplib, symname, &offs, &end, head, version, vername, globdefver, weakdefver);
+                        GetLocalSymbolStartEnd(maplib, symname, &offs, &end, head, version, vername, veropt, (void**)&elfsym);
                     if(!offs && !end && local_maplib && !deepbind)
-                        GetGlobalSymbolStartEnd(local_maplib, symname, &offs, &end, head, version, vername, globdefver, weakdefver);
+                        GetLocalSymbolStartEnd(local_maplib, symname, &offs, &end, head, version, vername, veropt, (void**)&elfsym);
                 }
+            } else {
+                if(!offs && !end && local_maplib && deepbind)
+                    GetGlobalSymbolStartEnd(local_maplib, symname, &offs, &end, head, version, vername, veropt, (void**)&elfsym);
+                if(!offs && !end)
+                    GetGlobalSymbolStartEnd(maplib, symname, &offs, &end, head, version, vername, veropt, (void**)&elfsym);
+                if(!offs && !end && local_maplib && !deepbind)
+                    GetGlobalSymbolStartEnd(local_maplib, symname, &offs, &end, head, version, vername, veropt, (void**)&elfsym);
             }
         }
-        old_bind = bind;
-        old_symname = symname;
-        old_offs = offs;
-        old_end = end;
+        sym_elf = FindElfSymbol(my_context, elfsym);
+        if(elfsym && (ELF64_ST_TYPE(elfsym->st_info)==STT_TLS))
+            offs = elfsym->st_value;
         uintptr_t globoffs, globend;
         uint64_t* globp;
         uintptr_t tmp = 0;
@@ -741,14 +570,14 @@ int RelocateElfRELA(lib_t *maplib, lib_t *local_maplib, int bindnow, int deepbin
                 // can be ignored
                 break;
             case R_X86_64_RELATIVE:
-                printf_dump(LOG_NEVER, "Apply %s R_X86_64_RELATIVE @%p (%p -> %p)\n", (bind==STB_LOCAL)?"Local":"Global", p, *(void**)p, (void*)(head->delta+ rela[i].r_addend));
+                printf_dump(LOG_NEVER, "Apply %s R_X86_64_RELATIVE @%p (%p -> %p)\n", BindSym(bind), p, *(void**)p, (void*)(head->delta+ rela[i].r_addend));
                 *p = head->delta+ rela[i].r_addend;
                 break;
             case R_X86_64_IRELATIVE:
                 {
                     x64emu_t* emu = thread_get_emu();
                     EmuCall(emu, head->delta+rela[i].r_addend);
-                    printf_dump(LOG_NEVER, "Apply %s R_X86_64_IRELATIVE @%p (%p -> %p()=%p)\n", (bind==STB_LOCAL)?"Local":"Global", p, *(void**)p, (void*)(head->delta+ rela[i].r_addend), (void*)(R_RAX));
+                    printf_dump(LOG_NEVER, "Apply %s R_X86_64_IRELATIVE @%p (%p -> %p()=%p)\n", BindSym(bind), p, *(void**)p, (void*)(head->delta+ rela[i].r_addend), (void*)(R_RAX));
                     *p = R_RAX;
                 }
                 break;
@@ -756,15 +585,16 @@ int RelocateElfRELA(lib_t *maplib, lib_t *local_maplib, int bindnow, int deepbin
                 globoffs = offs;
                 globend = end;
                 offs = end = 0;
-                GetSizedSymbolStartEnd(my_context->globdata, symname, &offs, &end, size, version, vername, 1, globdefver); // try globaldata symbols first
-                if(!offs && local_maplib)
-                    GetNoSelfSymbolStartEnd(local_maplib, symname, &offs, &end, head, size, version, vername, globdefver, weakdefver);
+                if(!offs && local_maplib && deepbind)
+                    GetNoSelfSymbolStartEnd(local_maplib, symname, &offs, &end, head, size, version, vername, veropt, NULL);
                 if(!offs)
-                    GetNoSelfSymbolStartEnd(maplib, symname, &offs, &end, head, size, version, vername, globdefver, weakdefver);
+                    GetNoSelfSymbolStartEnd(maplib, symname, &offs, &end, head, size, version, vername, veropt, NULL);
+                if(!offs && local_maplib && !deepbind)
+                    GetNoSelfSymbolStartEnd(local_maplib, symname, &offs, &end, head, size, version, vername, veropt, NULL);
                 if(!offs) {offs = globoffs; end = globend;}
                 if(offs) {
                     // add r_addend to p?
-                    printf_dump(LOG_NEVER, "Apply R_X86_64_COPY @%p with sym=%s (ver=%d/%s), @%p+0x%lx size=%ld\n", p, symname, version, vername?vername:"(none)", (void*)offs, rela[i].r_addend, sym->st_size);
+                    printf_dump(LOG_NEVER, "Apply R_X86_64_COPY @%p with sym=%s (%sver=%d/%s), @%p+0x%lx size=%ld\n", p, symname, veropt?"opt":"", version, vername?vername:"(none)", (void*)offs, rela[i].r_addend, sym->st_size);
                     if(p!=(void*)(offs+rela[i].r_addend))
                         memmove(p, (void*)(offs+rela[i].r_addend), sym->st_size);
                 } else {
@@ -772,33 +602,20 @@ int RelocateElfRELA(lib_t *maplib, lib_t *local_maplib, int bindnow, int deepbin
                 }
                 break;
             case R_X86_64_GLOB_DAT:
-                if((head!=my_context->elfs[0]) && !IsGlobalNoWeakSymbolInNative(maplib, symname, version, vername, globdefver) && FindR64COPYRel(my_context->elfs[0], symname, &globoffs, &globp, size, version, vername)) {
-                    // set global offs / size for the symbol
-                    offs = sym->st_value + head->delta;
-                    end = offs + sym->st_size;
-                    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=%zd on sym=%s (ver=%d/%s) \n", 
-                            (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
-                        AddUniqueSymbol(GetGlobalData(maplib), symname, globoffs, sym->st_size, version, vername);
-                        AddUniqueSymbol(my_context->globdata, 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), 
-                            (void*)(globp?(*globp):0), (void*)offs, (void*)globoffs, symname, version, vername?vername:"(none)");
-                    }
+                if(GetSymbolStartEnd(my_context->globdata, symname, &globoffs, &globend, version, vername, 1, veropt)) {
+                    globp = (uint64_t*)globoffs;
+                    printf_dump(LOG_NEVER, "Apply %s R_X86_64_GLOB_DAT with R_X86_64_COPY @%p/%p (%p/%p -> %p/%p) size=%zd on sym=%s (%sver=%d/%s) \n", 
+                        BindSym(bind), p, globp, (void*)(p?(*p):0), 
+                        (void*)(globp?(*globp):0), (void*)offs, (void*)globoffs, sym->st_size, symname, veropt?"opt":"", version, vername?vername:"(none)");
+                    sym_elf = my_context->elfs[0];
                     *p = globoffs;
                 } else {
-                    if((size==0) && GetSymbolStartEnd(GetGlobalData(maplib), symname, &globoffs, &globend, version, vername, 0, globdefver)) {
-                        offs = globoffs;
-                    }
                     if (!offs) {
                         if(strcmp(symname, "__gmon_start__") && strcmp(symname, "data_start") && strcmp(symname, "__data_start") && strcmp(symname, "collector_func_load"))
-                            printf_log((bind==STB_WEAK)?LOG_INFO:LOG_NONE, "%s: Global Symbol %s not found, cannot apply R_X86_64_GLOB_DAT @%p (%p) in %s\n", (bind==STB_WEAK)?"Warning":"Error", symname, p, *(void**)p, head->name);
+                            printf_log((bind==STB_WEAK)?LOG_DEBUG:LOG_NONE, "%s: Global Symbol %s not found, cannot apply R_X86_64_GLOB_DAT @%p (%p) in %s\n", (bind==STB_WEAK)?"Warning":"Error", symname, p, *(void**)p, head->name);
                     } else {
-                        printf_dump(LOG_NEVER, "Apply %s R_X86_64_GLOB_DAT @%p (%p -> %p) on sym=%s (ver=%d/%s)\n", (bind==STB_LOCAL)?"Local":"Global", p, (void*)(p?(*p):0), (void*)offs, symname, version, vername?vername:"(none)");
-                        *p = offs/* + rela[i].r_addend*/;   // not addend it seems
+                        printf_dump(LOG_NEVER, "Apply %s R_X86_64_GLOB_DAT @%p (%p -> %p) on sym=%s (%sver=%d/%s, elf=%s)\n", BindSym(bind), p, (void*)(p?(*p):0), (void*)(offs + rela[i].r_addend), symname, veropt?"opt":"", version, vername?vername:"(none)", sym_elf?sym_elf->name:"(native)");
+                        *p = offs + rela[i].r_addend;
                     }
                 }
                 break;
@@ -823,8 +640,9 @@ int RelocateElfRELA(lib_t *maplib, lib_t *local_maplib, int bindnow, int deepbin
                         // return -1;
                     } else {
                         if(p) {
-                            printf_dump(LOG_NEVER, "Apply %s R_X86_64_JUMP_SLOT @%p with sym=%s (%p -> %p)\n", 
-                                (bind==STB_LOCAL)?"Local":"Global", p, symname, *(void**)p, (void*)(offs+rela[i].r_addend));
+                            elfheader_t* sym_elf = FindElfAddress(my_context, offs);
+                            printf_dump(LOG_NEVER, "Apply %s R_X86_64_JUMP_SLOT @%p with sym=%s (%p -> %p / %s (%sver=%d / %s))\n", 
+                                BindSym(bind), p, symname, *(void**)p, (void*)(offs+rela[i].r_addend), sym_elf?sym_elf->name:"native", veropt?"opt":"", version, vername?vername:"(none)");
                             *p = offs + rela[i].r_addend;
                         } else {
                             printf_log(LOG_INFO, "Warning, Symbol %s found, but Jump Slot Offset is NULL \n", symname);
@@ -832,13 +650,13 @@ int RelocateElfRELA(lib_t *maplib, lib_t *local_maplib, int bindnow, int deepbin
                     }
                 } else {
                     printf_dump(LOG_NEVER, "Preparing (if needed) %s R_X86_64_JUMP_SLOT @%p (0x%lx->0x%0lx) with sym=%s to be apply later (addend=%ld)\n", 
-                        (bind==STB_LOCAL)?"Local":"Global", p, *p, *p+head->delta, symname, rela[i].r_addend);
+                        BindSym(bind), p, *p, *p+head->delta, symname, rela[i].r_addend);
                     *p += head->delta;
                     *need_resolv = 1;
                 }
                 break;
             case R_X86_64_64:
-                if (!offs) {
+                if (!offs && !elfsym) {
                     if(symname && !strcmp(symname, "__gxx_personality_v0")) {
                         printf_dump(LOG_NEVER, "Warning: Symbol %s not found, cannot apply R_X86_64_64 @%p (%p) in %s\n", symname, p, *(void**)p, head->name);
                     } else {
@@ -848,8 +666,8 @@ int RelocateElfRELA(lib_t *maplib, lib_t *local_maplib, int bindnow, int deepbin
                         // return -1;
                     }
                 } else {
-                    printf_dump(LOG_NEVER, "Apply %s R_X86_64_64 @%p with sym=%s (ver=%d/%s) addend=0x%lx (%p -> %p)\n", 
-                        (bind==STB_LOCAL)?"Local":"Global", p, symname, version, vername?vername:"(none)", rela[i].r_addend, *(void**)p, (void*)(offs+rela[i].r_addend/*+*(uint64_t*)p*/));
+                    printf_dump(LOG_NEVER, "Apply %s R_X86_64_64 @%p with sym=%s (%sver=%d/%s) addend=0x%lx (%p -> %p)\n", 
+                        BindSym(bind), p, symname, veropt?"opt":"", version, vername?vername:"(none)", rela[i].r_addend, *(void**)p, (void*)(offs+rela[i].r_addend/*+*(uint64_t*)p*/));
                     *p /*+*/= offs+rela[i].r_addend;
                 }
                 break;
@@ -857,21 +675,15 @@ int RelocateElfRELA(lib_t *maplib, lib_t *local_maplib, int bindnow, int deepbin
                 // Negated offset in static TLS block
                 {
                     if(!symname || !symname[0]) {
-                        h_tls = head;
+                        sym_elf = head;
                         offs = sym->st_value;
-                    } else {
-                        h_tls = NULL;
-                        if(local_maplib)
-                            h_tls = GetGlobalSymbolElf(local_maplib, symname, version, vername);
-                        if(!h_tls)
-                            h_tls = GetGlobalSymbolElf(maplib, symname, version, vername);
                     }
-                    if(h_tls) {
+                    if(sym_elf) {
                         delta = *(int64_t*)p;
-                        printf_dump(LOG_NEVER, "Applying %s %s on %s @%p (%ld -> %ld+%ld+%ld, size=%ld)\n", (bind==STB_LOCAL)?"Local":"Global", DumpRelType(t), symname, p, delta, h_tls->tlsbase, (int64_t)offs, rela[i].r_addend, end-offs);
-                        *p = (uintptr_t)((int64_t)offs + rela[i].r_addend + h_tls->tlsbase);
+                        printf_dump(LOG_NEVER, "Applying %s %s on %s @%p (%ld -> %ld+%ld+%ld, size=%ld)\n", BindSym(bind), DumpRelType(t), symname, p, delta, sym_elf->tlsbase, (int64_t)offs, rela[i].r_addend, end-offs);
+                        *p = (uintptr_t)((int64_t)offs + rela[i].r_addend + sym_elf->tlsbase);
                     } else {
-                        printf_log(LOG_INFO, "Warning, cannot apply %s %s on %s @%p (%ld), no elf_header found\n", (bind==STB_LOCAL)?"Local":"Global", DumpRelType(t), symname, p, (int64_t)offs);
+                        printf_log(LOG_INFO, "Warning, cannot apply %s %s on %s @%p (%ld), no elf_header found\n", BindSym(bind), DumpRelType(t), symname, p, (int64_t)offs);
                     }
                 }
                 break;
@@ -880,16 +692,10 @@ int RelocateElfRELA(lib_t *maplib, lib_t *local_maplib, int bindnow, int deepbin
                 if(!symname || symname[0]=='\0' || bind==STB_LOCAL)
                     offs = getElfIndex(my_context, head);
                 else {
-                    if(!h_tls) {
-                        if(local_maplib)
-                            h_tls = GetGlobalSymbolElf(local_maplib, symname, version, vername);
-                        if(!h_tls)
-                            h_tls = GetGlobalSymbolElf(maplib, symname, version, vername);
-                    }
-                    offs = getElfIndex(my_context, h_tls);
+                    offs = getElfIndex(my_context, sym_elf);
                 }
                 if(p) {
-                    printf_dump(LOG_NEVER, "Apply %s %s @%p with sym=%s (%p -> %p)\n", (bind==STB_LOCAL)?"Local":"Global", "R_X86_64_DTPMOD64", p, symname, *(void**)p, (void*)offs);
+                    printf_dump(LOG_NEVER, "Apply %s %s @%p with sym=%s (%p -> %p)\n", BindSym(bind), "R_X86_64_DTPMOD64", p, symname, *(void**)p, (void*)offs);
                     *p = offs;
                 } else {
                     printf_log(LOG_INFO, "Warning, Symbol %s or Elf not found, but R_X86_64_DTPMOD64 Slot Offset is NULL \n", symname);
@@ -897,7 +703,7 @@ int RelocateElfRELA(lib_t *maplib, lib_t *local_maplib, int bindnow, int deepbin
                 break;
             case R_X86_64_DTPOFF64:
                 // Offset in TLS block
-                if (!offs && !end) {
+                if (!offs && !sym_elf) {
                     if(bind==STB_WEAK) {
                         printf_log(LOG_INFO, "Warning: Weak Symbol %s not found, cannot apply R_X86_64_DTPOFF64 @%p (%p)\n", symname, p, *(void**)p);
                     } else {
@@ -908,8 +714,8 @@ int RelocateElfRELA(lib_t *maplib, lib_t *local_maplib, int bindnow, int deepbin
                     if(!symname || symname[0]=='\0')
                         offs = sym->st_value;
                     if(p) {
-                        int64_t tlsoffset = offs;    // it's not an offset in elf memory
-                        printf_dump(LOG_NEVER, "Apply %s R_X86_64_DTPOFF64 @%p with sym=%s (%p -> %p)\n", (bind==STB_LOCAL)?"Local":"Global", p, symname, (void*)tlsoffset, (void*)offs);
+                        int64_t tlsoffset = (int64_t)offs;    // it's not an offset in elf memory
+                        printf_dump(LOG_NEVER, "Apply %s R_X86_64_DTPOFF64 @%p with sym=%s (%p -> %p)\n", BindSym(bind), p, symname, (void*)tlsoffset, (void*)offs);
                         *p = tlsoffset;
                     } else {
                         printf_log(LOG_INFO, "Warning, Symbol %s found, but R_X86_64_DTPOFF64 Slot Offset is NULL \n", symname);
@@ -918,7 +724,7 @@ int RelocateElfRELA(lib_t *maplib, lib_t *local_maplib, int bindnow, int deepbin
                 break;
             case R_X86_64_TLSDESC:
                 if(!symname || !symname[0]) {
-                    printf_dump(LOG_NEVER, "Apply %s R_X86_64_TLSDESC @%p with addend=%zu\n", (bind==STB_LOCAL)?"Local":"Global", p, rela[i].r_addend);
+                    printf_dump(LOG_NEVER, "Apply %s R_X86_64_TLSDESC @%p with addend=%zu\n", BindSym(bind), p, rela[i].r_addend);
                     struct tlsdesc volatile *td = (struct tlsdesc volatile *)p;
                     if(!tlsdescUndefweak)
                         tlsdescUndefweak = AddBridge(my_context->system, pFE, _dl_tlsdesc_undefweak, 0, "_dl_tlsdesc_undefweak");
@@ -1067,93 +873,13 @@ uintptr_t GetLastByte(elfheader_t* h)
 #endif
 
 void checkHookedSymbols(elfheader_t* h); // in mallochook.c
-void AddSymbols(lib_t *maplib, kh_mapsymbols_t* mapsymbols, kh_mapsymbols_t* weaksymbols, kh_mapsymbols_t* localsymbols, elfheader_t* h)
+void AddSymbols(lib_t *maplib, elfheader_t* h)
 {
+    //if(box64_dump && h->hash)   old_elf_hash_dump(h);
+    //if(box64_dump && h->gnu_hash)   new_elf_hash_dump(h);
     if(box64_dump && h->DynSym) DumpDynSym(h);
-    printf_dump(LOG_NEVER, "Will look for Symbol to add in SymTable(%zu)\n", h->numSymTab);
-    for (size_t i=0; i<h->numSymTab; ++i) {
-        const char * symname = h->StrTab+h->SymTab[i].st_name;
-        int bind = ELF64_ST_BIND(h->SymTab[i].st_info);
-        int type = ELF64_ST_TYPE(h->SymTab[i].st_info);
-        int vis = h->SymTab[i].st_other&0x3;
-        size_t sz = h->SymTab[i].st_size;
-        if((type==STT_OBJECT || type==STT_FUNC || type==STT_COMMON || type==STT_TLS  || type==STT_NOTYPE) 
-        && (vis==STV_DEFAULT || vis==STV_PROTECTED || (vis==STV_HIDDEN && bind==STB_LOCAL)) && (h->SymTab[i].st_shndx!=0)) {
-            if(sz && strstr(symname, "@@")) {
-                char symnameversioned[strlen(symname)+1];
-                strcpy(symnameversioned, symname);
-                // extact symname@@vername
-                char* p = strchr(symnameversioned, '@');
-                *p=0;
-                p+=2;
-                symname = AddDictionnary(my_context->versym, symnameversioned);
-                const char* vername = AddDictionnary(my_context->versym, p);
-                AddDefaultVersion((bind==STB_WEAK)?h->weakdefver:h->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);
-                printf_dump(LOG_NEVER, "Adding Default Versioned Symbol(bind=%s) \"%s@%s\" with offset=%p sz=%zu\n", (bind==STB_LOCAL)?"LOCAL":((bind==STB_WEAK)?"WEAK":"GLOBAL"), symname, vername, (void*)offs, sz);
-                if(bind==STB_LOCAL)
-                    AddSymbol(localsymbols, symname, offs, sz, 2, vername);
-                else    // add in local and global map 
-                    if(bind==STB_WEAK) {
-                        AddSymbol(weaksymbols, symname, offs, sz, 2, vername);
-                    } else {
-                        AddSymbol(mapsymbols, symname, offs, sz, 2, vername);
-                    }
-            } else {
-                int to_add = 1;
-                if(!to_add || (bind==STB_GNU_UNIQUE && FindGlobalSymbol(maplib, symname, -1, NULL)))
-                    continue;
-                uintptr_t offs = (type==STT_TLS)?h->SymTab[i].st_value:(h->SymTab[i].st_value + h->delta);
-                printf_dump(LOG_NEVER, "Adding Symbol(bind=%s) \"%s\" with offset=%p sz=%zu\n", (bind==STB_LOCAL)?"LOCAL":((bind==STB_WEAK)?"WEAK":"GLOBAL"), symname, (void*)offs, sz);
-                if(bind==STB_LOCAL)
-                    AddSymbol(localsymbols, symname, offs, sz, 1, NULL);
-                else    // add in local and global map 
-                    if(bind==STB_WEAK) {
-                        AddSymbol(weaksymbols, symname, offs, sz, 1, NULL);
-                    } else {
-                        AddSymbol(mapsymbols, symname, offs, sz, 1, NULL);
-                    }
-            }
-        }
-    }
-    
-    int deepbind = 0;
-    if(h && h->lib)
-        deepbind = GetDeepBind(h->lib);
-    printf_dump(LOG_NEVER, "Will look for Symbol to add in DynSym (%zu)\n", h->numDynSym);
-    for (size_t i=0; i<h->numDynSym; ++i) {
-        const char * symname = h->DynStr+h->DynSym[i].st_name;
-        int bind = ELF64_ST_BIND(h->DynSym[i].st_info);
-        int type = ELF64_ST_TYPE(h->DynSym[i].st_info);
-        int vis = h->DynSym[i].st_other&0x3;
-        if((type==STT_OBJECT || type==STT_FUNC || type==STT_COMMON || type==STT_TLS  || type==STT_NOTYPE) 
-        && (vis==STV_DEFAULT || vis==STV_PROTECTED || (vis==STV_HIDDEN && bind==STB_LOCAL)) && (h->DynSym[i].st_shndx!=0 && h->DynSym[i].st_shndx<=65521)) {
-            uintptr_t offs = (type==STT_TLS)?h->DynSym[i].st_value:(h->DynSym[i].st_value + h->delta);
-            size_t sz = h->DynSym[i].st_size;
-            int version = h->VerSym?((Elf64_Half*)((uintptr_t)h->VerSym+h->delta))[i]:-1;
-            int add_default = (version!=-1 && (version&0x7fff)>1 && !(version&0x8000) && !GetMaplibDefaultVersion(my_context->maplib, (maplib==my_context->maplib)?NULL:maplib, (bind==STB_WEAK)?1:0, deepbind, symname))?1:0;
-            if(version!=-1) version &= 0x7fff;
-            const char* vername = GetSymbolVersion(h, version);
-            if(add_default) {
-                AddDefaultVersion((bind==STB_WEAK)?h->weakdefver:h->globaldefver, symname, vername);
-                printf_dump(LOG_NEVER, "Adding Default Version \"%s\" for Symbol\"%s\"\n", vername, symname);
-            }
-            int to_add = 1;
-            if(!to_add || (bind==STB_GNU_UNIQUE && FindGlobalSymbol(maplib, symname, version, vername)))
-                continue;
-            printf_dump(LOG_NEVER, "Adding Versioned Symbol(bind=%s) \"%s\" (ver=%d/%s) with offset=%p sz=%zu\n", (bind==STB_LOCAL)?"LOCAL":((bind==STB_WEAK)?"WEAK":"GLOBAL"), symname, version, vername?vername:"(none)", (void*)offs, sz);
-            if(bind==STB_LOCAL)
-                AddSymbol(localsymbols, symname, offs, sz, version, vername);
-            else // add in local and global map 
-                if(bind==STB_WEAK) {
-                    AddSymbol(weaksymbols, symname, offs, sz, version, vername);
-                } else {
-                    AddSymbol(mapsymbols, symname, offs, sz, version?version:1, vername);
-                }
-        }
-    }
+    if(h==my_context->elfs[0]) 
+        GrabX64CopyMainElfReloc(h);
     checkHookedSymbols(h);
 }
 
@@ -1297,39 +1023,6 @@ void MarkElfInitDone(elfheader_t* h)
         h->init_done = 1;
 }
 void startMallocHook();
-void RunElfInitPltResolver(elfheader_t* h, x64emu_t *emu)
-{
-    if(!h || h->init_done)
-        return;
-    uintptr_t p = h->initentry + h->delta;
-    h->init_done = 1;
-    for(int i=0; i<h->needed->size; ++i) {
-        library_t *lib = h->needed->libs[i];
-        elfheader_t *lib_elf = GetElf(lib);
-        if(lib_elf)
-            RunElfInitPltResolver(lib_elf, emu);
-    }
-    printf_dump(LOG_DEBUG, "Calling Init for %s @%p\n", ElfName(h), (void*)p);
-    if(h->initentry)
-        RunSafeFunction(p, 3, my_context->argc, my_context->argv, my_context->envv);
-    printf_dump(LOG_DEBUG, "Done Init for %s\n", ElfName(h));
-    // and check init array now
-    Elf64_Addr *addr = (Elf64_Addr*)(h->initarray + h->delta);
-    for (size_t i=0; i<h->initarray_sz; ++i) {
-        if(addr[i]) {
-            printf_dump(LOG_DEBUG, "Calling Init[%zu] for %s @%p\n", i, ElfName(h), (void*)addr[i]);
-            RunSafeFunction((uintptr_t)addr[i], 3, my_context->argc, my_context->argv, my_context->envv);
-        }
-    }
-
-    if(h->malloc_hook_2)
-        startMallocHook();
-
-    h->fini_done = 0;   // can be fini'd now (in case it was re-inited)
-    printf_dump(LOG_DEBUG, "All Init Done for %s\n", ElfName(h));
-    return;
-}
-
 void RunElfInit(elfheader_t* h, x64emu_t *emu)
 {
     if(!h || h->init_done)
@@ -1551,7 +1244,7 @@ const char* VersionedName(const char* name, int ver, const char* vername)
     return AddDictionnary(my_context->versym, buf);
 }
 
-int SameVersionedSymbol(const char* name1, int ver1, const char* vername1, const char* name2, int ver2, const char* vername2)
+int SameVersionedSymbol(const char* name1, int ver1, const char* vername1, int veropt1, const char* name2, int ver2, const char* vername2, int veropt2)
 {
     if(strcmp(name1, name2))    //name are different, no need to go further
         return 0;
@@ -1563,6 +1256,10 @@ int SameVersionedSymbol(const char* name1, int ver1, const char* vername1, const
         return 0;
     if(ver1==1 || ver2==1)  // one if global, ok
         return 1;
+    if(ver1<2 && ver2>1 && veropt2)
+        return 1;
+    if(ver2<2 && ver1>1 && veropt1)
+        return 1;
     if(!strcmp(vername1, vername2))  // same vername
         return 1;
     return 0;
@@ -1783,23 +1480,70 @@ void ElfAttachLib(elfheader_t* head, library_t* lib)
     head->lib = lib;
 }
 
-kh_mapsymbols_t* GetMapSymbols(elfheader_t* h)
+Elf64_Sym* ElfLocateSymbol(elfheader_t* head, uintptr_t *offs, uintptr_t *end, const char* symname, int* ver, const char** vername, int local, int* veropt)
 {
-    if(!h)
+    Elf64_Sym* sym = ElfLookup(head, symname, *ver, *vername, local, *veropt);
+    if(!sym) return NULL;
+    if(head->VerSym && !*veropt) {
+        int idx = ((uintptr_t)sym - (uintptr_t)head->DynSym)/sizeof(Elf64_Sym);
+        int version = ((Elf64_Half*)((uintptr_t)head->VerSym+head->delta))[idx];
+        if(version!=-1) version &=0x7fff;
+        const char* symvername = GetSymbolVersion(head, version);
+        Elf64_Half flags = GetSymbolVersionFlag(head, version);
+        if(version>1 && *ver<2 && (flags==0)) {
+            *ver = version;
+            *vername = symvername;
+            *veropt = 1;
+        } else if(flags==0 && !*veropt && version>1 && *ver>1 && !strcmp(symvername, *vername)) {
+            *veropt = 1;
+        }
+    }
+    if(!sym->st_shndx) return NULL;
+    int vis = ELF64_ST_VISIBILITY(sym->st_other);
+    if(vis==STV_HIDDEN && !local)
         return NULL;
-    return h->mapsymbols;
+    return sym;
 }
-kh_mapsymbols_t* GetWeakSymbols(elfheader_t* h)
+
+void* ElfGetLocalSymbolStartEnd(elfheader_t* head, uintptr_t *offs, uintptr_t *end, const char* symname, int* ver, const char** vername, int local, int* veropt)
 {
-    if(!h)
-        return NULL;
-    return h->weaksymbols;
+    Elf64_Sym* sym = ElfLocateSymbol(head, offs, end, symname, ver, vername, local, veropt);
+    if(!sym) return NULL;
+    int bind = ELF64_ST_BIND(sym->st_info);
+    if(bind!=STB_LOCAL) return 0;
+    if(offs) *offs = sym->st_value + head->delta;
+    if(end) *end = sym->st_value + head->delta + sym->st_size;
+    return sym;
 }
-kh_mapsymbols_t* GetLocalSymbols(elfheader_t* h)
+void* ElfGetGlobalSymbolStartEnd(elfheader_t* head, uintptr_t *offs, uintptr_t *end, const char* symname, int* ver, const char** vername, int local, int* veropt)
 {
-    if(!h)
-        return NULL;
-    return h->localsymbols;
+    Elf64_Sym* sym = ElfLocateSymbol(head, offs, end, symname, ver, vername, local, veropt);
+    if(!sym) return NULL;
+    int bind = ELF64_ST_BIND(sym->st_info);
+    if(bind!=STB_GLOBAL && bind!=STB_GNU_UNIQUE) return 0;
+    if(offs) *offs = sym->st_value + head->delta;
+    if(end) *end = sym->st_value + head->delta + sym->st_size;
+    return sym;
+}
+void* ElfGetWeakSymbolStartEnd(elfheader_t* head, uintptr_t *offs, uintptr_t *end, const char* symname, int* ver, const char** vername, int local, int* veropt)
+{
+    Elf64_Sym* sym = ElfLocateSymbol(head, offs, end, symname, ver, vername, local, veropt);
+    if(!sym) return NULL;
+    int bind = ELF64_ST_BIND(sym->st_info);
+    if(bind!=STB_WEAK) return 0;
+    if(offs) *offs = sym->st_value + head->delta;
+    if(end) *end = sym->st_value + head->delta + sym->st_size;
+    return sym;
+}
+int ElfGetSymTabStartEnd(elfheader_t* head, uintptr_t *offs, uintptr_t *end, const char* symname)
+{
+    Elf64_Sym* sym = ElfSymTabLookup(head, symname);
+    if(!sym) return 0;
+    if(!sym->st_shndx) return 0;
+    if(!sym->st_size) return 0; //needed?
+    if(offs) *offs = sym->st_value + head->delta;
+    if(end) *end = sym->st_value + head->delta + sym->st_size;
+    return 1;
 }
 
 typedef struct search_symbol_s{
@@ -1873,23 +1617,16 @@ void* GetNativeSymbolUnversioned(void* lib, const char* name)
     return s.addr;
 }
 
-kh_defaultversion_t* GetGlobalDefaultVersion(elfheader_t* h)
-{
-    return h?h->globaldefver:NULL;
-}
-kh_defaultversion_t* GetWeakDefaultVersion(elfheader_t* h)
-{
-    return h?h->weakdefver:NULL;
-}
-
-
 uintptr_t pltResolver = ~0LL;
 EXPORT void PltResolver(x64emu_t* emu)
 {
     uintptr_t addr = Pop64(emu);
     int slot = (int)Pop64(emu);
     elfheader_t *h = (elfheader_t*)addr;
-    printf_dump(LOG_DEBUG, "PltResolver: Addr=%p, Slot=%d Return=%p: elf is %s (VerSym=%p)\n", (void*)addr, slot, *(void**)(R_RSP), h->name, h->VerSym);
+    library_t* lib = h->lib;
+    lib_t* local_maplib = GetMaplib(lib);
+    int deepbind = GetDeepBind(lib);
+    printf_dump(LOG_DEBUG, "PltResolver: Addr=%p, Slot=%d Return=%p(%s): elf is %s (VerSym=%p, deepbind=%d, local_maplib=%p) func param: %p, %p...\n", (void*)addr, slot, *(void**)(R_RSP), getAddrFunctionName(*(uintptr_t*)R_RSP),h->name, h->VerSym, deepbind, local_maplib, (void*)R_RDI, (void*)R_RSI);
 
     Elf64_Rela * rel = (Elf64_Rela *)(h->jmprel + h->delta) + slot;
 
@@ -1899,42 +1636,53 @@ EXPORT void PltResolver(x64emu_t* emu)
     int version = h->VerSym?((Elf64_Half*)((uintptr_t)h->VerSym+h->delta))[ELF64_R_SYM(rel->r_info)]:-1;
     if(version!=-1) version &= 0x7fff;
     const char* vername = GetSymbolVersion(h, version);
+    Elf64_Half flags = GetSymbolVersionFlag(h, version);
+    int veropt = flags?0:1;
     uint64_t *p = (uint64_t*)(rel->r_offset + h->delta);
     uintptr_t offs = 0;
     uintptr_t end = 0;
 
-    library_t* lib = h->lib;
-    lib_t* local_maplib = GetMaplib(lib);
-    int deepbind = GetDeepBind(lib);
-    const char* globdefver = (bind==STB_WEAK)?NULL:GetMaplibDefaultVersion(my_context->maplib, (my_context->maplib==local_maplib)?NULL:local_maplib, 0, deepbind, symname);
-    const char* weakdefver = (bind==STB_WEAK)?GetMaplibDefaultVersion(my_context->maplib, (my_context->maplib==local_maplib)?NULL:local_maplib, 1, deepbind, symname):NULL;
-    if(!offs && !end && local_maplib && deepbind)
-        GetGlobalSymbolStartEnd(local_maplib, symname, &offs, &end, h, version, vername, globdefver, weakdefver);
-    else
-        GetGlobalSymbolStartEnd(my_context->maplib, symname, &offs, &end, h, version, vername, globdefver, weakdefver);
-    if(!offs && !end && local_maplib && !deepbind) {
-        GetGlobalSymbolStartEnd(local_maplib, symname, &offs, &end, h, version, vername, globdefver, weakdefver);
+    Elf64_Sym *elfsym = NULL;
+    if(bind==STB_LOCAL) {
+        elfsym = ElfDynSymLookup(h, symname);
+        if(elfsym && elfsym->st_shndx) {
+            offs = elfsym->st_value + h->delta;
+            end = offs + elfsym->st_size;
+        }
+        if(!offs && !end && local_maplib && deepbind)
+            GetLocalSymbolStartEnd(local_maplib, symname, &offs, &end, h, version, vername, veropt, (void**)&elfsym);
+        if(!offs && !end)
+            GetLocalSymbolStartEnd(my_context->maplib, symname, &offs, &end, h, version, vername, veropt, (void**)&elfsym);
+        if(!offs && !end && local_maplib && !deepbind)
+            GetLocalSymbolStartEnd(local_maplib, symname, &offs, &end, h, version, vername, veropt, (void**)&elfsym);
+    } else if(bind==STB_WEAK) {
+        if(local_maplib && deepbind)
+            GetGlobalWeakSymbolStartEnd(local_maplib, symname, &offs, &end, h, version, vername, veropt, (void**)&elfsym);
+        else
+            GetGlobalWeakSymbolStartEnd(my_context->maplib, symname, &offs, &end, h, version, vername, veropt, (void**)&elfsym);
+        if(!offs && !end && local_maplib && !deepbind)
+            GetGlobalWeakSymbolStartEnd(local_maplib, symname, &offs, &end, h, version, vername, veropt, (void**)&elfsym);
+    } else {
+        if(!offs && !end && local_maplib && deepbind)
+            GetGlobalSymbolStartEnd(local_maplib, symname, &offs, &end, h, version, vername, veropt, (void**)&elfsym);
+        if(!offs && !end)
+            GetGlobalSymbolStartEnd(my_context->maplib, symname, &offs, &end, h, version, vername, veropt, (void**)&elfsym);
+        if(!offs && !end && local_maplib && !deepbind)
+            GetGlobalSymbolStartEnd(local_maplib, symname, &offs, &end, h, version, vername, veropt, (void**)&elfsym);
     }
-    if(!offs && !end && !version)
-        GetGlobalSymbolStartEnd(my_context->maplib, symname, &offs, &end, h, -1, NULL, globdefver, weakdefver);
-
     if (!offs) {
-        printf_log(LOG_NONE, "Error: PltResolver: Symbol %s(ver %d: %s%s%s) not found, cannot apply R_X86_64_JUMP_SLOT %p (%p) in %s\n", symname, version, symname, vername?"@":"", vername?vername:"", p, *(void**)p, h->name);
+        printf_log(LOG_NONE, "Error: PltResolver: Symbol %s(%sver %d: %s%s%s) not found, cannot apply R_X86_64_JUMP_SLOT %p (%p) in %s\n", symname, veropt?"opt":"", version, symname, vername?"@":"", vername?vername:"", p, *(void**)p, h->name);
         emu->quit = 1;
         return;
     } else {
-        elfheader_t* sym_elf = FindElfAddress(my_context, offs);
-        if(sym_elf && sym_elf!=my_context->elfs[0] && !sym_elf->init_done) {
-            printf_dump(LOG_DEBUG, "symbol %s from %s but elf not initialized yet, run Init now (from %s)\n", symname, ElfName(sym_elf), ElfName(h));
-            RunElfInitPltResolver(sym_elf, emu);
-        }
+        elfheader_t* sym_elf = FindElfSymbol(my_context, elfsym);
         offs = (uintptr_t)getAlternate((void*)offs);
 
         if(p) {
-            printf_dump(LOG_DEBUG, "            Apply %s R_X86_64_JUMP_SLOT %p with sym=%s(ver %d: %s%s%s) (%p -> %p / %s)\n", (bind==STB_LOCAL)?"Local":"Global", p, symname, version, symname, vername?"@":"", vername?vername:"",*(void**)p, (void*)offs, ElfName(sym_elf));
+            printf_dump(LOG_DEBUG, "            Apply %s R_X86_64_JUMP_SLOT %p with sym=%s(%sver %d: %s%s%s) (%p -> %p / %s)\n", BindSym(bind), p, symname, veropt?"opt":"", version, symname, vername?"@":"", vername?vername:"",*(void**)p, (void*)offs, ElfName(sym_elf));
             *p = offs;
         } else {
-            printf_log(LOG_NONE, "PltResolver: Warning, Symbol %s(ver %d: %s%s%s) found, but Jump Slot Offset is NULL \n", symname, version, symname, vername?"@":"", vername?vername:"");
+            printf_log(LOG_NONE, "PltResolver: Warning, Symbol %s(%sver %d: %s%s%s) found, but Jump Slot Offset is NULL \n", symname, veropt?"opt":"", version, symname, vername?"@":"", vername?vername:"");
         }
     }
 
diff --git a/src/elfs/elfloader_private.h b/src/elfs/elfloader_private.h
index f13be551..7da8d6e5 100644
--- a/src/elfs/elfloader_private.h
+++ b/src/elfs/elfloader_private.h
@@ -3,8 +3,6 @@
 
 typedef struct library_s library_t;
 typedef struct needed_libs_s needed_libs_t;
-typedef struct kh_mapsymbols_s kh_mapsymbols_t;
-typedef struct kh_defaultversion_s kh_defaultversion_t;
 typedef struct cleanup_s cleanup_t;
 
 #include <elf.h>
@@ -48,6 +46,8 @@ typedef struct elfheader_s {
     int         szVerDef;
     int         e_type;
     uint32_t    flags;
+    uintptr_t   hash;
+    uintptr_t   gnu_hash;
 
     intptr_t    delta;  // should be 0
     void*       image;  // base of the elf image
@@ -117,11 +117,6 @@ typedef struct elfheader_s {
     int                 clean_sz;
     int                 clean_cap;
 
-    kh_mapsymbols_t   *mapsymbols;
-    kh_mapsymbols_t   *weaksymbols;
-    kh_mapsymbols_t   *localsymbols;
-    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)
 } elfheader_t;
 
 #define R_X86_64_NONE           0       /* No reloc */
@@ -171,4 +166,19 @@ typedef struct elfheader_s {
 
 elfheader_t* ParseElfHeader(FILE* f, const char* name, int exec);
 
+const char* BindSym(int bind);
+
+Elf64_Half GetSymbolVersionFlag(elfheader_t* h, int index);
+
+uint32_t old_elf_hash(const char* name);
+Elf64_Sym* old_elf_lookup(elfheader_t* h, const char* symname, int ver, const char* vername, int local, int veropt);
+void old_elf_hash_dump(elfheader_t* h);
+uint32_t new_elf_hash(const char *name);
+Elf64_Sym* new_elf_lookup(elfheader_t* h, const char* symname, int ver, const char* vername, int local, int veropt);
+void new_elf_hash_dump(elfheader_t* h);
+
+Elf64_Sym* ElfLookup(elfheader_t* h, const char* symname, int ver, const char* vername, int local, int veropt);
+Elf64_Sym* ElfSymTabLookup(elfheader_t* h, const char* symname);
+Elf64_Sym* ElfDynSymLookup(elfheader_t* h, const char* symname);
+
 #endif //__ELFLOADER_PRIVATE_H_
diff --git a/src/elfs/elfparser.c b/src/elfs/elfparser.c
index f9a3e844..803f7dce 100644
--- a/src/elfs/elfparser.c
+++ b/src/elfs/elfparser.c
@@ -13,6 +13,9 @@
 #ifndef PN_XNUM 
 #define PN_XNUM (0xffff)
 #endif
+#ifndef DT_GNU_HASH
+#define DT_GNU_HASH	0x6ffffef5
+#endif
 
 int LoadSH(FILE *f, Elf64_Shdr *s, void** SH, const char* name, uint32_t type)
 {
@@ -284,6 +287,14 @@ elfheader_t* ParseElfHeader(FILE* f, const char* name, int exec)
                     h->flags = val;
                     printf_dump(LOG_DEBUG, "The DT_FLAGS is 0x%x\n", h->flags);
                     break;
+                case DT_HASH:
+                    h->hash = ptr;
+                    printf_dump(LOG_DEBUG, "The DT_HASH is at address %p\n", (void*)h->hash);
+                    break;
+                case DT_GNU_HASH:
+                    h->gnu_hash = ptr;
+                    printf_dump(LOG_DEBUG, "The DT_GNU_HASH is at address %p\n", (void*)h->gnu_hash);
+                    break;
                 }
             }
             if(h->rel) {
@@ -374,112 +385,15 @@ elfheader_t* ParseElfHeader(FILE* f, const char* name, int exec)
     return h;
 }
 
-const char* GetSymbolVersion(elfheader_t* h, int version)
+const char* BindSym(int bind)
 {
-    if(version<2)
-        return NULL;
-    /*if(version==1)
-        return "*";*/
-    if(h->VerNeed) {
-        Elf64_Verneed *ver = (Elf64_Verneed*)((uintptr_t)h->VerNeed + h->delta);
-        while(ver) {
-            Elf64_Vernaux *aux = (Elf64_Vernaux*)((uintptr_t)ver + ver->vn_aux);
-            for(int j=0; j<ver->vn_cnt; ++j) {
-                if(aux->vna_other==version) 
-                    return h->DynStr+aux->vna_name;
-                aux = (Elf64_Vernaux*)((uintptr_t)aux + aux->vna_next);
-            }
-            ver = ver->vn_next?((Elf64_Verneed*)((uintptr_t)ver + ver->vn_next)):NULL;
-        }
+    switch(bind) {
+        case STB_GLOBAL: return "STB_GLOBAL";
+        case STB_WEAK: return "STB_WEAK";
+        case STB_LOCAL: return "STB_LOCAL";
+        case STB_GNU_UNIQUE: return "STB_GNU_UNIQUE";
     }
-    return GetParentSymbolVersion(h, version);  // if symbol is "internal", use Def table instead
-}
-
-const char* GetParentSymbolVersion(elfheader_t* h, int index)
-{
-    if(!h->VerDef || (index<1))
-        return NULL;
-    Elf64_Verdef *def = (Elf64_Verdef*)((uintptr_t)h->VerDef + h->delta);
-    while(def) {
-        if(def->vd_ndx==index) {
-            if(def->vd_cnt<1)
-                return NULL;
-            /*if(def->vd_flags&VER_FLG_BASE)
-                return NULL;*/
-            Elf64_Verdaux *aux = (Elf64_Verdaux*)((uintptr_t)def + def->vd_aux);
-            return h->DynStr+aux->vda_name; // return Parent, so 1st aux
-        }
-        def = def->vd_next?((Elf64_Verdef*)((uintptr_t)def + def->vd_next)):NULL;
-    }
-    return NULL;
-}
-
-int GetVersionIndice(elfheader_t* h, const char* vername)
-{
-    if(!vername)
-        return 0;
-    if(h->VerDef) {
-        Elf64_Verdef *def = (Elf64_Verdef*)((uintptr_t)h->VerDef + h->delta);
-        while(def) {
-            Elf64_Verdaux *aux = (Elf64_Verdaux*)((uintptr_t)def + def->vd_aux);
-            if(!strcmp(h->DynStr+aux->vda_name, vername))
-                return def->vd_ndx;
-            def = def->vd_next?((Elf64_Verdef*)((uintptr_t)def + def->vd_next)):NULL;
-        }
-    }
-    return 0;
-}
-
-int GetNeededVersionCnt(elfheader_t* h, const char* libname)
-{
-    if(!libname)
-        return 0;
-    if(h->VerNeed) {
-        Elf64_Verneed *ver = (Elf64_Verneed*)((uintptr_t)h->VerNeed + h->delta);
-        while(ver) {
-            char *filename = h->DynStr + ver->vn_file;
-            if(!strcmp(filename, libname))
-                return ver->vn_cnt;
-            ver = ver->vn_next?((Elf64_Verneed*)((uintptr_t)ver + ver->vn_next)):NULL;
-        }
-    }
-    return 0;
-}
-
-const char* GetNeededVersionString(elfheader_t* h, const char* libname, int idx)
-{
-    if(!libname)
-        return 0;
-    if(h->VerNeed) {
-        Elf64_Verneed *ver = (Elf64_Verneed*)((uintptr_t)h->VerNeed + h->delta);
-        while(ver) {
-            char *filename = h->DynStr + ver->vn_file;
-            Elf64_Vernaux *aux = (Elf64_Vernaux*)((uintptr_t)ver + ver->vn_aux);
-            if(!strcmp(filename, libname)) {
-                for(int j=0; j<ver->vn_cnt; ++j) {
-                    if(j==idx) 
-                        return h->DynStr+aux->vna_name;
-                    aux = (Elf64_Vernaux*)((uintptr_t)aux + aux->vna_next);
-                }
-                return NULL;    // idx out of bound, return NULL...
-           }
-            ver = ver->vn_next?((Elf64_Verneed*)((uintptr_t)ver + ver->vn_next)):NULL;
-        }
-    }
-    return NULL;
-}
-
-int GetNeededVersionForLib(elfheader_t* h, const char* libname, const char* ver)
-{
-    if(!libname || !ver)
-        return 0;
-    int n = GetNeededVersionCnt(h, libname);
-    if(!n)
-        return 0;
-    for(int i=0; i<n; ++i) {
-        const char* vername = GetNeededVersionString(h, libname, i);
-        if(vername && !strcmp(ver, vername))
-            return 1;
-    }
-    return 0;
-}
+    static char tmp[50];
+    sprintf(tmp, "??? 0x%x", bind);
+    return tmp;
+}
\ No newline at end of file
diff --git a/src/emu/x64run_private.c b/src/emu/x64run_private.c
index 4d8753e4..8d7ff9b9 100644
--- a/src/emu/x64run_private.c
+++ b/src/emu/x64run_private.c
@@ -1227,7 +1227,7 @@ const char* getAddrFunctionName(uintptr_t addr)
         else if(addr==start)
             sprintf(ret, "%s/%s", ElfName(elf), symbname);
         else
-            sprintf(ret, "%s/%s + %ld", ElfName(elf), symbname, addr - start);
+            sprintf(ret, "%s/%s + 0x%lx", ElfName(elf), symbname, addr - start);
     } else {
         if(elf) {
             sprintf(ret, "%s + 0x%lx", ElfName(elf), addr - (uintptr_t)GetBaseAddress(elf));
diff --git a/src/include/box64context.h b/src/include/box64context.h
index da09bc49..efe84223 100644
--- a/src/include/box64context.h
+++ b/src/include/box64context.h
@@ -121,6 +121,7 @@ typedef struct box64context_s {
     lib_t               *local_maplib;  // libs and symbols openned has local (only collection of libs, no symbols)
     dic_t               *versym;        // dictionnary of versioned symbols
     kh_mapsymbols_t     *globdata;      // GLOBAL_DAT relocation for COPY mapping in main elf
+    kh_mapsymbols_t     *uniques;       // symbols with STB_GNU_UNIQUE bindings
 
     kh_threadstack_t    *stacksizes;    // stack sizes attributes for thread (temporary)
     bridge_t            *system;        // other bridges
diff --git a/src/include/elfloader.h b/src/include/elfloader.h
index 80289c5c..ea0928b1 100644
--- a/src/include/elfloader.h
+++ b/src/include/elfloader.h
@@ -26,12 +26,13 @@ int CalcLoadAddr(elfheader_t* head);
 int AllocLoadElfMemory(box64context_t* context, elfheader_t* head, int mainbin);
 void FreeElfMemory(elfheader_t* head);
 int isElfHasNeededVer(elfheader_t* head, const char* libname, elfheader_t* verneeded);
+void GrabX64CopyMainElfReloc(elfheader_t* head);
 int RelocateElf(lib_t *maplib, lib_t* local_maplib, int bindnow, int deepbind, elfheader_t* head);
 int RelocateElfPlt(lib_t *maplib, lib_t* local_maplib, int bindnow, int deepbind, elfheader_t* head);
 void CalcStack(elfheader_t* h, uint64_t* stacksz, size_t* stackalign);
 uintptr_t GetEntryPoint(lib_t* maplib, elfheader_t* h);
 uintptr_t GetLastByte(elfheader_t* h);
-void AddSymbols(lib_t *maplib, kh_mapsymbols_t* mapsymbols, kh_mapsymbols_t* weaksymbols, kh_mapsymbols_t* localsymbols, elfheader_t* h);
+void AddSymbols(lib_t *maplib, elfheader_t* h);
 int LoadNeededLibs(elfheader_t* h, lib_t *maplib, int local, int bindnow, int deepbind, box64context_t *box64, x64emu_t* emu);
 uintptr_t GetElfInit(elfheader_t* h);
 uintptr_t GetElfFini(elfheader_t* h);
@@ -62,17 +63,16 @@ int ElfCheckIfUseTCMallocMinimal(elfheader_t* h);   // return 1 if tcmalloc is u
 const char* GetSymbolVersion(elfheader_t* h, int version);
 const char* GetParentSymbolVersion(elfheader_t* h, int index);
 const char* VersionedName(const char* name, int ver, const char* vername);
-int SameVersionedSymbol(const char* name1, int ver1, const char* vername1, const char* name2, int ver2, const char* vername2);
+int SameVersionedSymbol(const char* name1, int ver1, const char* vername1, int veropt1, const char* name2, int ver2, const char* vername2, int veropt2);
 int GetVersionIndice(elfheader_t* h, const char* vername);
 int GetNeededVersionCnt(elfheader_t* h, const char* libname);
 const char* GetNeededVersionString(elfheader_t* h, const char* libname, int idx);
 int GetNeededVersionForLib(elfheader_t* h, const char* libname, const char* ver);
 
-kh_mapsymbols_t* GetMapSymbols(elfheader_t* h);
-kh_mapsymbols_t* GetWeakSymbols(elfheader_t* h);
-kh_mapsymbols_t* GetLocalSymbols(elfheader_t* h);
-kh_defaultversion_t* GetGlobalDefaultVersion(elfheader_t* h);
-kh_defaultversion_t* GetWeakDefaultVersion(elfheader_t* h);
+void* ElfGetLocalSymbolStartEnd(elfheader_t* head, uintptr_t *offs, uintptr_t *sz, const char* symname, int* ver, const char** vername, int local, int* veropt);
+void* ElfGetGlobalSymbolStartEnd(elfheader_t* head, uintptr_t *offs, uintptr_t *sz, const char* symname, int* ver, const char** vername, int local, int* veropt);
+void* ElfGetWeakSymbolStartEnd(elfheader_t* head, uintptr_t *offs, uintptr_t *sz, const char* symname, int* ver, const char** vername, int local, int* veropt);
+int ElfGetSymTabStartEnd(elfheader_t* head, uintptr_t *offs, uintptr_t *end, const char* symname);
 
 void* GetNativeSymbolUnversioned(void* lib, const char* name);
 
diff --git a/src/include/librarian.h b/src/include/librarian.h
index 2864f246..74a94373 100644
--- a/src/include/librarian.h
+++ b/src/include/librarian.h
@@ -12,9 +12,10 @@ typedef struct x64emu_s x64emu_t;
 typedef struct elfheader_s elfheader_t;
 typedef struct needed_libs_s needed_libs_t;
 typedef struct kh_mapoffsets_s kh_mapoffsets_t;
+typedef enum   symbol_type_s    symbol_type_t;
 typedef char* cstr_t;
 
-lib_t *NewLibrarian(box64context_t* context, int ownlibs);
+lib_t *NewLibrarian(box64context_t* context);
 void FreeLibrarian(lib_t **maplib, x64emu_t* emu);
 dlprivate_t *NewDLPrivate(void);
 void FreeDLPrivate(dlprivate_t **lib);
@@ -27,20 +28,19 @@ library_t* GetLibMapLib(lib_t* maplib, const char* name);
 library_t* GetLibInternal(const char* name);
 void promoteLocalLibGlobal(library_t* lib);
 int isLibLocal(library_t* lib);
-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, size_t size, int version, const char* vername, const char* globdefver, const char* weakdefver);
-int GetGlobalSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, elfheader_t *self, int version, const char* vername, const char* globdefver, const char* weakdefver);
-int GetGlobalWeakSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, elfheader_t *self, int version, const char* vername, const char* globdefver, const char* weakdefver);
-int GetGlobalNoWeakSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, int version, const char* vername, const char* defver);
-int GetLocalSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, elfheader_t *self, int version, const char* vername, const char* globdefver, const char* weakdefver);
-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, const char* defver);
+uintptr_t FindGlobalSymbol(lib_t *maplib, const char* name, int version, const char* vername, int veropt);
+int GetNoSelfSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, elfheader_t* self, size_t size, int version, const char* vername, int veropt, void** elfsym);
+int GetGlobalSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, elfheader_t* self, int version, const char* vername, int veropt, void** elfsym);
+int GetGlobalWeakSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, elfheader_t *self, int version, const char* vername, int veropt, void** elfsym);
+int GetGlobalNoWeakSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, int version, const char* vername, int veropt, void** elfsym);
+int GetLocalSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, elfheader_t *self, int version, const char* vername, int veropt, void** elfsym);
+elfheader_t* GetGlobalSymbolElf(lib_t *maplib, const char* name, int version, const char* vername, int veropt);
+int IsGlobalNoWeakSymbolInNative(lib_t *maplib, const char* name, int version, const char* vername, int veropt);
+int GetSymTabStartEnd(lib_t* maplib, const char* name, uintptr_t* start, uintptr_t* end);
 
 void MapLibRemoveLib(lib_t* maplib, library_t* lib);
 void MapLibPrependLib(lib_t* maplib, library_t* lib, library_t* ref);
 
-const char* GetMaplibDefaultVersion(lib_t *maplib, lib_t *local_maplib, int isweak, int deepbind, const char* symname);
-
 const char* FindSymbolName(lib_t *maplib, void* p, void** start, uint64_t* sz, const char** libname, void** base, library_t** lib);
 
 void AddOffsetSymbol(lib_t *maplib, void* offs, const char* name);
diff --git a/src/include/library.h b/src/include/library.h
index 4cc1012f..4e7ba0d1 100644
--- a/src/include/library.h
+++ b/src/include/library.h
@@ -21,9 +21,9 @@ int FinalizeLibrary(library_t* lib, lib_t* local_maplib, int bindnow, int deepbi
 
 char* GetNameLib(library_t *lib);
 int IsSameLib(library_t* lib, const char* path);    // check if lib is same (path -> name)
-int GetLibGlobalSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start, uintptr_t* end, size_t size, int* weak, int version, const char* vername, int local, const char* defver);
-int GetLibWeakSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start, uintptr_t* end, size_t size, int* weak, int version, const char* vername, int local, const char* defver);
-int GetLibLocalSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start, uintptr_t* end, size_t size, int* weak, int version, const char* vername, int local, const char* defver);
+int GetLibGlobalSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start, uintptr_t* end, size_t size, int* weak, int* version, const char** vername, int local, int* veropt, void** elfsym);
+int GetLibWeakSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start, uintptr_t* end, size_t size, int* weak, int* version, const char** vername, int local, int* veropt, void** elfsym);
+int GetLibLocalSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start, uintptr_t* end, size_t size, int* weak, int* version, const char** vername, int local, int* veropt, void** elfsym);
 char** GetNeededLibsNames(library_t* lib);
 int GetNeededLibsN(library_t* lib);
 library_t* GetNeededLib(library_t* lib, int idx);
diff --git a/src/include/symbols.h b/src/include/symbols.h
index 32e54b20..367c274b 100644
--- a/src/include/symbols.h
+++ b/src/include/symbols.h
@@ -13,22 +13,14 @@ kh_mapsymbols_t* NewMapSymbols(void);
 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, const char* defver);
+void AddSymbol(kh_mapsymbols_t *mapsymbols, const char* name, uintptr_t addr, uint32_t sz, int ver, const char* vername, int veropt);
+uintptr_t FindSymbol(kh_mapsymbols_t *mapsymbols, const char* name, int ver, const char* vername, int local, int veropt);
 // Update addr and sz of existing symbols
 void ForceUpdateSymbol(kh_mapsymbols_t *mapsymbols, const char* name, uintptr_t addr, uint32_t sz);
 // don't add if already there
-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);
-int GetSizedSymbolStartEnd(kh_mapsymbols_t* mapsymbols, const char* name, uintptr_t* start, uintptr_t* end, size_t size, int ver, const char* vername, int local, const char* defver);
+void AddUniqueSymbol(kh_mapsymbols_t *mapsymbols, const char* name, uintptr_t addr, uint32_t sz, int ver, const char* vername, int veropt);
+int GetSymbolStartEnd(kh_mapsymbols_t* mapsymbols, const char* name, uintptr_t* start, uintptr_t* end, int ver, const char* vername, int local, int veropt);
+int GetSizedSymbolStartEnd(kh_mapsymbols_t* mapsymbols, const char* name, uintptr_t* start, uintptr_t* end, size_t size, int ver, const char* vername, int local, int veropt);
 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);
-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 afe997cb..9379a905 100644
--- 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, size_t size, int* weak, int version, const char* vername, int local, const char* defver);
+typedef int (*wrappedlib_get_t)(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, size_t size, int* weak, int* version, const char** vername, int local, int* veropt, void** elfsym);
 
 void setNeededLibs(library_t* lib, int n, ...);
 #define SETALT0(v) #v
diff --git a/src/librarian/globalsymbols.c b/src/librarian/globalsymbols.c
index 462af7fb..8da444ad 100644
--- a/src/librarian/globalsymbols.c
+++ b/src/librarian/globalsymbols.c
@@ -17,21 +17,21 @@
 // workaround for Globals symbols

 

 #define GLOB(A, B) \

-    if (GetGlobalNoWeakSymbolStartEnd(my_context->maplib, #A, &globoffs, &globend, -1, NULL, NULL)) {     \

+    if (GetGlobalNoWeakSymbolStartEnd(my_context->maplib, #A, &globoffs, &globend, -1, NULL, 0, NULL)) {  \

         printf_log(LOG_DEBUG, "Global " #A " workaround, @%p <- %p\n", (void*)globoffs, &A);              \

         memcpy((void*)globoffs, &A, sizeof(A));                                                           \

     }                                                                                                     \

-    if (B && GetGlobalNoWeakSymbolStartEnd(my_context->maplib, #A, &globoffs, &globend, -1, NULL, B)) {   \

+    if (B && GetGlobalNoWeakSymbolStartEnd(my_context->maplib, #A, &globoffs, &globend, 2, B, 1, NULL)) { \

         printf_log(LOG_DEBUG, "Global " #A " workaround, @%p <- %p\n", (void*)globoffs, &A);              \

         memcpy((void*)globoffs, &A, sizeof(A));                                                           \

     }

 

 #define TOGLOB(A, B) \

-    if (GetGlobalNoWeakSymbolStartEnd(my_context->maplib, #A, &globoffs, &globend, -1, NULL, NULL)) {     \

+    if (GetGlobalNoWeakSymbolStartEnd(my_context->maplib, #A, &globoffs, &globend, -1, NULL, 0, NULL)) {  \

         printf_log(LOG_DEBUG, "Global " #A " workaround, @%p -> %p\n", (void*)globoffs, &A);              \

         memcpy(&A, (void*)globoffs, sizeof(A));                                                           \

     }                                                                                                     \

-    if (B && GetGlobalNoWeakSymbolStartEnd(my_context->maplib, #A, &globoffs, &globend, -1, NULL, B)) {   \

+    if (B && GetGlobalNoWeakSymbolStartEnd(my_context->maplib, #A, &globoffs, &globend, 2, B, 1, NULL)) { \

         printf_log(LOG_DEBUG, "Global " #A " workaround, @%p -> %p\n", (void*)globoffs, &A);              \

         memcpy(&A, (void*)globoffs, sizeof(A));                                                           \

     }

@@ -50,7 +50,7 @@ void my_setGlobalGThreadsInit()
 {

     int val = 1;

     uintptr_t globoffs, globend;

-    if (GetGlobalNoWeakSymbolStartEnd(my_context->maplib, "g_threads_got_initialized", &globoffs, &globend, -1, NULL, NULL)) {

+    if (GetGlobalNoWeakSymbolStartEnd(my_context->maplib, "g_threads_got_initialized", &globoffs, &globend, -1, NULL, 0, NULL)) {

         printf_log(LOG_DEBUG, "Global g_threads_got_initialized workaround, @%p <= %d\n", (void*)globoffs, val);

         memcpy((void*)globoffs, &val, sizeof(val));

     }

diff --git a/src/librarian/librarian.c b/src/librarian/librarian.c
index cc8c746c..93034ed1 100644
--- a/src/librarian/librarian.c
+++ b/src/librarian/librarian.c
@@ -17,15 +17,13 @@
 
 KHASH_MAP_IMPL_INT(mapoffsets, cstr_t);
 
-lib_t *NewLibrarian(box64context_t* context, int ownlibs)
+lib_t *NewLibrarian(box64context_t* context)
 {
     lib_t *maplib = (lib_t*)box_calloc(1, sizeof(lib_t));
     
     maplib->mapoffsets = kh_init(mapoffsets);
     maplib->globaldata = NewMapSymbols();
 
-    maplib->ownlibs = ownlibs;
-
     return maplib;
 }
 
@@ -37,11 +35,9 @@ void FreeLibrarian(lib_t **maplib, x64emu_t *emu)
 
     library_t* owner = (*maplib)->owner;
     (*maplib)->owner = NULL;    // to avoid recursive free...
-    if((*maplib)->ownlibs && (*maplib)->libsz) {
-        for(int i=0; i<(*maplib)->libsz; ++i) {
-            printf_dump(LOG_DEBUG, "Unloading %s\n", (*maplib)->libraries[i]->name);
-            DecRefCount(&(*maplib)->libraries[i], emu);
-        }
+    for(int i=0; i<(*maplib)->libsz; ++i) {
+        printf_dump(LOG_DEBUG, "Unloading %s\n", (*maplib)->libraries[i]->name);
+        DecRefCount(&(*maplib)->libraries[i], emu);
     }
     box_free((*maplib)->libraries);
     (*maplib)->libraries = NULL;
@@ -131,12 +127,6 @@ static void MapLibAddMapLib(lib_t* dest, library_t* lib_src, lib_t* src)
         library_t* lib = src->libraries[i];
         if(!lib || libraryInMapLib(dest, lib)) continue;
         MapLibAddLib(dest, lib);
-        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);
@@ -179,9 +169,13 @@ void promoteLocalLibGlobal(library_t* lib)
         return;
     // promote lib from local to global...
     // for add the depending local libs...
-    if(lib->maplib) {
-        MapLibAddMapLib(my_context->maplib, lib, lib->maplib);
+    if(lib->maplib && !lib->maplib_ref) {
+        lib_t* maplib = lib->maplib;
+        lib->maplib = NULL;
+        MapLibAddMapLib(my_context->maplib, lib, maplib);
     }
+    lib->maplib = NULL;
+    lib->maplib_ref = 0;
     if(!libraryInMapLib(my_context->maplib, lib))
         MapLibAddLib(my_context->maplib, lib);
     MapLibRemoveMapLib(my_context->local_maplib, my_context->maplib);
@@ -203,6 +197,8 @@ static int AddNeededLib_add(lib_t** maplib, int local, needed_libs_t* needed, in
     if(lib) {
         IncRefCount(lib, emu);   // increment cntref
         needed->libs[n] = lib;
+        if(local && *maplib)
+            MapLibAddLib(*maplib, lib);
         printf_dump(LOG_DEBUG, "Already present in maplib => success\n");
         return 0;
     }
@@ -215,10 +211,7 @@ static int AddNeededLib_add(lib_t** maplib, int local, needed_libs_t* needed, in
         if(local) {
             // add lib to maplib...
             if(*maplib) {
-                if(!libraryInMapLib(*maplib, lib))
-                     MapLibPrependLib(*maplib, lib, NULL);    // todo: Also insert libs needed by lib, after lib? But current lib->maplib is probably not the solution
-                if((*maplib)->ownlibs)
-                    MapLibRemoveMapLib(my_context->local_maplib, *maplib);
+                MapLibAddLib(*maplib, lib);
             }
         } else {
             // promote lib from local to global...
@@ -239,7 +232,7 @@ static int AddNeededLib_add(lib_t** maplib, int local, needed_libs_t* needed, in
         if(*maplib) {
             MapLibAddLib(*maplib, lib);
         } else {
-            lib->maplib = NewLibrarian(box64, 0);
+            lib->maplib = NewLibrarian(box64);
             MapLibAddLib(lib->maplib, lib);
         }
     } else {
@@ -249,6 +242,11 @@ static int AddNeededLib_add(lib_t** maplib, int local, needed_libs_t* needed, in
     if(!*maplib)
         *maplib = (local)?lib->maplib:my_context->maplib;
 
+    if(local && !lib->maplib) {
+        lib->maplib = *maplib;
+        lib->maplib_ref = 1;
+    }
+
     if(AddSymbolsLibrary(*maplib, lib, emu)) {   // also add needed libs
         printf_dump(LOG_DEBUG, "Failure to Add lib => fail\n");
         return 1;
@@ -266,6 +264,7 @@ static int AddNeededLib_add(lib_t** maplib, int local, needed_libs_t* needed, in
         lm->l_name = lib->name;
         lm->l_ld = GetDynamicSection(lib->e.elf);
     }
+    IncRefCount(lib, emu);
     return 0;
 }
 
@@ -283,29 +282,10 @@ int AddNeededLib_init(lib_t* maplib, int local, int bindnow, int deepbind, libra
     } else {
         // it's an emulated lib, 
         // load dependancies and launch init sequence
-        if(LoadNeededLibs(mainelf, maplib, 0, bindnow, deepbind, box64, emu)) {
+        if(LoadNeededLibs(mainelf, maplib, local, bindnow, deepbind, box64, emu)) {
             printf_dump(LOG_DEBUG, "Failure to Add dependant lib => fail\n");
             return 1;
         }
-        // some special case, where dependancies may not be correct
-        if(!strcmp(GetNameLib(lib), "libCgGL.so")) {
-            char* names[] = {"libGL.so.1"};    // TODO: it will never be uninit...
-            library_t* libs[] = { NULL };
-            needed_libs_t tmp = {0};
-            tmp.size = tmp.cap = 1;
-            tmp.names = names;
-            tmp.libs = libs;
-            AddNeededLib(maplib, 0, 0, deepbind, &tmp, verneeded, box64, emu);
-        }
-        if(!strcmp(GetNameLib(lib), "libmss.so.6")) {
-            char* names[] = {"libSDL-1.2.so.0", "libdl.so.2"}; // TODO: they will never be uninit...
-            library_t* libs[] = { NULL, NULL };
-            needed_libs_t tmp = {0};
-            tmp.size = tmp.cap = 2;
-            tmp.names = names;
-            tmp.libs = libs;
-            AddNeededLib(maplib, 0, 0, deepbind, &tmp, verneeded, box64, emu);
-        }
 
         // finalize the lib
         if(FinalizeLibrary(lib, local?maplib:NULL, bindnow, deepbind, emu)) {
@@ -347,9 +327,11 @@ int AddNeededLib(lib_t* maplib, int local, int bindnow, int deepbind, needed_lib
     if(ret) {
         return ret;
     }
+    
     // add dependant libs and init them
-    for (int i=0; i<needed->size; ++i)
-        if(AddNeededLib_init(maplib, local, bindnow, deepbind, needed->libs[i], verneeded, box64, emu)) {
+    int n = needed->size;
+    for (int i=0; i<n; ++i)
+        if(AddNeededLib_init(maplib, local, bindnow, deepbind, needed->libs[n-i-1], verneeded, box64, emu)) {
             printf_log(LOG_INFO, "Error initializing needed lib %s\n", needed->names[i]);
             if(!allow_missing_libs) ret = 1;
         }
@@ -383,12 +365,10 @@ library_t* GetLibInternal(const char* name)
 }
 
 EXPORTDYN
-uintptr_t FindGlobalSymbol(lib_t *maplib, const char* name, int version, const char* vername)
+uintptr_t FindGlobalSymbol(lib_t *maplib, const char* name, int version, const char* vername, int veropt)
 {
     uintptr_t start = 0, end = 0;
-    const char *globdefver = GetMaplibDefaultVersion(my_context->maplib, (my_context->maplib==maplib)?NULL:maplib, 0, 0, name);
-    const char *weakdefver = GetMaplibDefaultVersion(my_context->maplib, (my_context->maplib==maplib)?NULL:maplib, 1, 0, name);
-    if(GetGlobalSymbolStartEnd(maplib, name, &start, &end, (void*)1, version, vername, globdefver, weakdefver))
+    if(GetGlobalSymbolStartEnd(maplib, name, &start, &end, (void*)1, version, vername, veropt, NULL))
         return start;
     return 0;
 }
@@ -414,139 +394,99 @@ static void CheckNeededLibs(needed_libs_t* needed)
     }
 }
 
-int GetNoSelfSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, elfheader_t* self, size_t size, int version, const char* vername, const char* globdefver, const char* weakdefver)
+int GetNoSelfSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, elfheader_t* self, size_t size, int version, const char* vername, int veropt, void** elfsym)
 {
     assert(self);   // need self for this one
-    //search for the self, to start "next"
-    int go = -1;
     int weak = 0;
-    for(int i=0; i<maplib->libsz && (go==-1); ++i) {
-        if(GetElfIndex(maplib->libraries[i])!=-1 && (GetElf(maplib->libraries[i])==self))
-            go = i+1;
+    void* sym;
+    // search in needed libs from preloaded first, in order
+    if(my_context->preload)
+        for(int i=0; i<my_context->preload->size; ++i)
+            if(self!=GetElf(my_context->preload->libs[i]) && GetLibGlobalSymbolStartEnd(my_context->preload->libs[i], name, start, end, size, &weak, &version, &vername, 0, &veropt, elfsym)) {
+                return 1;
+            }
+    if(maplib==my_context->maplib) {
+        // search non-weak symbol
+        if(self!=my_context->elfs[0] && (sym = ElfGetGlobalSymbolStartEnd(my_context->elfs[0], start, end, name, &version, &vername, 0, &veropt))) {
+            if(elfsym) *elfsym = sym;
+            return 1;
+        }
     }
-    if(go<0)
-        go = 0; // not found...
-    if(maplib)
-    for(int i=go; i<maplib->libsz; ++i) {
-        if(GetElfIndex(maplib->libraries[i])==-1 || (GetElf(maplib->libraries[i])!=self))
-            if(GetLibGlobalSymbolStartEnd(maplib->libraries[i], name, start, end, size, &weak, version, vername, 0, globdefver))
-                if(*start)
-                    return 1;
+    // search in global symbols
+    if(maplib) {
+        for(int i=0; i<maplib->libsz; ++i) {
+            if(self!=GetElf(maplib->libraries[i]) && GetLibGlobalSymbolStartEnd(maplib->libraries[i], name, start, end, size, &weak, &version, &vername, 0, &veropt, elfsym))
+                return 1;
+        }
     }
+
+    // GetSymbolStartEnd should not change start/end if symbol is not found
+    if(self!=my_context->elfs[0] && (sym = ElfGetWeakSymbolStartEnd(my_context->elfs[0], start, end, name, &version, &vername, 0, &veropt))) {
+        if(elfsym) *elfsym = sym;
+        weak = 1;
+    }
+
     if(maplib)
-    for(int i=go; i<maplib->libsz; ++i)
-        if(GetElfIndex(maplib->libraries[i])==-1 || (GetElf(maplib->libraries[i])!=self))
-            GetLibWeakSymbolStartEnd(maplib->libraries[i], name, start, end, size, &weak, version, vername, 0, weakdefver);
-    // loop done, weak symbol found
-    if(weak && *start)
-        return 1;
-    // if self defined, give it another chance with self...
-    if(self) {
-        if(my_context->elfs[0]!=self) {
-            if(GetSizedSymbolStartEnd(GetMapSymbols(my_context->elfs[0]), name, start, end, size, version, vername, 1, globdefver))
-                if(*start)
-                    return 1;
-            if(GetSizedSymbolStartEnd(GetWeakSymbols(my_context->elfs[0]), name, start, end, size, version, vername, 1, weakdefver))
-                if(*start)
-                    weak = 1;
-        }
-        for(int i=0; i<go; ++i) {
-            if(GetElfIndex(maplib->libraries[i])==-1 || (GetElf(maplib->libraries[i])!=self))
-                if(GetLibGlobalSymbolStartEnd(maplib->libraries[i], name, start, end, size, &weak, version, vername, 1, globdefver))
-                    if(*start)
-                        return 1;
-        }
-        if(maplib)
-        for(int i=0; i<go; ++i) {
-            if(GetElfIndex(maplib->libraries[i])==-1 || (GetElf(maplib->libraries[i])!=self))
-                GetLibWeakSymbolStartEnd(maplib->libraries[i], name, start, end, size, &weak, version, vername, 1, weakdefver);
+    for(int i=0; i<maplib->libsz; ++i) {
+        if(self!=GetElf(maplib->libraries[i]) && GetLibWeakSymbolStartEnd(maplib->libraries[i], name, start, end, size, &weak, &version, &vername, 0, &veropt, elfsym)) {
+            weak = 1;
         }
-    if(weak && *start)
-        return 1;
     }
+
     // nope, not found
-    return 0;
+    return weak;
 }
-static int GetGlobalSymbolStartEnd_internal(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, elfheader_t* self, int version, const char* vername, const char* globdefver, const char* weakdefver)
+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* veropt, void** elfsym)
 {
     int weak = 0;
     size_t size = 0;
+    void* sym;
     // search in needed libs from preloaded first, in order
     if(my_context->preload)
         for(int i=0; i<my_context->preload->size; ++i)
-            if(GetLibGlobalSymbolStartEnd(my_context->preload->libs[i], name, start, end, size, &weak, version, vername, isLocal(self, my_context->preload->libs[i]), globdefver))
-                if(*start) {
-                    return 1;
-                }
-    if(maplib==my_context->maplib) {
-        // search non-weak symbol, from older to newer (first GLOBAL object wins, starting with self)
-        if(GetSymbolStartEnd(GetMapSymbols(my_context->elfs[0]), name, start, end, version, vername, (my_context->elfs[0]==self || !self)?1:0, globdefver))
-            if(*start) {
+            if(GetLibGlobalSymbolStartEnd(my_context->preload->libs[i], name, start, end, size, &weak, version, vername, isLocal(self, my_context->preload->libs[i]), veropt, elfsym)) {
                 return 1;
             }
-        // This kind-of create a map to search lib only 1 time, and in order of needed...
-        if(my_context->neededlibs)
-            CheckNeededLibs(my_context->neededlibs);
-        // search in needed libs from neededlibs first, in order
-        if(my_context->neededlibs)
-            for(int i=0; i<my_context->neededlibs->size; ++i)
-                if(GetLibGlobalSymbolStartEnd(my_context->neededlibs->libs[i], name, start, end, size, &weak, version, vername, isLocal(self, my_context->neededlibs->libs[i]), globdefver))
-                    if(*start) {
-                        return 1;
-                    }
+    if(maplib==my_context->maplib) {
+        // search non-weak symbol, from older to newer (first GLOBAL object wins, starting with self)
+        if((sym = ElfGetGlobalSymbolStartEnd(my_context->elfs[0], start, end, name, version, vername, (my_context->elfs[0]==self || !self)?1:0, veropt))) {
+            if(elfsym) *elfsym = sym;
+            return 1;
+        }
     }
     // search in global symbols
     if(maplib) {
-        if((maplib==my_context->maplib) && self && self!=my_context->elfs[0] && self!=(void*)1)
-            if(GetSymbolStartEnd(GetMapSymbols(self), name, start, end, version, vername, 1, globdefver))
-                if(*start) {
-                    return 1;
-                }
         for(int i=0; i<maplib->libsz; ++i) {
-            if(GetLibGlobalSymbolStartEnd(maplib->libraries[i], name, start, end, size, &weak, version, vername, isLocal(self, maplib->libraries[i]), globdefver))
-                if(*start) {
-                    return 1;
-                }
+            if(GetLibGlobalSymbolStartEnd(maplib->libraries[i], name, start, end, size, &weak, version, vername, isLocal(self, maplib->libraries[i]), veropt, elfsym))
+                return 1;
         }
     }
 
-    // check with default version...
-    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, weakdefver))
-        if(*start) {
-            ok = 1;
-        }
-
-    // search in needed libs from neededlibs first, in order
-    if(my_context->neededlibs)
-        for(int i=0; i<my_context->neededlibs->size; ++i)
-            if(GetLibWeakSymbolStartEnd(my_context->neededlibs->libs[i], name, start, end, size, &weak, version, vername, isLocal(self, my_context->neededlibs->libs[i]), weakdefver))
-                if(*start) {
-                    return 1;
-                }
-
+    if((sym = ElfGetWeakSymbolStartEnd(my_context->elfs[0], start, end, name, version, vername, (my_context->elfs[0]==self || !self)?1:0, veropt))) {
+        if(elfsym) *elfsym = sym;
+        weak = 1;
+    }
     if(maplib)
     for(int i=0; i<maplib->libsz; ++i) {
-        if(GetLibWeakSymbolStartEnd(maplib->libraries[i], name, start, end, size, &weak, version, vername, isLocal(self, maplib->libraries[i]), weakdefver))
-            if(*start) {
-                ok = 1;
-            }
+        if(GetLibWeakSymbolStartEnd(maplib->libraries[i], name, start, end, size, &weak, version, vername, isLocal(self, maplib->libraries[i]), veropt, elfsym)) {
+            weak = 1;
+        }
     }
     // nope, not found
-    return (ok && *start)?1:0;
+    return weak;
 }
 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, const char* globdefver, const char* weakdefver)
+int GetGlobalSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, elfheader_t* self, int version, const char* vername, int veropt, void** elfsym)
 {
-    if(GetGlobalSymbolStartEnd_internal(maplib, name, start, end, self, version, vername, globdefver, weakdefver)) {
+    if(GetGlobalSymbolStartEnd_internal(maplib, name, start, end, self, &version, &vername, &veropt, elfsym)) {
         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*)malloc(strlen(name) + strlen("_END") + 1);
             strcpy(buff, name);
             strcat(buff, "_END");
-            if(GetGlobalSymbolStartEnd_internal(maplib, buff, &start2, &end2, self, version, vername, globdefver, weakdefver)) {
+            if(GetGlobalSymbolStartEnd_internal(maplib, buff, &start2, &end2, self, &version, &vername, &veropt, elfsym)) {
                 if(end2>*end && start2==end2)
                     *end = end2;
             }
@@ -571,63 +511,53 @@ int GetGlobalSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, u
     return 0;
 }
 
-static int GetGlobalWeakSymbolStartEnd_internal(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, elfheader_t* self, int version, const char* vername, const char* globdefver, const char* weakdefver)
+static int GetGlobalWeakSymbolStartEnd_internal(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, elfheader_t* self, int* version, const char** vername, int* veropt, void** elfsym)
 {
     int weak = 0;
     size_t size = 0;
+    void* sym;
     // search in needed libs from preloaded first, in order
     if(my_context->preload)
         for(int i=0; i<my_context->preload->size; ++i)
-            if(GetLibGlobalSymbolStartEnd(my_context->preload->libs[i], name, start, end, size, &weak, version, vername, isLocal(self, my_context->preload->libs[i]), globdefver))
-                if(*start)
-                    return 1;
+            if(GetLibGlobalSymbolStartEnd(my_context->preload->libs[i], name, start, end, size, &weak, version, vername, isLocal(self, my_context->preload->libs[i]), veropt, elfsym))
+                return 1;
     // search non-weak symbol, from older to newer (first GLOBAL object wins)
-    if(GetSymbolStartEnd(GetMapSymbols(my_context->elfs[0]), name, start, end, version, vername, (my_context->elfs[0]==self || !self)?1:0, globdefver))
-        if(*start)
-            return 1;
-    // This kind-of create a map to search lib only 1 time, and in order of needed...
-    if(my_context->neededlibs)
-        CheckNeededLibs(my_context->neededlibs);
-    // search in needed libs from neededlibs first, in order
-    if(my_context->neededlibs)
-        for(int i=0; i<my_context->neededlibs->size; ++i)
-            if(GetLibGlobalSymbolStartEnd(my_context->neededlibs->libs[i], name, start, end, size, &weak, version, vername, isLocal(self, my_context->neededlibs->libs[i]), globdefver))
-                if(*start)
-                    return 1;
-    // search in global symbols
+    if((sym = ElfGetGlobalSymbolStartEnd(my_context->elfs[0], start, end, name, version, vername, (my_context->elfs[0]==self || !self)?1:0, veropt))) {
+        if(elfsym) *elfsym = sym;
+        return 1;
+    }
     if(maplib)
     for(int i=0; i<maplib->libsz; ++i) {
-        if(GetLibGlobalSymbolStartEnd(maplib->libraries[i], name, start, end, size, &weak, version, vername, isLocal(self, maplib->libraries[i]), globdefver))
-            if(*start)
-                return 1;
+        if(GetLibGlobalSymbolStartEnd(maplib->libraries[i], name, start, end, size, &weak, version, vername, isLocal(self, maplib->libraries[i]), veropt, elfsym))
+            return 1;
     }
 
     // check with default version...
     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, weakdefver))
-        if(*start)
-            ok = 1;
+    if(( sym = ElfGetWeakSymbolStartEnd(my_context->elfs[0], start, end, name, version, vername, (my_context->elfs[0]==self || !self)?1:0, veropt))) {
+        if(elfsym) *elfsym = sym;
+        ok = 1;
+    }
 
     if(maplib)
     for(int i=0; i<maplib->libsz; ++i) {
-        if(GetLibWeakSymbolStartEnd(maplib->libraries[i], name, start, end, size, &weak, version, vername, isLocal(self, maplib->libraries[i]), weakdefver))
-            if(*start)
-                ok = 1;
+        if(GetLibWeakSymbolStartEnd(maplib->libraries[i], name, start, end, size, &weak, version, vername, isLocal(self, maplib->libraries[i]), veropt, elfsym))
+            ok = 1;
     }
     // nope, not found
-    return (ok && *start)?1:0;
+    return ok;
 }
 
-int GetGlobalWeakSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, elfheader_t* self, int version, const char* vername, const char* globdefver, const char* weakdefver)
+int GetGlobalWeakSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, elfheader_t* self, int version, const char* vername, int veropt, void** elfsym)
 {
-    if(GetGlobalWeakSymbolStartEnd_internal(maplib, name, start, end, self, version, vername, globdefver, weakdefver)) {
+    if(GetGlobalWeakSymbolStartEnd_internal(maplib, name, start, end, self, &version, &vername, &veropt, elfsym)) {
         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*)malloc(strlen(name) + strlen("_END") + 1);
             strcpy(buff, name);
             strcat(buff, "_END");
-            if(GetGlobalWeakSymbolStartEnd_internal(maplib, buff, &start2, &end2, self, version, vername, globdefver, weakdefver)) {
+            if(GetGlobalWeakSymbolStartEnd_internal(maplib, buff, &start2, &end2, self, &version, &vername, &veropt, elfsym)) {
                 if(end2>*end && start2==end2)
                     *end = end2;
             }
@@ -639,12 +569,14 @@ int GetGlobalWeakSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* star
     if(!strcmp(name, "gdk_display")) {
         *start = (uintptr_t)my_GetGTKDisplay();
         *end = *start+sizeof(void*);
+        if(elfsym) *elfsym = NULL;
         printf_log(LOG_INFO, "Using global gdk_display for gdk-x11 (%p:%p)\n", start, *(void**)start);
         return 1;
     }
     if(!strcmp(name, "g_threads_got_initialized")) {
         *start = (uintptr_t)my_GetGthreadsGotInitialized();
         *end = *start+sizeof(int);
+        if(elfsym) *elfsym = NULL;
         printf_log(LOG_INFO, "Using global g_threads_got_initialized for gthread2 (%p:%p)\n", start, *(void**)start);
         return 1;
     }
@@ -652,31 +584,7 @@ int GetGlobalWeakSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* star
     return 0;
 }
 
-static const char* internal_GetMaplibDefaultVersion(lib_t* maplib, int isweak, const char* symname)
-{
-    const char* ret = NULL;
-    for(int i=0; maplib && i<maplib->libsz; ++i) {
-        elfheader_t *h = GetElf(maplib->libraries[i]);
-        if(h)
-            ret = GetDefaultVersion(isweak?GetWeakDefaultVersion(h):GetGlobalDefaultVersion(h), symname);
-        if(ret)
-            return ret;
-    }
-    return ret;
-}
-const char* GetMaplibDefaultVersion(lib_t *maplib, lib_t* local_maplib, int isweak, int deepbind, const char* symname)
-{
-    const char* ret = GetDefaultVersion(isweak?GetWeakDefaultVersion(my_context->elfs[0]):GetGlobalDefaultVersion(my_context->elfs[0]), symname);
-    if(ret)
-        return ret;
-    ret = internal_GetMaplibDefaultVersion(deepbind?local_maplib:maplib, isweak, symname);
-    if(ret)
-        return ret;
-    ret = internal_GetMaplibDefaultVersion(deepbind?maplib:local_maplib, isweak, symname);
-    return ret;
-}
-
-elfheader_t* GetGlobalSymbolElf(lib_t *maplib, const char* name, int version, const char* vername)
+elfheader_t* GetGlobalSymbolElf(lib_t *maplib, const char* name, int version, const char* vername, int veropt)
 {
     uintptr_t start = 0;
     uintptr_t end = 0;
@@ -684,12 +592,10 @@ elfheader_t* GetGlobalSymbolElf(lib_t *maplib, const char* name, int version, co
     int weak = 0;
     elfheader_t* ret = NULL;
     // check with default version...
-    const char* defver = GetMaplibDefaultVersion(my_context->maplib, (my_context->maplib==maplib)?NULL:maplib, 0, 0, name);
-
-    if(GetSymbolStartEnd(GetMapSymbols(my_context->elfs[0]), name, &start, &end, version, vername, 1, defver))
+    if(ElfGetGlobalSymbolStartEnd(my_context->elfs[0], &start, &end, name, &version, &vername, 1, &veropt))
         return my_context->elfs[0];
     for(int i=0; i<maplib->libsz; ++i) {
-        if(GetLibGlobalSymbolStartEnd(maplib->libraries[i], name, &start, &end, size, &weak, version, vername, 1, defver)) {
+        if(GetLibGlobalSymbolStartEnd(maplib->libraries[i], name, &start, &end, size, &weak, &version, &vername, 1, &veropt, NULL)) {
             elfheader_t* h = GetElf(maplib->libraries[i]);
             if(!h) {
                 printf_log(LOG_NONE, "Warning, getting Elf info for a native symbol \"%s\" from lib \"%s\"\n", name, GetNameLib(maplib->libraries[i]));
@@ -702,11 +608,10 @@ elfheader_t* GetGlobalSymbolElf(lib_t *maplib, const char* name, int version, co
         }
     }
 
-    defver = GetMaplibDefaultVersion(my_context->maplib, (my_context->maplib==maplib)?NULL:maplib, 1, 0, name);
-    if(GetSymbolStartEnd(GetWeakSymbols(my_context->elfs[0]), name, &start, &end, version, vername, 1, defver))
+    if(ElfGetWeakSymbolStartEnd(my_context->elfs[0], &start, &end, name, &version, &vername, 1, &veropt))
         ret = my_context->elfs[0];
     for(int i=0; i<maplib->libsz; ++i) {
-        if(GetLibWeakSymbolStartEnd(maplib->libraries[i], name, &start, &end, size, &weak, version, vername, 1, defver)) {
+        if(GetLibWeakSymbolStartEnd(maplib->libraries[i], name, &start, &end, size, &weak, &version, &vername, 1, &veropt, NULL)) {
             elfheader_t* h = GetElf(maplib->libraries[i]);
             if(!h) {
                 printf_log(LOG_NONE, "Warning, getting Elf info for a native symbol \"%s\" from lib \"%s\"\n", name, GetNameLib(maplib->libraries[i]));
@@ -722,27 +627,29 @@ elfheader_t* GetGlobalSymbolElf(lib_t *maplib, const char* name, int version, co
     return ret;
 }
 
-int GetGlobalNoWeakSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, int version, const char* vername, const char* defver)
+int GetGlobalNoWeakSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, int version, const char* vername, int veropt, void** elfsym)
 {
     int weak = 0;
     size_t size = 0;
+    void* sym;
     // check global GLOB_DAT kind of symbols
-    if(GetSymbolStartEnd(GetGlobalData(maplib), name, start, end, version, vername, 1, defver))
-        if(*start || *end)
-            return 1;
+    if(GetSymbolStartEnd(GetGlobalData(maplib), name, start, end, version, vername, 1, veropt)) {
+        if(elfsym) *elfsym = NULL;
+        return 1;
+    }
     // check with default version...
-    if(GetSymbolStartEnd(GetMapSymbols(my_context->elfs[0]), name, start, end, version, vername, 1, defver))
-        if(*start || *end)
-            return 1;
+    if((sym = ElfGetGlobalSymbolStartEnd(my_context->elfs[0], start, end, name, &version, &vername, 1, &veropt))) {
+        if(elfsym) *elfsym = sym;
+        return 1;
+    }
     for(int i=0; i<maplib->libsz; ++i)
-        if(GetLibGlobalSymbolStartEnd(maplib->libraries[i], name, start, end, size, &weak, version, vername, 1, defver))
-            if(*start || *end)
-                return 1;
+        if(GetLibGlobalSymbolStartEnd(maplib->libraries[i], name, start, end, size, &weak, &version, &vername, 1, &veropt, elfsym))
+            return 1;
     // nope, not found
     return 0;
 }
 
-int IsGlobalNoWeakSymbolInNative(lib_t *maplib, const char* name, int version, const char* vername, const char* defver)
+int IsGlobalNoWeakSymbolInNative(lib_t *maplib, const char* name, int version, const char* vername, int veropt)
 {
     uintptr_t start, end;
     size_t size = 0;
@@ -750,33 +657,31 @@ int IsGlobalNoWeakSymbolInNative(lib_t *maplib, const char* name, int version, c
     // check with default version...
     for(int i=0; i<maplib->libsz; ++i)
         if(GetElfIndex(maplib->libraries[i])==-1)
-            if(GetLibGlobalSymbolStartEnd(maplib->libraries[i], name, &start, &end, size, &weak, version, vername, 1, defver))
-                if(start || end)
-                    return 1;
+            if(GetLibGlobalSymbolStartEnd(maplib->libraries[i], name, &start, &end, size, &weak, &version, &vername, 1, &veropt, NULL))
+                return 1;
     // nope, not found
     return 0;
 
 }
 
-int GetLocalSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, elfheader_t *self, int version, const char* vername, const char* globdefver, const char* weakdefver)
+int GetLocalSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, elfheader_t *self, int version, const char* vername, int veropt, void** elfsym)
 {
     // check with default version...
     int weak;
     size_t size = 0;
-    const char* defver = globdefver?globdefver:weakdefver;
-
+    void* sym;
     if(my_context->elfs[0]==self || !self) {
-        if(GetSymbolStartEnd(GetLocalSymbols(my_context->elfs[0]), name, start, end, version, vername, 1, defver))
-            if(*start || *end)
-                return 1;
+        if((sym = ElfGetLocalSymbolStartEnd(my_context->elfs[0], start, end, name, &version, &vername, 1, &veropt))) {
+            if(elfsym) *elfsym = sym;
+            return 1;
+        }
         if(self)
             return 0;
     }
     for(int i=0; i<maplib->libsz; ++i) {
         if(GetElfIndex(maplib->libraries[i])!=-1 && (!self || GetElf(maplib->libraries[i])==self)) {
-            if(GetLibLocalSymbolStartEnd(maplib->libraries[i], name, start, end, size, &weak, version, vername, 1, defver))
-                if(*start || *end)
-                    return 1;
+            if(GetLibLocalSymbolStartEnd(maplib->libraries[i], name, start, end, size, &weak, &version, &vername, 1, &veropt, elfsym))
+                return 1;
             if(self)
                 return 0;
         }
@@ -785,6 +690,18 @@ int GetLocalSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, ui
     return 0;
 }
 
+int GetSymTabStartEnd(lib_t* maplib, const char* name, uintptr_t* start, uintptr_t* end)
+{
+    if(!maplib)
+        return 0;
+    for(int i=0; i<maplib->libsz; ++i) {
+        elfheader_t* h = GetElf(maplib->libraries[i]);
+        if(h && ElfGetSymTabStartEnd(h, start, end, name))
+            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)
 {
diff --git a/src/librarian/librarian_private.h b/src/librarian/librarian_private.h
index 2991eb32..b36ed21a 100644
--- a/src/librarian/librarian_private.h
+++ b/src/librarian/librarian_private.h
@@ -18,7 +18,6 @@ typedef struct lib_s {
     library_t             **libraries;
     int                   libsz;
     int                   libcap;
-    int                   ownlibs;
     library_t             *owner;       // in case that maplib is owned by a lib
 } lib_t;
 
diff --git a/src/librarian/library.c b/src/librarian/library.c
index cb5862ee..e7ca6bd5 100644
--- a/src/librarian/library.c
+++ b/src/librarian/library.c
@@ -43,14 +43,6 @@ wrappedlib_t wrappedlibs[] = {
 };
 #undef GO
 
-typedef struct bridged_s {
-    char*       name;
-    uintptr_t   start;
-    uintptr_t   end;
-} bridged_t;
-
-KHASH_MAP_INIT_STR(bridgemap, bridged_t)
-
 KHASH_MAP_IMPL_STR(symbolmap, symbol1_t)
 KHASH_MAP_IMPL_STR(symbol2map, symbol2_t)
 KHASH_MAP_IMPL_STR(datamap, uint64_t)
@@ -123,13 +115,13 @@ void DummyLib_Fini(library_t* lib)
 {
 }
 
-int WrappedLib_GetWeak(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, size_t asked_size, int* weak, int version, const char* vername, int local, const char* defver)
+int WrappedLib_GetWeak(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, size_t asked_size, int* weak, int* version, const char** vername, int local, int* veropt, void** elfsym)
 {
     // ignoring asked size on wrapped libs
     uintptr_t addr = 0;
     uintptr_t size = 0;
     int wk = 0;
-    if (!getSymbolInMaps(lib, name, 0, &addr, &size, &wk, version, vername, local)) {
+    if (!getSymbolInMaps(lib, name, 0, &addr, &size, &wk, *version, *vername, local, *veropt)) {
         return 0;
     }
     if(!addr && !size)
@@ -139,34 +131,37 @@ int WrappedLib_GetWeak(library_t* lib, const char* name, uintptr_t *offs, uintpt
     *offs = addr;
     *sz = size;
     *weak = wk;
+    if(elfsym) *elfsym = NULL;
     return 1;
 }
-int EmuLib_GetWeak(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, size_t asked_size, int*weak, int version, const char* vername, int local, const char* defver)
+int EmuLib_GetWeak(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, size_t asked_size, int* weak, int* version, const char** vername, int local, int* veropt, void** elfsym)
 {
     // symbols...
     uintptr_t start, end;
     // weak symbols...
-    if(GetSizedSymbolStartEnd(GetWeakSymbols(lib->e.elf), name, &start, &end, asked_size, version, vername, local, defver))
+    void* sym;
+    if((sym = ElfGetWeakSymbolStartEnd(lib->e.elf, &start, &end, name, version, vername, local, veropt)))
     {
         *offs = start;
         *sz = end-start;
         *weak = 1;
+        if(elfsym) *elfsym = sym;
         return 1;
     }
     return 0;
 }
-int DummyLib_GetWeak(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, size_t asked_size, int* weak, int version, const char* vername, int local, const char* defver)
+int DummyLib_GetWeak(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, size_t asked_size, int* weak, int* version, const char** vername, int local, int* veropt, void** elfsym)
 {
     return 0;
 }
 
-int WrappedLib_GetGlobal(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, size_t asked_size, int* weak, int version, const char* vername, int local, const char* defver)
+int WrappedLib_GetGlobal(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, size_t asked_size, int* weak, int* version, const char** vername, int local, int* veropt, void** elfsym)
 {
     // ignoring asked size on wrapped libs
     uintptr_t addr = 0;
     uintptr_t size = 0;
     int wk = 0;
-    if (!getSymbolInMaps(lib, name, 1, &addr, &size, &wk, version, vername, local)) {
+    if (!getSymbolInMaps(lib, name, 1, &addr, &size, &wk, *version, *vername, local, *veropt)) {
         return 0;
     }
     if(!addr && !size)
@@ -176,44 +171,49 @@ int WrappedLib_GetGlobal(library_t* lib, const char* name, uintptr_t *offs, uint
     *offs = addr;
     *sz = size;
     *weak = 0;
+    if(elfsym) *elfsym = NULL;
     return 1;
 }
-int EmuLib_GetGlobal(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, size_t asked_size, int* weak, int version, const char* vername, int local, const char* defver)
+int EmuLib_GetGlobal(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, size_t asked_size, int* weak, int* version, const char** vername, int local, int* veropt, void** elfsym)
 {
     uintptr_t start, end;
-    if(GetSizedSymbolStartEnd(GetMapSymbols(lib->e.elf), name, &start, &end, asked_size, version, vername, local, defver))
+    void* sym;
+    if((sym = ElfGetGlobalSymbolStartEnd(lib->e.elf, &start, &end, name, version, vername, local, veropt)))
     {
         *offs = start;
         *sz = end-start;
         *weak = 0;
+        if(elfsym) *elfsym = sym;
         return 1;
     }
     return 0;
 }
-int DummyLib_GetGlobal(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, size_t asked_size, int* weak, int version, const char* vername, int local, const char* defver)
+int DummyLib_GetGlobal(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, size_t asked_size, int* weak, int* version, const char** vername, int local, int* veropt, void** elfsym)
 {
     return 0;
 }
-int EmuLib_GetLocal(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, size_t asked_size, int* weak, int version, const char* vername, int local, const char* defver)
+int EmuLib_GetLocal(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, size_t asked_size, int* weak, int* version, const char** vername, int local, int* veropt, void** elfsym)
 {
     // ignoring asked size on wrapped libs
     uintptr_t start, end;
-    if(GetSymbolStartEnd(GetLocalSymbols(lib->e.elf), name, &start, &end, version, vername, local, defver))
+    void* sym;
+    if((sym = ElfGetLocalSymbolStartEnd(lib->e.elf, &start, &end, name, version, vername, local, veropt)))
     {
         *offs = start;
         *sz = end-start;
         *weak = 0;
+        if(elfsym) *elfsym = sym;
         return 1;
     }
     return 0;
 }
 
-int WrappedLib_GetLocal(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, size_t asked_size, int* weak, int version, const char* vername, int local, const char* defver)
+int WrappedLib_GetLocal(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, size_t asked_size, int* weak, int* version, const char** vername, int local, int* veropt, void** elfsym)
 {
     (void)lib; (void)name; (void)offs; (void)sz; (void)version; (void)vername; (void)local;
     return 0;
 }
-int DummyLib_GetLocal(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, size_t asked_size, int* weak, int version, const char* vername, int local, const char* defver)
+int DummyLib_GetLocal(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, size_t asked_size, int* weak, int* version, const char** vername, int local, int* veropt, void** elfsym)
 {
     (void)lib; (void)name; (void)offs; (void)sz; (void)version; (void)vername; (void)local;
     return 0;
@@ -483,9 +483,6 @@ library_t *NewLibrary(const char* path, box64context_t* context, elfheader_t* ve
         //box_free(lib);
         return NULL;
     }
-    lib->gbridgemap = kh_init(bridgemap);
-    lib->wbridgemap = kh_init(bridgemap);
-    lib->lbridgemap = kh_init(bridgemap);
 
     return lib;
 }
@@ -496,7 +493,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, GetMapSymbols(lib->e.elf), GetWeakSymbols(lib->e.elf), GetLocalSymbols(lib->e.elf), elf_header);
+        AddSymbols(maplib, elf_header);
     }
     return 0;
 }
@@ -522,12 +519,14 @@ int FinalizeLibrary(library_t* lib, lib_t* local_maplib, int bindnow, int deepbi
 #ifdef HAVE_TRACE
         if(trace_func) {
             int weak;
-            if (GetGlobalSymbolStartEnd(local_maplib, trace_func, &trace_start, &trace_end, elf_header, -1, NULL, NULL, NULL)) {
+            int ver = -1, veropt = 0;
+            const char* vername = NULL;
+            if (GetGlobalSymbolStartEnd(local_maplib, trace_func, &trace_start, &trace_end, elf_header, ver, vername, veropt, NULL)) {
                 SetTraceEmu(trace_start, trace_end);
                 printf_dump(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, 0, &weak, -1, NULL, 0, NULL)) {
+            } else if(GetLibLocalSymbolStartEnd(lib, trace_func, &trace_start, &trace_end, 0, &weak, &ver, &vername, 0, &veropt, NULL)) {
                 SetTraceEmu(trace_start, trace_end);
                 printf_dump(LOG_INFO, "TRACE on %s only (%p-%p)\n", trace_func, (void*)trace_start, (void*)trace_end);
                 box_free(trace_func);
@@ -565,42 +564,33 @@ void Free1Library(library_t **the_lib, x64emu_t* emu)
         MapLibRemoveLib(my_context->local_maplib, lib);
     }
     // free elf is relevant
-    if(lib->type==LIB_EMULATED) {
+    int lib_type = lib->type;
+    // Handle needed for cleaning
+    needed_libs_t* needed = (lib_type==LIB_EMULATED && lib->e.elf)?lib->e.elf->needed:((lib_type==LIB_WRAPPED)?lib->w.needed:NULL);
+    // handle needed libs now
+    if(needed)
+        for(int i=0; i<needed->size; ++i)
+            DecRefCount(&needed->libs[i], emu);
+    // free elf
+    if(lib_type==LIB_EMULATED) {
         FreeElfHeader(&lib->e.elf);
     }
 
     // No "Fini" logic here, only memory handling
-    if(lib->maplib)
-        FreeLibrarian(&lib->maplib, emu);
-
-    if(lib->type!=LIB_UNNKNOW && lib->fini) {
+    if(lib->maplib && !lib->maplib_ref) {
+        lib_t* maplib = lib->maplib;
+        lib->maplib = NULL;
+        FreeLibrarian(&maplib, emu);
+    }
+    lib->maplib = NULL;
+    lib->maplib_ref = 0;
+    if(lib_type!=LIB_UNNKNOW && lib->fini) {
         lib->fini(lib);
     }
     box_free(lib->name);
     box_free(lib->path);
 
-    if(lib->gbridgemap) {
-        bridged_t *br;
-        kh_foreach_value_ref(lib->gbridgemap, br,
-            box_free(br->name);
-        );
-        kh_destroy(bridgemap, lib->gbridgemap);
-    }
-    if(lib->wbridgemap) {
-        bridged_t *br;
-        kh_foreach_value_ref(lib->wbridgemap, br,
-            box_free(br->name);
-        );
-        kh_destroy(bridgemap, lib->wbridgemap);
-    }
-    if(lib->lbridgemap) {
-        bridged_t *br;
-        kh_foreach_value_ref(lib->lbridgemap, br,
-            box_free(br->name);
-        );
-        kh_destroy(bridgemap, lib->lbridgemap);
-    }
-    if(lib->type == LIB_WRAPPED) {
+    if(lib_type == LIB_WRAPPED) {
         if(lib->w.symbolmap)
             kh_destroy(symbolmap, lib->w.symbolmap);
         if(lib->w.wsymbolmap)
@@ -671,81 +661,37 @@ int IsSameLib(library_t* lib, const char* path)
     box_free(name);
     return ret;
 }
-int GetLibWeakSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start, uintptr_t* end, size_t size, int* weak, int version, const char* vername, int local, const char* defver)
+int GetLibWeakSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start, uintptr_t* end, size_t size, int* weak, int* version, const char** vername, int local, int* veropt, void** elfsym)
 {
     if(!name[0] || !lib || (lib->type==LIB_UNNKNOW))
         return 0;
-    khint_t k;
-    kh_bridgemap_t *map = local?lib->lbridgemap:((*weak)?lib->wbridgemap:lib->gbridgemap);
-    // check first if already in the map
-    k = kh_get(bridgemap, map, VersionedName(name, version, vername));
-    if(k!=kh_end(map)) {
-        *start = kh_value(map, k).start;
-        *end = kh_value(map, k).end;
-        return 1;
-    }
     // get a new symbol
-    if(lib->getweak(lib, name, start, end, size, weak, version, vername, local, defver)) {
+    if(lib->getweak(lib, name, start, end, size, weak, version, vername, local, veropt, elfsym)) {
         *end += *start;     // lib->get(...) gives size, not end
-        char* symbol = box_strdup(VersionedName(name, version, vername));
-        int ret;
-        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 GetLibGlobalSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start, uintptr_t* end, size_t size, int* weak, int version, const char* vername, int local, const char* defver)
+int GetLibGlobalSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start, uintptr_t* end, size_t size, int* weak, int* version, const char** vername, int local, int* veropt, void** elfsym)
 {
     if(!name[0] || !lib || (lib->type==LIB_UNNKNOW))
         return 0;
-    khint_t k;
-    kh_bridgemap_t *map = local?lib->lbridgemap:((*weak)?lib->wbridgemap:lib->gbridgemap);
-    // check if already in the map
-    k = kh_get(bridgemap, map, VersionedName(name, version, vername));
-    if(k!=kh_end(map)) {
-        *start = kh_value(map, k).start;
-        *end = kh_value(map, k).end;
-        return 1;
-    }
     // get a new symbol
-    if(lib->getglobal(lib, name, start, end, size, weak, version, vername, local, defver)) {
+    if(lib->getglobal(lib, name, start, end, size, weak, version, vername, local, veropt, elfsym)) {
         *end += *start;     // lib->get(...) gives size, not end
-        char* symbol = box_strdup(VersionedName(name, version, vername));
-        int ret;
-        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, size_t size, int* weak, int version, const char* vername, int local, const char* defver)
+int GetLibLocalSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start, uintptr_t* end, size_t size, int* weak, int* version, const char** vername, int local, int* veropt, void** elfsym)
 {
     if(!name[0] || !lib || (lib->type==LIB_UNNKNOW))
         return 0;
-    khint_t k;
-    // check first if already in the map
-    k = kh_get(bridgemap, lib->lbridgemap, VersionedName(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, size, weak, version, vername, local, defver)) {
+    if(lib->getlocal(lib, name, start, end, size, weak, version, vername, local, veropt, elfsym)) {
         *end += *start;     // lib->get(...) gives size, not end
-        char* symbol = box_strdup(VersionedName(name, version, vername));
-        int ret;
-        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
@@ -981,7 +927,7 @@ static int getSymbolInSymbolMaps(library_t*lib, const char* name, int noweak, ui
     return 0;
 }
 
-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)
+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, int veropt)
 {
     if(version==-2) // don't send global native symbol for a version==-2 search
         return 0;
@@ -1191,18 +1137,11 @@ void IncRefCount(library_t* lib, x64emu_t* emu)
             if(lib->w.refcnt==LIB_MAXCNT)
                 return;
             ++lib->w.refcnt;
-            if(lib->w.needed)
-                for(int i=0; i<lib->w.needed->size; ++i) {
-                    IncRefCount(lib->w.needed->libs[i], emu);
-                }
             break;
         case LIB_EMULATED:
             if(lib->e.elf->refcnt==LIB_MAXCNT)
                 return;
             ++lib->e.elf->refcnt;
-            if(lib->e.elf->needed)
-                for(int i=0; i<lib->e.elf->needed->size; ++i)   // some libs may not be loaded yet
-                    IncRefCount(lib->e.elf->needed->libs[i], emu);
     }
 }
 
@@ -1215,39 +1154,29 @@ int DecRefCount(library_t** lib, x64emu_t* emu)
         return 0;
     }
     int ret = 1;
-    needed_libs_t* needed = NULL;
-    int freed = 0;
     switch ((*lib)->type) {
         case LIB_WRAPPED:
             if((*lib)->w.refcnt==LIB_MAXCNT)
                 return ret;
-            needed = (*lib)->w.needed;
             ret=--(*lib)->w.refcnt;
             if(!ret) {
-                needed = copy_neededlib(needed);
-                freed=1;
                 Free1Library(lib, emu);
             }
             break;
         case LIB_EMULATED:
-            if((*lib)->e.elf->refcnt==LIB_MAXCNT)
-                return ret;
-            needed = (*lib)->e.elf->needed;
-            ret=--(*lib)->e.elf->refcnt;
+            if(!(*lib)->e.elf)
+                ret = 0;
+            else {
+                if((*lib)->e.elf->refcnt==LIB_MAXCNT)
+                    return ret;
+                ret=--(*lib)->e.elf->refcnt;
+            }
             if(!ret) {
-                needed = copy_neededlib(needed);
-                freed=1;
-                removeLinkMapLib(*lib);
                 FiniLibrary(*lib, emu);
                 Free1Library(lib, emu);
             }
             break;
     }
-    if(needed)
-        for(int i=0; i<needed->size; ++i)
-            DecRefCount(&needed->libs[i], emu);
-    if(freed)
-        free_neededlib(needed);
     return ret;
 }
 
diff --git a/src/librarian/library_private.h b/src/librarian/library_private.h
index b7e1e45d..1da4c264 100644
--- a/src/librarian/library_private.h
+++ b/src/librarian/library_private.h
@@ -11,7 +11,6 @@
 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;
 
@@ -80,9 +79,7 @@ typedef struct library_s {
         elib_t  e;
     };                              // private lib data
     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
+    int                 maplib_ref;     // ref to maplib (not owned)
     size_t              dlopen;   // idx to the dlopen idx (or 0 if not dlopen)
 } library_t;
 
@@ -104,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 *weak, 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, int veropt);  // 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 ddebbe75..d8cbdb31 100644
--- a/src/librarian/symbols.c
+++ b/src/librarian/symbols.c
@@ -18,6 +18,7 @@ typedef struct onesymbol_s {
 
 typedef struct versymbol_s {
     int         version;    // -1 = no-version, 0=local, 1=global, X=versioned
+    int         veropt;
     const char* vername;    // NULL or version name if version=X
     onesymbol_t sym;
 } versymbol_t;
@@ -48,10 +49,14 @@ void FreeMapSymbols(kh_mapsymbols_t** map)
 }
 
 // Exact same version (ver<2 or vername if ver>=2)
-static int SameVersion(versymbol_t* s, int ver, const char* vername)
+static int SameVersion(versymbol_t* s, int ver, const char* vername, int veropt)
 {
+    if(ver<2 && s->veropt)
+        return 1;
     if(ver<2)
         return (s->version == ver)?1:0;
+    if(ver>1 && veropt && s->version<2)
+        return 1;
     if(s->vername && !strcmp(s->vername, vername))
         return 1;
     return 0;
@@ -80,9 +85,12 @@ static versymbol_t* FindVersionGlobal(versymbols_t* s, size_t size)
 {
     if(!s || !s->sz)
         return NULL;
-    for (int i=0; i<s->sz; ++i)
+    for (int i=0; i<s->sz; ++i) {
         if(s->syms[i].version==1 && (!size || (size==s->syms[i].sym.sz)))
             return &s->syms[i];
+        if(s->syms[i].version>1 && s->syms[i].veropt && (!size || (size==s->syms[i].sym.sz)))
+            return &s->syms[i];
+    }
     return NULL;
 }
 static versymbol_t* FindVersion(versymbols_t* s, size_t size, const char* vername)
@@ -105,7 +113,7 @@ static versymbol_t* FindFirstVersion(versymbols_t* s, size_t size)
 }
 
 // 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, size_t size, int local, const char* defver)
+static versymbol_t* MatchVersion(versymbols_t* s, int ver, const char* vername, size_t size, int local, int veropt)
 {
     if(!s || !s->sz)
         return NULL;
@@ -114,14 +122,12 @@ static versymbol_t* MatchVersion(versymbols_t* s, int ver, const char* vername,
         if(local) ret = FindVersionLocal(s, size);
         if(!ret) ret = FindNoVersion(s, size);
         if(!ret) ret = FindVersionGlobal(s, size);
-        if(!ret && defver) ret = FindVersion(s, size, defver);
         return ret;
     }
     if(ver==-1) {
         if(local) ret = FindVersionLocal(s, size);
         if(!ret) ret = FindNoVersion(s, size);
         if(!ret) ret = FindVersionGlobal(s, size);
-        if(!ret && defver) ret = FindVersion(s, size, defver);
         //if(!ret) ret = FindFirstVersion(s, size);
         return ret;
     }
@@ -134,18 +140,20 @@ static versymbol_t* MatchVersion(versymbols_t* s, int ver, const char* vername,
         if(local) ret = FindVersionLocal(s, size);
         if(!ret) ret = FindVersionGlobal(s, size);
         if(!ret) ret = FindNoVersion(s, size);
-        if(!ret && defver) ret = FindVersion(s, size, defver);
         //if(!ret) ret = FindFirstVersion(s);
         return ret;
     }
+    if(veropt && ver>1) {
+        ret = FindVersionGlobal(s, size);
+        if(ret) return ret;
+    }
     ret = FindVersion(s, size, vername);
     if(local && !ret) ret = FindVersionLocal(s, size);
-    if(!ret && defver && vername && !strcmp(defver, vername)) ret = FindVersionGlobal(s, size);
     //if(!ret) return FindVersionGlobal(s);
     return ret;
 }
 
-void AddSymbol(kh_mapsymbols_t *mapsymbols, const char* name, uintptr_t addr, uint32_t sz, int ver, const char* vername)
+void AddSymbol(kh_mapsymbols_t *mapsymbols, const char* name, uintptr_t addr, uint32_t sz, int ver, const char* vername, int veropt)
 {
     int ret;
     khint_t k = kh_put(mapsymbols, mapsymbols, name, &ret);
@@ -153,7 +161,7 @@ void AddSymbol(kh_mapsymbols_t *mapsymbols, const char* name, uintptr_t addr, ui
     if(ret) {v->sz = v->cap = 0; v->syms = NULL;}
     // now check if that version already exist, and update record and exit if yes
     for(int i=0; i<v->sz; ++i)
-        if(SameVersion(&v->syms[i], ver, vername)) {
+        if(SameVersion(&v->syms[i], ver, vername, veropt)) {
             v->syms[i].sym.offs = addr;
             v->syms[i].sym.sz = sz;
             return;
@@ -183,7 +191,7 @@ void ForceUpdateSymbol(kh_mapsymbols_t *mapsymbols, const char* name, uintptr_t
     }
 }
 
-uintptr_t FindSymbol(kh_mapsymbols_t *mapsymbols, const char* name, int ver, const char* vername, int local, const char* defver)
+uintptr_t FindSymbol(kh_mapsymbols_t *mapsymbols, const char* name, int ver, const char* vername, int local, int veropt)
 {
     if(!mapsymbols)
         return 0;
@@ -191,13 +199,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, 0, local, defver);
+    versymbol_t * s = MatchVersion(v, ver, vername, 0, local, veropt);
     if(s)
         return s->sym.offs;
     return 0;
 }
 
-void AddUniqueSymbol(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 veropt)
 {
     int ret;
     khint_t k = kh_put(mapsymbols, mapsymbols, name, &ret);
@@ -205,7 +213,7 @@ void AddUniqueSymbol(kh_mapsymbols_t *mapsymbols, const char* name, uintptr_t ad
     if(ret) {v->sz = v->cap = 0; v->syms = NULL;}
     // now check if that version already exist, and exit if yes
     for(int i=0; i<v->sz; ++i)
-        if(SameVersion(&v->syms[i], ver, vername)) {
+        if(SameVersion(&v->syms[i], ver, vername, veropt)) {
             return;
         }
     // add a new record
@@ -218,9 +226,10 @@ void AddUniqueSymbol(kh_mapsymbols_t *mapsymbols, const char* name, uintptr_t ad
     v->syms[idx].vername = vername;
     v->syms[idx].sym.offs = addr;
     v->syms[idx].sym.sz = sz;
+    v->syms[idx].veropt = veropt;
 }
 
-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)
+int GetSymbolStartEnd(kh_mapsymbols_t* mapsymbols, const char* name, uintptr_t* start, uintptr_t* end, int ver, const char* vername, int local, int veropt)
 {
     if(!mapsymbols)
         return 0;
@@ -228,7 +237,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, 0, local, defver);
+    versymbol_t* s = MatchVersion(v, ver, vername, 0, local, veropt);
     if(s) {
         if(start) *start = s->sym.offs;
         if(end) *end = *start + s->sym.sz;
@@ -237,7 +246,7 @@ int GetSymbolStartEnd(kh_mapsymbols_t* mapsymbols, const char* name, uintptr_t*
     return 0;
 }
 
-int GetSizedSymbolStartEnd(kh_mapsymbols_t* mapsymbols, const char* name, uintptr_t* start, uintptr_t* end, size_t size, int ver, const char* vername, int local, const char* defver)
+int GetSizedSymbolStartEnd(kh_mapsymbols_t* mapsymbols, const char* name, uintptr_t* start, uintptr_t* end, size_t size, int ver, const char* vername, int local, int veropt)
 {
     if(!mapsymbols)
         return 0;
@@ -245,7 +254,7 @@ int GetSizedSymbolStartEnd(kh_mapsymbols_t* mapsymbols, const char* name, uintpt
     if(k==kh_end(mapsymbols))
         return 0;
     versymbols_t * v = &kh_val(mapsymbols, k);
-    versymbol_t* s = MatchVersion(v, ver, vername, size, local, defver);
+    versymbol_t* s = MatchVersion(v, ver, vername, size, local, veropt);
     if(s) {
         *start = s->sym.offs;
         *end = *start + s->sym.sz;
@@ -270,38 +279,3 @@ 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, box_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) = box_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;
-    else
-        return kh_value(def, k);
-}
diff --git a/src/libtools/sdl2rwops.c b/src/libtools/sdl2rwops.c
index 085c7837..1273d36c 100644
--- a/src/libtools/sdl2rwops.c
+++ b/src/libtools/sdl2rwops.c
@@ -121,8 +121,8 @@ static void checkSDL2isNative()
 {
     if(my_context->sdl2allocrw)
         return;
-    emulated_sdl2allocrw = FindGlobalSymbol(my_context->maplib, "SDL_AllocRW", -1, NULL);
-    emulated_sdl2freerw = FindGlobalSymbol(my_context->maplib, "SDL_FreeRW", -1, NULL);
+    emulated_sdl2allocrw = FindGlobalSymbol(my_context->maplib, "SDL_AllocRW", -1, NULL, 0);
+    emulated_sdl2freerw = FindGlobalSymbol(my_context->maplib, "SDL_FreeRW", -1, NULL, 0);
     if(emulated_sdl2allocrw && emulated_sdl2freerw) {
         my_context->sdl2allocrw = my_wrapped_sdl2allocrw;
         my_context->sdl2freerw = my_wrapped_sdl2freerw;
diff --git a/src/libtools/signals.c b/src/libtools/signals.c
index 079a5780..8a3294f5 100644
--- a/src/libtools/signals.c
+++ b/src/libtools/signals.c
@@ -1386,7 +1386,8 @@ void my_box64signalhandler(int32_t sig, siginfo_t* info, void * ucntx)
             dynarec_log(LOG_INFO, "Warning, addr inside current dynablock!\n");
         }
         // mark stuff as unclean
-        cleanDBFromAddressRange(((uintptr_t)addr)&~(box64_pagesize-1), box64_pagesize, 0);
+        if(box64_dynarec)
+            cleanDBFromAddressRange(((uintptr_t)addr)&~(box64_pagesize-1), box64_pagesize, 0);
         static void* glitch_pc = NULL;
         static void* glitch_addr = NULL;
         static uint32_t glitch_prot = 0;
@@ -1511,7 +1512,7 @@ dynarec_log(/*LOG_DEBUG*/LOG_INFO, "Repeated SIGSEGV with Access error on %p for
 #error Unsupported Architecture
 #endif //arch
 #endif //DYNAREC
-        if(!db && (sig==SIGSEGV) && ((uintptr_t)addr==x64pc-1))
+        if(!db && (sig==SIGSEGV) && ((uintptr_t)addr==(x64pc-1)))
             x64pc--;
         if(log_minimum<=box64_log) {
             signal_jmpbuf_active = 1;
@@ -1632,7 +1633,7 @@ dynarec_log(/*LOG_DEBUG*/LOG_INFO, "Repeated SIGSEGV with Access error on %p for
             if(db)
                 hash = X31_hash_code(db->x64_addr, db->x64_size);
             printf_log(log_minimum, "%04d|%s @%p (%s) (x64pc=%p/%s:\"%s\", rsp=%p, stack=%p:%p own=%p fp=%p), for accessing %p (code=%d/prot=%x), db=%p(%p:%p/%p:%p/%s:%s, hash:%x/%x) handler=%p",
-                GetTID(), signame, pc, name, (void*)x64pc, elfname?elfname:"???", x64name?x64name:"???", rsp,
+                GetTID(), signame, pc, name, (void*)x64pc, elfname?:"???", x64name?:"???", rsp,
                 emu->init_stack, emu->init_stack+emu->size_stack, emu->stack2free, (void*)R_RBP,
                 addr, info->si_code,
                 prot, db, db?db->block:0, db?(db->block+db->size):0,
@@ -1674,7 +1675,7 @@ dynarec_log(/*LOG_DEBUG*/LOG_INFO, "Repeated SIGSEGV with Access error on %p for
             #warning TODO
 #endif
 #else
-            printf_log(log_minimum, "%04d|%s @%p (%s) (x64pc=%p/%s:\"%s\", rsp=%p), for accessing %p (code=%d)", GetTID(), signame, pc, name, (void*)x64pc, elfname?elfname:"???", x64name?x64name:"???", rsp, addr, info->si_code);
+            printf_log(log_minimum, "%04d|%s @%p (%s) (x64pc=%p/%s:\"%s\", rsp=%p), for accessing %p (code=%d)", GetTID(), signame, pc, name, (void*)x64pc, elfname?:"???", x64name?:"???", rsp, addr, info->si_code);
 #endif
             if(!shown_regs) {
                 for (int i=0; i<16; ++i) {
diff --git a/src/main.c b/src/main.c
index 7c74bc5a..b3363338 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1221,6 +1221,7 @@ void LoadEnvVars(box64context_t *context)
     AddPath("libpng12.so.0", &context->box64_emulated_libs, 0);
     AddPath("libcurl.so.4", &context->box64_emulated_libs, 0);
     AddPath("libtbbmalloc.so.2", &context->box64_emulated_libs, 0);
+    AddPath("libtbbmalloc_proxy.so.2", &context->box64_emulated_libs, 0);
 
     if(getenv("BOX64_SSE_FLUSHTO0")) {
         if (strcmp(getenv("BOX64_SSE_FLUSHTO0"), "1")==0) {
@@ -1312,10 +1313,10 @@ void setupTraceInit()
             if(s_trace_start || s_trace_end)
                 SetTraceEmu(s_trace_start, s_trace_end);
         } else {
-            if (GetGlobalSymbolStartEnd(my_context->maplib, p, &s_trace_start, &s_trace_end, NULL, -1, NULL, NULL, NULL)) {
+            if (GetGlobalSymbolStartEnd(my_context->maplib, p, &s_trace_start, &s_trace_end, NULL, -1, NULL, 0, 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 if(GetLocalSymbolStartEnd(my_context->maplib, p, &s_trace_start, &s_trace_end, NULL, -1, NULL, NULL, NULL)) {
+            } else if(GetLocalSymbolStartEnd(my_context->maplib, p, &s_trace_start, &s_trace_end, NULL, -1, NULL, 0, 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 {
@@ -1332,6 +1333,54 @@ void setupTraceInit()
 #endif
 }
 
+void setupTraceMapLib(lib_t* maplib)
+{
+    if(!trace_func)
+        return;
+    char* p = trace_func;
+    uintptr_t s_trace_start=0, s_trace_end=0;
+    if(maplib) {
+        if (GetGlobalSymbolStartEnd(maplib, p, &s_trace_start, &s_trace_end, NULL, -1, NULL, 0, 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);
+            box_free(trace_func);
+            trace_func = NULL;
+            return;
+        } else if(GetLocalSymbolStartEnd(maplib, p, &s_trace_start, &s_trace_end, NULL, -1, NULL, 0, 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);
+            box_free(trace_func);
+            trace_func = NULL;
+            return;
+        } else if(GetSymTabStartEnd(maplib, p, &s_trace_start, &s_trace_end)) {
+            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);
+            box_free(trace_func);
+            trace_func = NULL;
+            return;
+        }
+    }
+    if (my_context->elfs && GetGlobalSymbolStartEnd(my_context->maplib, p, &s_trace_start, &s_trace_end, NULL, -1, NULL, 0, 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);
+        box_free(trace_func);
+        trace_func = NULL;
+    } else if(my_context->elfs && GetLocalSymbolStartEnd(my_context->maplib, p, &s_trace_start, &s_trace_end, NULL, -1, NULL, 0, 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);
+        box_free(trace_func);
+        trace_func = NULL;
+    } else if(GetSymTabStartEnd(my_context->maplib, p, &s_trace_start, &s_trace_end)) {
+        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);
+        box_free(trace_func);
+        trace_func = NULL;
+    } else {
+        printf_log(LOG_NONE, "Warning, Symbol to trace (\"%s\") not found. Trying to set trace later\n", p);
+        SetTraceEmu(0, 1);  // disabling trace, mostly
+    }
+}
+
 EXPORTDYN
 void setupTrace()
 {
@@ -1356,10 +1405,10 @@ void setupTrace()
                 }
             }
         } else {
-            if (my_context->elfs && GetGlobalSymbolStartEnd(my_context->maplib, p, &s_trace_start, &s_trace_end, NULL, -1, NULL, NULL, NULL)) {
+            if (my_context->elfs && GetGlobalSymbolStartEnd(my_context->maplib, p, &s_trace_start, &s_trace_end, NULL, -1, NULL, 0, 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 if(my_context->elfs && GetLocalSymbolStartEnd(my_context->maplib, p, &s_trace_start, &s_trace_end, NULL, -1, NULL, NULL, NULL)) {
+            } else if(my_context->elfs && GetLocalSymbolStartEnd(my_context->maplib, p, &s_trace_start, &s_trace_end, NULL, -1, NULL, 0, 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 {
@@ -1981,11 +2030,14 @@ int main(int argc, const char **argv, char **env) {
     thread_set_emu(emu);
 
     // export symbols
-    AddSymbols(my_context->maplib, GetMapSymbols(elf_header), GetWeakSymbols(elf_header), GetLocalSymbols(elf_header), elf_header);
+    AddSymbols(my_context->maplib, elf_header);
     if(wine_preloaded) {
-        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);
+        uintptr_t wineinfo = 0;
+        int ver = -1, veropt = 0;
+        const char* vername = NULL;
+        if(!ElfGetGlobalSymbolStartEnd(elf_header, &wineinfo, NULL, "wine_main_preload_info", &ver, &vername, 1, &veropt))
+            if(!ElfGetWeakSymbolStartEnd(elf_header, &wineinfo, NULL, "wine_main_preload_info", &ver, &vername, 1, &veropt))
+                if(!ElfGetLocalSymbolStartEnd(elf_header, &wineinfo, NULL, "wine_main_preload_info", &ver, &vername, 1, &veropt))
         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/mallochook.c b/src/mallochook.c
index 3d50d219..4c636dd4 100644
--- a/src/mallochook.c
+++ b/src/mallochook.c
@@ -778,7 +778,8 @@ void checkHookedSymbols(elfheader_t* h)
         return;
     for (size_t i=0; i<h->numSymTab; ++i) {
         int type = ELF64_ST_TYPE(h->SymTab[i].st_info);
-        if(type==STT_FUNC) {
+        int sz = ELF64_ST_TYPE(h->SymTab[i].st_size);
+        if(type==STT_FUNC && sz) {
             const char * symname = h->StrTab+h->SymTab[i].st_name;
             #define GO(A, B) if(!strcmp(symname, #A)) ++hooked; else if(!strcmp(symname, "__libc_" #A)) ++hooked;
             #define GO2(A, B)
@@ -824,7 +825,7 @@ void checkHookedSymbols(elfheader_t* h)
                 #undef GO
                 #undef GO2
                 #define GO(A, B) if(!strcmp(symname, #A)) {uintptr_t alt = AddCheckBridge(my_context->system, B, A, 0, #A); printf_log(LOG_DEBUG, "Redirecting %s function from %p (%s)\n", symname, (void*)offs, ElfName(h)); addRelocJmp((void*)offs, (void*)alt, sz, #A, h, &real_##A);}
-                #define GO2(A, B) if(!strcmp(symname, #A)) {uintptr_t alt = AddCheckBridge(my_context->system, B, my_##A, 0, "my_" #A); printf_log(LOG_DEBUG, "Redirecting %s function from %p (%s)\n", symname, (void*)offs, ElfName(h)); addRelocJmp((void*)offs, (void*)alt, sz, "my_" #A, h, &real_##A);}
+                #define GO2(A, B) if(!strcmp(symname, #A) && (box64_malloc_hack>1)) {uintptr_t alt = AddCheckBridge(my_context->system, B, my_##A, 0, "my_" #A); printf_log(LOG_DEBUG, "Redirecting %s function from %p (%s)\n", symname, (void*)offs, ElfName(h)); addRelocJmp((void*)offs, (void*)alt, sz, "my_" #A, h, &real_##A);}
                 SUPER()
                 #undef GO
                 #undef GO2
@@ -847,7 +848,7 @@ void checkHookedSymbols(elfheader_t* h)
                     #undef GO
                     #undef GO2
                     #define GO(A, B) if(!strcmp(symname, #A)) {uintptr_t alt = AddCheckBridge(my_context->system, B, A, 0, #A); printf_log(LOG_DEBUG, "Redirecting %s function from %p (%s)\n", symname, (void*)offs, ElfName(h)); addRelocJmp((void*)offs, (void*)alt, sz, #A, h, &real_##A);}
-                    #define GO2(A, B) if(!strcmp(symname, #A)) {uintptr_t alt = AddCheckBridge(my_context->system, B, my_##A, 0, "my_" #A); printf_log(LOG_DEBUG, "Redirecting %s function from %p (%s)\n", symname, (void*)offs, ElfName(h)); addRelocJmp((void*)offs, (void*)alt, sz, "my_" #A, h, &real_##A);}
+                    #define GO2(A, B) if(!strcmp(symname, #A) && (box64_malloc_hack>1)) {uintptr_t alt = AddCheckBridge(my_context->system, B, my_##A, 0, "my_" #A); printf_log(LOG_DEBUG, "Redirecting %s function from %p (%s)\n", symname, (void*)offs, ElfName(h)); addRelocJmp((void*)offs, (void*)alt, sz, "my_" #A, h, &real_##A);}
                     SUPER()
                     #undef GO
                     #undef GO2
diff --git a/src/tools/bridge.c b/src/tools/bridge.c
index c12bc706..fd53c255 100644
--- a/src/tools/bridge.c
+++ b/src/tools/bridge.c
@@ -229,7 +229,7 @@ uintptr_t AddVSyscall(bridge_t* bridge, int num)
 
 const char* getBridgeName(void* addr)
 {
-    onebridge_t* one = (onebridge_t*)(((uintptr_t)addr/sizeof(onebridge_t))*sizeof(onebridge_t));   // align to start of bridge
+    onebridge_t* one = (onebridge_t*)(((uintptr_t)addr&~(sizeof(onebridge_t)-1)));   // align to start of bridge
     if(one->C3==0xC3 && one->S=='S' && one->C=='C')
         return one->name;
     return NULL;
diff --git a/src/wrapped/wrappedgtk3.c b/src/wrapped/wrappedgtk3.c
index 92192fcb..77611a34 100644
--- a/src/wrapped/wrappedgtk3.c
+++ b/src/wrapped/wrappedgtk3.c
@@ -685,7 +685,7 @@ static void my3_gtk_builder_connect_signals_default(void* builder, void* object,
   }
   // Mixing Native and emulated code... the my_g_signal_* function will handle that (GetNativeFnc does)
   if(!func)
-      func = (void*)FindGlobalSymbol(my_context->maplib, handler_name, 0, NULL);
+      func = (void*)FindGlobalSymbol(my_context->maplib, handler_name, 0, NULL, 0);
 
   if(!func) {
       my->g_log("Gtk", 1<<4, "Could not find signal handler '%s'.", handler_name);
diff --git a/src/wrapped/wrappedgtkx112.c b/src/wrapped/wrappedgtkx112.c
index 4b069d16..39f1b08a 100644
--- a/src/wrapped/wrappedgtkx112.c
+++ b/src/wrapped/wrappedgtkx112.c
@@ -1034,7 +1034,7 @@ static void my_gtk_builder_connect_signals_custom(void* builder,
 
     uintptr_t offs = 0;
     uintptr_t end = 0;
-    GetGlobalSymbolStartEnd(my_context->maplib, handler_name, &offs, &end, NULL, -1, NULL, NULL, NULL);
+    GetGlobalSymbolStartEnd(my_context->maplib, handler_name, &offs, &end, NULL, -1, NULL, 0, NULL);
     if(!offs) {
         if (args->module == NULL)
             args->my->g_log("Gtk", 1<<2 ,"gtk_builder_connect_signals() requires working GModule");
diff --git a/src/wrapped/wrappedlibdl.c b/src/wrapped/wrappedlibdl.c
index 48b56e46..f85b007d 100644
--- a/src/wrapped/wrappedlibdl.c
+++ b/src/wrapped/wrappedlibdl.c
@@ -80,6 +80,7 @@ void RemoveDlopen(library_t** lib, size_t idx)
 }
 
 extern int box64_zoom;
+void setupTraceMapLib(lib_t* maplib);
 // Implementation
 void* my_dlopen(x64emu_t* emu, void *filename, int flag)
 {
@@ -204,6 +205,7 @@ void* my_dlopen(x64emu_t* emu, void *filename, int flag)
             my_context->deferredInitCap = old_deferredInitCap;
             return NULL;
         }
+        setupTraceMapLib(tmp->libs[0]->maplib);
         free_neededlib(tmp);
         lib = GetLibInternal(rfilename);
         RunDeferredElfInit(emu);
@@ -258,7 +260,7 @@ char* my_dlerror(x64emu_t* emu)
 KHASH_SET_INIT_INT(libs);
 
 // TODO: deepbind is probably not followed correctly here
-int recursive_dlsym_lib(kh_libs_t* collection, library_t* lib, const char* rsymbol, uintptr_t *start, uintptr_t *end, int version, const char* vername, const char* globdefver, const char* weakdefver)
+int recursive_dlsym_lib(kh_libs_t* collection, library_t* lib, const char* rsymbol, uintptr_t *start, uintptr_t *end, int* version, const char** vername, int* veropt)
 {
     if(!lib)
         return 0;
@@ -270,25 +272,26 @@ int recursive_dlsym_lib(kh_libs_t* collection, library_t* lib, const char* rsymb
     // TODO: should use librarian functions instead!
     int weak;
     // look in the library itself
-    if(lib->getglobal(lib, rsymbol, start, end, 0, &weak, version, vername, 1, globdefver))
+    if(lib->getglobal(lib, rsymbol, start, end, 0, &weak, version, vername, 1, veropt, NULL))
         return 1;
-    if(lib->getweak(lib, rsymbol, start, end, 0, &weak, version, vername, 1, weakdefver))
+    if(lib->getweak(lib, rsymbol, start, end, 0, &weak, version, vername, 1, veropt, NULL))
         return 1;
     // look in other libs
     int n = GetNeededLibsN(lib);
     for (int i=0; i<n; ++i) {
         library_t *l = GetNeededLib(lib, i);
-        if(recursive_dlsym_lib(collection, l, rsymbol, start, end, version, vername, globdefver, weakdefver))
+        if(recursive_dlsym_lib(collection, l, rsymbol, start, end, version, vername, veropt))
             return 1;
     }
         
     return 0;
 }
 
-int my_dlsym_lib(library_t* lib, const char* rsymbol, uintptr_t *start, uintptr_t *end, int version, const char* vername, const char* globdefver, const char* weakdefver)
+int my_dlsym_lib(library_t* lib, const char* rsymbol, uintptr_t *start, uintptr_t *end, int version, const char* vername)
 {
     kh_libs_t *collection = kh_init(libs);
-    int ret = recursive_dlsym_lib(collection, lib, rsymbol, start, end, version, vername, globdefver, weakdefver);
+    int veropt = 0;
+    int ret = recursive_dlsym_lib(collection, lib, rsymbol, start, end, &version, &vername, &veropt);
     kh_destroy(libs, collection);
 
     return ret;
@@ -306,9 +309,7 @@ void* my_dlsym(x64emu_t* emu, void *handle, void *symbol)
     printf_dlsym(LOG_DEBUG, "%04d|Call to dlsym(%p, \"%s\")%s", GetTID(), handle, rsymbol, dlsym_error?"":"\n");
     if(handle==NULL) {
         // special case, look globably
-        const char* globdefver = GetMaplibDefaultVersion(my_context->maplib, NULL, 0, 0, rsymbol);
-        const char* weakdefver = GetMaplibDefaultVersion(my_context->maplib, NULL, 1, 0, rsymbol);
-        if(GetGlobalSymbolStartEnd(my_context->maplib, rsymbol, &start, &end, NULL, -1, NULL, globdefver, weakdefver)) {
+        if(GetGlobalSymbolStartEnd(my_context->maplib, rsymbol, &start, &end, NULL, -1, NULL, 0, NULL)) {
             printf_dlsym(LOG_NEVER, "%p\n", (void*)start);
             pthread_mutex_unlock(&mutex);
             return (void*)start;
@@ -322,10 +323,8 @@ void* my_dlsym(x64emu_t* emu, void *handle, void *symbol)
     }
     if(handle==(void*)~0LL) {
         // special case, look globably but no self (RTLD_NEXT)
-        const char* globdefver = GetMaplibDefaultVersion(my_context->maplib, NULL, 0, 0, rsymbol);
-        const char* weakdefver = GetMaplibDefaultVersion(my_context->maplib, NULL, 1, 0, rsymbol);
         elfheader_t *elf = FindElfAddress(my_context, *(uintptr_t*)R_RSP); // use return address to guess "self"
-        if(GetNoSelfSymbolStartEnd(my_context->maplib, rsymbol, &start, &end, elf, 0, -1, NULL, globdefver, weakdefver)) {
+        if(GetNoSelfSymbolStartEnd(my_context->maplib, rsymbol, &start, &end, elf, 0, -1, NULL, 0, NULL)) {
             printf_dlsym(LOG_NEVER, "%p\n", (void*)start);
             pthread_mutex_unlock(&mutex);
             return (void*)start;
@@ -358,9 +357,7 @@ void* my_dlsym(x64emu_t* emu, void *handle, void *symbol)
     }
     if(dl->dllibs[nlib].lib) {
         int deepbind = GetDeepBind(dl->dllibs[nlib].lib);
-        const char* globdefver = GetMaplibDefaultVersion(my_context->maplib, (my_context->maplib==dl->dllibs[nlib].lib->maplib)?NULL:dl->dllibs[nlib].lib->maplib, 0, deepbind, rsymbol);
-        const char* weakdefver = GetMaplibDefaultVersion(my_context->maplib, (my_context->maplib==dl->dllibs[nlib].lib->maplib)?NULL:dl->dllibs[nlib].lib->maplib, 1, deepbind, rsymbol);
-        if(my_dlsym_lib(dl->dllibs[nlib].lib, rsymbol, &start, &end, -1, NULL, globdefver, weakdefver)==0) {
+        if(my_dlsym_lib(dl->dllibs[nlib].lib, rsymbol, &start, &end, -1, NULL)==0) {
             // not found
             printf_dlsym(LOG_NEVER, "%p\nCall to dlsym(%s, \"%s\") Symbol not found\n", NULL, GetNameLib(dl->dllibs[nlib].lib), rsymbol);
             printf_log(LOG_DEBUG, " Symbol not found\n");
@@ -373,9 +370,7 @@ void* my_dlsym(x64emu_t* emu, void *handle, void *symbol)
     } else {
         // still usefull?
         //  => look globably
-        const char* globdefver = GetMaplibDefaultVersion(my_context->maplib, NULL, 0, 0, rsymbol);
-        const char* weakdefver = GetMaplibDefaultVersion(my_context->maplib, NULL, 1, 0, rsymbol);
-        if(GetGlobalSymbolStartEnd(my_context->maplib, rsymbol, &start, &end, NULL, -1, NULL, globdefver, weakdefver)) {
+        if(GetGlobalSymbolStartEnd(my_context->maplib, rsymbol, &start, &end, NULL, -1, NULL, 0, NULL)) {
             printf_dlsym(LOG_NEVER, "%p\n", (void*)start);
             pthread_mutex_unlock(&mutex);
             return (void*)start;
@@ -463,9 +458,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
-        const char* globdefver = GetMaplibDefaultVersion(my_context->maplib, NULL, 0, 0, rsymbol);
-        const char* weakdefver = GetMaplibDefaultVersion(my_context->maplib, NULL, 1, 0, rsymbol);
-        if(GetGlobalSymbolStartEnd(my_context->maplib, rsymbol, &start, &end, NULL, version, vername, globdefver, weakdefver)) {
+        if(GetGlobalSymbolStartEnd(my_context->maplib, rsymbol, &start, &end, NULL, version, vername, 0, NULL)) {
             printf_dlsym(LOG_NEVER, "%p\n", (void*)start);
             return (void*)start;
         }
@@ -477,10 +470,8 @@ void* my_dlvsym(x64emu_t* emu, void *handle, void *symbol, const char *vername)
     }
     if(handle==(void*)~0LL) {
         // special case, look globably but no self (RTLD_NEXT)
-        const char* globdefver = GetMaplibDefaultVersion(my_context->maplib, NULL, 0, 0, rsymbol);
-        const char* weakdefver = GetMaplibDefaultVersion(my_context->maplib, NULL, 1, 0, rsymbol);
         elfheader_t *elf = FindElfAddress(my_context, *(uintptr_t*)R_RSP); // use return address to guess "self"
-        if(GetNoSelfSymbolStartEnd(my_context->maplib, rsymbol, &start, &end, elf, 0, version, vername, globdefver, weakdefver)) {
+        if(GetNoSelfSymbolStartEnd(my_context->maplib, rsymbol, &start, &end, elf, 0, version, vername, 0, NULL)) {
                 printf_dlsym(LOG_NEVER, "%p\n", (void*)start);
             return (void*)start;
         }
@@ -509,9 +500,7 @@ void* my_dlvsym(x64emu_t* emu, void *handle, void *symbol, const char *vername)
     }
     if(dl->dllibs[nlib].lib) {
         int deepbind = GetDeepBind(dl->dllibs[nlib].lib);
-        const char* globdefver = GetMaplibDefaultVersion(my_context->maplib, (my_context->maplib==dl->dllibs[nlib].lib->maplib)?NULL:dl->dllibs[nlib].lib->maplib, 0, deepbind, rsymbol);
-        const char* weakdefver = GetMaplibDefaultVersion(my_context->maplib, (my_context->maplib==dl->dllibs[nlib].lib->maplib)?NULL:dl->dllibs[nlib].lib->maplib, 1, deepbind, rsymbol);
-        if(my_dlsym_lib(dl->dllibs[nlib].lib, rsymbol, &start, &end, version, vername, globdefver, weakdefver)==0) {
+        if(my_dlsym_lib(dl->dllibs[nlib].lib, rsymbol, &start, &end, version, vername)==0) {
             // not found
                 printf_dlsym(LOG_NEVER, "%p\nCall to dlvsym(%s, \"%s\", %s) Symbol not found\n", NULL, GetNameLib(dl->dllibs[nlib].lib), rsymbol, vername?vername:"(nil)");
             printf_log(LOG_DEBUG, " Symbol not found\n");
@@ -522,9 +511,7 @@ void* my_dlvsym(x64emu_t* emu, void *handle, void *symbol, const char *vername)
         }
     } else {
         // still usefull?
-        const char* globdefver = GetMaplibDefaultVersion(my_context->maplib, NULL, 0, 0, rsymbol);
-        const char* weakdefver = GetMaplibDefaultVersion(my_context->maplib, NULL, 1, 0, rsymbol);
-        if(GetGlobalSymbolStartEnd(my_context->maplib, rsymbol, &start, &end, NULL, -1, NULL, globdefver, weakdefver)) {
+        if(GetGlobalSymbolStartEnd(my_context->maplib, rsymbol, &start, &end, NULL, -1, NULL, 0, NULL)) {
             printf_dlsym(LOG_NEVER, "%p\n", (void*)start);
             return (void*)start;
         }