about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2022-11-13 00:04:26 +0100
committerptitSeb <sebastien.chev@gmail.com>2022-11-13 00:04:26 +0100
commit3cb7632dc84c954c76b84bb3477de2b6ba3d599c (patch)
treee250dc582585fa5abda034c9f654ff8863263af6 /src
parentcde8e54b513cce726008fecf2bb6b67d81da9a21 (diff)
downloadbox64-3cb7632dc84c954c76b84bb3477de2b6ba3d599c.tar.gz
box64-3cb7632dc84c954c76b84bb3477de2b6ba3d599c.zip
Also use size when selecting symbol for R_X86_64_COPY and R_X86_64_GLOB_DAT relocations
Diffstat (limited to 'src')
-rwxr-xr-xsrc/elfs/elfloader.c22
-rwxr-xr-xsrc/include/librarian.h2
-rwxr-xr-xsrc/include/library.h6
-rw-r--r--src/include/symbols.h1
-rwxr-xr-xsrc/include/wrappedlibs.h2
-rwxr-xr-xsrc/librarian/librarian.c35
-rwxr-xr-xsrc/librarian/library.c75
-rw-r--r--src/librarian/symbols.c76
-rwxr-xr-xsrc/wrapped/wrappedlibdl.c8
9 files changed, 124 insertions, 103 deletions
diff --git a/src/elfs/elfloader.c b/src/elfs/elfloader.c
index 227ef075..d7f4a530 100755
--- a/src/elfs/elfloader.c
+++ b/src/elfs/elfloader.c
@@ -382,7 +382,7 @@ int ReloadElfMemory(FILE* f, box64context_t* context, elfheader_t* head)
     return 0;
 }
 
