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 | |
| parent | 6035cbd5c1204d7c68bb144b948b0ee1c66061d9 (diff) | |
| download | box64-72df0bd1a034f0e7f85b4d778f78ba2e542f5148.tar.gz box64-72df0bd1a034f0e7f85b4d778f78ba2e542f5148.zip | |
Fixed dlsym with RTLD_NEXT and preloaded libs
Diffstat (limited to 'src')
| -rw-r--r-- | src/core.c | 2 | ||||
| -rw-r--r-- | src/include/librarian.h | 1 | ||||
| -rw-r--r-- | src/librarian/librarian.c | 61 | ||||
| -rw-r--r-- | src/librarian/library_private.h | 2 | ||||
| -rw-r--r-- | src/wrapped/wrappedlibdl.c | 4 |
5 files changed, 66 insertions, 4 deletions
diff --git a/src/core.c b/src/core.c index a6972f8b..530f616d 100644 --- a/src/core.c +++ b/src/core.c @@ -2513,7 +2513,7 @@ int initialize(int argc, const char **argv, char** env, x64emu_t** emulator, elf dynarec_wine_prereserve(); #endif } - AddMainElfToLinkmap(elf_header); + AddMainElfToLinkmap(elf_header); //TODO: LinkMap seems incorect // pre-load lib if needed if(ld_preload.size) { my_context->preload = new_neededlib(0); diff --git a/src/include/librarian.h b/src/include/librarian.h index 710c3d43..836b053d 100644 --- a/src/include/librarian.h +++ b/src/include/librarian.h @@ -30,6 +30,7 @@ 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 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 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); 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); 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; diff --git a/src/wrapped/wrappedlibdl.c b/src/wrapped/wrappedlibdl.c index 81ee1ff6..2687b7ad 100644 --- a/src/wrapped/wrappedlibdl.c +++ b/src/wrapped/wrappedlibdl.c @@ -370,7 +370,7 @@ void* my_dlsym(x64emu_t* emu, void *handle, void *symbol) return NULL; } if(handle==(void*)~0LL) { - // special case, look globably but no self (RTLD_NEXT) + // special case, look globably after self in the lm chain (RTLD_NEXT) uintptr_t ret_addr = 0; #ifdef BOX32 if(box64_is32bits) @@ -379,7 +379,7 @@ void* my_dlsym(x64emu_t* emu, void *handle, void *symbol) #endif ret_addr = *(uintptr_t*)R_RSP; elfheader_t *elf = FindElfAddress(my_context, ret_addr); // use return address to guess "self" - if(GetNoSelfSymbolStartEnd(my_context->maplib, rsymbol, &start, &end, elf, 0, -1, NULL, 0, NULL)) { + if(GetNextSymbolStartEnd(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; |