diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2025-01-15 11:48:58 +0100 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2025-01-15 11:48:58 +0100 |
| commit | 72df0bd1a034f0e7f85b4d778f78ba2e542f5148 (patch) | |
| tree | 72099c6cf4d11fc41215f68c4eed493dbbf43ca1 /src/librarian | |
| parent | 6035cbd5c1204d7c68bb144b948b0ee1c66061d9 (diff) | |
| download | box64-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.c | 61 | ||||
| -rw-r--r-- | src/librarian/library_private.h | 2 |
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; |