From f8a969d43ed26e64d21238ead0e9512360fb1fdd Mon Sep 17 00:00:00 2001 From: ptitSeb Date: Sat, 29 May 2021 18:05:37 +0200 Subject: Reworked elfloader, handle versionned symbols now --- src/wrapped/wrappedlib_init.h | 18 ++++-- src/wrapped/wrappedlibdl.c | 144 ++++++++++++++++++++++++++++++++++++------ 2 files changed, 137 insertions(+), 25 deletions(-) (limited to 'src/wrapped') 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; isymbolmap, 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; iwsymbolmap, 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; imysymbolmap, 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; istsymbolmap, 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; isymbol2map, 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; icontext, 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; icontext->maplib, rsymbol, &start, &end)) { + if(GetGlobalSymbolStartEnd(emu->context->maplib, rsymbol, &start, &end, NULL, -1, NULL)) { if(dlsym_error && box64_logcontext, *(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_loglibs[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_loglibs[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_logcontext->maplib), rsymbol, &start, &end)) { + if(GetSymbolStartEnd(GetWeakSymbol(emu->context->maplib), rsymbol, &start, &end, -1, NULL, 0)) { if(dlsym_error && box64_logcontext->maplib), rsymbol, &start, &end)) { + if(GetSymbolStartEnd(GetMapSymbol(emu->context->maplib), rsymbol, &start, &end, -1, NULL, 0)) { if(dlsym_error && box64_logdli_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_logcontext->maplib, rsymbol, &start, &end, NULL, version, vername)) { + if(dlsym_error && box64_loglast_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_logcontext, *(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_loglast_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=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_logcount[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_loglibs[nlib]) { + if(my_dlsym_lib(dl->libs[nlib], rsymbol, &start, &end, version, vername)==0) { + // not found + if(dlsym_error && box64_loglibs[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_logcontext->maplib), rsymbol, &start, &end, version, vername, 1)) { + if(dlsym_error && box64_logcontext->maplib), rsymbol, &start, &end, version, vername, 1)) { + if(dlsym_error && box64_loglast_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