diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2023-04-10 14:33:56 +0200 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2023-04-10 14:33:56 +0200 |
| commit | 8439a3add954a038b4219af7fad3abd93cdac119 (patch) | |
| tree | 3d9225afd976b1d26f8de6f0ea63d9e4acfc8b6e /src | |
| parent | 9b3511cc88ea3c03590ccd9158095086de53c9ed (diff) | |
| download | box64-8439a3add954a038b4219af7fad3abd93cdac119.tar.gz box64-8439a3add954a038b4219af7fad3abd93cdac119.zip | |
[ELFLOADER] Improved handling of default versions
Diffstat (limited to 'src')
| -rwxr-xr-x | src/box64context.c | 4 | ||||
| -rwxr-xr-x | src/elfs/elfloader.c | 70 | ||||
| -rwxr-xr-x | src/elfs/elfloader_private.h | 3 | ||||
| -rwxr-xr-x | src/include/box64context.h | 2 | ||||
| -rwxr-xr-x | src/include/elfloader.h | 3 | ||||
| -rwxr-xr-x | src/include/librarian.h | 12 | ||||
| -rwxr-xr-x | src/include/library.h | 6 | ||||
| -rwxr-xr-x | src/include/wrappedlibs.h | 2 | ||||
| -rwxr-xr-x | src/librarian/globalsymbols.c | 14 | ||||
| -rwxr-xr-x | src/librarian/librarian.c | 92 | ||||
| -rwxr-xr-x | src/librarian/library.c | 32 | ||||
| -rwxr-xr-x | src/main.c | 8 | ||||
| -rwxr-xr-x | src/wrapped/wrappedgtkx112.c | 2 | ||||
| -rwxr-xr-x | src/wrapped/wrappedlibdl.c | 48 |
14 files changed, 173 insertions, 125 deletions
diff --git a/src/box64context.c b/src/box64context.c index bae00f9c..082831f3 100755 --- a/src/box64context.c +++ b/src/box64context.c @@ -201,8 +201,6 @@ box64context_t *NewBox64Context(int argc) context->local_maplib = NewLibrarian(context, 1); context->versym = NewDictionnary(); context->system = NewBridge(); - context->globaldefver = NewDefaultVersion(); - context->weakdefver = NewDefaultVersion(); // create vsyscall context->vsyscall = AddBridge(context->system, vFEv, x64Syscall, 0, NULL); // create the vsyscalls @@ -252,8 +250,6 @@ void FreeBox64Context(box64context_t** context) if(ctx->maplib) FreeLibrarian(&ctx->maplib, NULL); FreeDictionnary(&ctx->versym); - FreeDefaultVersion(&ctx->globaldefver); - FreeDefaultVersion(&ctx->weakdefver); for(int i=0; i<ctx->elfsize; ++i) { FreeElfHeader(&ctx->elfs[i]); diff --git a/src/elfs/elfloader.c b/src/elfs/elfloader.c index c2705250..a0007f41 100755 --- a/src/elfs/elfloader.c +++ b/src/elfs/elfloader.c @@ -65,6 +65,8 @@ elfheader_t* LoadAndCheckElfHeader(FILE* f, const char* name, int exec) h->mapsymbols = NewMapSymbols(); h->weaksymbols = NewMapSymbols(); h->localsymbols = NewMapSymbols(); + h->globaldefver = NewDefaultVersion(); + h->weakdefver = NewDefaultVersion(); h->refcnt = 1; return h; @@ -95,6 +97,8 @@ void FreeElfHeader(elfheader_t** head) FreeMapSymbols(&h->mapsymbols); FreeMapSymbols(&h->weaksymbols); FreeMapSymbols(&h->localsymbols); + FreeDefaultVersion(&h->globaldefver); + FreeDefaultVersion(&h->weakdefver); FreeElfMemory(h); box_free(h); @@ -446,16 +450,17 @@ int RelocateElfREL(lib_t *maplib, lib_t *local_maplib, int bindnow, elfheader_t* int version = head->VerSym?((Elf64_Half*)((uintptr_t)head->VerSym+head->delta))[ELF64_R_SYM(rel[i].r_info)]:-1; if(version!=-1) version &=0x7fff; const char* vername = GetSymbolVersion(head, version); - const char* defver = GetDefaultVersion((bind==STB_WEAK)?my_context->weakdefver:my_context->globaldefver, symname); + const char* globdefver = (bind==STB_WEAK)?NULL:GetMaplibDefaultVersion(maplib, local_maplib, 0, symname); + const char* weakdefver = (bind==STB_WEAK)?GetMaplibDefaultVersion(maplib, local_maplib, 1, symname):NULL; if(bind==STB_LOCAL) { if(!symname || !symname[0]) { offs = sym->st_value + head->delta; end = offs + sym->st_size; } else { if(!offs && !end && local_maplib) - GetLocalSymbolStartEnd(local_maplib, symname, &offs, &end, head, version, vername); + GetLocalSymbolStartEnd(local_maplib, symname, &offs, &end, head, version, vername, globdefver, weakdefver); if(!offs && !end) - GetLocalSymbolStartEnd(maplib, symname, &offs, &end, head, version, vername); + GetLocalSymbolStartEnd(maplib, symname, &offs, &end, head, version, vername, globdefver, weakdefver); } } else { // this is probably very very wrong. A proprer way to get reloc need to be written, but this hack seems ok for now @@ -467,9 +472,9 @@ int RelocateElfREL(lib_t *maplib, lib_t *local_maplib, int bindnow, elfheader_t* // so weak symbol are the one left if(!offs && !end) { if(!offs && !end && local_maplib) - GetGlobalSymbolStartEnd(local_maplib, symname, &offs, &end, head, version, vername); + GetGlobalSymbolStartEnd(local_maplib, symname, &offs, &end, head, version, vername, globdefver, weakdefver); if(!offs && !end && local_maplib) - GetGlobalSymbolStartEnd(maplib, symname, &offs, &end, head, version, vername); + GetGlobalSymbolStartEnd(maplib, symname, &offs, &end, head, version, vername, globdefver, weakdefver); } } uintptr_t globoffs, globend; @@ -490,7 +495,7 @@ int RelocateElfREL(lib_t *maplib, lib_t *local_maplib, int bindnow, elfheader_t* *p += offs; break; case R_X86_64_GLOB_DAT: - if(head!=my_context->elfs[0] && !IsGlobalNoWeakSymbolInNative(maplib, symname, version, vername) && FindR64COPYRel(my_context->elfs[0], symname, &globoffs, &globp, size, version, vername)) { + if(head!=my_context->elfs[0] && !IsGlobalNoWeakSymbolInNative(maplib, symname, version, vername, globdefver) && FindR64COPYRel(my_context->elfs[0], symname, &globoffs, &globp, size, version, vername)) { // set global offs / size for the symbol offs = sym->st_value; end = offs + sym->st_size; @@ -504,7 +509,7 @@ int RelocateElfREL(lib_t *maplib, lib_t *local_maplib, int bindnow, elfheader_t* *p = globoffs; } else { // Look for same symbol already loaded but not in self (so no need for local_maplib here) - if (GetGlobalNoWeakSymbolStartEnd(local_maplib?local_maplib:maplib, symname, &globoffs, &globend, version, vername)) { + if (GetGlobalNoWeakSymbolStartEnd(local_maplib?local_maplib:maplib, symname, &globoffs, &globend, version, vername, globdefver)) { offs = globoffs; end = globend; } @@ -522,11 +527,11 @@ int RelocateElfREL(lib_t *maplib, lib_t *local_maplib, int bindnow, elfheader_t* uintptr_t old_offs = offs; uintptr_t old_end = end; offs = 0; - GetSizedSymbolStartEnd(GetGlobalData(maplib), symname, &offs, &end, size, version, vername, 1, defver); // try globaldata symbols first + GetSizedSymbolStartEnd(GetGlobalData(maplib), symname, &offs, &end, size, version, vername, 1, globdefver); // try globaldata symbols first if(offs==0) { - GetNoSelfSymbolStartEnd(maplib, symname, &offs, &end, head, size, version, vername); // get original copy if any + GetNoSelfSymbolStartEnd(maplib, symname, &offs, &end, head, size, version, vername, globdefver, weakdefver); // get original copy if any if(!offs && local_maplib) - GetNoSelfSymbolStartEnd(local_maplib, symname, &offs, &end, head, size, version, vername); + GetNoSelfSymbolStartEnd(local_maplib, symname, &offs, &end, head, size, version, vername, globdefver, weakdefver); } if(!offs) { offs = old_offs; @@ -626,16 +631,17 @@ int RelocateElfRELA(lib_t *maplib, lib_t *local_maplib, int bindnow, elfheader_t int version = head->VerSym?((Elf64_Half*)((uintptr_t)head->VerSym+head->delta))[ELF64_R_SYM(rela[i].r_info)]:-1; if(version!=-1) version &=0x7fff; const char* vername = GetSymbolVersion(head, version); - const char* defver = GetDefaultVersion((bind==STB_WEAK)?my_context->weakdefver:my_context->globaldefver, symname); + const char* globdefver = (bind==STB_WEAK)?NULL:GetMaplibDefaultVersion(maplib, local_maplib, 0, symname); + const char* weakdefver = (bind==STB_WEAK)?GetMaplibDefaultVersion(maplib, local_maplib, 1, symname):NULL; if(bind==STB_LOCAL) { if(!symname || !symname[0]) { offs = sym->st_value + head->delta; end = offs + sym->st_size; } else { if(!offs && !end && local_maplib) - GetLocalSymbolStartEnd(local_maplib, symname, &offs, &end, head, version, vername); + GetLocalSymbolStartEnd(local_maplib, symname, &offs, &end, head, version, vername, globdefver, weakdefver); if(!offs && !end) - GetLocalSymbolStartEnd(maplib, symname, &offs, &end, head, version, vername); + GetLocalSymbolStartEnd(maplib, symname, &offs, &end, head, version, vername, globdefver, weakdefver); } } else { // this is probably very very wrong. A proprer way to get reloc need to be written, but this hack seems ok for now @@ -646,9 +652,9 @@ int RelocateElfRELA(lib_t *maplib, lib_t *local_maplib, int bindnow, elfheader_t }*/ // so weak symbol are the one left if(!offs && !end) { - GetGlobalSymbolStartEnd(maplib, symname, &offs, &end, head, version, vername); + GetGlobalSymbolStartEnd(maplib, symname, &offs, &end, head, version, vername, globdefver, weakdefver); if(!offs && !end && local_maplib) { - GetGlobalSymbolStartEnd(local_maplib, symname, &offs, &end, head, version, vername); + GetGlobalSymbolStartEnd(local_maplib, symname, &offs, &end, head, version, vername, globdefver, weakdefver); } } } @@ -679,11 +685,11 @@ int RelocateElfRELA(lib_t *maplib, lib_t *local_maplib, int bindnow, elfheader_t globoffs = offs; globend = end; offs = end = 0; - GetSizedSymbolStartEnd(GetGlobalData(maplib), symname, &offs, &end, size, version, vername, 1, defver); // try globaldata symbols first + GetSizedSymbolStartEnd(GetGlobalData(maplib), symname, &offs, &end, size, version, vername, 1, globdefver); // try globaldata symbols first if(!offs && local_maplib) - GetNoSelfSymbolStartEnd(local_maplib, symname, &offs, &end, head, size, version, vername); + GetNoSelfSymbolStartEnd(local_maplib, symname, &offs, &end, head, size, version, vername, globdefver, weakdefver); if(!offs) - GetNoSelfSymbolStartEnd(maplib, symname, &offs, &end, head, size, version, vername); + GetNoSelfSymbolStartEnd(maplib, symname, &offs, &end, head, size, version, vername, globdefver, weakdefver); if(!offs) {offs = globoffs; end = globend;} if(offs) { // add r_addend to p? @@ -695,7 +701,7 @@ int RelocateElfRELA(lib_t *maplib, lib_t *local_maplib, int bindnow, elfheader_t } break; case R_X86_64_GLOB_DAT: - if(head!=my_context->elfs[0] && !IsGlobalNoWeakSymbolInNative(maplib, symname, version, vername) && FindR64COPYRel(my_context->elfs[0], symname, &globoffs, &globp, size, version, vername)) { + if(head!=my_context->elfs[0] && !IsGlobalNoWeakSymbolInNative(maplib, symname, version, vername, globdefver) && FindR64COPYRel(my_context->elfs[0], symname, &globoffs, &globp, size, version, vername)) { // set global offs / size for the symbol offs = sym->st_value + head->delta; end = offs + sym->st_size; @@ -713,7 +719,7 @@ int RelocateElfRELA(lib_t *maplib, lib_t *local_maplib, int bindnow, elfheader_t *p = globoffs; } else { // Look for same symbol already loaded but not in self (so no need for local_maplib here) - if (GetGlobalNoWeakSymbolStartEnd(local_maplib?local_maplib:maplib, symname, &globoffs, &globend, version, vername)) { + if (GetGlobalNoWeakSymbolStartEnd(local_maplib?local_maplib:maplib, symname, &globoffs, &globend, version, vername, globdefver)) { offs = globoffs; end = globend; } @@ -1008,7 +1014,7 @@ void AddSymbols(lib_t *maplib, kh_mapsymbols_t* mapsymbols, kh_mapsymbols_t* wea p+=2; symname = AddDictionnary(my_context->versym, symnameversioned); const char* vername = AddDictionnary(my_context->versym, p); - AddDefaultVersion((bind==STB_WEAK)?my_context->weakdefver:my_context->globaldefver, symname, vername); + AddDefaultVersion((bind==STB_WEAK)?h->weakdefver:h->globaldefver, symname, vername); if((bind==STB_GNU_UNIQUE /*|| (bind==STB_GLOBAL && type==STT_FUNC)*/) && FindGlobalSymbol(maplib, symname, 2, p)) continue; uintptr_t offs = (type==STT_TLS)?h->SymTab[i].st_value:(h->SymTab[i].st_value + h->delta); @@ -1050,11 +1056,11 @@ void AddSymbols(lib_t *maplib, kh_mapsymbols_t* mapsymbols, kh_mapsymbols_t* wea uintptr_t offs = (type==STT_TLS)?h->DynSym[i].st_value:(h->DynSym[i].st_value + h->delta); size_t sz = h->DynSym[i].st_size; int version = h->VerSym?((Elf64_Half*)((uintptr_t)h->VerSym+h->delta))[i]:-1; - int add_default = (version!=-1 && (version&0x7fff)>1 && !(version&0x8000) && !GetDefaultVersion((bind==STB_WEAK)?my_context->weakdefver:my_context->globaldefver, symname))?1:0; + int add_default = (version!=-1 && (version&0x7fff)>1 && !(version&0x8000) && !GetMaplibDefaultVersion(my_context->maplib, (maplib==my_context->maplib)?NULL:maplib, (bind==STB_WEAK)?1:0, symname))?1:0; if(version!=-1) version &= 0x7fff; const char* vername = GetSymbolVersion(h, version); if(add_default) { - AddDefaultVersion((bind==STB_WEAK)?my_context->weakdefver:my_context->globaldefver, symname, vername); + AddDefaultVersion((bind==STB_WEAK)?h->weakdefver:h->globaldefver, symname, vername); printf_dump(LOG_NEVER, "Adding Default Version \"%s\" for Symbol\"%s\"\n", vername, symname); } int to_add = 1; @@ -1771,6 +1777,16 @@ void* GetNativeSymbolUnversioned(void* lib, const char* name) return s.addr; } +kh_defaultversion_t* GetGlobalDefaultVersion(elfheader_t* h) +{ + return h?h->globaldefver:NULL; +} +kh_defaultversion_t* GetWeakDefaultVersion(elfheader_t* h) +{ + return h?h->weakdefver:NULL; +} + + uintptr_t pltResolver = ~0LL; EXPORT void PltResolver(x64emu_t* emu) { @@ -1793,12 +1809,14 @@ EXPORT void PltResolver(x64emu_t* emu) library_t* lib = h->lib; lib_t* local_maplib = GetMaplib(lib); - GetGlobalSymbolStartEnd(my_context->maplib, symname, &offs, &end, h, version, vername); + const char* globdefver = (bind==STB_WEAK)?NULL:GetMaplibDefaultVersion(my_context->maplib, (my_context->maplib==local_maplib)?NULL:local_maplib, 0, symname); + const char* weakdefver = (bind==STB_WEAK)?GetMaplibDefaultVersion(my_context->maplib, (my_context->maplib==local_maplib)?NULL:local_maplib, 1, symname):NULL; + GetGlobalSymbolStartEnd(my_context->maplib, symname, &offs, &end, h, version, vername, globdefver, weakdefver); if(!offs && !end && local_maplib) { - GetGlobalSymbolStartEnd(local_maplib, symname, &offs, &end, h, version, vername); + GetGlobalSymbolStartEnd(local_maplib, symname, &offs, &end, h, version, vername, globdefver, weakdefver); } if(!offs && !end && !version) - GetGlobalSymbolStartEnd(my_context->maplib, symname, &offs, &end, h, -1, NULL); + GetGlobalSymbolStartEnd(my_context->maplib, symname, &offs, &end, h, -1, NULL, globdefver, weakdefver); if (!offs) { printf_log(LOG_NONE, "Error: PltResolver: Symbol %s(ver %d: %s%s%s) not found, cannot apply R_X86_64_JUMP_SLOT %p (%p) in %s\n", symname, version, symname, vername?"@":"", vername?vername:"", p, *(void**)p, h->name); diff --git a/src/elfs/elfloader_private.h b/src/elfs/elfloader_private.h index c3d387ef..a6116ad7 100755 --- a/src/elfs/elfloader_private.h +++ b/src/elfs/elfloader_private.h @@ -4,6 +4,7 @@ typedef struct library_s library_t; typedef struct needed_libs_s needed_libs_t; typedef struct kh_mapsymbols_s kh_mapsymbols_t; +typedef struct kh_defaultversion_s kh_defaultversion_t; #include <elf.h> #include "elfloader.h" @@ -98,6 +99,8 @@ struct elfheader_s { kh_mapsymbols_t *mapsymbols; kh_mapsymbols_t *weaksymbols; kh_mapsymbols_t *localsymbols; + kh_defaultversion_t *globaldefver; // the global default version for symbols (the XXX@@vvvv of symbols) + kh_defaultversion_t *weakdefver; // the weak default version for symbols (the XXX@@vvvv of symbols) }; #define R_X86_64_NONE 0 /* No reloc */ diff --git a/src/include/box64context.h b/src/include/box64context.h index 62e4bad5..c4e88a83 100755 --- a/src/include/box64context.h +++ b/src/include/box64context.h @@ -118,8 +118,6 @@ typedef struct box64context_s { kh_symbolmap_t *almymap; // link to the mysymbolmap if libOpenAL kh_symbolmap_t *vkwrappers; // the map of wrapper for VulkanProcs (TODO: check SDL2) kh_symbolmap_t *vkmymap; // link to the mysymbolmap of libGL - kh_defaultversion_t *globaldefver; // the global default version for symbols (the XXX@@vvvv of symbols) - kh_defaultversion_t *weakdefver; // the weak default version for symbols (the XXX@@vvvv of symbols) vkprocaddess_t vkprocaddress; #ifndef DYNAREC diff --git a/src/include/elfloader.h b/src/include/elfloader.h index c197249d..d5b54145 100755 --- a/src/include/elfloader.h +++ b/src/include/elfloader.h @@ -9,6 +9,7 @@ typedef struct kh_mapsymbols_s kh_mapsymbols_t; typedef struct box64context_s box64context_t; typedef struct x64emu_s x64emu_t; typedef struct needed_libs_s needed_libs_t; +typedef struct kh_defaultversion_s kh_defaultversion_t; #ifdef DYNAREC typedef struct dynablock_s dynablock_t; #endif @@ -67,6 +68,8 @@ int GetVersionIndice(elfheader_t* h, const char* vername); kh_mapsymbols_t* GetMapSymbols(elfheader_t* h); kh_mapsymbols_t* GetWeakSymbols(elfheader_t* h); kh_mapsymbols_t* GetLocalSymbols(elfheader_t* h); +kh_defaultversion_t* GetGlobalDefaultVersion(elfheader_t* h); +kh_defaultversion_t* GetWeakDefaultVersion(elfheader_t* h); void* GetNativeSymbolUnversioned(void* lib, const char* name); diff --git a/src/include/librarian.h b/src/include/librarian.h index 5c1fe0f2..d374ae93 100755 --- a/src/include/librarian.h +++ b/src/include/librarian.h @@ -25,12 +25,14 @@ int AddNeededLib(lib_t* maplib, int local, int bindnow, needed_libs_t* needed, b library_t* GetLibMapLib(lib_t* maplib, const char* name); library_t* GetLibInternal(const char* name); uintptr_t FindGlobalSymbol(lib_t *maplib, const char* name, int version, const char* vername); -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 GetGlobalSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, elfheader_t *self, int version, const char* vername); -int GetGlobalNoWeakSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, int version, const char* vername); -int GetLocalSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, elfheader_t *self, int version, const char* vername); +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, const char* globdefver, const char* weakdefver); +int GetGlobalSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, elfheader_t *self, int version, const char* vername, const char* globdefver, const char* weakdefver); +int GetGlobalNoWeakSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, int version, const char* vername, const char* defver); +int GetLocalSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, elfheader_t *self, int version, const char* vername, const char* globdefver, const char* weakdefver); elfheader_t* GetGlobalSymbolElf(lib_t *maplib, const char* name, int version, const char* vername); -int IsGlobalNoWeakSymbolInNative(lib_t *maplib, const char* name, int version, const char* vername); +int IsGlobalNoWeakSymbolInNative(lib_t *maplib, const char* name, int version, const char* vername, const char* defver); + +const char* GetMaplibDefaultVersion(lib_t *maplib, lib_t *local_maplib, int isweak, const char* symname); const char* FindSymbolName(lib_t *maplib, void* p, void** start, uint64_t* sz, const char** libname, void** base, library_t** lib); diff --git a/src/include/library.h b/src/include/library.h index afe108e7..29c7061d 100755 --- a/src/include/library.h +++ b/src/include/library.h @@ -25,9 +25,9 @@ void Free1Library(library_t **lib, x64emu_t* emu); char* GetNameLib(library_t *lib); int IsSameLib(library_t* lib, const char* path); // check if lib is same (path -> name) -int GetLibGlobalSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start, uintptr_t* end, size_t size, int* weak, int version, const char* vername, int local); -int GetLibWeakSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start, uintptr_t* end, size_t size, int* weak, int version, const char* vername, int local); -int GetLibLocalSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start, uintptr_t* end, size_t size, int* weak, int version, const char* vername, int local); +int GetLibGlobalSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start, uintptr_t* end, size_t size, int* weak, int version, const char* vername, int local, const char* defver); +int GetLibWeakSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start, uintptr_t* end, size_t size, int* weak, int version, const char* vername, int local, const char* defver); +int GetLibLocalSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start, uintptr_t* end, size_t size, int* weak, int version, const char* vername, int local, const char* defver); char** GetNeededLibsNames(library_t* lib); int GetNeededLibsN(library_t* lib); library_t* GetNeededLib(library_t* lib, int idx); diff --git a/src/include/wrappedlibs.h b/src/include/wrappedlibs.h index 07014e46..2d87a933 100755 --- a/src/include/wrappedlibs.h +++ b/src/include/wrappedlibs.h @@ -7,7 +7,7 @@ typedef struct box64context_s box64context_t; typedef int (*wrappedlib_init_t)(library_t * lib, box64context_t* box64); // 0 = success typedef void (*wrappedlib_fini_t)(library_t * lib); -typedef int (*wrappedlib_get_t)(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, size_t size, int* weak, int version, const char* vername, int local); +typedef int (*wrappedlib_get_t)(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, size_t size, int* weak, int version, const char* vername, int local, const char* defver); void setNeededLibs(library_t* lib, int n, ...); #define SETALT(A) lib->w.altmy = box_strdup(#A) diff --git a/src/librarian/globalsymbols.c b/src/librarian/globalsymbols.c index 3a932d86..cedf1248 100755 --- a/src/librarian/globalsymbols.c +++ b/src/librarian/globalsymbols.c @@ -17,15 +17,15 @@ // workaround for Globals symbols #define GLOB(A) \ - if (GetGlobalNoWeakSymbolStartEnd(my_context->maplib, #A, &globoffs, &globend, -1, NULL)) { \ - printf_log(LOG_DEBUG, "Global " #A " workaround, @%p <- %p\n", (void*)globoffs, &A); \ - memcpy((void*)globoffs, &A, sizeof(A)); \ + if (GetGlobalNoWeakSymbolStartEnd(my_context->maplib, #A, &globoffs, &globend, -1, NULL, NULL)) { \ + printf_log(LOG_DEBUG, "Global " #A " workaround, @%p <- %p\n", (void*)globoffs, &A); \ + memcpy((void*)globoffs, &A, sizeof(A)); \ } #define TOGLOB(A) \ - if (GetGlobalNoWeakSymbolStartEnd(my_context->maplib, #A, &globoffs, &globend, -1, NULL)) { \ - printf_log(LOG_DEBUG, "Global " #A " workaround, @%p -> %p\n", (void*)globoffs, &A); \ - memcpy(&A, (void*)globoffs, sizeof(A)); \ + if (GetGlobalNoWeakSymbolStartEnd(my_context->maplib, #A, &globoffs, &globend, -1, NULL, NULL)) { \ + printf_log(LOG_DEBUG, "Global " #A " workaround, @%p -> %p\n", (void*)globoffs, &A); \ + memcpy(&A, (void*)globoffs, sizeof(A)); \ } @@ -42,7 +42,7 @@ void my_setGlobalGThreadsInit() { int val = 1; uintptr_t globoffs, globend; - if (GetGlobalNoWeakSymbolStartEnd(my_context->maplib, "g_threads_got_initialized", &globoffs, &globend, -1, NULL)) { + if (GetGlobalNoWeakSymbolStartEnd(my_context->maplib, "g_threads_got_initialized", &globoffs, &globend, -1, NULL, NULL)) { printf_log(LOG_DEBUG, "Global g_threads_got_initialized workaround, @%p <= %d\n", (void*)globoffs, val); memcpy((void*)globoffs, &val, sizeof(val)); } diff --git a/src/librarian/librarian.c b/src/librarian/librarian.c index 919389bc..e3cca3de 100755 --- a/src/librarian/librarian.c +++ b/src/librarian/librarian.c @@ -338,7 +338,9 @@ EXPORTDYN uintptr_t FindGlobalSymbol(lib_t *maplib, const char* name, int version, const char* vername) { uintptr_t start = 0, end = 0; - if(GetGlobalSymbolStartEnd(maplib, name, &start, &end, (void*)1, version, vername)) + const char *globdefver = GetMaplibDefaultVersion(my_context->maplib, (my_context->maplib==maplib)?NULL:maplib, 0, name); + const char *weakdefver = GetMaplibDefaultVersion(my_context->maplib, (my_context->maplib==maplib)?NULL:maplib, 1, name); + if(GetGlobalSymbolStartEnd(maplib, name, &start, &end, (void*)1, version, vername, globdefver, weakdefver)) return start; return 0; } @@ -350,7 +352,7 @@ static int isLocal(elfheader_t* self, library_t* l) return 0; } -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 GetNoSelfSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, elfheader_t* self, size_t size, int version, const char* vername, const char* globdefver, const char* weakdefver) { assert(self); // need self for this one //search for the self, to start "next" @@ -364,37 +366,35 @@ int GetNoSelfSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, u go = 0; // not found... for(int i=go; i<maplib->libsz; ++i) { if(GetElfIndex(maplib->libraries[i])==-1 || (my_context->elfs[GetElfIndex(maplib->libraries[i])]!=self)) - if(GetLibGlobalSymbolStartEnd(maplib->libraries[i], name, start, end, size, &weak, version, vername, 0)) + if(GetLibGlobalSymbolStartEnd(maplib->libraries[i], name, start, end, size, &weak, version, vername, 0, globdefver)) if(*start) return 1; } for(int i=go; i<maplib->libsz; ++i) if(GetElfIndex(maplib->libraries[i])==-1 || (my_context->elfs[GetElfIndex(maplib->libraries[i])]!=self)) - GetLibWeakSymbolStartEnd(maplib->libraries[i], name, start, end, size, &weak, version, vername, 0); + GetLibWeakSymbolStartEnd(maplib->libraries[i], name, start, end, size, &weak, version, vername, 0, weakdefver); // loop done, weak symbol found if(weak && *start) return 1; // if self defined, give it another chance with self... if(self) { if(my_context->elfs[0]!=self) { - const char* defver = GetDefaultVersion(my_context->globaldefver, name); - if(GetSizedSymbolStartEnd(GetMapSymbols(my_context->elfs[0]), name, start, end, size, version, vername, 1, defver)) + if(GetSizedSymbolStartEnd(GetMapSymbols(my_context->elfs[0]), name, start, end, size, version, vername, 1, globdefver)) if(*start) return 1; - defver = GetDefaultVersion(my_context->weakdefver, name); - if(GetSizedSymbolStartEnd(GetWeakSymbols(my_context->elfs[0]), name, start, end, size, version, vername, 1, defver)) + if(GetSizedSymbolStartEnd(GetWeakSymbols(my_context->elfs[0]), name, start, end, size, version, vername, 1, weakdefver)) if(*start) weak = 1; } for(int i=0; i<go; ++i) { if(GetElfIndex(maplib->libraries[i])==-1 || (my_context->elfs[GetElfIndex(maplib->libraries[i])]!=self)) - if(GetLibGlobalSymbolStartEnd(maplib->libraries[i], name, start, end, size, &weak, version, vername, 1)) + if(GetLibGlobalSymbolStartEnd(maplib->libraries[i], name, start, end, size, &weak, version, vername, 1, globdefver)) if(*start) return 1; } for(int i=0; i<go; ++i) { if(GetElfIndex(maplib->libraries[i])==-1 || (my_context->elfs[GetElfIndex(maplib->libraries[i])]!=self)) - GetLibWeakSymbolStartEnd(maplib->libraries[i], name, start, end, size, &weak, version, vername, 1); + GetLibWeakSymbolStartEnd(maplib->libraries[i], name, start, end, size, &weak, version, vername, 1, weakdefver); } if(weak && *start) return 1; @@ -402,46 +402,43 @@ int GetNoSelfSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, u // nope, not found 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) +static int GetGlobalSymbolStartEnd_internal(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, elfheader_t* self, int version, const char* vername, const char* globdefver, const char* weakdefver) { int weak = 0; size_t size = 0; - // check with default version... - const char* defver = GetDefaultVersion(my_context->globaldefver, name); // search in needed libs from preloaded first, in order if(my_context->preload) for(int i=0; i<my_context->preload->size; ++i) - if(GetLibGlobalSymbolStartEnd(my_context->preload->libs[i], name, start, end, size, &weak, version, vername, isLocal(self, my_context->preload->libs[i]))) + if(GetLibGlobalSymbolStartEnd(my_context->preload->libs[i], name, start, end, size, &weak, version, vername, isLocal(self, my_context->preload->libs[i]), globdefver)) if(*start) return 1; // search non-weak symbol, from older to newer (first GLOBAL object wins) - if(GetSymbolStartEnd(GetMapSymbols(my_context->elfs[0]), name, start, end, version, vername, (my_context->elfs[0]==self || !self)?1:0, defver)) + if(GetSymbolStartEnd(GetMapSymbols(my_context->elfs[0]), name, start, end, version, vername, (my_context->elfs[0]==self || !self)?1:0, globdefver)) if(*start) return 1; // TODO: create a temporary map to search lib only 1 time, and in order of needed... // search in needed libs from neededlibs first, in order if(my_context->neededlibs) for(int i=0; i<my_context->neededlibs->size; ++i) - if(GetLibGlobalSymbolStartEnd(my_context->neededlibs->libs[i], name, start, end, size, &weak, version, vername, isLocal(self, my_context->neededlibs->libs[i]))) + if(GetLibGlobalSymbolStartEnd(my_context->neededlibs->libs[i], name, start, end, size, &weak, version, vername, isLocal(self, my_context->neededlibs->libs[i]), globdefver)) if(*start) return 1; // search in global symbols for(int i=0; i<maplib->libsz; ++i) { - if(GetLibGlobalSymbolStartEnd(maplib->libraries[i], name, start, end, size, &weak, version, vername, isLocal(self, maplib->libraries[i]))) + if(GetLibGlobalSymbolStartEnd(maplib->libraries[i], name, start, end, size, &weak, version, vername, isLocal(self, maplib->libraries[i]), globdefver)) if(*start) return 1; } // check with default version... - defver = GetDefaultVersion(my_context->weakdefver, name); int ok = 0; // GetSymbolStartEnd should not change start/end if symbol is not found - if(GetSymbolStartEnd(GetWeakSymbols(my_context->elfs[0]), name, start, end, version, vername, (my_context->elfs[0]==self || !self)?1:0, defver)) + if(GetSymbolStartEnd(GetWeakSymbols(my_context->elfs[0]), name, start, end, version, vername, (my_context->elfs[0]==self || !self)?1:0, weakdefver)) if(*start) ok = 1; for(int i=0; i<maplib->libsz; ++i) { - if(GetLibWeakSymbolStartEnd(maplib->libraries[i], name, start, end, size, &weak, version, vername, isLocal(self, maplib->libraries[i]))) + if(GetLibWeakSymbolStartEnd(maplib->libraries[i], name, start, end, size, &weak, version, vername, isLocal(self, maplib->libraries[i]), weakdefver)) if(*start) ok = 1; } @@ -450,15 +447,15 @@ static int GetGlobalSymbolStartEnd_internal(lib_t *maplib, const char* name, uin } void** my_GetGTKDisplay(); void** my_GetGthreadsGotInitialized(); -int GetGlobalSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, elfheader_t* self, int version, const char* vername) +int GetGlobalSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, elfheader_t* self, int version, const char* vername, const char* globdefver, const char* weakdefver) { - if(GetGlobalSymbolStartEnd_internal(maplib, name, start, end, self, version, vername)) { + if(GetGlobalSymbolStartEnd_internal(maplib, name, start, end, self, version, vername, globdefver, weakdefver)) { if(start && end && *end==*start) { // object is of 0 sized, try to see an "_END" object of null size uintptr_t start2, end2; char* buff = (char*)malloc(strlen(name) + strlen("_END") + 1); strcpy(buff, name); strcat(buff, "_END"); - if(GetGlobalSymbolStartEnd_internal(maplib, buff, &start2, &end2, self, version, vername)) { + if(GetGlobalSymbolStartEnd_internal(maplib, buff, &start2, &end2, self, version, vername, globdefver, weakdefver)) { if(end2>*end && start2==end2) *end = end2; } @@ -483,6 +480,30 @@ int GetGlobalSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, u return 0; } +const char* GetMaplibDefaultVersion(lib_t *maplib, lib_t* local_maplib, int isweak, const char* symname) +{ + const char* ret = GetDefaultVersion(isweak?GetWeakDefaultVersion(my_context->elfs[0]):GetGlobalDefaultVersion(my_context->elfs[0]), symname); + if(ret) + return ret; + for(int i=0; i<maplib->libsz; ++i) { + elfheader_t *h = GetElf(maplib->libraries[i]); + if(h) + ret = GetDefaultVersion(isweak?GetWeakDefaultVersion(h):GetGlobalDefaultVersion(h), symname); + if(ret) + return ret; + } + if(local_maplib) + for(int i=0; i<local_maplib->libsz; ++i) { + elfheader_t *h = GetElf(local_maplib->libraries[i]); + if(h) + ret = GetDefaultVersion(isweak?GetWeakDefaultVersion(h):GetGlobalDefaultVersion(h), symname); + if(ret) + return ret; + } + + return NULL; +} + elfheader_t* GetGlobalSymbolElf(lib_t *maplib, const char* name, int version, const char* vername) { uintptr_t start = 0; @@ -491,12 +512,12 @@ elfheader_t* GetGlobalSymbolElf(lib_t *maplib, const char* name, int version, co int weak = 0; elfheader_t* ret = NULL; // check with default version... - const char* defver = GetDefaultVersion(my_context->globaldefver, name); + const char* defver = GetMaplibDefaultVersion(my_context->maplib, (my_context->maplib==maplib)?NULL:maplib, 0, name); if(GetSymbolStartEnd(GetMapSymbols(my_context->elfs[0]), name, &start, &end, version, vername, 1, defver)) return my_context->elfs[0]; for(int i=0; i<maplib->libsz; ++i) { - if(GetLibGlobalSymbolStartEnd(maplib->libraries[i], name, &start, &end, size, &weak, version, vername, 1)) { + if(GetLibGlobalSymbolStartEnd(maplib->libraries[i], name, &start, &end, size, &weak, version, vername, 1, defver)) { int idx = GetElfIndex(maplib->libraries[i]); if(idx==-1) { printf_log(LOG_NONE, "Warning, getting Elf info for a native symbol \"%s\" from lib \"%s\"\n", name, GetNameLib(maplib->libraries[i])); @@ -509,11 +530,11 @@ elfheader_t* GetGlobalSymbolElf(lib_t *maplib, const char* name, int version, co } } - defver = GetDefaultVersion(my_context->weakdefver, name); + defver = GetMaplibDefaultVersion(my_context->maplib, (my_context->maplib==maplib)?NULL:maplib, 1, name); if(GetSymbolStartEnd(GetWeakSymbols(my_context->elfs[0]), name, &start, &end, version, vername, 1, defver)) ret = my_context->elfs[0]; for(int i=0; i<maplib->libsz; ++i) { - if(GetLibWeakSymbolStartEnd(maplib->libraries[i], name, &start, &end, size, &weak, version, vername, 1)) { + if(GetLibWeakSymbolStartEnd(maplib->libraries[i], name, &start, &end, size, &weak, version, vername, 1, defver)) { int idx = GetElfIndex(maplib->libraries[i]); if(idx==-1) { printf_log(LOG_NONE, "Warning, getting Elf info for a native symbol \"%s\" from lib \"%s\"\n", name, GetNameLib(maplib->libraries[i])); @@ -529,25 +550,23 @@ elfheader_t* GetGlobalSymbolElf(lib_t *maplib, const char* name, int version, co return ret; } -int GetGlobalNoWeakSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, int version, const char* vername) +int GetGlobalNoWeakSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, int version, const char* vername, const char* defver) { int weak = 0; size_t size = 0; // check with default version... - const char* defver = GetDefaultVersion(my_context->globaldefver, name); - if(GetSymbolStartEnd(GetMapSymbols(my_context->elfs[0]), name, start, end, version, vername, 1, defver)) if(*start || *end) return 1; for(int i=0; i<maplib->libsz; ++i) - if(GetLibGlobalSymbolStartEnd(maplib->libraries[i], name, start, end, size, &weak, version, vername, 1)) + if(GetLibGlobalSymbolStartEnd(maplib->libraries[i], name, start, end, size, &weak, version, vername, 1, defver)) if(*start || *end) return 1; // nope, not found return 0; } -int IsGlobalNoWeakSymbolInNative(lib_t *maplib, const char* name, int version, const char* vername) +int IsGlobalNoWeakSymbolInNative(lib_t *maplib, const char* name, int version, const char* vername, const char* defver) { uintptr_t start, end; size_t size = 0; @@ -555,7 +574,7 @@ int IsGlobalNoWeakSymbolInNative(lib_t *maplib, const char* name, int version, c // check with default version... for(int i=0; i<maplib->libsz; ++i) if(GetElfIndex(maplib->libraries[i])==-1) - if(GetLibGlobalSymbolStartEnd(maplib->libraries[i], name, &start, &end, size, &weak, version, vername, 1)) + if(GetLibGlobalSymbolStartEnd(maplib->libraries[i], name, &start, &end, size, &weak, version, vername, 1, defver)) if(start || end) return 1; // nope, not found @@ -563,14 +582,15 @@ int IsGlobalNoWeakSymbolInNative(lib_t *maplib, const char* name, int version, c } -int GetLocalSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, elfheader_t *self, int version, const char* vername) +int GetLocalSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, elfheader_t *self, int version, const char* vername, const char* globdefver, const char* weakdefver) { // check with default version... int weak; size_t size = 0; + const char* defver = globdefver?globdefver:weakdefver; if(my_context->elfs[0]==self || !self) { - if(GetSymbolStartEnd(GetLocalSymbols(my_context->elfs[0]), name, start, end, version, vername, 1, NULL)) + if(GetSymbolStartEnd(GetLocalSymbols(my_context->elfs[0]), name, start, end, version, vername, 1, defver)) if(*start || *end) return 1; if(self) @@ -578,7 +598,7 @@ int GetLocalSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, ui } for(int i=0; i<maplib->libsz; ++i) { if(GetElfIndex(maplib->libraries[i])!=-1 && (!self || my_context->elfs[GetElfIndex(maplib->libraries[i])]==self)) { - if(GetLibLocalSymbolStartEnd(maplib->libraries[i], name, start, end, size, &weak, version, vername, 1)) + if(GetLibLocalSymbolStartEnd(maplib->libraries[i], name, start, end, size, &weak, version, vername, 1, defver)) if(*start || *end) return 1; if(self) diff --git a/src/librarian/library.c b/src/librarian/library.c index 2549010c..6a88b5c2 100755 --- a/src/librarian/library.c +++ b/src/librarian/library.c @@ -116,7 +116,7 @@ void WrappedLib_FinishFini(library_t* lib) FreeBridge(&lib->w.bridge); } -int WrappedLib_GetWeak(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, size_t asked_size, int* weak, int version, const char* vername, int local) +int WrappedLib_GetWeak(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, size_t asked_size, int* weak, int version, const char* vername, int local, const char* defver) { // ignoring asked size on wrapped libs uintptr_t addr = 0; @@ -134,11 +134,10 @@ int WrappedLib_GetWeak(library_t* lib, const char* name, uintptr_t *offs, uintpt *weak = wk; return 1; } -int EmuLib_GetWeak(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, size_t asked_size, int*weak, int version, const char* vername, int local) +int EmuLib_GetWeak(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, size_t asked_size, int*weak, int version, const char* vername, int local, const char* defver) { // symbols... uintptr_t start, end; - const char* defver = GetDefaultVersion(my_context->weakdefver, name); // weak symbols... if(GetSizedSymbolStartEnd(GetWeakSymbols(lib->e.elf), name, &start, &end, asked_size, version, vername, local, defver)) { @@ -149,7 +148,7 @@ int EmuLib_GetWeak(library_t* lib, const char* name, uintptr_t *offs, uintptr_t } return 0; } -int WrappedLib_GetGlobal(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, size_t asked_size, int* weak, int version, const char* vername, int local) +int WrappedLib_GetGlobal(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, size_t asked_size, int* weak, int version, const char* vername, int local, const char* defver) { // ignoring asked size on wrapped libs uintptr_t addr = 0; @@ -167,10 +166,9 @@ int WrappedLib_GetGlobal(library_t* lib, const char* name, uintptr_t *offs, uint *weak = 0; return 1; } -int EmuLib_GetGlobal(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, size_t asked_size, int* weak, int version, const char* vername, int local) +int EmuLib_GetGlobal(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, size_t asked_size, int* weak, int version, const char* vername, int local, const char* defver) { uintptr_t start, end; - const char* defver = GetDefaultVersion(my_context->globaldefver, name); if(GetSizedSymbolStartEnd(GetMapSymbols(lib->e.elf), name, &start, &end, asked_size, version, vername, local, defver)) { *offs = start; @@ -180,12 +178,10 @@ int EmuLib_GetGlobal(library_t* lib, const char* name, uintptr_t *offs, uintptr_ } return 0; } -int EmuLib_GetLocal(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, size_t asked_size, int* weak, int version, const char* vername, int local) +int EmuLib_GetLocal(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, size_t asked_size, int* weak, int version, const char* vername, int local, const char* defver) { // ignoring asked size on wrapped libs uintptr_t start, end; - const char* defver = GetDefaultVersion(my_context->globaldefver, name); - if(!defver) defver = GetDefaultVersion(my_context->weakdefver, name); if(GetSymbolStartEnd(GetLocalSymbols(lib->e.elf), name, &start, &end, version, vername, local, defver)) { *offs = start; @@ -196,7 +192,7 @@ int EmuLib_GetLocal(library_t* lib, const char* name, uintptr_t *offs, uintptr_t return 0; } -int WrappedLib_GetLocal(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, size_t asked_size, int* weak, int version, const char* vername, int local) +int WrappedLib_GetLocal(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, size_t asked_size, int* weak, int version, const char* vername, int local, const char* defver) { (void)lib; (void)name; (void)offs; (void)sz; (void)version; (void)vername; (void)local; return 0; @@ -449,12 +445,12 @@ int FinalizeLibrary(library_t* lib, lib_t* local_maplib, int bindnow, x64emu_t* #ifdef HAVE_TRACE if(trace_func) { int weak; - if (GetGlobalSymbolStartEnd(local_maplib, trace_func, &trace_start, &trace_end, elf_header, -1, NULL)) { + if (GetGlobalSymbolStartEnd(local_maplib, trace_func, &trace_start, &trace_end, elf_header, -1, NULL, NULL, NULL)) { SetTraceEmu(trace_start, trace_end); printf_log(LOG_INFO, "TRACE on %s only (%p-%p)\n", trace_func, (void*)trace_start, (void*)trace_end); box_free(trace_func); trace_func = NULL; - } else if(GetLibLocalSymbolStartEnd(lib, trace_func, &trace_start, &trace_end, 0, &weak, -1, NULL, 0)) { + } else if(GetLibLocalSymbolStartEnd(lib, trace_func, &trace_start, &trace_end, 0, &weak, -1, NULL, 0, NULL)) { SetTraceEmu(trace_start, trace_end); printf_log(LOG_INFO, "TRACE on %s only (%p-%p)\n", trace_func, (void*)trace_start, (void*)trace_end); box_free(trace_func); @@ -626,13 +622,13 @@ int IsSameLib(library_t* lib, const char* path) box_free(name); return ret; } -int GetLibWeakSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start, uintptr_t* end, size_t size, int* weak, int version, const char* vername, int local) +int GetLibWeakSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start, uintptr_t* end, size_t size, int* weak, int version, const char* vername, int local, const char* defver) { if(!name[0] || !lib->active) return 0; khint_t k; // get a new symbol - if(lib->getweak(lib, name, start, end, size, weak, version, vername, local)) { + if(lib->getweak(lib, name, start, end, size, weak, version, vername, local, defver)) { *end += *start; // lib->get(...) gives size, not end kh_bridgemap_t *map = local?lib->lbridgemap:((*weak)?lib->wbridgemap:lib->gbridgemap); // check first if already in the map @@ -653,13 +649,13 @@ int GetLibWeakSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start, // nope return 0; } -int GetLibGlobalSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start, uintptr_t* end, size_t size, int* weak, int version, const char* vername, int local) +int GetLibGlobalSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start, uintptr_t* end, size_t size, int* weak, int version, const char* vername, int local, const char* defver) { if(!name[0] || !lib || !lib->active) return 0; khint_t k; // get a new symbol - if(lib->getglobal(lib, name, start, end, size, weak, version, vername, local)) { + if(lib->getglobal(lib, name, start, end, size, weak, version, vername, local, defver)) { *end += *start; // lib->get(...) gives size, not end kh_bridgemap_t *map = local?lib->lbridgemap:((*weak)?lib->wbridgemap:lib->gbridgemap); // check if already in the map @@ -680,13 +676,13 @@ int GetLibGlobalSymbolStartEnd(library_t* lib, const char* name, uintptr_t* star // nope return 0; } -int GetLibLocalSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start, uintptr_t* end, size_t size, int* weak, int version, const char* vername, int local) +int GetLibLocalSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start, uintptr_t* end, size_t size, int* weak, int version, const char* vername, int local, const char* defver) { if(!name[0] || !lib->active) return 0; khint_t k; // get a new symbol - if(lib->getlocal(lib, name, start, end, size, weak, version, vername, local)) { + if(lib->getlocal(lib, name, start, end, size, weak, version, vername, local, defver)) { *end += *start; // lib->get(...) gives size, not end // check first if already in the map k = kh_get(bridgemap, lib->lbridgemap, VersionedName(name, version, vername)); diff --git a/src/main.c b/src/main.c index 3916b4ff..22bb6721 100755 --- a/src/main.c +++ b/src/main.c @@ -1096,10 +1096,10 @@ void setupTraceInit() if(s_trace_start || s_trace_end) SetTraceEmu(s_trace_start, s_trace_end); } else { - if (GetGlobalSymbolStartEnd(my_context->maplib, p, &s_trace_start, &s_trace_end, NULL, -1, NULL)) { + if (GetGlobalSymbolStartEnd(my_context->maplib, p, &s_trace_start, &s_trace_end, NULL, -1, NULL, NULL, NULL)) { SetTraceEmu(s_trace_start, s_trace_end); printf_log(LOG_INFO, "TRACE on %s only (%p-%p)\n", p, (void*)s_trace_start, (void*)s_trace_end); - } else if(GetLocalSymbolStartEnd(my_context->maplib, p, &s_trace_start, &s_trace_end, NULL, -1, NULL)) { + } else if(GetLocalSymbolStartEnd(my_context->maplib, p, &s_trace_start, &s_trace_end, NULL, -1, NULL, NULL, NULL)) { SetTraceEmu(s_trace_start, s_trace_end); printf_log(LOG_INFO, "TRACE on %s only (%p-%p)\n", p, (void*)s_trace_start, (void*)s_trace_end); } else { @@ -1140,10 +1140,10 @@ void setupTrace() } } } else { - if (GetGlobalSymbolStartEnd(my_context->maplib, p, &s_trace_start, &s_trace_end, NULL, -1, NULL)) { + if (GetGlobalSymbolStartEnd(my_context->maplib, p, &s_trace_start, &s_trace_end, NULL, -1, NULL, NULL, NULL)) { SetTraceEmu(s_trace_start, s_trace_end); printf_log(LOG_INFO, "TRACE on %s only (%p-%p)\n", p, (void*)s_trace_start, (void*)s_trace_end); - } else if(GetLocalSymbolStartEnd(my_context->maplib, p, &s_trace_start, &s_trace_end, NULL, -1, NULL)) { + } else if(GetLocalSymbolStartEnd(my_context->maplib, p, &s_trace_start, &s_trace_end, NULL, -1, NULL, NULL, NULL)) { SetTraceEmu(s_trace_start, s_trace_end); printf_log(LOG_INFO, "TRACE on %s only (%p-%p)\n", p, (void*)s_trace_start, (void*)s_trace_end); } else { diff --git a/src/wrapped/wrappedgtkx112.c b/src/wrapped/wrappedgtkx112.c index 4955385c..55bcc091 100755 --- a/src/wrapped/wrappedgtkx112.c +++ b/src/wrapped/wrappedgtkx112.c @@ -964,7 +964,7 @@ static void my_gtk_builder_connect_signals_custom(void* builder, uintptr_t offs = 0; uintptr_t end = 0; - GetGlobalSymbolStartEnd(my_context->maplib, handler_name, &offs, &end, NULL, -1, NULL); + GetGlobalSymbolStartEnd(my_context->maplib, handler_name, &offs, &end, NULL, -1, NULL, NULL, NULL); if(!offs) { if (args->module == NULL) args->my->g_log("Gtk", 1<<2 ,"gtk_builder_connect_signals() requires working GModule"); diff --git a/src/wrapped/wrappedlibdl.c b/src/wrapped/wrappedlibdl.c index 198b572e..952de79d 100755 --- a/src/wrapped/wrappedlibdl.c +++ b/src/wrapped/wrappedlibdl.c @@ -196,7 +196,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 version, const char* vername) +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, const char* globdefver, const char* weakdefver) { if(!lib) return 0; @@ -208,25 +208,25 @@ int recursive_dlsym_lib(kh_libs_t* collection, library_t* lib, const char* rsymb // TODO: should use librarian functions instead! int weak; // look in the library itself - if(lib->getglobal(lib, rsymbol, start, end, 0, &weak, version, vername, 1)) + if(lib->getglobal(lib, rsymbol, start, end, 0, &weak, version, vername, 1, globdefver)) return 1; - if(lib->getweak(lib, rsymbol, start, end, 0, &weak, version, vername, 1)) + if(lib->getweak(lib, rsymbol, start, end, 0, &weak, version, vername, 1, weakdefver)) return 1; // look in other libs int n = GetNeededLibsN(lib); for (int i=0; i<n; ++i) { library_t *l = GetNeededLib(lib, i); - if(recursive_dlsym_lib(collection, l, rsymbol, start, end, version, vername)) + if(recursive_dlsym_lib(collection, l, rsymbol, start, end, version, vername, globdefver, weakdefver)) return 1; } return 0; } -int my_dlsym_lib(library_t* lib, const char* rsymbol, uintptr_t *start, uintptr_t *end, int version, const char* vername) +int my_dlsym_lib(library_t* lib, const char* rsymbol, uintptr_t *start, uintptr_t *end, int version, const char* vername, const char* globdefver, const char* weakdefver) { kh_libs_t *collection = kh_init(libs); - int ret = recursive_dlsym_lib(collection, lib, rsymbol, start, end, version, vername); + int ret = recursive_dlsym_lib(collection, lib, rsymbol, start, end, version, vername, globdefver, weakdefver); kh_destroy(libs, collection); return ret; @@ -241,7 +241,9 @@ void* my_dlsym(x64emu_t* emu, void *handle, void *symbol) printf_dlsym(LOG_DEBUG, "Call to dlsym(%p, \"%s\")%s", handle, rsymbol, dlsym_error?"":"\n"); if(handle==NULL) { // special case, look globably - if(GetGlobalSymbolStartEnd(my_context->maplib, rsymbol, &start, &end, NULL, -1, NULL)) { + const char* globdefver = GetMaplibDefaultVersion(my_context->maplib, NULL, 0, rsymbol); + const char* weakdefver = GetMaplibDefaultVersion(my_context->maplib, NULL, 1, rsymbol); + if(GetGlobalSymbolStartEnd(my_context->maplib, rsymbol, &start, &end, NULL, -1, NULL, globdefver, weakdefver)) { printf_dlsym(LOG_NEVER, "%p\n", (void*)start); return (void*)start; } @@ -253,8 +255,10 @@ void* my_dlsym(x64emu_t* emu, void *handle, void *symbol) } if(handle==(void*)~0LL) { // special case, look globably but no self (RTLD_NEXT) + const char* globdefver = GetMaplibDefaultVersion(my_context->maplib, NULL, 0, rsymbol); + const char* weakdefver = GetMaplibDefaultVersion(my_context->maplib, NULL, 1, rsymbol); elfheader_t *elf = FindElfAddress(my_context, *(uintptr_t*)R_RSP); // use return address to guess "self" - if(GetNoSelfSymbolStartEnd(my_context->maplib, rsymbol, &start, &end, elf, 0, -1, NULL)) { + if(GetNoSelfSymbolStartEnd(my_context->maplib, rsymbol, &start, &end, elf, 0, -1, NULL, globdefver, weakdefver)) { printf_dlsym(LOG_NEVER, "%p\n", (void*)start); return (void*)start; } @@ -282,7 +286,9 @@ 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, -1, NULL)==0) { + const char* globdefver = GetMaplibDefaultVersion(my_context->maplib, (my_context->maplib==dl->libs[nlib]->maplib)?NULL:dl->libs[nlib]->maplib, 0, rsymbol); + const char* weakdefver = GetMaplibDefaultVersion(my_context->maplib, (my_context->maplib==dl->libs[nlib]->maplib)?NULL:dl->libs[nlib]->maplib, 1, rsymbol); + if(my_dlsym_lib(dl->libs[nlib], rsymbol, &start, &end, -1, NULL, globdefver, weakdefver)==0) { // not found printf_dlsym(LOG_NEVER, "%p\nCall to dlsym(%s, \"%s\") Symbol not found\n", NULL, GetNameLib(dl->libs[nlib]), rsymbol); printf_log(LOG_DEBUG, " Symbol not found\n"); @@ -294,9 +300,9 @@ void* my_dlsym(x64emu_t* emu, void *handle, void *symbol) } else { // still usefull? // => look globably - const char* defver = GetDefaultVersion(my_context->globaldefver, rsymbol); - if(!defver) defver = GetDefaultVersion(my_context->weakdefver, rsymbol); - if(GetGlobalSymbolStartEnd(my_context->maplib, rsymbol, &start, &end, NULL, -1, defver)) { + const char* globdefver = GetMaplibDefaultVersion(my_context->maplib, NULL, 0, rsymbol); + const char* weakdefver = GetMaplibDefaultVersion(my_context->maplib, NULL, 1, rsymbol); + if(GetGlobalSymbolStartEnd(my_context->maplib, rsymbol, &start, &end, NULL, -1, NULL, globdefver, weakdefver)) { printf_dlsym(LOG_NEVER, "%p\n", (void*)start); return (void*)start; } @@ -372,7 +378,9 @@ void* my_dlvsym(x64emu_t* emu, void *handle, void *symbol, const char *vername) printf_dlsym(LOG_DEBUG, "Call to dlvsym(%p, \"%s\", %s)%s", handle, rsymbol, vername?vername:"(nil)", dlsym_error?"":"\n"); if(handle==NULL) { // special case, look globably - if(GetGlobalSymbolStartEnd(my_context->maplib, rsymbol, &start, &end, NULL, version, vername)) { + const char* globdefver = GetMaplibDefaultVersion(my_context->maplib, NULL, 0, rsymbol); + const char* weakdefver = GetMaplibDefaultVersion(my_context->maplib, NULL, 1, rsymbol); + if(GetGlobalSymbolStartEnd(my_context->maplib, rsymbol, &start, &end, NULL, version, vername, globdefver, weakdefver)) { printf_dlsym(LOG_NEVER, "%p\n", (void*)start); return (void*)start; } @@ -384,8 +392,10 @@ void* my_dlvsym(x64emu_t* emu, void *handle, void *symbol, const char *vername) } if(handle==(void*)~0LL) { // special case, look globably but no self (RTLD_NEXT) + const char* globdefver = GetMaplibDefaultVersion(my_context->maplib, NULL, 0, rsymbol); + const char* weakdefver = GetMaplibDefaultVersion(my_context->maplib, NULL, 1, rsymbol); elfheader_t *elf = FindElfAddress(my_context, *(uintptr_t*)R_RSP); // use return address to guess "self" - if(GetNoSelfSymbolStartEnd(my_context->maplib, rsymbol, &start, &end, elf, 0, version, vername)) { + if(GetNoSelfSymbolStartEnd(my_context->maplib, rsymbol, &start, &end, elf, 0, version, vername, globdefver, weakdefver)) { printf_dlsym(LOG_NEVER, "%p\n", (void*)start); return (void*)start; } @@ -413,7 +423,9 @@ void* my_dlvsym(x64emu_t* emu, void *handle, void *symbol, const char *vername) return NULL; } if(dl->libs[nlib]) { - if(my_dlsym_lib(dl->libs[nlib], rsymbol, &start, &end, version, vername)==0) { + const char* globdefver = GetMaplibDefaultVersion(my_context->maplib, (my_context->maplib==dl->libs[nlib]->maplib)?NULL:dl->libs[nlib]->maplib, 0, rsymbol); + const char* weakdefver = GetMaplibDefaultVersion(my_context->maplib, (my_context->maplib==dl->libs[nlib]->maplib)?NULL:dl->libs[nlib]->maplib, 1, rsymbol); + if(my_dlsym_lib(dl->libs[nlib], rsymbol, &start, &end, version, vername, globdefver, weakdefver)==0) { // not found printf_dlsym(LOG_NEVER, "%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"); @@ -424,9 +436,9 @@ void* my_dlvsym(x64emu_t* emu, void *handle, void *symbol, const char *vername) } } else { // still usefull? - const char* defver = GetDefaultVersion(my_context->globaldefver, rsymbol); - if(!defver) defver = GetDefaultVersion(my_context->weakdefver, rsymbol); - if(GetGlobalSymbolStartEnd(my_context->maplib, rsymbol, &start, &end, NULL, -1, defver)) { + const char* globdefver = GetMaplibDefaultVersion(my_context->maplib, NULL, 0, rsymbol); + const char* weakdefver = GetMaplibDefaultVersion(my_context->maplib, NULL, 1, rsymbol); + if(GetGlobalSymbolStartEnd(my_context->maplib, rsymbol, &start, &end, NULL, -1, NULL, globdefver, weakdefver)) { printf_dlsym(LOG_NEVER, "%p\n", (void*)start); return (void*)start; } |