-int FindR64COPYRel(elfheader_t* h, const char* name, uintptr_t *offs, uint64_t** p, int version, const char* vername)
+int FindR64COPYRel(elfheader_t* h, const char* name, uintptr_t *offs, uint64_t** p, size_t size, int version, const char* vername)
 {
     if(!h)
         return 0;
@@ -394,7 +394,7 @@ int FindR64COPYRel(elfheader_t* h, const char* name, uintptr_t *offs, uint64_t**
         int t = ELF64_R_TYPE(rela[i].r_info);
         Elf64_Sym *sym = &h->DynSym[ELF64_R_SYM(rela[i].r_info)];
         const char* symname = SymName(h, sym);
-        if(t==R_X86_64_COPY && symname && !strcmp(symname, name)) {
+        if(t==R_X86_64_COPY && symname && !strcmp(symname, name) && sym->st_size==size) {
             int version2 = h->VerSym?((Elf64_Half*)((uintptr_t)h->VerSym+h->delta))[ELF64_R_SYM(rela[i].r_info)]:-1;
             if(version2!=-1) version2 &= 0x7fff;
             if(version && !version2) version2=-1;   // match a versionned symbol against a global "local" symbol
@@ -421,6 +421,7 @@ int RelocateElfREL(lib_t *maplib, lib_t *local_maplib, int bindnow, elfheader_t*
         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;
@@ -462,7 +463,7 @@ int RelocateElfREL(lib_t *maplib, lib_t *local_maplib, int bindnow, elfheader_t*
                     *p += offs;
                 break;
             case R_X86_64_GLOB_DAT:
-                if(head!=my_context->elfs[0] && !IsGlobalNoWeakSymbolInNative(maplib, symname, version, vername) && FindR64COPYRel(my_context->elfs[0], symname, &globoffs, &globp, version, vername)) {
+                if(head!=my_context->elfs[0] && !IsGlobalNoWeakSymbolInNative(maplib, symname, version, vername) && 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;
@@ -494,11 +495,11 @@ int RelocateElfREL(lib_t *maplib, lib_t *local_maplib, int bindnow, elfheader_t*
                     uintptr_t old_offs = offs;
                     uintptr_t old_end = end;
                     offs = 0;
-                    GetSymbolStartEnd(GetGlobalData(maplib), symname, &offs, &end, version, vername, 1, defver); // try globaldata symbols first
+                    GetSizedSymbolStartEnd(GetGlobalData(maplib), symname, &offs, &end, size, version, vername, 1, defver); // try globaldata symbols first
                     if(offs==0) {
-                        GetNoSelfSymbolStartEnd(maplib, symname, &offs, &end, head, version, vername);   // get original copy if any
+                        GetNoSelfSymbolStartEnd(maplib, symname, &offs, &end, head, size, version, vername);   // get original copy if any
                         if(!offs && local_maplib)
-                            GetNoSelfSymbolStartEnd(local_maplib, symname, &offs, &end, head, version, vername);
+                            GetNoSelfSymbolStartEnd(local_maplib, symname, &offs, &end, head, size, version, vername);
                     }
                     if(!offs) {
                         offs = old_offs;
@@ -593,6 +594,7 @@ int RelocateElfRELA(lib_t *maplib, lib_t *local_maplib, int bindnow, elfheader_t
         uint64_t *p = (uint64_t*)(rela[i].r_offset + head->delta);
         uintptr_t offs = 0;
         uintptr_t end = 0;
+        size_t size = sym->st_size;
         elfheader_t* h_tls = NULL;//head;
         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;
@@ -643,11 +645,11 @@ int RelocateElfRELA(lib_t *maplib, lib_t *local_maplib, int bindnow, elfheader_t
                 globoffs = offs;
                 globend = end;
                 offs = end = 0;
-                GetSymbolStartEnd(GetGlobalData(maplib), symname, &offs, &end, version, vername, 1, defver); // try globaldata symbols first
+                GetSizedSymbolStartEnd(GetGlobalData(maplib), symname, &offs, &end, size, version, vername, 1, defver); // try globaldata symbols first
                 if(!offs && local_maplib)
-                    GetNoSelfSymbolStartEnd(local_maplib, symname, &offs, &end, head, version, vername);
+                    GetNoSelfSymbolStartEnd(local_maplib, symname, &offs, &end, head, size, version, vername);
                 if(!offs)
-                    GetNoSelfSymbolStartEnd(maplib, symname, &offs, &end, head, version, vername);
+                    GetNoSelfSymbolStartEnd(maplib, symname, &offs, &end, head, size, version, vername);
                 if(!offs) {offs = globoffs; end = globend;}
                 if(offs) {
                     // add r_addend to p?
@@ -659,7 +661,7 @@ int RelocateElfRELA(lib_t *maplib, lib_t *local_maplib, int bindnow, elfheader_t
                 }
                 break;
             case R_X86_64_GLOB_DAT:
-                if(head!=my_context->elfs[0] && !IsGlobalNoWeakSymbolInNative(maplib, symname, version, vername) && FindR64COPYRel(my_context->elfs[0], symname, &globoffs, &globp, version, vername)) {
+                if(head!=my_context->elfs[0] && !IsGlobalNoWeakSymbolInNative(maplib, symname, version, vername) && 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;
diff --git a/src/include/librarian.h b/src/include/librarian.h
index a3fdfb3d..87a78a34 100755
--- a/src/include/librarian.h
+++ b/src/include/librarian.h
@@ -25,7 +25,7 @@ int AddNeededLib(lib_t* maplib, needed_libs_t* neededlibs, library_t* deplib, in
 library_t* GetLibMapLib(lib_t* maplib, const char* name);
 library_t* GetLibInternal(const char* name);
 uintptr_t FindGlobalSymbol(lib_t *maplib, const char* name, int version, const char* vername);
-int GetNoSelfSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, elfheader_t* self, int version, const char* vername);
+int 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 GetGlobalSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, elfheader_t *self, int version, const char* vername);
 int GetGlobalNoWeakSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, int version, const char* vername);
 int GetLocalSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, elfheader_t *self, int version, const char* vername);
diff --git a/src/include/library.h b/src/include/library.h
index b62e122d..b88aaa04 100755
--- a/src/include/library.h
+++ b/src/include/library.h
@@ -24,9 +24,9 @@ void Free1Library(library_t **lib, x64emu_t* emu);
 
 char* GetNameLib(library_t *lib);
 int IsSameLib(library_t* lib, const char* path);    // check if lib is same (path -> name)
-int GetLibGlobalSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start, uintptr_t* end, int* weak, int version, const char* vername, int local);
-int GetLibWeakSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start, uintptr_t* end, int* weak, int version, const char* vername, int local);
-int GetLibLocalSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start, uintptr_t* end, int* weak, int version, const char* vername, int local);
+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 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 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);
 void fillGLProcWrapper(box64context_t* context);
 void freeGLProcWrapper(box64context_t* context);
 void fillALProcWrapper(box64context_t* context);
diff --git a/src/include/symbols.h b/src/include/symbols.h
index 98eb9db7..b00a354b 100644
--- a/src/include/symbols.h
+++ b/src/include/symbols.h
@@ -19,6 +19,7 @@ uintptr_t FindSymbol(kh_mapsymbols_t *mapsymbols, const char* name, int ver, con
 
 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);
 const char* GetSymbolName(kh_mapsymbols_t* mapsymbols, void* p, uintptr_t* offs, uint32_t* sz, const char** vername);
 
 // default version handling
diff --git a/src/include/wrappedlibs.h b/src/include/wrappedlibs.h
index 7bb4d5a2..07014e46 100755
--- a/src/include/wrappedlibs.h
+++ b/src/include/wrappedlibs.h
@@ -7,7 +7,7 @@ typedef struct box64context_s  box64context_t;
 
 typedef int (*wrappedlib_init_t)(library_t * lib, box64context_t* box64);  // 0 = success
 typedef void (*wrappedlib_fini_t)(library_t * lib);
-typedef int (*wrappedlib_get_t)(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, int* weak, int version, const char* vername, int local);
+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);
 
 void setNeededLibs(library_t* lib, int n, ...);
 #define SETALT(A)       lib->w.altmy = box_strdup(#A)
diff --git a/src/librarian/librarian.c b/src/librarian/librarian.c
index 84b0b9a7..58f21aa6 100755
--- a/src/librarian/librarian.c
+++ b/src/librarian/librarian.c
@@ -384,7 +384,7 @@ static int isLocal(elfheader_t* self, library_t* l)
     return 0;
 }
 
-int GetNoSelfSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, elfheader_t* self, 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)
 {
     assert(self);   // need self for this one
     //search for the self, to start "next"
@@ -398,13 +398,13 @@ int GetNoSelfSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, u
         go = 0; // not found...
     for(int i=go; i<maplib->libsz; ++i) {
         if(GetElfIndex(maplib->libraries[i])==-1 || (my_context->elfs[GetElfIndex(maplib->libraries[i])]!=self))
-            if(GetLibGlobalSymbolStartEnd(maplib->libraries[i], name, start, end, &weak, version, vername, 0))
+            if(GetLibGlobalSymbolStartEnd(maplib->libraries[i], name, start, end, size, &weak, version, vername, 0))
                 if(*start)
                     return 1;
     }
     for(int i=go; i<maplib->libsz; ++i)
         if(GetElfIndex(maplib->libraries[i])==-1 || (my_context->elfs[GetElfIndex(maplib->libraries[i])]!=self))
-            GetLibWeakSymbolStartEnd(maplib->libraries[i], name, start, end, &weak, version, vername, 0);
+            GetLibWeakSymbolStartEnd(maplib->libraries[i], name, start, end, size, &weak, version, vername, 0);
     // loop done, weak symbol found
     if(weak && *start)
         return 1;
@@ -412,23 +412,23 @@ int GetNoSelfSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, u
     if(self) {
         if(my_context->elfs[0]!=self) {
             const char* defver = GetDefaultVersion(my_context->globaldefver, name);
-            if(GetSymbolStartEnd(GetMapSymbols(my_context->elfs[0]), name, start, end, version, vername, 1, defver))
+            if(GetSizedSymbolStartEnd(GetMapSymbols(my_context->elfs[0]), name, start, end, size, version, vername, 1, defver))
                 if(*start)
                     return 1;
             defver = GetDefaultVersion(my_context->weakdefver, name);
-            if(GetSymbolStartEnd(GetWeakSymbols(my_context->elfs[0]), name, start, end, version, vername, 1, defver))
+            if(GetSizedSymbolStartEnd(GetWeakSymbols(my_context->elfs[0]), name, start, end, size, version, vername, 1, defver))
                 if(*start)
                     weak = 1;
         }
         for(int i=0; i<go; ++i) {
             if(GetElfIndex(maplib->libraries[i])==-1 || (my_context->elfs[GetElfIndex(maplib->libraries[i])]!=self))
-                if(GetLibGlobalSymbolStartEnd(maplib->libraries[i], name, start, end, &weak, version, vername, 1))
+                if(GetLibGlobalSymbolStartEnd(maplib->libraries[i], name, start, end, size, &weak, version, vername, 1))
                     if(*start)
                         return 1;
         }
         for(int i=0; i<go; ++i) {
             if(GetElfIndex(maplib->libraries[i])==-1 || (my_context->elfs[GetElfIndex(maplib->libraries[i])]!=self))
-                GetLibWeakSymbolStartEnd(maplib->libraries[i], name, start, end, &weak, version, vername, 1);
+                GetLibWeakSymbolStartEnd(maplib->libraries[i], name, start, end, size, &weak, version, vername, 1);
         }
     if(weak && *start)
         return 1;
@@ -439,6 +439,7 @@ int GetNoSelfSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, u
 static int GetGlobalSymbolStartEnd_internal(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, elfheader_t* self, int version, const char* vername)
 {
     int weak = 0;
+    size_t size = 0;
     // check with default version...
     const char* defver = GetDefaultVersion(my_context->globaldefver, name);
     // search non-weak symbol, from older to newer (first GLOBAL object wins)
@@ -448,12 +449,12 @@ static int GetGlobalSymbolStartEnd_internal(lib_t *maplib, const char* name, uin
     // TODO: create a temporary map to search lib only 1 time, and in order of needed...
     // search in needed libs from neededlibs first, in order
     for(int i=0; i<my_context->neededlibs.size; ++i)
-        if(GetLibGlobalSymbolStartEnd(my_context->neededlibs.libs[i], name, start, end, &weak, version, vername, isLocal(self, my_context->neededlibs.libs[i])))
+        if(GetLibGlobalSymbolStartEnd(my_context->neededlibs.libs[i], name, start, end, size, &weak, version, vername, isLocal(self, my_context->neededlibs.libs[i])))
             if(*start)
                 return 1;
     // search in global symbols
     for(int i=0; i<maplib->libsz; ++i) {
-        if(GetLibGlobalSymbolStartEnd(maplib->libraries[i], name, start, end, &weak, version, vername, isLocal(self, maplib->libraries[i])))
+        if(GetLibGlobalSymbolStartEnd(maplib->libraries[i], name, start, end, size, &weak, version, vername, isLocal(self, maplib->libraries[i])))
             if(*start)
                 return 1;
     }
@@ -467,7 +468,7 @@ static int GetGlobalSymbolStartEnd_internal(lib_t *maplib, const char* name, uin
             ok = 1;
 
     for(int i=0; i<maplib->libsz; ++i) {
-        if(GetLibWeakSymbolStartEnd(maplib->libraries[i], name, start, end, &weak, version, vername, isLocal(self, maplib->libraries[i])))
+        if(GetLibWeakSymbolStartEnd(maplib->libraries[i], name, start, end, size, &weak, version, vername, isLocal(self, maplib->libraries[i])))
             if(*start)
                 ok = 1;
     }
@@ -513,6 +514,7 @@ elfheader_t* GetGlobalSymbolElf(lib_t *maplib, const char* name, int version, co
 {
     uintptr_t start = 0;
     uintptr_t end = 0;
+    size_t size = 0;
     int weak = 0;
     elfheader_t* ret = NULL;
     // check with default version...
@@ -521,7 +523,7 @@ elfheader_t* GetGlobalSymbolElf(lib_t *maplib, const char* name, int version, co
     if(GetSymbolStartEnd(GetMapSymbols(my_context->elfs[0]), name, &start, &end, version, vername, 1, defver))
         return my_context->elfs[0];
     for(int i=0; i<maplib->libsz; ++i) {
-        if(GetLibGlobalSymbolStartEnd(maplib->libraries[i], name, &start, &end, &weak, version, vername, 1)) {
+        if(GetLibGlobalSymbolStartEnd(maplib->libraries[i], name, &start, &end, size, &weak, version, vername, 1)) {
             int idx = GetElfIndex(maplib->libraries[i]);
             if(idx==-1) {
                 printf_log(LOG_NONE, "Warning, getting Elf info for a native symbol \"%s\" from lib \"%s\"\n", name, GetNameLib(maplib->libraries[i]));
@@ -538,7 +540,7 @@ elfheader_t* GetGlobalSymbolElf(lib_t *maplib, const char* name, int version, co
     if(GetSymbolStartEnd(GetWeakSymbols(my_context->elfs[0]), name, &start, &end, version, vername, 1, defver))
         ret = my_context->elfs[0];
     for(int i=0; i<maplib->libsz; ++i) {
-        if(GetLibWeakSymbolStartEnd(maplib->libraries[i], name, &start, &end, &weak, version, vername, 1)) {
+        if(GetLibWeakSymbolStartEnd(maplib->libraries[i], name, &start, &end, size, &weak, version, vername, 1)) {
             int idx = GetElfIndex(maplib->libraries[i]);
             if(idx==-1) {
                 printf_log(LOG_NONE, "Warning, getting Elf info for a native symbol \"%s\" from lib \"%s\"\n", name, GetNameLib(maplib->libraries[i]));
@@ -557,6 +559,7 @@ elfheader_t* GetGlobalSymbolElf(lib_t *maplib, const char* name, int version, co
 int GetGlobalNoWeakSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, int version, const char* vername)
 {
     int weak = 0;
+    size_t size = 0;
     // check with default version...
     const char* defver = GetDefaultVersion(my_context->globaldefver, name);
 
@@ -564,7 +567,7 @@ int GetGlobalNoWeakSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* st
         if(*start || *end)
             return 1;
     for(int i=0; i<maplib->libsz; ++i)
-        if(GetLibGlobalSymbolStartEnd(maplib->libraries[i], name, start, end, &weak, version, vername, 1))
+        if(GetLibGlobalSymbolStartEnd(maplib->libraries[i], name, start, end, size, &weak, version, vername, 1))
             if(*start || *end)
                 return 1;
     // nope, not found
@@ -574,11 +577,12 @@ int GetGlobalNoWeakSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* st
 int IsGlobalNoWeakSymbolInNative(lib_t *maplib, const char* name, int version, const char* vername)
 {
     uintptr_t start, end;
+    size_t size = 0;
     int weak;
     // 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, &weak, version, vername, 1))
+            if(GetLibGlobalSymbolStartEnd(maplib->libraries[i], name, &start, &end, size, &weak, version, vername, 1))
                 if(start || end)
                     return 1;
     // nope, not found
@@ -590,6 +594,7 @@ int GetLocalSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, ui
 {
     // check with default version...
     int weak;
+    size_t size = 0;
 
     if(my_context->elfs[0]==self || !self) {
         if(GetSymbolStartEnd(GetLocalSymbols(my_context->elfs[0]), name, start, end, version, vername, 1, NULL))
@@ -600,7 +605,7 @@ int GetLocalSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, ui
     }
     for(int i=0; i<maplib->libsz; ++i) {
         if(GetElfIndex(maplib->libraries[i])!=-1 && (!self || my_context->elfs[GetElfIndex(maplib->libraries[i])]==self)) {
-            if(GetLibLocalSymbolStartEnd(maplib->libraries[i], name, start, end, &weak, version, vername, 1))
+            if(GetLibLocalSymbolStartEnd(maplib->libraries[i], name, start, end, size, &weak, version, vername, 1))
                 if(*start)
                     return 1;
             if(self)
diff --git a/src/librarian/library.c b/src/librarian/library.c
index 7baceeca..29c595a1 100755
--- a/src/librarian/library.c
+++ b/src/librarian/library.c
@@ -118,7 +118,9 @@ void WrappedLib_FinishFini(library_t* lib)
     FreeBridge(&lib->w.bridge);
 }
 
-int WrappedLib_GetWeak(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, int* weak, int version, const char* vername, int local) {
+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)
+{
+    // ignoring asked size on wrapped libs
     uintptr_t addr = 0;
     uintptr_t size = 0;
     int wk = 0;
@@ -134,13 +136,13 @@ int WrappedLib_GetWeak(library_t* lib, const char* name, uintptr_t *offs, uintpt
     *weak = wk;
     return 1;
 }
-int EmuLib_GetWeak(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, int*weak, int version, const char* vername, int local)
+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)
 {
     // symbols...
     uintptr_t start, end;
     const char* defver = GetDefaultVersion(my_context->weakdefver, name);
     // weak symbols...
-    if(GetSymbolStartEnd(GetWeakSymbols(lib->e.elf), name, &start, &end, version, vername, local, defver))
+    if(GetSizedSymbolStartEnd(GetWeakSymbols(lib->e.elf), name, &start, &end, asked_size, version, vername, local, defver))
     {
         *offs = start;
         *sz = end-start;
@@ -149,7 +151,9 @@ int EmuLib_GetWeak(library_t* lib, const char* name, uintptr_t *offs, uintptr_t
     }
     return 0;
 }
-int WrappedLib_GetGlobal(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, int* weak, int version, const char* vername, int local) {
+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)
+{
+    // ignoring asked size on wrapped libs
     uintptr_t addr = 0;
     uintptr_t size = 0;
     int wk = 0;
@@ -165,11 +169,11 @@ int WrappedLib_GetGlobal(library_t* lib, const char* name, uintptr_t *offs, uint
     *weak = 0;
     return 1;
 }
-int EmuLib_GetGlobal(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, int* weak, int version, const char* vername, int local)
+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)
 {
     uintptr_t start, end;
     const char* defver = GetDefaultVersion(my_context->globaldefver, name);
-    if(GetSymbolStartEnd(GetMapSymbols(lib->e.elf), name, &start, &end, version, vername, local, defver))
+    if(GetSizedSymbolStartEnd(GetMapSymbols(lib->e.elf), name, &start, &end, asked_size, version, vername, local, defver))
     {
         *offs = start;
         *sz = end-start;
@@ -178,8 +182,9 @@ int EmuLib_GetGlobal(library_t* lib, const char* name, uintptr_t *offs, uintptr_
     }
     return 0;
 }
-int EmuLib_GetLocal(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, int* weak, int version, const char* vername, int local)
+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)
 {
+    // ignoring asked size on wrapped libs
     uintptr_t start, end;
     const char* defver = GetDefaultVersion(my_context->globaldefver, name);
     if(!defver) defver = GetDefaultVersion(my_context->weakdefver, name);
@@ -193,7 +198,7 @@ int EmuLib_GetLocal(library_t* lib, const char* name, uintptr_t *offs, uintptr_t
     return 0;
 }
 
-int WrappedLib_GetLocal(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, int* weak, int version, const char* vername, int local)
+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)
 {
     (void)lib; (void)name; (void)offs; (void)sz; (void)version; (void)vername; (void)local;
     return 0;
@@ -448,7 +453,7 @@ int FinalizeLibrary(library_t* lib, lib_t* local_maplib, int bindnow, x64emu_t*
                 printf_log(LOG_INFO, "TRACE on %s only (%p-%p)\n", trace_func, (void*)trace_start, (void*)trace_end);
                 box_free(trace_func);
                 trace_func = NULL;
-            } else if(GetLibLocalSymbolStartEnd(lib, trace_func, &trace_start, &trace_end, &weak, -1, NULL, 0)) {
+            } else if(GetLibLocalSymbolStartEnd(lib, trace_func, &trace_start, &trace_end, 0, &weak, -1, NULL, 0)) {
                 SetTraceEmu(trace_start, trace_end);
                 printf_log(LOG_INFO, "TRACE on %s only (%p-%p)\n", trace_func, (void*)trace_start, (void*)trace_end);
                 box_free(trace_func);
@@ -609,34 +614,24 @@ 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, int* weak, int version, const char* vername, int local)
+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)
 {
     if(!name[0] || !lib->active)
         return 0;
     khint_t k;
-    // check first if already in the map
-    k = kh_get(bridgemap, lib->wbridgemap, VersionnedName(name, version, vername));
-    if(k!=kh_end(lib->wbridgemap)) {
-        *start = kh_value(lib->wbridgemap, k).start;
-        *end = kh_value(lib->wbridgemap, k).end;
-        *weak = 1;
-        return 1;
-    }
-    if(local) {
-        k = kh_get(bridgemap, lib->lbridgemap, VersionnedName(name, version, vername));
-        if(k!=kh_end(lib->lbridgemap)) {
-            *start = kh_value(lib->lbridgemap, k).start;
-            *end = kh_value(lib->lbridgemap, k).end;
-            *weak = 0;
-            return 1;
-        }
-    }
     // get a new symbol
-    if(lib->getweak(lib, name, start, end, weak, version, vername, local)) {
+    if(lib->getweak(lib, name, start, end, size, weak, version, vername, local)) {
         *end += *start;     // lib->get(...) gives size, not end
+        kh_bridgemap_t *map = local?lib->lbridgemap:((*weak)?lib->wbridgemap:lib->gbridgemap);
+        // check first if already in the map
+        k = kh_get(bridgemap, map, VersionnedName(name, version, vername));
+        if(k!=kh_end(map)) {
+            *start = kh_value(map, k).start;
+            *end = kh_value(map, k).end;
+            return 1;
+        }
         char* symbol = box_strdup(VersionnedName(name, version, vername));
         int ret;
-        kh_bridgemap_t *map = local?lib->lbridgemap:((*weak)?lib->wbridgemap:lib->gbridgemap);
         k = kh_put(bridgemap, map, symbol, &ret);
         kh_value(map, k).name = symbol;
         kh_value(map, k).start = *start;
@@ -646,13 +641,13 @@ int GetLibWeakSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start,
     // nope
     return 0;
 }
-int GetLibGlobalSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start, uintptr_t* end, int* weak, int version, const char* vername, int local)
+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)
 {
     if(!name[0] || !lib->active)
         return 0;
     khint_t k;
     // get a new symbol
-    if(lib->getglobal(lib, name, start, end, weak, version, vername, local)) {
+    if(lib->getglobal(lib, name, start, end, size, weak, version, vername, local)) {
         *end += *start;     // lib->get(...) gives size, not end
         kh_bridgemap_t *map = local?lib->lbridgemap:((*weak)?lib->wbridgemap:lib->gbridgemap);
         // check if already in the map
@@ -673,21 +668,21 @@ int GetLibGlobalSymbolStartEnd(library_t* lib, const char* name, uintptr_t* star
     // nope
     return 0;
 }
-int GetLibLocalSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start, uintptr_t* end, int* weak, int version, const char* vername, int local)
+int GetLibLocalSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start, uintptr_t* end, size_t size, int* weak, int version, const char* vername, int local)
 {
     if(!name[0] || !lib->active)
         return 0;
     khint_t k;
-    // check first if already in the map
-    k = kh_get(bridgemap, lib->lbridgemap, VersionnedName(name, version, vername));
-    if(k!=kh_end(lib->lbridgemap)) {
-        *start = kh_value(lib->lbridgemap, k).start;
-        *end = kh_value(lib->lbridgemap, k).end;
-        return 1;
-    }
     // get a new symbol
-    if(lib->getlocal(lib, name, start, end, weak, version, vername, local)) {
+    if(lib->getlocal(lib, name, start, end, size, weak, version, vername, local)) {
         *end += *start;     // lib->get(...) gives size, not end
+        // check first if already in the map
+        k = kh_get(bridgemap, lib->lbridgemap, VersionnedName(name, version, vername));
+        if(k!=kh_end(lib->lbridgemap)) {
+            *start = kh_value(lib->lbridgemap, k).start;
+            *end = kh_value(lib->lbridgemap, k).end;
+            return 1;
+        }
         char* symbol = box_strdup(VersionnedName(name, version, vername));
         int ret;
         k = kh_put(bridgemap, lib->lbridgemap, symbol, &ret);
diff --git a/src/librarian/symbols.c b/src/librarian/symbols.c
index 2fbbf118..83feb019 100644
--- a/src/librarian/symbols.c
+++ b/src/librarian/symbols.c
@@ -58,88 +58,89 @@ static int SameVersion(versymbol_t* s, int ver, const char* vername)
     
 }
 
-static versymbol_t* FindVersionLocal(versymbols_t* s)
+static versymbol_t* FindVersionLocal(versymbols_t* s, size_t size)
 {
     if(!s || !s->sz)
         return NULL;
     for (int i=0; i<s->sz; ++i)
-        if(s->syms[i].version==0)
+        if(s->syms[i].version==0 && (!size || (size==s->syms[i].sym.sz)))
             return &s->syms[i];
     return NULL;
 }
-static versymbol_t* FindNoVersion(versymbols_t* s)
+static versymbol_t* FindNoVersion(versymbols_t* s, size_t size)
 {
     if(!s || !s->sz)
         return NULL;
     for (int i=0; i<s->sz; ++i)
-        if(s->syms[i].version==-1)
+        if(s->syms[i].version==-1 && (!size || (size==s->syms[i].sym.sz)))
             return &s->syms[i];
     return NULL;
 }
-static versymbol_t* FindVersionGlobal(versymbols_t* s)
+static versymbol_t* FindVersionGlobal(versymbols_t* s, size_t size)
 {
     if(!s || !s->sz)
         return NULL;
     for (int i=0; i<s->sz; ++i)
-        if(s->syms[i].version==1)
+        if(s->syms[i].version==1 && (!size || (size==s->syms[i].sym.sz)))
             return &s->syms[i];
     return NULL;
 }
-static versymbol_t* FindVersion(versymbols_t* s, const char* vername)
+static versymbol_t* FindVersion(versymbols_t* s, size_t size, const char* vername)
 {
     if(!s || !s->sz)
         return NULL;
     for (int i=0; i<s->sz; ++i)
-        if(s->syms[i].vername && !strcmp(s->syms[i].vername, vername))
+        if(s->syms[i].vername && !strcmp(s->syms[i].vername, vername) && (!size || (size==s->syms[i].sym.sz)))
             return &s->syms[i];
     return NULL;
 }
-static versymbol_t* FindFirstVersion(versymbols_t* s)
+static versymbol_t* FindFirstVersion(versymbols_t* s, size_t size)
 {
     if(!s || !s->sz)
         return NULL;
     for (int i=0; i<s->sz; ++i)
-        if(s->syms[i].version>1)
+        if(s->syms[i].version>1 && (!size || (size==s->syms[i].sym.sz)))
             return &s->syms[i];
     return NULL;
 }
 
 // Match version (so ver=0:0, ver=1:-1/1/X, ver=-1:any, ver=X:1/"name")
-static versymbol_t* MatchVersion(versymbols_t* s, int ver, const char* vername, int local, const char* defver)
+static versymbol_t* MatchVersion(versymbols_t* s, int ver, const char* vername, size_t size, int local, const char* defver)
 {
     if(!s || !s->sz)
         return NULL;
     versymbol_t* ret = NULL;
     if(ver==0) {
-        if(local) ret = FindVersionLocal(s);
-        if(!ret) ret = FindNoVersion(s);
-        if(!ret) ret = FindVersionGlobal(s);
+        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);
-        if(!ret) ret = FindNoVersion(s);
-        if(!ret) ret = FindVersionGlobal(s);
-        if(!ret && defver) ret = FindVersion(s, defver);
+        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);
         return ret;
     }
     if(ver==-2) {
-        if(local) ret = FindVersionLocal(s);
-        if(!ret) ret = FindVersionGlobal(s);
+        if(local) ret = FindVersionLocal(s, size);
+        if(!ret) ret = FindVersionGlobal(s, size);
         return ret;
     }
     if(ver==1) {
-        if(local) ret = FindVersionLocal(s);
-        if(!ret) ret = FindVersionGlobal(s);
-        if(!ret) ret = FindNoVersion(s);
-        if(!ret && defver) ret = FindVersion(s, defver);
+        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;
     }
-    ret = FindVersion(s, vername);
-    if(local && !ret) ret = FindVersionLocal(s);
-    if(!ret && defver && vername && !strcmp(defver, vername)) ret = FindVersionGlobal(s);
+    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;
 }
@@ -177,7 +178,7 @@ uintptr_t FindSymbol(kh_mapsymbols_t *mapsymbols, const char* name, int ver, con
     if(k==kh_end(mapsymbols))
         return 0;
     versymbols_t * v = &kh_val(mapsymbols, k);
-    versymbol_t * s = MatchVersion(v, ver, vername, local, defver);
+    versymbol_t * s = MatchVersion(v, ver, vername, 0, local, defver);
     if(s)
         return s->sym.offs;
     return 0;
@@ -214,7 +215,24 @@ int GetSymbolStartEnd(kh_mapsymbols_t* mapsymbols, const char* name, uintptr_t*
     if(k==kh_end(mapsymbols))
         return 0;
     versymbols_t * v = &kh_val(mapsymbols, k);
-    versymbol_t* s = MatchVersion(v, ver, vername, local, defver);
+    versymbol_t* s = MatchVersion(v, ver, vername, 0, local, defver);
+    if(s) {
+        *start = s->sym.offs;
+        *end = *start + s->sym.sz;
+        return 1;
+    }
+    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)
+{
+    if(!mapsymbols)
+        return 0;
+    khint_t k = kh_get(mapsymbols, mapsymbols, name);
+    if(k==kh_end(mapsymbols))
+        return 0;
+    versymbols_t * v = &kh_val(mapsymbols, k);
+    versymbol_t* s = MatchVersion(v, ver, vername, size, local, defver);
     if(s) {
         *start = s->sym.offs;
         *end = *start + s->sym.sz;
diff --git a/src/wrapped/wrappedlibdl.c b/src/wrapped/wrappedlibdl.c
index 4cd70df4..a0f7f4b1 100755
--- a/src/wrapped/wrappedlibdl.c
+++ b/src/wrapped/wrappedlibdl.c
@@ -192,9 +192,9 @@ 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, &weak, version, vername, 1))
+    if(lib->getglobal(lib, rsymbol, start, end, 0, &weak, version, vername, 1))
         return 1;
-    if(lib->getweak(lib, rsymbol, start, end, &weak, version, vername, 1))
+    if(lib->getweak(lib, rsymbol, start, end, 0, &weak, version, vername, 1))
         return 1;
     // look in other libs
     int n = GetNeededLibN(lib);
@@ -238,7 +238,7 @@ void* my_dlsym(x64emu_t* emu, void *handle, void *symbol)
     if(handle==(void*)~0LL) {
         // special case, look globably but no self (RTLD_NEXT)
         elfheader_t *elf = FindElfAddress(my_context, *(uintptr_t*)R_RSP); // use return address to guess "self"
-        if(GetNoSelfSymbolStartEnd(my_context->maplib, rsymbol, &start, &end, elf, -1, NULL)) {
+        if(GetNoSelfSymbolStartEnd(my_context->maplib, rsymbol, &start, &end, elf, 0, -1, NULL)) {
             printf_dlsym(LOG_NEVER, "%p\n", (void*)start);
             return (void*)start;
         }
@@ -376,7 +376,7 @@ void* my_dlvsym(x64emu_t* emu, void *handle, void *symbol, const char *vername)
     if(handle==(void*)~0LL) {
         // special case, look globably but no self (RTLD_NEXT)
         elfheader_t *elf = FindElfAddress(my_context, *(uintptr_t*)R_RSP); // use return address to guess "self"
-        if(GetNoSelfSymbolStartEnd(my_context->maplib, rsymbol, &start, &end, elf, version, vername)) {
+        if(GetNoSelfSymbolStartEnd(my_context->maplib, rsymbol, &start, &end, elf, 0, version, vername)) {
                 printf_dlsym(LOG_NEVER, "%p\n", (void*)start);
             return (void*)start;
         }