about summary refs log tree commit diff stats
path: root/src/librarian
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2025-01-15 11:48:58 +0100
committerptitSeb <sebastien.chev@gmail.com>2025-01-15 11:48:58 +0100
commit72df0bd1a034f0e7f85b4d778f78ba2e542f5148 (patch)
tree72099c6cf4d11fc41215f68c4eed493dbbf43ca1 /src/librarian
parent6035cbd5c1204d7c68bb144b948b0ee1c66061d9 (diff)
downloadbox64-72df0bd1a034f0e7f85b4d778f78ba2e542f5148.tar.gz
box64-72df0bd1a034f0e7f85b4d778f78ba2e542f5148.zip
Fixed dlsym with RTLD_NEXT and preloaded libs
Diffstat (limited to 'src/librarian')
-rw-r--r--src/librarian/librarian.c61
-rw-r--r--src/librarian/library_private.h2
2 files changed, 62 insertions, 1 deletions
diff --git a/src/librarian/librarian.c b/src/librarian/librarian.c
index 415278ae..4298ee05 100644
--- a/src/librarian/librarian.c
+++ b/src/librarian/librarian.c
@@ -462,6 +462,67 @@ int GetNoSelfSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, u
     // nope, not found
     return weak;
 }
+static int isLibPreloaded(library_t* lib)
+{
+    if(my_context->preload)
+        for(int i=0; i<my_context->preload->size; ++i)
+            if(my_context->preload->libs[i] == lib)
+                return 1;
+    return 0;
+}
+int GetNextSymbolStartEnd(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
+    int weak = 0;
+    int next = 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(next) {
+                if(GetLibGlobalSymbolStartEnd(my_context->preload->libs[i], name, start, end, size, &weak, &version, &vername, 0, &veropt, elfsym)) {
+                    return 1;
+                }
+                if(GetLibWeakSymbolStartEnd(my_context->preload->libs[i], name, start, end, size, &weak, &version, &vername, 0, &veropt, elfsym)) {
+                    return 1;
+                }
+            }
+            if(self==GetElf(my_context->preload->libs[i])) {
+                next = 1;
+            }
+        }
+    if(maplib==my_context->maplib) {
+        if(next) {
+            if((sym = ElfGetGlobalSymbolStartEnd(my_context->elfs[0], start, end, name, &version, &vername, 0, &veropt))) {
+                if(elfsym) *elfsym = sym;
+                return 1;
+            }
+            if((sym = ElfGetWeakSymbolStartEnd(my_context->elfs[0], start, end, name, &version, &vername, 0, &veropt))) {
+                if(elfsym) *elfsym = sym;
+                return 1;
+            }
+        }
+        if(self==my_context->elfs[0]) {
+            next = 1;
+        }
+    }
+    // search in global symbols
+    if(maplib) {
+        for(int i=0; i<maplib->libsz; ++i) if(!isLibPreloaded(maplib->libraries[i])) {
+            if(next) {
+                if(GetLibGlobalSymbolStartEnd(maplib->libraries[i], name, start, end, size, &weak, &version, &vername, 0, &veropt, elfsym)) {
+                    return 1;
+                }
+                if(GetLibWeakSymbolStartEnd(maplib->libraries[i], name, start, end, size, &weak, &version, &vername, 0, &veropt, elfsym)) {
+                    return 1;
+                }
+            }
+            if(self==GetElf(maplib->libraries[i]))
+                next = 1;
+        }
+    }
+    return 0;
+}
 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;
diff --git a/src/librarian/library_private.h b/src/librarian/library_private.h
index 495ad000..bd69a364 100644
--- a/src/librarian/library_private.h
+++ b/src/librarian/library_private.h
@@ -78,7 +78,7 @@ typedef struct elib_s {
 typedef struct library_s {
     char*               name;   // <> path
     char*               path;   // original path
-    int8_t              nbdot;  // nombre of "." after .so
+    int8_t              nbdot;  // number of "." after .so
     int8_t              type;   // 0: native(wrapped) 1: emulated(elf) -1: undetermined
     uint8_t             deepbind;
     wrappedlib_fini_t   fini;