about summary refs log tree commit diff stats
path: root/src/librarian/library.c
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/librarian/library.c
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/librarian/library.c')
-rwxr-xr-xsrc/librarian/library.c75
1 files changed, 35 insertions, 40 deletions
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);