diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2021-05-29 18:05:37 +0200 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2021-05-29 18:05:37 +0200 |
| commit | f8a969d43ed26e64d21238ead0e9512360fb1fdd (patch) | |
| tree | 96dd023f4fef48fe62f8a1d9b7c3a1d61b0c2af4 /src/wrapped | |
| parent | 55720342adbf22ba318a66b30ed9ea6ec789b032 (diff) | |
| download | box64-f8a969d43ed26e64d21238ead0e9512360fb1fdd.tar.gz box64-f8a969d43ed26e64d21238ead0e9512360fb1fdd.zip | |
Reworked elfloader, handle versionned symbols now
Diffstat (limited to 'src/wrapped')
| -rwxr-xr-x | src/wrapped/wrappedlib_init.h | 18 | ||||
| -rwxr-xr-x | src/wrapped/wrappedlibdl.c | 144 |
2 files changed, 137 insertions, 25 deletions
diff --git a/src/wrapped/wrappedlib_init.h b/src/wrapped/wrappedlib_init.h index a3a2049c..d991f8a2 100755 --- a/src/wrapped/wrappedlib_init.h +++ b/src/wrapped/wrappedlib_init.h @@ -130,21 +130,29 @@ int FUNC(_init)(library_t* lib, box64context_t* box64) for (int i=0; i<cnt; ++i) { k = kh_put(symbolmap, lib->symbolmap, MAPNAME(symbolmap)[i].name, &ret); kh_value(lib->symbolmap, k) = MAPNAME(symbolmap)[i].w; + if(strchr(MAPNAME(symbolmap)[i].name, '@')) + AddDictionnary(box64->versym, MAPNAME(symbolmap)[i].name); } cnt = sizeof(MAPNAME(wsymbolmap))/sizeof(map_onesymbol_t); for (int i=0; i<cnt; ++i) { k = kh_put(symbolmap, lib->wsymbolmap, MAPNAME(wsymbolmap)[i].name, &ret); kh_value(lib->wsymbolmap, k) = MAPNAME(wsymbolmap)[i].w; + if(strchr(MAPNAME(wsymbolmap)[i].name, '@')) + AddDictionnary(box64->versym, MAPNAME(wsymbolmap)[i].name); } cnt = sizeof(MAPNAME(mysymbolmap))/sizeof(map_onesymbol_t); for (int i=0; i<cnt; ++i) { k = kh_put(symbolmap, lib->mysymbolmap, MAPNAME(mysymbolmap)[i].name, &ret); kh_value(lib->mysymbolmap, k) = MAPNAME(mysymbolmap)[i].w; + if(strchr(MAPNAME(mysymbolmap)[i].name, '@')) + AddDictionnary(box64->versym, MAPNAME(mysymbolmap)[i].name); } cnt = sizeof(MAPNAME(stsymbolmap))/sizeof(map_onesymbol_t); for (int i=0; i<cnt; ++i) { k = kh_put(symbolmap, lib->stsymbolmap, MAPNAME(stsymbolmap)[i].name, &ret); kh_value(lib->stsymbolmap, k) = MAPNAME(stsymbolmap)[i].w; + if(strchr(MAPNAME(stsymbolmap)[i].name, '@')) + AddDictionnary(box64->versym, MAPNAME(stsymbolmap)[i].name); } cnt = sizeof(MAPNAME(symbol2map))/sizeof(map_onesymbol2_t); for (int i=0; i<cnt; ++i) { @@ -152,6 +160,8 @@ int FUNC(_init)(library_t* lib, box64context_t* box64) kh_value(lib->symbol2map, k).name = MAPNAME(symbol2map)[i].name2; kh_value(lib->symbol2map, k).w = MAPNAME(symbol2map)[i].w; kh_value(lib->symbol2map, k).weak = MAPNAME(symbol2map)[i].weak; + if(strchr(MAPNAME(symbol2map)[i].name, '@')) + AddDictionnary(box64->versym, MAPNAME(symbol2map)[i].name); } cnt = sizeof(MAPNAME(datamap))/sizeof(map_onedata_t); for (int i=0; i<cnt; ++i) { @@ -194,7 +204,7 @@ int FUNC(_fini)(library_t* lib) return 1; } -int FUNC(_get)(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz) +int FUNC(_get)(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, int version, const char* vername, int local) { uintptr_t addr = 0; uintptr_t size = 0; @@ -202,7 +212,7 @@ int FUNC(_get)(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz) void* symbol = NULL; #endif //PRE - if (!getSymbolInMaps(lib, name, 0, &addr, &size)) { + if (!getSymbolInMaps(lib, name, 0, &addr, &size, version, vername, local)) { #ifdef CUSTOM_FAIL CUSTOM_FAIL #else @@ -217,7 +227,7 @@ int FUNC(_get)(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz) return 1; } -int FUNC(_getnoweak)(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz) +int FUNC(_getnoweak)(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, int version, const char* vername, int local) { uintptr_t addr = 0; uintptr_t size = 0; @@ -225,7 +235,7 @@ int FUNC(_getnoweak)(library_t* lib, const char* name, uintptr_t *offs, uintptr_ void* symbol = NULL; #endif //PRE - if (!getSymbolInMaps(lib, name, 1, &addr, &size)) { + if (!getSymbolInMaps(lib, name, 1, &addr, &size, version, vername, local)) { #ifdef CUSTOM_FAIL CUSTOM_FAIL #else diff --git a/src/wrapped/wrappedlibdl.c b/src/wrapped/wrappedlibdl.c index 0d9aa8cb..5655616c 100755 --- a/src/wrapped/wrappedlibdl.c +++ b/src/wrapped/wrappedlibdl.c @@ -42,7 +42,7 @@ char* my_dlerror(x64emu_t* emu) EXPORT; void* my_dlsym(x64emu_t* emu, void *handle, void *symbol) EXPORT; int my_dlclose(x64emu_t* emu, void *handle) EXPORT; int my_dladdr(x64emu_t* emu, void *addr, void *info) EXPORT; -void* my_dlvsym(x64emu_t* emu, void *handle, void *symbol, void *version) EXPORT; +void* my_dlvsym(x64emu_t* emu, void *handle, void *symbol, const char *vername) EXPORT; int my_dlinfo(x64emu_t* emu, void* handle, int request, void* info) EXPORT; #define LIBNAME libdl @@ -97,7 +97,8 @@ void* my_dlopen(x64emu_t* emu, void *filename, int flag) } dlopened = (GetLibInternal(rfilename)==NULL); // Then open the lib - if(AddNeededLib(NULL, NULL, NULL, is_local, rfilename, emu->context, emu)) { + const char* libs[] = {rfilename}; + if(AddNeededLib(NULL, NULL, NULL, is_local, libs, 1, emu->context, emu)) { printf_log(LOG_INFO, "Warning: Cannot dlopen(\"%s\"/%p, %X)\n", rfilename, filename, flag); if(!dl->last_error) dl->last_error = malloc(129); @@ -152,7 +153,7 @@ char* my_dlerror(x64emu_t* emu) KHASH_SET_INIT_INT(libs); -int recursive_dlsym_lib(kh_libs_t* collection, library_t* lib, const char* rsymbol, uintptr_t *start, uintptr_t *end) +int recursive_dlsym_lib(kh_libs_t* collection, library_t* lib, const char* rsymbol, uintptr_t *start, uintptr_t *end, int version, const char* vername) { if(!lib) return 0; @@ -162,23 +163,23 @@ int recursive_dlsym_lib(kh_libs_t* collection, library_t* lib, const char* rsymb int ret; kh_put(libs, collection, (uintptr_t)lib, &ret); // look in the library itself - if(lib->get(lib, rsymbol, start, end)) + if(lib->get(lib, rsymbol, start, end, version, vername, 1)) return 1; // look in other libs int n = GetNeededLibN(lib); for (int i=0; i<n; ++i) { library_t *l = GetNeededLib(lib, i); - if(recursive_dlsym_lib(collection, l, rsymbol, start, end)) + if(recursive_dlsym_lib(collection, l, rsymbol, start, end, version, vername)) return 1; } return 0; } -int my_dlsym_lib(library_t* lib, const char* rsymbol, uintptr_t *start, uintptr_t *end) +int my_dlsym_lib(library_t* lib, const char* rsymbol, uintptr_t *start, uintptr_t *end, int version, const char* vername) { kh_libs_t *collection = kh_init(libs); - int ret = recursive_dlsym_lib(collection, lib, rsymbol, start, end); + int ret = recursive_dlsym_lib(collection, lib, rsymbol, start, end, version, vername); kh_destroy(libs, collection); return ret; @@ -196,7 +197,7 @@ void* my_dlsym(x64emu_t* emu, void *handle, void *symbol) printf_log(LOG_DEBUG, "Call to dlsym(%p, \"%s\")\n", handle, rsymbol); if(handle==NULL) { // special case, look globably - if(GetGlobalSymbolStartEnd(emu->context->maplib, rsymbol, &start, &end)) { + if(GetGlobalSymbolStartEnd(emu->context->maplib, rsymbol, &start, &end, NULL, -1, NULL)) { if(dlsym_error && box64_log<LOG_DEBUG) { printf_log(LOG_NONE, "%p\n", (void*)start); } @@ -212,8 +213,8 @@ void* my_dlsym(x64emu_t* emu, void *handle, void *symbol) } if(handle==(void*)0xFFFFFFFF) { // special case, look globably but no self (RTLD_NEXT) - elfheader_t *elf = FindElfAddress(emu->context, *(uint32_t*)R_RSP); // use return address to guess "self" - if(GetNoSelfSymbolStartEnd(emu->context->maplib, rsymbol, &start, &end, elf)) { + elfheader_t *elf = FindElfAddress(emu->context, *(uintptr_t*)R_RSP); // use return address to guess "self" + if(GetNoSelfSymbolStartEnd(emu->context->maplib, rsymbol, &start, &end, elf, -1, NULL)) { if(dlsym_error && box64_log<LOG_DEBUG) { printf_log(LOG_NONE, "%p\n", (void*)start); } @@ -249,7 +250,7 @@ void* my_dlsym(x64emu_t* emu, void *handle, void *symbol) return NULL; } if(dl->libs[nlib]) { - if(my_dlsym_lib(dl->libs[nlib], rsymbol, &start, &end)==0) { + if(my_dlsym_lib(dl->libs[nlib], rsymbol, &start, &end, -1, NULL)==0) { // not found if(dlsym_error && box64_log<LOG_DEBUG) { printf_log(LOG_NONE, "%p\nCall to dlsym(%s, \"%s\") Symbol not found\n", NULL, GetNameLib(dl->libs[nlib]), rsymbol); @@ -262,19 +263,19 @@ void* my_dlsym(x64emu_t* emu, void *handle, void *symbol) } } else { // still usefull? - if(GetSymbolStartEnd(GetLocalSymbol(emu->context->maplib), rsymbol, &start, &end)) { + if(GetSymbolStartEnd(GetLocalSymbol(emu->context->maplib), rsymbol, &start, &end, -1, NULL, 0)) { if(dlsym_error && box64_log<LOG_DEBUG) { printf_log(LOG_NONE, "%p\n", (void*)start); } return (void*)start; } - if(GetSymbolStartEnd(GetWeakSymbol(emu->context->maplib), rsymbol, &start, &end)) { + if(GetSymbolStartEnd(GetWeakSymbol(emu->context->maplib), rsymbol, &start, &end, -1, NULL, 0)) { if(dlsym_error && box64_log<LOG_DEBUG) { printf_log(LOG_NONE, "%p\n", (void*)start); } return (void*)start; } - if(GetSymbolStartEnd(GetMapSymbol(emu->context->maplib), rsymbol, &start, &end)) { + if(GetSymbolStartEnd(GetMapSymbol(emu->context->maplib), rsymbol, &start, &end, -1, NULL, 0)) { if(dlsym_error && box64_log<LOG_DEBUG) { printf_log(LOG_NONE, "%p\n", (void*)start); } @@ -352,16 +353,117 @@ int my_dladdr(x64emu_t* emu, void *addr, void *i) printf_log(LOG_DEBUG, " dladdr return saddr=%p, fname=\"%s\", sname=\"%s\"\n", info->dli_saddr, info->dli_sname?info->dli_sname:"", info->dli_fname?info->dli_fname:""); return (info->dli_sname)?1:0; // success is non-null here... } -void* my_dlvsym(x64emu_t* emu, void *handle, void *symbol, void *version) +void* my_dlvsym(x64emu_t* emu, void *handle, void *symbol, const char *vername) { dlprivate_t *dl = emu->context->dlprivate; - CLEARERR - //void *dlvsym(void *handle, char *symbol, char *version); + int version = (vername)?2:-1; + uintptr_t start, end; char* rsymbol = (char*)symbol; - char* rversion = (char*)version; - printf_log(LOG_INFO, "Warning: unimplement call to dlvsym(%p, %s, %s), fallback to dlsym\n", handle, rsymbol, rversion); - - return my_dlsym(emu, handle, symbol); + CLEARERR + if(dlsym_error && box64_log<LOG_DEBUG) { + printf_log(LOG_NONE, "Call to dlvsym(%p, %s, %s) :", handle, rsymbol, vername?vername:"(nil)"); + } + printf_log(LOG_DEBUG, "Call to dlvsym(%p, \"%s\", %s)\n", handle, rsymbol, vername?vername:"(nil)"); + if(handle==NULL) { + // special case, look globably + if(GetGlobalSymbolStartEnd(emu->context->maplib, rsymbol, &start, &end, NULL, version, vername)) { + if(dlsym_error && box64_log<LOG_DEBUG) { + printf_log(LOG_NONE, "%p\n", (void*)start); + } + return (void*)start; + } + if(!dl->last_error) + dl->last_error = malloc(129); + snprintf(dl->last_error, 129, "Symbol \"%s\" version %s not found in %p)\n", rsymbol, vername?vername:"(nil)", handle); + if(dlsym_error && box64_log<LOG_DEBUG) { + printf_log(LOG_NONE, "%p\n", NULL); + } + return NULL; + } + if(handle==(void*)0xFFFFFFFF) { + // special case, look globably but no self (RTLD_NEXT) + elfheader_t *elf = FindElfAddress(emu->context, *(uintptr_t*)R_RSP); // use return address to guess "self" + if(GetNoSelfSymbolStartEnd(emu->context->maplib, rsymbol, &start, &end, elf, version, vername)) { + if(dlsym_error && box64_log<LOG_DEBUG) { + printf_log(LOG_NONE, "%p\n", (void*)start); + } + return (void*)start; + } + if(!dl->last_error) + dl->last_error = malloc(129); + snprintf(dl->last_error, 129, "Symbol \"%s\" version %s not found in %p)\n", rsymbol, vername?vername:"(nil)", handle); + if(dlsym_error && box64_log<LOG_DEBUG) { + printf_log(LOG_NONE, "%p\n", NULL); + } + return NULL; + } + size_t nlib = (size_t)handle; + --nlib; + // size_t is unsigned + if(nlib>=dl->lib_sz) { + if(!dl->last_error) + dl->last_error = malloc(129); + snprintf(dl->last_error, 129, "Bad handle %p)\n", handle); + if(dlsym_error && box64_log<LOG_DEBUG) { + printf_log(LOG_NONE, "%p\n", NULL); + } + return NULL; + } + if(dl->count[nlib]==0) { + if(!dl->last_error) + dl->last_error = malloc(129); + snprintf(dl->last_error, 129, "Bad handle %p (already closed))\n", handle); + if(dlsym_error && box64_log<LOG_DEBUG) { + printf_log(LOG_NONE, "%p\n", (void*)NULL); + } + return NULL; + } + if(dl->libs[nlib]) { + if(my_dlsym_lib(dl->libs[nlib], rsymbol, &start, &end, version, vername)==0) { + // not found + if(dlsym_error && box64_log<LOG_DEBUG) { + printf_log(LOG_NONE, "%p\nCall to dlvsym(%s, \"%s\", %s) Symbol not found\n", NULL, GetNameLib(dl->libs[nlib]), rsymbol, vername?vername:"(nil)"); + } + printf_log(LOG_DEBUG, " Symbol not found\n"); + if(!dl->last_error) + dl->last_error = malloc(129); + snprintf(dl->last_error, 129, "Symbol \"%s\" not found in %p(%s)", rsymbol, handle, GetNameLib(dl->libs[nlib])); + return NULL; + } + } else { + // still usefull? + if(GetSymbolStartEnd(GetLocalSymbol(emu->context->maplib), rsymbol, &start, &end, version, vername, 1)) { + if(dlsym_error && box64_log<LOG_DEBUG) { + printf_log(LOG_NONE, "%p\n", (void*)start); + } + return (void*)start; + } + if(GetSymbolStartEnd(GetWeakSymbol(emu->context->maplib), rsymbol, &start, &end, version, vername, 1)) { + if(dlsym_error && box64_log<LOG_DEBUG) { + printf_log(LOG_NONE, "%p\n", (void*)start); + } + return (void*)start; + } + if(GetSymbolStartEnd(GetMapSymbol(emu->context->maplib), rsymbol, &start, &end, version, vername, 1)) { + if(dlsym_error && box64_log<LOG_DEBUG) { + printf_log(LOG_NONE, "%p\n", (void*)start); + } + return (void*)start; + } + // not found + if(dlsym_error && box64_log<LOG_DEBUG) { + printf_log(LOG_NONE, "%p\nCall to dlvsym(%s, \"%s\", %s) Symbol not found\n", NULL, "Self", rsymbol, vername?vername:"(nil)"); + } + printf_log(LOG_DEBUG, " Symbol not found\n"); + if(!dl->last_error) + dl->last_error = malloc(129); + snprintf(dl->last_error, 129, "Symbol \"%s\" version %s not found in %p)\n", rsymbol, vername?vername:"(nil)", handle); + return NULL; + } + if(dlsym_error && box64_log<LOG_DEBUG) { + printf_log(LOG_NONE, "%p\n", (void*)start); + } + return (void*)start; } typedef struct link_map_s { |