From 58cdb1bda2f2dd6a0bc5ea42e99b279fc687c06b Mon Sep 17 00:00:00 2001 From: ptitSeb Date: Sat, 22 Oct 2022 20:57:31 +0200 Subject: Refactored, again, elfloader symbol fetching (ported from box86) --- src/box64context.c | 53 +------- src/elfs/elfloader.c | 48 ++++++- src/elfs/elfloader_private.h | 5 + src/include/box64context.h | 6 +- src/include/elfloader.h | 4 + src/include/librarian.h | 7 +- src/include/library.h | 14 +- src/include/symbols.h | 14 +- src/include/wrappedlibs.h | 4 +- src/librarian/librarian.c | 260 +++++++++++++++++------------------ src/librarian/librarian_private.h | 5 - src/librarian/library.c | 280 ++++++++++++++++++++++++++------------ src/librarian/library_inner.h | 7 + src/librarian/library_private.h | 34 +++-- src/librarian/symbols.c | 68 +++++++-- src/main.c | 10 +- src/wrapped/wrappedlib_init.h | 47 +------ src/wrapped/wrappedlibdl.c | 54 ++++---- 18 files changed, 521 insertions(+), 399 deletions(-) create mode 100644 src/librarian/library_inner.h (limited to 'src') diff --git a/src/box64context.c b/src/box64context.c index 9a522748..1610c4e8 100755 --- a/src/box64context.c +++ b/src/box64context.c @@ -169,6 +169,8 @@ 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 @@ -217,6 +219,8 @@ 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; ielfsize; ++i) { FreeElfHeader(&ctx->elfs[i]); @@ -338,52 +342,3 @@ int AddTLSPartition(box64context_t* context, int tlssize) { return -context->tlssize; // negative offset } -void add_neededlib(needed_libs_t* needed, library_t* lib) -{ - if(!needed) - return; - for(int i=0; isize; ++i) - if(needed->libs[i] == lib) - return; - if(needed->size == needed->cap) { - needed->cap += 8; - needed->libs = (library_t**)box_realloc(needed->libs, needed->cap*sizeof(library_t*)); - } - needed->libs[needed->size++] = lib; -} - -void free_neededlib(needed_libs_t* needed) -{ - if(!needed) - return; - needed->cap = 0; - needed->size = 0; - if(needed->libs) - box_free(needed->libs); - needed->libs = NULL; -} - -void add_dependedlib(needed_libs_t* depended, library_t* lib) -{ - if(!depended) - return; - for(int i=0; isize; ++i) - if(depended->libs[i] == lib) - return; - if(depended->size == depended->cap) { - depended->cap += 8; - depended->libs = (library_t**)box_realloc(depended->libs, depended->cap*sizeof(library_t*)); - } - depended->libs[depended->size++] = lib; -} - -void free_dependedlib(needed_libs_t* depended) -{ - if(!depended) - return; - depended->cap = 0; - depended->size = 0; - if(depended->libs) - box_free(depended->libs); - depended->libs = NULL; -} diff --git a/src/elfs/elfloader.c b/src/elfs/elfloader.c index 43eb7157..f93ce1df 100755 --- a/src/elfs/elfloader.c +++ b/src/elfs/elfloader.c @@ -11,6 +11,7 @@ #include #include +#include "custommem.h" #include "box64version.h" #include "elfloader.h" #include "debug.h" @@ -26,7 +27,6 @@ #include "box64stack.h" #include "callback.h" #include "box64stack.h" -#include "custommem.h" #include "wine_tools.h" #include "dictionnary.h" #include "symbols.h" @@ -58,6 +58,11 @@ elfheader_t* LoadAndCheckElfHeader(FILE* f, const char* name, int exec) h->path = (char*)box_malloc(1); h->path[0] = '\0'; } + + h->mapsymbols = NewMapSymbols(); + h->weaksymbols = NewMapSymbols(); + h->localsymbols = NewMapSymbols(); + return h; } @@ -83,6 +88,10 @@ void FreeElfHeader(elfheader_t** head) box_free(h->SymTab); box_free(h->DynSym); + FreeMapSymbols(&h->mapsymbols); + FreeMapSymbols(&h->weaksymbols); + FreeMapSymbols(&h->localsymbols); + FreeElfMemory(h); box_free(h); @@ -416,6 +425,7 @@ 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); if(bind==STB_LOCAL) { offs = sym->st_value + head->delta; end = offs + sym->st_size; @@ -459,7 +469,7 @@ int RelocateElfREL(lib_t *maplib, lib_t *local_maplib, int bindnow, elfheader_t* if(sym->st_size && offs) { printf_dump(LOG_NEVER, "Apply %s R_X86_64_GLOB_DAT with R_X86_64_COPY @%p/%p (%p/%p -> %p/%p) size=%ld on sym=%s \n", (bind==STB_LOCAL)?"Local":"Global", p, globp, (void*)(p?(*p):0), (void*)(globp?(*globp):0), (void*)(offs + head->delta), (void*)globoffs, sym->st_size, symname); memmove((void*)globoffs, (void*)offs, sym->st_size); // preapply to copy part from lib to main elf - AddWeakSymbol(GetGlobalData(maplib), symname, offs + head->delta, sym->st_size, version, vername); + AddUniqueSymbol(GetGlobalData(maplib), symname, offs + head->delta, sym->st_size, version, vername); } else { printf_dump(LOG_NEVER, "Apply %s R_X86_64_GLOB_DAT with R_X86_64_COPY @%p/%p (%p/%p -> %p/%p) null sized on sym=%s \n", (bind==STB_LOCAL)?"Local":"Global", p, globp, (void*)(p?(*p):0), (void*)(globp?(*globp):0), (void*)offs, (void*)globoffs, symname); } @@ -484,7 +494,7 @@ 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; - GetSymbolStartEnd(GetGlobalData(maplib), symname, &offs, &end, version, vername, 1); // try globaldata symbols first + GetSymbolStartEnd(GetGlobalData(maplib), symname, &offs, &end, version, vername, 1, defver); // try globaldata symbols first if(offs==0) { GetNoSelfSymbolStartEnd(maplib, symname, &offs, &end, head, version, vername); // get original copy if any if(!offs && local_maplib) @@ -587,6 +597,7 @@ 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); if(bind==STB_LOCAL) { offs = sym->st_value + head->delta; end = offs + sym->st_size; @@ -632,7 +643,7 @@ int RelocateElfRELA(lib_t *maplib, lib_t *local_maplib, int bindnow, elfheader_t globoffs = offs; globend = end; offs = end = 0; - GetSymbolStartEnd(GetGlobalData(maplib), symname, &offs, &end, version, vername, 1); // try globaldata symbols first + GetSymbolStartEnd(GetGlobalData(maplib), symname, &offs, &end, version, vername, 1, defver); // try globaldata symbols first if(!offs && local_maplib) GetNoSelfSymbolStartEnd(local_maplib, symname, &offs, &end, head, version, vername); if(!offs) @@ -657,7 +668,7 @@ int RelocateElfRELA(lib_t *maplib, lib_t *local_maplib, int bindnow, elfheader_t (bind==STB_LOCAL)?"Local":"Global", p, globp, (void*)(p?(*p):0), (void*)(globp?(*globp):0), (void*)offs, (void*)globoffs, sym->st_size, symname, version, vername?vername:"(none)"); //memmove((void*)globoffs, (void*)offs, sym->st_size); // preapply to copy part from lib to main elf - AddWeakSymbol(GetGlobalData(maplib), symname, offs, sym->st_size, version, vername); + AddUniqueSymbol(GetGlobalData(maplib), symname, offs, sym->st_size, version, vername); } else { printf_dump(LOG_NEVER, "Apply %s R_X86_64_GLOB_DAT with R_X86_64_COPY @%p/%p (%p/%p -> %p/%p) null sized on sym=%s (ver=%d/%s)\n", (bind==STB_LOCAL)?"Local":"Global", p, globp, (void*)(p?(*p):0), @@ -968,6 +979,7 @@ void AddSymbols(lib_t *maplib, kh_mapsymbols_t* mapsymbols, kh_mapsymbols_t* wea p+=2; symname = AddDictionnary(my_context->versym, symnameversionned); const char* vername = AddDictionnary(my_context->versym, p); + AddDefaultVersion((bind==STB_WEAK)?my_context->weakdefver:my_context->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); @@ -1016,8 +1028,13 @@ 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; 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); + printf_dump(LOG_NEVER, "Adding Default Version \"%s\" for Symbol\"%s\"\n", vername, symname); + } int to_add = 1; if(libcef) { if(strstr(symname, "_Zn")==symname || strstr(symname, "_Zd")==symname) @@ -1035,7 +1052,7 @@ void AddSymbols(lib_t *maplib, kh_mapsymbols_t* mapsymbols, kh_mapsymbols_t* wea if(bind==STB_WEAK) { AddSymbol(weaksymbols, symname, offs, sz, version, vername); } else { - AddWeakSymbol(mapsymbols, symname, offs, sz, version?version:1, vername); + AddSymbol(mapsymbols, symname, offs, sz, version?version:1, vername); } } } @@ -1591,6 +1608,25 @@ void ElfAttachLib(elfheader_t* head, library_t* lib) head->lib = lib; } +kh_mapsymbols_t* GetMapSymbols(elfheader_t* h) +{ + if(!h) + return NULL; + return h->mapsymbols; +} +kh_mapsymbols_t* GetWeakSymbols(elfheader_t* h) +{ + if(!h) + return NULL; + return h->weaksymbols; +} +kh_mapsymbols_t* GetLocalSymbols(elfheader_t* h) +{ + if(!h) + return NULL; + return h->localsymbols; +} + typedef struct search_symbol_s{ const char* name; void* addr; diff --git a/src/elfs/elfloader_private.h b/src/elfs/elfloader_private.h index c1c34d0c..e75ba1ca 100755 --- a/src/elfs/elfloader_private.h +++ b/src/elfs/elfloader_private.h @@ -7,6 +7,7 @@ typedef struct dynablocklist_s dynablocklist_t; typedef struct library_s library_t; typedef struct needed_libs_s needed_libs_t; +typedef struct kh_mapsymbols_s kh_mapsymbols_t; #include #include "elfloader.h" @@ -95,6 +96,10 @@ struct elfheader_s { library_t *lib; needed_libs_t *neededlibs; + + kh_mapsymbols_t *mapsymbols; + kh_mapsymbols_t *weaksymbols; + kh_mapsymbols_t *localsymbols; }; #define R_X86_64_NONE 0 /* No reloc */ diff --git a/src/include/box64context.h b/src/include/box64context.h index 036a2b6d..17f4a2a0 100755 --- a/src/include/box64context.h +++ b/src/include/box64context.h @@ -14,6 +14,7 @@ typedef struct lib_s lib_t; typedef struct bridge_s bridge_t; typedef struct dlprivate_s dlprivate_t; typedef struct kh_symbolmap_s kh_symbolmap_t; +typedef struct kh_defaultversion_s kh_defaultversion_t; typedef struct library_s library_t; typedef struct linkmap_s linkmap_t; typedef struct kh_threadstack_s kh_threadstack_t; @@ -52,10 +53,7 @@ typedef struct needed_libs_s { library_t **libs; } needed_libs_t; -void add_neededlib(needed_libs_t* needed, library_t* lib); void free_neededlib(needed_libs_t* needed); -void add_dependedlib(needed_libs_t* depended, library_t* lib); -void free_dependedlib(needed_libs_t* depended); typedef struct base_segment_s { uintptr_t base; @@ -120,6 +118,8 @@ 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; pthread_mutex_t mutex_once; diff --git a/src/include/elfloader.h b/src/include/elfloader.h index ca7a6621..6846dcd4 100755 --- a/src/include/elfloader.h +++ b/src/include/elfloader.h @@ -63,6 +63,10 @@ const char* GetParentSymbolVersion(elfheader_t* h, int index); const char* VersionnedName(const char* name, int ver, const char* vername); int SameVersionnedSymbol(const char* name1, int ver1, const char* vername1, const char* name2, int ver2, const char* vername2); +kh_mapsymbols_t* GetMapSymbols(elfheader_t* h); +kh_mapsymbols_t* GetWeakSymbols(elfheader_t* h); +kh_mapsymbols_t* GetLocalSymbols(elfheader_t* h); + void* GetNativeSymbolUnversionned(void* lib, const char* name); void AddMainElfToLinkmap(elfheader_t* lib); diff --git a/src/include/librarian.h b/src/include/librarian.h index d2f0740c..a3fdfb3d 100755 --- a/src/include/librarian.h +++ b/src/include/librarian.h @@ -20,20 +20,15 @@ dlprivate_t *NewDLPrivate(); void FreeDLPrivate(dlprivate_t **lib); box64context_t* GetLibrarianContext(lib_t* maplib); -kh_mapsymbols_t* GetMapSymbol(lib_t* maplib); -kh_mapsymbols_t* GetWeakSymbol(lib_t* maplib); -kh_mapsymbols_t* GetLocalSymbol(lib_t* maplib); kh_mapsymbols_t* GetGlobalData(lib_t* maplib); -int AddNeededLib(lib_t* maplib, needed_libs_t* neededlibs, library_t *deplib, int local, int bindnow, const char** paths, int npath, box64context_t* box64, x64emu_t* emu); // 0=success, 1=error +int AddNeededLib(lib_t* maplib, needed_libs_t* neededlibs, library_t* deplib, int local, int bindnow, const char** paths, int npath, box64context_t* box64, x64emu_t* emu); // 0=success, 1=error 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, int version, const char* vername); -int GetSelfSymbolStartEnd(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); 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 GetNoWeakSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, elfheader_t *self, int version, const char* vername); 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); diff --git a/src/include/library.h b/src/include/library.h index 1bd9be3a..b62e122d 100755 --- a/src/include/library.h +++ b/src/include/library.h @@ -9,8 +9,9 @@ typedef struct kh_symbolmap_s kh_symbolmap_t; typedef struct box64context_s box64context_t; typedef struct x64emu_s x64emu_t; typedef struct needed_libs_s needed_libs_t; +typedef struct elfheader_s elfheader_t; -#define LIB_NATIVE 0 +#define LIB_WRAPPED 0 #define LIB_EMULATED 1 #define LIB_UNNKNOW -1 @@ -23,9 +24,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 GetLibSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start, uintptr_t* end, int version, const char* vername, int local); -int GetLibNoWeakSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start, uintptr_t* end, int version, const char* vername, int local); -int GetLibLocalSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start, uintptr_t* end, int version, const char* vername, int local); +int GetLibGlobalSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start, uintptr_t* end, int* weak, int version, const char* vername, int local); +int GetLibWeakSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start, uintptr_t* end, int* weak, int version, const char* vername, int local); +int GetLibLocalSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start, uintptr_t* end, int* weak, int version, const char* vername, int local); void fillGLProcWrapper(box64context_t* context); void freeGLProcWrapper(box64context_t* context); void fillALProcWrapper(box64context_t* context); @@ -35,7 +36,8 @@ int GetNeededLibN(library_t* lib); library_t* GetNeededLib(library_t* lib, int idx); lib_t* GetMaplib(library_t* lib); -int GetElfIndex(library_t* lib); // -1 if no elf (i.e. native) -void* GetHandle(library_t* lib); // NULL if not native +int GetElfIndex(library_t* lib); // -1 if no elf (i.e. wrapped) +elfheader_t* GetElf(library_t* lib); // NULL if no elf (i.e. wrapped) +void* GetHandle(library_t* lib); // NULL if not wrapped #endif //__LIBRARY_H_ diff --git a/src/include/symbols.h b/src/include/symbols.h index 49cd40f0..98eb9db7 100644 --- a/src/include/symbols.h +++ b/src/include/symbols.h @@ -14,11 +14,19 @@ void FreeMapSymbols(kh_mapsymbols_t** map); // replace if already there void AddSymbol(kh_mapsymbols_t *mapsymbols, const char* name, uintptr_t addr, uint32_t sz, int ver, const char* vername); -uintptr_t FindSymbol(kh_mapsymbols_t *mapsymbols, const char* name, int ver, const char* vername, int local); +uintptr_t FindSymbol(kh_mapsymbols_t *mapsymbols, const char* name, int ver, const char* vername, int local, const char* defver); // don't add if already there -void AddWeakSymbol(kh_mapsymbols_t *mapsymbols, const char* name, uintptr_t addr, uint32_t sz, int ver, const char* vername); -int GetSymbolStartEnd(kh_mapsymbols_t* mapsymbols, const char* name, uintptr_t* start, uintptr_t* end, int ver, const char* vername, int local); +void AddUniqueSymbol(kh_mapsymbols_t *mapsymbols, const char* name, uintptr_t addr, uint32_t sz, int ver, const char* vername); +int GetSymbolStartEnd(kh_mapsymbols_t* mapsymbols, const char* name, uintptr_t* start, uintptr_t* end, int ver, const char* vername, int local, const char* defver); const char* GetSymbolName(kh_mapsymbols_t* mapsymbols, void* p, uintptr_t* offs, uint32_t* sz, const char** vername); +// default version handling +KHASH_MAP_DECLARE_STR(defaultversion, const char*) +kh_defaultversion_t* NewDefaultVersion(); +void FreeDefaultVersion(kh_defaultversion_t** def); + +void AddDefaultVersion(kh_defaultversion_t* def, const char* symname, const char* vername); +const char* GetDefaultVersion(kh_defaultversion_t* def, const char* symname); + #endif //__SYMBOLS_PRIVATE_H_ \ No newline at end of file diff --git a/src/include/wrappedlibs.h b/src/include/wrappedlibs.h index 5ff61939..871f7af0 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, int version, const char* vername, int local); +typedef int (*wrappedlib_get_t)(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, int* weak, int version, const char* vername, int local); void setNeededLibs(library_t* lib, int n, ...); #define SETALT(A) lib->w.altmy = strdup(#A) @@ -17,8 +17,6 @@ typedef struct wrappedlib_s { const char* name; wrappedlib_init_t init; wrappedlib_fini_t fini; - wrappedlib_get_t get; - wrappedlib_get_t getnoweak; } wrappedlib_t; #endif //__WRAPPEDLIBS_H__ diff --git a/src/librarian/librarian.c b/src/librarian/librarian.c index e871b68e..170ff329 100755 --- a/src/librarian/librarian.c +++ b/src/librarian/librarian.c @@ -19,17 +19,12 @@ KHASH_MAP_IMPL_INT(mapoffsets, cstr_t); lib_t *NewLibrarian(box64context_t* context, int ownlibs) { - lib_t *maplib = (lib_t*)box_calloc(1, sizeof(lib_t)); + lib_t *maplib = (lib_t*)calloc(1, sizeof(lib_t)); - maplib->mapsymbols = NewMapSymbols(); - maplib->weaksymbols = NewMapSymbols(); - maplib->localsymbols = NewMapSymbols(); maplib->mapoffsets = kh_init(mapoffsets); maplib->globaldata = NewMapSymbols(); maplib->bridge = NewBridge(); - maplib->context = context; - maplib->ownlibs = ownlibs; return maplib; @@ -38,43 +33,47 @@ static void freeLibraryRecurse(lib_t *maplib, x64emu_t *emu, int idx, char *free if (freed[idx]) return; // Already freed library_t *lib = maplib->libraries[idx]; - if(lib==owner) return; // don't free owner of maplib + if(lib==owner) return; // don't free owner of maplib freed[idx] = 1; // Avoid infinite loops - printf_log(LOG_DEBUG, "Free %s\n", lib->name); - for (int i = lib->depended.size - 1; i >= 0; --i) { + printf_log(LOG_DEBUG, "Unloading %s\n", lib->name); + for (int i = lib->dependedby.size - 1; i >= 0; --i) { int j; for (j = 0; j < maplib->libsz; ++j) { - if (lib->depended.libs[i] == maplib->libraries[j]) break; + if (lib->dependedby.libs[i] == maplib->libraries[j]) break; } if (j == maplib->libsz) { // dependant lib already freed + // library as been freed already continue; } if (freed[j] == 1) { - printf_log(LOG_DEBUG, "Cyclic dependancy detected (cycle is between %s and %s)\n", lib->name, lib->depended.libs[i]->name); + printf_log(LOG_DEBUG, "Cyclic dependancy detected (cycle is between %s and %s)\n", lib->name, lib->dependedby.libs[i]->name); continue; } freeLibraryRecurse(maplib, emu, j, freed, owner); if (freed[idx] != 1) { - printf_log(LOG_DEBUG, "Library cleared (cyclic dependancy break)\n"); + printf_log(LOG_DEBUG, "Note: library already freed (cyclic dependancy break)\n"); return; } } + library_t *ptr = maplib->libraries[idx]; - if(maplib->ownlibs) + if(maplib->ownlibs/* && (!maplib->owner || ptr->maplib==maplib)*/) Free1Library(&ptr, emu); freed[idx] = 2; } void FreeLibrarian(lib_t **maplib, x64emu_t *emu) { + // should that be in reverse order? if(!maplib || !*maplib) return; - + library_t* owner = (*maplib)->owner; - (*maplib)->owner = NULL; // to avoid recursive free + (*maplib)->owner = NULL; // to avoid recursive free... + if((*maplib)->ownlibs && (*maplib)->libsz) { printf_log(LOG_DEBUG, "Closing %d libs from maplib %p\n", (*maplib)->libsz, *maplib); - char *freed = (char*)box_calloc((*maplib)->libsz, sizeof(char)); + char *freed = (char*)calloc((*maplib)->libsz, sizeof(char)); if (!freed) { printf_log(LOG_INFO, "Failed to malloc freed table, using old algorithm (a crash is likely)\n"); for (int i=(*maplib)->libsz-1; i>=0; --i) @@ -88,15 +87,12 @@ void FreeLibrarian(lib_t **maplib, x64emu_t *emu) } memset((*maplib)->libraries, 0, (*maplib)->libsz*sizeof(library_t*)); // NULL = 0 anyway (*maplib)->libsz = 0; - box_free(freed); + free(freed); } } - box_free((*maplib)->libraries); + free((*maplib)->libraries); (*maplib)->libraries = NULL; - FreeMapSymbols(&(*maplib)->mapsymbols); - FreeMapSymbols(&(*maplib)->weaksymbols); - FreeMapSymbols(&(*maplib)->localsymbols); if((*maplib)->mapoffsets) { kh_destroy(mapoffsets, (*maplib)->mapoffsets); } @@ -106,29 +102,14 @@ void FreeLibrarian(lib_t **maplib, x64emu_t *emu) if((*maplib)->bridge) FreeBridge(&(*maplib)->bridge); - box_free(*maplib); + free(*maplib); *maplib = NULL; } box64context_t* GetLibrarianContext(lib_t* maplib) { - return maplib->context; -} - -kh_mapsymbols_t* GetMapSymbol(lib_t* maplib) -{ - return maplib->mapsymbols; -} - -kh_mapsymbols_t* GetWeakSymbol(lib_t* maplib) -{ - return maplib->weaksymbols; -} - -kh_mapsymbols_t* GetLocalSymbol(lib_t* maplib) -{ - return maplib->localsymbols; + return my_context; } kh_mapsymbols_t* GetGlobalData(lib_t* maplib) @@ -163,29 +144,35 @@ void MapLibAddLib(lib_t* maplib, library_t* lib) return; if (maplib->libsz == maplib->libcap) { maplib->libcap += 8; - maplib->libraries = (library_t**)box_realloc(maplib->libraries, maplib->libcap*sizeof(library_t*)); + maplib->libraries = (library_t**)realloc(maplib->libraries, maplib->libcap*sizeof(library_t*)); } maplib->libraries[maplib->libsz] = lib; ++maplib->libsz; } -void MapLibAddMapLib(lib_t* dest, lib_t* src) +static void MapLibRemoveLib(lib_t* maplib, library_t* lib); + +static void MapLibAddMapLib(lib_t* dest, library_t* lib_src, lib_t* src) { if(!src) return; + library_t *owner = src->owner; for(int i=0; ilibsz; ++i) { library_t* lib = src->libraries[i]; if(!lib || libraryInMapLib(dest, lib)) continue; MapLibAddLib(dest, lib); - if(lib->maplib && src!=lib->maplib) { //TODO: find why is src!=lib->maplib needed - MapLibAddMapLib(dest, lib->maplib); - box_free(lib->maplib); - lib->maplib = NULL; + if(lib->maplib && src!=lib->maplib && dest!=lib->maplib) { + MapLibAddMapLib(dest, lib, lib->maplib); + MapLibRemoveLib(src, lib); + if(lib->maplib) + lib->maplib = (dest==my_context->maplib)?NULL:dest; } } + if(lib_src == owner) + FreeLibrarian(&src, NULL); } -void MapLibRemoveLib(lib_t* maplib, library_t* lib) +static void MapLibRemoveLib(lib_t* maplib, library_t* lib) { if(!maplib || !lib) return; @@ -196,6 +183,7 @@ void MapLibRemoveLib(lib_t* maplib, library_t* lib) --maplib->libsz; if(idx!=(maplib->libsz)) memmove(&maplib->libraries[idx], &maplib->libraries[idx+1], sizeof(library_t*)*(maplib->libsz-idx)); + maplib->libraries[maplib->libsz] = NULL; } static void MapLibRemoveMapLib(lib_t* dest, lib_t* src) @@ -222,7 +210,7 @@ int AddNeededLib_add(lib_t* maplib, needed_libs_t* neededlibs, library_t* deplib library_t *lib = getLib(my_context->maplib, path); if(lib) { add_neededlib(neededlibs, lib); - if (lib && deplib) add_dependedlib(&lib->depended, deplib); + if (lib && deplib) add_dependedbylib(&lib->dependedby, deplib); printf_log(LOG_DEBUG, "Already present in maplib => success\n"); return 0; } @@ -234,7 +222,7 @@ int AddNeededLib_add(lib_t* maplib, needed_libs_t* neededlibs, library_t* deplib // add lib to maplib... if(maplib) { if(lib->maplib) { - MapLibAddMapLib(maplib, lib->maplib); + MapLibAddMapLib(maplib, lib, lib->maplib); } if(!libraryInMapLib(maplib, lib)) MapLibAddLib(maplib, lib); @@ -245,16 +233,14 @@ int AddNeededLib_add(lib_t* maplib, needed_libs_t* neededlibs, library_t* deplib // promote lib from local to global... // for add the depending local libs... if(lib->maplib) { - MapLibAddMapLib(my_context->maplib, lib->maplib); - box_free(lib->maplib); - lib->maplib = NULL; + MapLibAddMapLib(my_context->maplib, lib, lib->maplib); } if(!libraryInMapLib(my_context->maplib, lib)) MapLibAddLib(my_context->maplib, lib); MapLibRemoveMapLib(my_context->local_maplib, my_context->maplib); } add_neededlib(neededlibs, lib); - if (lib && deplib) add_dependedlib(&lib->depended, deplib); + if (lib && deplib) add_dependedbylib(&lib->dependedby, deplib); return 0; } // load a new one @@ -265,15 +251,19 @@ int AddNeededLib_add(lib_t* maplib, needed_libs_t* neededlibs, library_t* deplib } add_neededlib(neededlibs, lib); - if (lib && deplib) add_dependedlib(&lib->depended, deplib); + if (lib && deplib) add_dependedbylib(&lib->dependedby, deplib); // add lib now if(local) { MapLibAddLib(my_context->local_maplib, lib); - if(maplib) + if(maplib) { MapLibAddLib(maplib, lib); - lib->maplib = NewLibrarian(box64, 0); - MapLibAddLib(lib->maplib, lib); + if(!lib->maplib) + lib->maplib = maplib; + } else { + lib->maplib = NewLibrarian(box64, 0); + MapLibAddLib(lib->maplib, lib); + } } else { MapLibAddLib(my_context->maplib, lib); } @@ -281,7 +271,6 @@ int AddNeededLib_add(lib_t* maplib, needed_libs_t* neededlibs, library_t* deplib if(!maplib) maplib = (local)?lib->maplib:my_context->maplib; - if(AddSymbolsLibrary(maplib, lib, emu)) { // also add needed libs printf_log(LOG_DEBUG, "Failure to Add lib => fail\n"); return 1; @@ -345,7 +334,7 @@ int AddNeededLib(lib_t* maplib, needed_libs_t* neededlibs, library_t* deplib, in { box64_mapclean = 0; if(!neededlibs) { - neededlibs = box_calloc(1, sizeof(needed_libs_t)); + neededlibs = calloc(1, sizeof(needed_libs_t)); } int idx = neededlibs->size; // Add libs and symbol @@ -390,9 +379,7 @@ uintptr_t FindGlobalSymbol(lib_t *maplib, const char* name, int version, const c static int isLocal(elfheader_t* self, library_t* l) { - if(GetElfIndex(l)==-1) - return 1; - if(my_context->elfs[GetElfIndex(l)]==self) + if(GetElf(l)==self) return 1; return 0; } @@ -402,31 +389,41 @@ int GetNoSelfSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, u assert(self); // need self for this one //search for the self, to start "next" int go = -1; + int weak = 0; + const char* defver = GetDefaultVersion(my_context->globaldefver, name); for(int i=0; ilibsz && (go==-1); ++i) { - if(GetElfIndex(maplib->libraries[i])!=-1 && (maplib->context->elfs[GetElfIndex(maplib->libraries[i])]==self)) + if(GetElfIndex(maplib->libraries[i])!=-1 && (GetElf(maplib->libraries[i])==self)) go = i+1; } if(go<0) go = 0; // not found... for(int i=go; ilibsz; ++i) { - if(GetElfIndex(maplib->libraries[i])==-1 || (maplib->context->elfs[GetElfIndex(maplib->libraries[i])]!=self)) - if(GetLibSymbolStartEnd(maplib->libraries[i], name, start, end, version, vername, 0)) + if(GetElfIndex(maplib->libraries[i])==-1 || (my_context->elfs[GetElfIndex(maplib->libraries[i])]!=self)) + if(GetLibGlobalSymbolStartEnd(maplib->libraries[i], name, start, end, &weak, version, vername, 0)) if(*start) return 1; } + for(int i=go; ilibsz; ++i) + if(GetElfIndex(maplib->libraries[i])==-1 || (my_context->elfs[GetElfIndex(maplib->libraries[i])]!=self)) + GetLibWeakSymbolStartEnd(maplib->libraries[i], name, start, end, &weak, version, vername, 0); + // loop done, weak symbol found + if(weak && *start) + return 1; // if self defined, give it another chance with self... + defver = GetDefaultVersion(my_context->weakdefver, name); if(self) { - if(maplib->context->elfs[0]==self) { - if(GetSymbolStartEnd(maplib->mapsymbols, name, start, end, version, vername, 1)) + if(my_context->elfs[0]==self) { + if(GetSymbolStartEnd(GetMapSymbols(my_context->elfs[0]), name, start, end, version, vername, 1, defver)) if(*start) return 1; - if(GetSymbolStartEnd(maplib->weaksymbols, name, start, end, version, vername, 1)) + if(GetSymbolStartEnd(GetWeakSymbols(my_context->elfs[0]), name, start, end, version, vername, 1, defver)) if(*start) return 1; } + // should check weak here? for(int i=0; ilibraries[i])==-1 || (maplib->context->elfs[GetElfIndex(maplib->libraries[i])]==self)) - if(GetLibSymbolStartEnd(maplib->libraries[i], name, start, end, version, vername, 1)) + if(GetElfIndex(maplib->libraries[i])==-1 || (my_context->elfs[GetElfIndex(maplib->libraries[i])]==self)) + if(GetLibWeakSymbolStartEnd(maplib->libraries[i], name, start, end, &weak, version, vername, 1)) if(*start) return 1; } @@ -436,52 +433,57 @@ int GetNoSelfSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, u } 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 weak = 0; + // check with default version... + const char* defver = GetDefaultVersion(my_context->globaldefver, name); // search non-weak symbol, from older to newer (first GLOBAL object wins) - if(GetSymbolStartEnd(maplib->mapsymbols, name, start, end, version, vername, (maplib->context->elfs[0]==self || !self)?1:0)) + if(GetSymbolStartEnd(GetMapSymbols(my_context->elfs[0]), name, start, end, version, vername, (my_context->elfs[0]==self || !self)?1:0, defver)) 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 for(int i=0; ineededlibs.size; ++i) - if(GetLibNoWeakSymbolStartEnd(my_context->neededlibs.libs[i], name, start, end, version, vername, isLocal(self, my_context->neededlibs.libs[i]))) + if(GetLibGlobalSymbolStartEnd(my_context->neededlibs.libs[i], name, start, end, &weak, version, vername, isLocal(self, my_context->neededlibs.libs[i]))) if(*start) return 1; // search in global symbols for(int i=0; ilibsz; ++i) { - if(GetLibNoWeakSymbolStartEnd(maplib->libraries[i], name, start, end, version, vername, isLocal(self, maplib->libraries[i]))) + if(GetLibGlobalSymbolStartEnd(maplib->libraries[i], name, start, end, &weak, version, vername, isLocal(self, maplib->libraries[i]))) if(*start) return 1; } - if(GetSymbolStartEnd(maplib->weaksymbols, name, start, end, version, vername, (maplib->context->elfs[0]==self || !self)?1:0)) + // 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(*start) - return 1; - + ok = 1; + for(int i=0; ilibsz; ++i) { - if(GetLibSymbolStartEnd(maplib->libraries[i], name, start, end, version, vername, isLocal(self, maplib->libraries[i]))) // only weak symbol haven't been found yet + if(GetLibWeakSymbolStartEnd(maplib->libraries[i], name, start, end, &weak, version, vername, isLocal(self, maplib->libraries[i]))) if(*start) - return 1; + ok = 1; } // nope, not found - return 0; + return (ok && *start)?1:0; } 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) { - if(!maplib) - return 0; if(GetGlobalSymbolStartEnd_internal(maplib, name, start, end, self, version, vername)) { 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*)box_malloc(strlen(name) + strlen("_END") + 1); + 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(end2>*end && start2==end2) *end = end2; } - box_free(buff); + free(buff); } return 1; } @@ -506,31 +508,58 @@ elfheader_t* GetGlobalSymbolElf(lib_t *maplib, const char* name, int version, co { uintptr_t start = 0; uintptr_t end = 0; - if(GetSymbolStartEnd(maplib->mapsymbols, name, &start, &end, version, vername, 1)) - return maplib->context->elfs[0]; - if(GetSymbolStartEnd(maplib->weaksymbols, name, &start, &end, version, vername, 1)) - return maplib->context->elfs[0]; + int weak = 0; + elfheader_t* ret = NULL; + // 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)) + return my_context->elfs[0]; for(int i=0; ilibsz; ++i) { - if(GetLibSymbolStartEnd(maplib->libraries[i], name, &start, &end, version, vername, 1)) { + if(GetLibGlobalSymbolStartEnd(maplib->libraries[i], name, &start, &end, &weak, version, vername, 1)) { 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])); return NULL; } - return maplib->context->elfs[idx]; + if(weak) + ret = my_context->elfs[idx]; + else + return my_context->elfs[idx]; } } - // nope, not found - return NULL; + + defver = GetDefaultVersion(my_context->weakdefver, name); + if(GetSymbolStartEnd(GetWeakSymbols(my_context->elfs[0]), name, &start, &end, version, vername, 1, defver)) + ret = my_context->elfs[0]; + for(int i=0; ilibsz; ++i) { + if(GetLibWeakSymbolStartEnd(maplib->libraries[i], name, &start, &end, &weak, version, vername, 1)) { + 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])); + return NULL; + } + if(weak) + ret = my_context->elfs[idx]; + else + return my_context->elfs[idx]; + } + } + // return what has been found (maybe nothing) + return ret; } int GetGlobalNoWeakSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, int version, const char* vername) { - if(GetSymbolStartEnd(maplib->mapsymbols, name, start, end, version, vername, 1)) + int weak = 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; ilibsz; ++i) - if(GetLibNoWeakSymbolStartEnd(maplib->libraries[i], name, start, end, version, vername, 1)) + if(GetLibGlobalSymbolStartEnd(maplib->libraries[i], name, start, end, &weak, version, vername, 1)) if(*start || *end) return 1; // nope, not found @@ -540,9 +569,11 @@ int GetGlobalNoWeakSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* st int IsGlobalNoWeakSymbolInNative(lib_t *maplib, const char* name, int version, const char* vername) { uintptr_t start, end; + int weak; + // check with default version... for(int i=0; ilibsz; ++i) if(GetElfIndex(maplib->libraries[i])==-1) - if(GetLibNoWeakSymbolStartEnd(maplib->libraries[i], name, &start, &end, version, vername, 1)) + if(GetLibGlobalSymbolStartEnd(maplib->libraries[i], name, &start, &end, &weak, version, vername, 1)) if(start || end) return 1; // nope, not found @@ -552,58 +583,30 @@ 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) { - if(maplib->context->elfs[0]==self || !self) { - if(GetSymbolStartEnd(maplib->localsymbols, name, start, end, version, vername, 1)) + // check with default version... + int weak; + + if(my_context->elfs[0]==self || !self) { + if(GetSymbolStartEnd(GetLocalSymbols(my_context->elfs[0]), name, start, end, version, vername, 1, NULL)) if(*start || *end) return 1; if(self) return 0; } for(int i=0; ilibsz; ++i) { - if(GetElfIndex(maplib->libraries[i])!=-1 && (!self || maplib->context->elfs[GetElfIndex(maplib->libraries[i])]==self)) { - if(GetLibLocalSymbolStartEnd(maplib->libraries[i], name, start, end, version, vername, 1)) + if(GetElfIndex(maplib->libraries[i])!=-1 && (!self || my_context->elfs[GetElfIndex(maplib->libraries[i])]==self)) { + if(GetLibLocalSymbolStartEnd(maplib->libraries[i], name, start, end, &weak, version, vername, 1)) if(*start) return 1; if(self) return 0; } } - return 0; -} -int GetSelfSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, elfheader_t *self, int version, const char* vername) -{ - if(maplib->context->elfs[0]==self) { - if(GetSymbolStartEnd(maplib->localsymbols, name, start, end, version, vername, 1)) - if(*start || *end) - return 1; - } else { - for(int i=0; ilibsz; ++i) { - if(GetElfIndex(maplib->libraries[i])!=-1 && (maplib->context->elfs[GetElfIndex(maplib->libraries[i])]==self)) - if(GetLibSymbolStartEnd(maplib->libraries[i], name, start, end, version, vername, 1)) - if(*start || *end) - return 1; - } - } return 0; } -int GetNoWeakSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, elfheader_t *self, int version, const char* vername) -{ - if(maplib->context->elfs[0]==self) { - if(GetSymbolStartEnd(maplib->mapsymbols, name, start, end, version, vername, 1)) - if(*start || *end) - return 1; - } else { - for(int i=0; ilibsz; ++i) { - if(GetElfIndex(maplib->libraries[i])!=-1 && (maplib->context->elfs[GetElfIndex(maplib->libraries[i])]==self)) - if(GetLibNoWeakSymbolStartEnd(maplib->libraries[i], name, start, end, version, vername, 1)) - if(*start || *end) - return 1; - } - } - return 0; -} + const char* FindSymbolName(lib_t *maplib, void* p, void** start, uint64_t* sz, const char** libname, void** base, library_t** lib) { // first, search in self... @@ -645,7 +648,6 @@ const char* FindSymbolName(lib_t *maplib, void* p, void** start, uint64_t* sz, c return ret; } // TODO: find if cyclic references exists (should also fix MapLibAddMapLib) - (void)maplib; /* for (int i = 0; i < maplib->libsz; ++i) { // if (maplib == maplib->libraries[i]->maplib) continue; const char *nameInLib = FindSymbolName(maplib->libraries[i]->maplib, p, start, sz, libname, base); diff --git a/src/librarian/librarian_private.h b/src/librarian/librarian_private.h index da2b1f0f..b7ff5c0c 100755 --- a/src/librarian/librarian_private.h +++ b/src/librarian/librarian_private.h @@ -13,9 +13,6 @@ typedef char* cstr_t; KHASH_MAP_DECLARE_INT(mapoffsets, cstr_t); typedef struct lib_s { - khash_t(mapsymbols) *mapsymbols; - khash_t(mapsymbols) *weaksymbols; - khash_t(mapsymbols) *localsymbols; khash_t(mapoffsets) *mapoffsets; khash_t(mapsymbols) *globaldata; library_t **libraries; @@ -24,8 +21,6 @@ typedef struct lib_s { int ownlibs; library_t *owner; // in case that maplib is owned by a lib - box64context_t* context; - bridge_t *bridge; // all x86 -> arm bridge } lib_t; diff --git a/src/librarian/library.c b/src/librarian/library.c index 50fd6df2..77a8d3a9 100755 --- a/src/librarian/library.c +++ b/src/librarian/library.c @@ -24,17 +24,20 @@ #include "librarian_private.h" #include "pathcoll.h" #include "x64emu.h" +#include "symbols.h" +#include "elfs/elfloader_private.h" +#include "library_inner.h" #include "wrappedlibs.h" // create the native lib list #define GO(P, N) int wrapped##N##_init(library_t* lib, box64context_t *box64); \ - void wrapped##N##_fini(library_t* lib); \ - int wrapped##N##_get(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, int version, const char* vername, int local); \ - int wrapped##N##_getnoweak(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, int version, const char* vername, int local); + void wrapped##N##_fini(library_t* lib); + #include "library_list.h" + #undef GO -#define GO(P, N) {P, wrapped##N##_init, wrapped##N##_fini, wrapped##N##_get, wrapped##N##_getnoweak}, +#define GO(P, N) {P, wrapped##N##_init, wrapped##N##_fini}, wrappedlib_t wrappedlibs[] = { #include "library_list.h" }; @@ -81,7 +84,7 @@ int NbDot(const char* name) return ret; } -void NativeLib_CommonInit(library_t *lib) { +void WrappedLib_CommonInit(library_t *lib) { lib->w.bridge = NewBridge(); lib->w.symbolmap = kh_init(symbolmap); @@ -97,10 +100,8 @@ void NativeLib_CommonInit(library_t *lib) { void EmuLib_Fini(library_t* lib) { - kh_destroy(mapsymbols, lib->e.mapsymbols); - kh_destroy(mapsymbols, lib->e.localsymbols); } -void NativeLib_FinishFini(library_t* lib) +void WrappedLib_FinishFini(library_t* lib) { if(lib->w.lib) dlclose(lib->w.lib); @@ -117,79 +118,88 @@ void NativeLib_FinishFini(library_t* lib) FreeBridge(&lib->w.bridge); } -int WrappedLib_defget(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, int version, const char* vername, int local) { +int WrappedLib_GetWeak(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, int* weak, int version, const char* vername, int local) { uintptr_t addr = 0; uintptr_t size = 0; - if (!getSymbolInMaps(lib, name, 0, &addr, &size, version, vername, local)) { + int wk = 0; + if (!getSymbolInMaps(lib, name, 0, &addr, &size, &wk, version, vername, local)) { return 0; } if(!addr && !size) return 0; + if(!wk) // found a global symbol + return 0; *offs = addr; *sz = size; + *weak = wk; return 1; } -int EmuLib_Get(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, int version, const char* vername, int local) +int EmuLib_GetWeak(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, int*weak, int version, const char* vername, int local) { // symbols... uintptr_t start, end; - if(GetSymbolStartEnd(lib->e.mapsymbols, name, &start, &end, version, vername, local)) - { - *offs = start; - *sz = end-start; - return 1; - } + const char* defver = GetDefaultVersion(my_context->weakdefver, name); // weak symbols... - if(GetSymbolStartEnd(lib->e.weaksymbols, name, &start, &end, version, vername, local)) + if(GetSymbolStartEnd(GetWeakSymbols(lib->e.elf), name, &start, &end, version, vername, local, defver)) { *offs = start; *sz = end-start; + *weak = 1; return 1; } return 0; } -int WrappedLib_defgetnoweak(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, int version, const char* vername, int local) { +int WrappedLib_GetGlobal(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, int* weak, int version, const char* vername, int local) { uintptr_t addr = 0; uintptr_t size = 0; - if (!getSymbolInMaps(lib, name, 1, &addr, &size, version, vername, local)) { + int wk = 0; + if (!getSymbolInMaps(lib, name, 1, &addr, &size, &wk, version, vername, local)) { return 0; } if(!addr && !size) return 0; + if(wk) + return 0; //found a weak symbol *offs = addr; *sz = size; + *weak = 0; return 1; } -int EmuLib_GetNoWeak(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, int version, const char* vername, int local) +int EmuLib_GetGlobal(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, int* weak, int version, const char* vername, int local) { uintptr_t start, end; - if(GetSymbolStartEnd(lib->e.mapsymbols, name, &start, &end, version, vername, local)) + const char* defver = GetDefaultVersion(my_context->globaldefver, name); + if(GetSymbolStartEnd(GetMapSymbols(lib->e.elf), name, &start, &end, version, vername, local, defver)) { *offs = start; *sz = end-start; + *weak = 0; return 1; } return 0; } -int EmuLib_GetLocal(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, int version, const char* vername, int local) +int EmuLib_GetLocal(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, int* weak, int version, const char* vername, int local) { uintptr_t start, end; - if(GetSymbolStartEnd(lib->e.localsymbols, name, &start, &end, version, vername, local)) + 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; *sz = end-start; + *weak = 0; return 1; } return 0; } -int NativeLib_GetLocal(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, int version, const char* vername, int local) +int WrappedLib_GetLocal(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, int* weak, int version, const char* vername, int local) { (void)lib; (void)name; (void)offs; (void)sz; (void)version; (void)vername; (void)local; return 0; } -static void initNativeLib(library_t *lib, box64context_t* context) { +static void initWrappedLib(library_t *lib, box64context_t* context) { int nb = sizeof(wrappedlibs) / sizeof(wrappedlib_t); for (int i=0; iname, wrappedlibs[i].name)==0) { @@ -202,10 +212,10 @@ static void initNativeLib(library_t *lib, box64context_t* context) { } printf_log(LOG_INFO, "Using native(wrapped) %s\n", lib->name); lib->fini = wrappedlibs[i].fini; - lib->get = wrappedlibs[i].get; - lib->getnoweak = wrappedlibs[i].getnoweak; - lib->getlocal = NativeLib_GetLocal; - lib->type = LIB_NATIVE; + lib->getglobal = WrappedLib_GetGlobal; + lib->getweak = WrappedLib_GetWeak; + lib->getlocal = WrappedLib_GetLocal; + lib->type = LIB_WRAPPED; // Call librarian to load all dependant elf if(AddNeededLib(context->maplib, &lib->needed, lib, 0, 0, (const char**)lib->w.neededlibs, lib->w.needed, context, thread_get_emu())) { printf_log(LOG_NONE, "Error: loading a needed libs in elf %s\n", lib->name); @@ -271,14 +281,11 @@ static int loadEmulatedLib(const char* libname, library_t *lib, box64context_t* lib->type = LIB_EMULATED; lib->fini = EmuLib_Fini; - lib->get = EmuLib_Get; - lib->getnoweak = EmuLib_GetNoWeak; + lib->getglobal = EmuLib_GetGlobal; + lib->getweak = EmuLib_GetWeak; lib->getlocal = EmuLib_GetLocal; lib->e.elf_index = mainelf; lib->e.elf = elf_header; - lib->e.mapsymbols = kh_init(mapsymbols); - lib->e.weaksymbols = kh_init(mapsymbols); - lib->e.localsymbols = kh_init(mapsymbols); if(lib->path && strcmp(lib->path, libname)) { box_free(lib->path); @@ -381,13 +388,13 @@ library_t *NewLibrary(const char* path, box64context_t* context) // And now, actually loading a library // look for native(wrapped) libs first if(!notwrapped && !precise) - initNativeLib(lib, context); + initWrappedLib(lib, context); // then look for a native one if(lib->type==LIB_UNNKNOW) initEmulatedLib(path, lib, context); // still not loaded but notwrapped indicated: use wrapped... if(lib->type==LIB_UNNKNOW && notwrapped && !precise) - initNativeLib(lib, context); + initWrappedLib(lib, context); // nothing loaded, so error... if(lib->type==LIB_UNNKNOW) { @@ -396,7 +403,9 @@ library_t *NewLibrary(const char* path, box64context_t* context) box_free(lib); return NULL; } - lib->bridgemap = kh_init(bridgemap); + lib->gbridgemap = kh_init(bridgemap); + lib->wbridgemap = kh_init(bridgemap); + lib->lbridgemap = kh_init(bridgemap); return lib; } @@ -408,7 +417,7 @@ int AddSymbolsLibrary(lib_t *maplib, library_t* lib, x64emu_t* emu) if(lib->type==LIB_EMULATED) { elfheader_t *elf_header = lib->e.elf; // add symbols - AddSymbols(maplib, lib->e.mapsymbols, lib->e.weaksymbols, lib->e.localsymbols, elf_header); + AddSymbols(maplib, GetMapSymbols(lib->e.elf), GetWeakSymbols(lib->e.elf), GetLocalSymbols(lib->e.elf), elf_header); } return 0; } @@ -432,12 +441,13 @@ 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)) { 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, -1, NULL, 0)) { + } else if(GetLibLocalSymbolStartEnd(lib, trace_func, &trace_start, &trace_end, &weak, -1, NULL, 0)) { 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); @@ -518,14 +528,28 @@ void Free1Library(library_t **lib, x64emu_t* emu) box_free((*lib)->name); box_free((*lib)->path); - if((*lib)->bridgemap) { + if((*lib)->gbridgemap) { + bridged_t *br; + kh_foreach_value_ref((*lib)->gbridgemap, br, + free(br->name); + ); + kh_destroy(bridgemap, (*lib)->gbridgemap); + } + if((*lib)->wbridgemap) { bridged_t *br; - kh_foreach_value_ref((*lib)->bridgemap, br, - box_free(br->name); + kh_foreach_value_ref((*lib)->wbridgemap, br, + free(br->name); ); - kh_destroy(bridgemap, (*lib)->bridgemap); + kh_destroy(bridgemap, (*lib)->wbridgemap); } - if((*lib)->type == LIB_NATIVE) { + if((*lib)->lbridgemap) { + bridged_t *br; + kh_foreach_value_ref((*lib)->lbridgemap, br, + free(br->name); + ); + kh_destroy(bridgemap, (*lib)->lbridgemap); + } + if((*lib)->type == LIB_WRAPPED) { if((*lib)->w.symbolmap) kh_destroy(symbolmap, (*lib)->w.symbolmap); if((*lib)->w.wsymbolmap) @@ -546,7 +570,7 @@ void Free1Library(library_t **lib, x64emu_t* emu) kh_destroy(symbol2map, (*lib)->w.symbol2map); } free_neededlib(&(*lib)->needed); - free_neededlib(&(*lib)->depended); + free_neededlib(&(*lib)->dependedby); box_free(*lib); *lib = NULL; @@ -562,7 +586,7 @@ int IsSameLib(library_t* lib, const char* path) if(!lib) return 0; char* name = Path2Name(path); - if(!strchr(path, '/') || lib->type==LIB_NATIVE || !lib->path) { + if(!strchr(path, '/') || lib->type==LIB_WRAPPED || !lib->path) { if(strcmp(name, lib->name)==0) ret=1; } else { @@ -581,79 +605,91 @@ int IsSameLib(library_t* lib, const char* path) box_free(name); return ret; } -int GetLibSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start, uintptr_t* end, int version, const char* vername, int local) +int GetLibWeakSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start, uintptr_t* end, int* weak, int version, const char* vername, int local) { if(!name[0] || !lib->active) return 0; khint_t k; // check first if already in the map - k = kh_get(bridgemap, lib->bridgemap, VersionnedName(name, version, vername)); - if(k!=kh_end(lib->bridgemap)) { - *start = kh_value(lib->bridgemap, k).start; - *end = kh_value(lib->bridgemap, k).end; + k = kh_get(bridgemap, lib->wbridgemap, VersionnedName(name, version, vername)); + if(k!=kh_end(lib->wbridgemap)) { + *start = kh_value(lib->wbridgemap, k).start; + *end = kh_value(lib->wbridgemap, k).end; + *weak = 1; return 1; } + if(local) { + k = kh_get(bridgemap, lib->lbridgemap, VersionnedName(name, version, vername)); + if(k!=kh_end(lib->lbridgemap)) { + *start = kh_value(lib->lbridgemap, k).start; + *end = kh_value(lib->lbridgemap, k).end; + *weak = 0; + return 1; + } + } // get a new symbol - if(lib->get(lib, name, start, end, version, vername, local)) { + if(lib->getweak(lib, name, start, end, weak, version, vername, local)) { *end += *start; // lib->get(...) gives size, not end char* symbol = box_strdup(VersionnedName(name, version, vername)); int ret; - k = kh_put(bridgemap, lib->bridgemap, symbol, &ret); - kh_value(lib->bridgemap, k).name = symbol; - kh_value(lib->bridgemap, k).start = *start; - kh_value(lib->bridgemap, k).end = *end; + kh_bridgemap_t *map = local?lib->lbridgemap:((*weak)?lib->wbridgemap:lib->gbridgemap); + k = kh_put(bridgemap, map, symbol, &ret); + kh_value(map, k).name = symbol; + kh_value(map, k).start = *start; + kh_value(map, k).end = *end; return 1; } // nope return 0; } -int GetLibNoWeakSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start, uintptr_t* end, int version, const char* vername, int local) +int GetLibGlobalSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start, uintptr_t* end, int* weak, int version, const char* vername, int local) { if(!name[0] || !lib->active) return 0; khint_t k; // get a new symbol - if(lib->getnoweak(lib, name, start, end, version, vername, local)) { + if(lib->getglobal(lib, name, start, end, weak, version, vername, local)) { *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 - k = kh_get(bridgemap, lib->bridgemap, VersionnedName(name, version, vername)); - if(k!=kh_end(lib->bridgemap)) { - *start = kh_value(lib->bridgemap, k).start; - *end = kh_value(lib->bridgemap, k).end; + k = kh_get(bridgemap, map, VersionnedName(name, version, vername)); + if(k!=kh_end(map)) { + *start = kh_value(map, k).start; + *end = kh_value(map, k).end; return 1; } char* symbol = box_strdup(VersionnedName(name, version, vername)); int ret; - k = kh_put(bridgemap, lib->bridgemap, symbol, &ret); - kh_value(lib->bridgemap, k).name = symbol; - kh_value(lib->bridgemap, k).start = *start; - kh_value(lib->bridgemap, k).end = *end; + k = kh_put(bridgemap, map, symbol, &ret); + kh_value(map, k).name = symbol; + kh_value(map, k).start = *start; + kh_value(map, k).end = *end; return 1; } // nope return 0; } -int GetLibLocalSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start, uintptr_t* end, int version, const char* vername, int local) +int GetLibLocalSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start, uintptr_t* end, int* weak, int version, const char* vername, int local) { if(!name[0] || !lib->active) return 0; khint_t k; // check first if already in the map - k = kh_get(bridgemap, lib->bridgemap, VersionnedName(name, version, vername)); - if(k!=kh_end(lib->bridgemap)) { - *start = kh_value(lib->bridgemap, k).start; - *end = kh_value(lib->bridgemap, k).end; + k = kh_get(bridgemap, lib->lbridgemap, VersionnedName(name, version, vername)); + if(k!=kh_end(lib->lbridgemap)) { + *start = kh_value(lib->lbridgemap, k).start; + *end = kh_value(lib->lbridgemap, k).end; return 1; } // get a new symbol - if(lib->getlocal(lib, name, start, end, version, vername, local)) { + if(lib->getlocal(lib, name, start, end, weak, version, vername, local)) { *end += *start; // lib->get(...) gives size, not end char* symbol = box_strdup(VersionnedName(name, version, vername)); int ret; - k = kh_put(bridgemap, lib->bridgemap, symbol, &ret); - kh_value(lib->bridgemap, k).name = symbol; - kh_value(lib->bridgemap, k).start = *start; - kh_value(lib->bridgemap, k).end = *end; + k = kh_put(bridgemap, lib->lbridgemap, symbol, &ret); + kh_value(lib->lbridgemap, k).name = symbol; + kh_value(lib->lbridgemap, k).start = *start; + kh_value(lib->lbridgemap, k).end = *end; return 1; } // nope @@ -665,8 +701,14 @@ int GetElfIndex(library_t* lib) return -1; return lib->e.elf_index; } +elfheader_t* GetElf(library_t* lib) +{ + if(!lib || lib->type!=LIB_EMULATED) + return NULL; + return lib->e.elf; +} -static int getSymbolInDataMaps(library_t*lib, const char* name, int noweak, uintptr_t *addr, uintptr_t *size) +static int getSymbolInDataMaps(library_t*lib, const char* name, int noweak, uintptr_t *addr, uintptr_t *size, int* weak) { void* symbol; khint_t k = kh_get(datamap, lib->w.datamap, name); @@ -676,6 +718,7 @@ static int getSymbolInDataMaps(library_t*lib, const char* name, int noweak, uint // found! *addr = (uintptr_t)symbol; *size = kh_value(lib->w.datamap, k); + *weak = 0; return 1; } } @@ -687,6 +730,7 @@ static int getSymbolInDataMaps(library_t*lib, const char* name, int noweak, uint // found! *addr = (uintptr_t)symbol; *size = kh_value(lib->w.wdatamap, k); + *weak = 1; return 1; } } @@ -707,12 +751,13 @@ static int getSymbolInDataMaps(library_t*lib, const char* name, int noweak, uint // found! *addr = (uintptr_t)symbol; *size = kh_value(lib->w.mydatamap, k); + *weak = 0; return 1; } } return 0; } -static int getSymbolInSymbolMaps(library_t*lib, const char* name, int noweak, uintptr_t *addr, uintptr_t *size) +static int getSymbolInSymbolMaps(library_t*lib, const char* name, int noweak, uintptr_t *addr, uintptr_t *size, int* weak) { void* symbol; // check in mysymbolmap @@ -731,6 +776,7 @@ static int getSymbolInSymbolMaps(library_t*lib, const char* name, int noweak, ui AddOffsetSymbol(my_context->maplib, symbol, name); *addr = AddBridge(lib->w.bridge, kh_value(lib->w.mysymbolmap, k), symbol, 0, name); *size = sizeof(void*); + *weak = 0; return 1; } // check in stsymbolmap (return struct...) @@ -749,6 +795,7 @@ static int getSymbolInSymbolMaps(library_t*lib, const char* name, int noweak, ui AddOffsetSymbol(my_context->maplib, symbol, name); *addr = AddBridge(lib->w.bridge, kh_value(lib->w.stsymbolmap, k), symbol, sizeof(void*), name); *size = sizeof(void*); + *weak = 0; return 1; } // check in symbolmap @@ -776,6 +823,7 @@ static int getSymbolInSymbolMaps(library_t*lib, const char* name, int noweak, ui AddOffsetSymbol(my_context->maplib, symbol, name); *addr = AddBridge(lib->w.bridge, kh_value(lib->w.symbolmap, k), symbol, 0, name); *size = sizeof(void*); + *weak = 0; return 1; } if(!noweak) { @@ -795,6 +843,7 @@ static int getSymbolInSymbolMaps(library_t*lib, const char* name, int noweak, ui AddOffsetSymbol(my_context->maplib, symbol, name); *addr = AddBridge(lib->w.bridge, kh_value(lib->w.wmysymbolmap, k), symbol, 0, name); *size = sizeof(void*); + *weak = 1; return 1; } k = kh_get(symbolmap, lib->w.wsymbolmap, name); @@ -821,6 +870,7 @@ static int getSymbolInSymbolMaps(library_t*lib, const char* name, int noweak, ui AddOffsetSymbol(my_context->maplib, symbol, name); *addr = AddBridge(lib->w.bridge, kh_value(lib->w.wsymbolmap, k), symbol, 0, name); *size = sizeof(void*); + *weak = 1; return 1; } } @@ -841,26 +891,27 @@ static int getSymbolInSymbolMaps(library_t*lib, const char* name, int noweak, ui AddOffsetSymbol(my_context->maplib, symbol, name); *addr = AddBridge(lib->w.bridge, kh_value(lib->w.symbol2map, k).w, symbol, 0, name); *size = sizeof(void*); + *weak = kh_value(lib->w.symbol2map, k).weak; return 1; } return 0; } -int getSymbolInMaps(library_t *lib, const char* name, int noweak, uintptr_t *addr, uintptr_t *size, int version, const char* vername, int local) +int getSymbolInMaps(library_t *lib, const char* name, int noweak, uintptr_t *addr, uintptr_t *size, int* weak, int version, const char* vername, int local) { if(!lib->active) return 0; if(version==-2) // don't send global native symbol for a version==-2 search return 0; // check in datamaps (but no version, it's not handled there) - if(getSymbolInDataMaps(lib, name, noweak, addr, size)) + if(getSymbolInDataMaps(lib, name, noweak, addr, size, weak)) return 1; - if(getSymbolInSymbolMaps(lib, VersionnedName(name, version, vername), noweak, addr, size)) + if(getSymbolInSymbolMaps(lib, VersionnedName(name, version, vername), noweak, addr, size, weak)) return 1; - if(getSymbolInSymbolMaps(lib, name, noweak, addr, size)) + if(getSymbolInSymbolMaps(lib, name, noweak, addr, size, weak)) return 1; return 0; @@ -884,7 +935,7 @@ void* GetHandle(library_t* lib) { if(!lib) return NULL; - if(lib->type!=LIB_NATIVE) + if(lib->type!=LIB_WRAPPED) return NULL; return lib->w.lib; } @@ -941,9 +992,66 @@ void AddMainElfToLinkmap(elfheader_t* elf) lm->l_ld = GetDynamicSection(elf); } +static int is_neededlib_present(needed_libs_t* needed, library_t* lib) +{ + if(!needed || !lib) + return 0; + if(!needed->size) + return 0; + for(int i=0; isize; ++i) + if(needed->libs[i] == lib) + return 1; + return 0; +} + +void add_neededlib(needed_libs_t* needed, library_t* lib) +{ + if(!needed) + return; + if(is_neededlib_present(needed, lib)) + return; + if(needed->size == needed->cap) { + needed->cap += 8; + needed->libs = (library_t**)realloc(needed->libs, needed->cap*sizeof(library_t*)); + } + needed->libs[needed->size++] = lib; +} +void free_neededlib(needed_libs_t* needed) +{ + if(!needed) + return; + needed->cap = 0; + needed->size = 0; + if(needed->libs) + free(needed->libs); + needed->libs = NULL; +} +void add_dependedbylib(needed_libs_t* dependedby, library_t* lib) +{ + if(!dependedby) + return; + if(is_neededlib_present(dependedby, lib)) + return; + if(dependedby->size == dependedby->cap) { + dependedby->cap += 8; + dependedby->libs = (library_t**)realloc(dependedby->libs, dependedby->cap*sizeof(library_t*)); + } + dependedby->libs[dependedby->size++] = lib; +} +void free_dependedbylib(needed_libs_t* dependedby) +{ + if(!dependedby) + return; + dependedby->cap = 0; + dependedby->size = 0; + if(dependedby->libs) + free(dependedby->libs); + dependedby->libs = NULL; +} + void setNeededLibs(library_t* lib, int n, ...) { - if(lib->type!=LIB_NATIVE && lib->type!=LIB_UNNKNOW) + if(lib->type!=LIB_WRAPPED && lib->type!=LIB_UNNKNOW) return; lib->w.needed = n; lib->w.neededlibs = (char**)box_calloc(n, sizeof(char*)); @@ -953,4 +1061,4 @@ void setNeededLibs(library_t* lib, int n, ...) lib->w.neededlibs[i] = box_strdup(va_arg(va, char*)); } va_end (va); -} \ No newline at end of file +} diff --git a/src/librarian/library_inner.h b/src/librarian/library_inner.h new file mode 100644 index 00000000..68598b32 --- /dev/null +++ b/src/librarian/library_inner.h @@ -0,0 +1,7 @@ +#ifndef __LIBRARY_INNER_H__ +#define __LIBRARY_INNER_H__ + +void WrappedLib_CommonInit(library_t* lib); +void WrappedLib_FinishFini(library_t* lib); + +#endif \ No newline at end of file diff --git a/src/librarian/library_private.h b/src/librarian/library_private.h index 34810f86..3015c55e 100755 --- a/src/librarian/library_private.h +++ b/src/librarian/library_private.h @@ -8,12 +8,13 @@ #include "wrappedlibs.h" #include "box64context.h" -typedef struct lib_s lib_t; -typedef struct bridge_s bridge_t; -typedef struct kh_bridgemap_s kh_bridgemap_t; -typedef struct kh_mapsymbols_s kh_mapsymbols_t; +typedef struct lib_s lib_t; +typedef struct bridge_s bridge_t; +typedef struct elfheader_s elfheader_t; +typedef struct kh_bridgemap_s kh_bridgemap_t; +typedef struct kh_mapsymbols_s kh_mapsymbols_t; +typedef struct x64emu_s x64emu_t; -typedef struct x64emu_s x64emu_t; typedef void (*wrapper_t)(x64emu_t* emu, uintptr_t fnc); typedef struct symbol2_s { @@ -54,9 +55,6 @@ typedef struct elib_s { int elf_index; elfheader_t *elf; int finalized; - kh_mapsymbols_t *mapsymbols; - kh_mapsymbols_t *weaksymbols; - kh_mapsymbols_t *localsymbols; } elib_t; typedef struct library_s { @@ -66,18 +64,24 @@ typedef struct library_s { int type; // 0: native(wrapped) 1: emulated(elf) -1: undetermined int active; wrappedlib_fini_t fini; - wrappedlib_get_t get; // get weak and no weak - wrappedlib_get_t getnoweak; // get only non weak symbol - wrappedlib_get_t getlocal; + wrappedlib_get_t getglobal; // get global (non-weak) + wrappedlib_get_t getweak; // get weak symbol + wrappedlib_get_t getlocal; // get local symbol union { wlib_t w; elib_t e; }; // private lib data needed_libs_t needed; - needed_libs_t depended; // used to free library - lib_t *maplib; // local maplib, for dlopen'd library with LOCAL binding (most of the dlopen) - kh_bridgemap_t *bridgemap; + needed_libs_t dependedby; // used to free library + lib_t *maplib; // local maplib, for dlopen'd library with LOCAL binding (most of the dlopen) + kh_bridgemap_t *gbridgemap; // global symbol bridgemap + kh_bridgemap_t *wbridgemap; // weak symbol bridgemap + kh_bridgemap_t *lbridgemap; // local symbol bridgemap } library_t; +void add_neededlib(needed_libs_t* needed, library_t* lib); +void free_neededlib(needed_libs_t* needed); +void add_dependedbylib(needed_libs_t* dependedby, library_t* lib); +void free_dependedbylib(needed_libs_t* dependedby); // type for map elements typedef struct map_onesymbol_s { @@ -97,7 +101,7 @@ typedef struct map_onedata_s { int weak; } map_onedata_t; -int getSymbolInMaps(library_t *lib, const char* name, int noweak, uintptr_t *addr, uintptr_t *size, int version, const char* vername, int local); // Add bridges to functions +int getSymbolInMaps(library_t *lib, const char* name, int noweak, uintptr_t *addr, uintptr_t *size, int *weak, int version, const char* vername, int local); // Add bridges to functions typedef struct linkmap_s { // actual struct link_map diff --git a/src/librarian/symbols.c b/src/librarian/symbols.c index 8042c860..3f5bc657 100644 --- a/src/librarian/symbols.c +++ b/src/librarian/symbols.c @@ -41,7 +41,7 @@ void FreeMapSymbols(kh_mapsymbols_t** map) if(!map || !(*map)) return; versymbols_t *v; - kh_foreach_value_ref(*map, v, box_free(v->syms);); + kh_foreach_value_ref(*map, v, free(v->syms);); kh_destroy(mapsymbols, *map); *map = NULL; @@ -105,7 +105,7 @@ static versymbol_t* FindFirstVersion(versymbols_t* s) } // Match version (so ver=0:0, ver=1:-1/1/X, ver=-1:any, ver=X:1/"name") -static versymbol_t* MatchVersion(versymbols_t* s, int ver, const char* vername, int local) +static versymbol_t* MatchVersion(versymbols_t* s, int ver, const char* vername, int local, const char* defver) { if(!s || !s->sz) return NULL; @@ -120,19 +120,27 @@ static versymbol_t* MatchVersion(versymbols_t* s, int ver, const char* vername, if(local) ret = FindVersionLocal(s); if(!ret) ret = FindNoVersion(s); if(!ret) ret = FindVersionGlobal(s); - if(!ret) ret = FindFirstVersion(s); + if(!ret && defver) ret = FindVersion(s, defver); + //if(!ret) ret = FindFirstVersion(s); + return ret; + } + if(ver==-2) { + if(local) ret = FindVersionLocal(s); + if(!ret) ret = FindVersionGlobal(s); return ret; } if(ver==1) { if(local) ret = FindVersionLocal(s); if(!ret) ret = FindVersionGlobal(s); if(!ret) ret = FindNoVersion(s); - if(!ret) ret = FindFirstVersion(s); + if(!ret && defver) ret = FindVersion(s, defver); + //if(!ret) ret = FindFirstVersion(s); return ret; } ret = FindVersion(s, vername); - if(local && !ret) FindVersionLocal(s); - if(!ret) return FindVersionGlobal(s); + if(local && !ret) ret = FindVersionLocal(s); + if(!ret && defver && vername && !strcmp(defver, vername)) ret = FindVersionGlobal(s); + //if(!ret) return FindVersionGlobal(s); return ret; } @@ -152,7 +160,7 @@ void AddSymbol(kh_mapsymbols_t *mapsymbols, const char* name, uintptr_t addr, ui // add a new record if(v->sz == v->cap) { v->cap+=4; - v->syms = (versymbol_t*)box_realloc(v->syms, v->cap*sizeof(versymbol_t)); + v->syms = (versymbol_t*)realloc(v->syms, v->cap*sizeof(versymbol_t)); } int idx = v->sz++; v->syms[idx].version = ver; @@ -161,7 +169,7 @@ void AddSymbol(kh_mapsymbols_t *mapsymbols, const char* name, uintptr_t addr, ui v->syms[idx].sym.sz = sz; } -uintptr_t FindSymbol(kh_mapsymbols_t *mapsymbols, const char* name, int ver, const char* vername, int local) +uintptr_t FindSymbol(kh_mapsymbols_t *mapsymbols, const char* name, int ver, const char* vername, int local, const char* defver) { if(!mapsymbols) return 0; @@ -169,13 +177,13 @@ uintptr_t FindSymbol(kh_mapsymbols_t *mapsymbols, const char* name, int ver, con if(k==kh_end(mapsymbols)) return 0; versymbols_t * v = &kh_val(mapsymbols, k); - versymbol_t * s = MatchVersion(v, ver, vername, local); + versymbol_t * s = MatchVersion(v, ver, vername, local, defver); if(s) return s->sym.offs; return 0; } -void AddWeakSymbol(kh_mapsymbols_t *mapsymbols, const char* name, uintptr_t addr, uint32_t sz, int ver, const char* vername) +void AddUniqueSymbol(kh_mapsymbols_t *mapsymbols, const char* name, uintptr_t addr, uint32_t sz, int ver, const char* vername) { int ret; khint_t k = kh_put(mapsymbols, mapsymbols, name, &ret); @@ -189,7 +197,7 @@ void AddWeakSymbol(kh_mapsymbols_t *mapsymbols, const char* name, uintptr_t addr // add a new record if(v->sz == v->cap) { v->cap+=4; - v->syms = (versymbol_t*)box_realloc(v->syms, v->cap*sizeof(versymbol_t)); + v->syms = (versymbol_t*)realloc(v->syms, v->cap*sizeof(versymbol_t)); } int idx = v->sz++; v->syms[idx].version = ver; @@ -198,7 +206,7 @@ void AddWeakSymbol(kh_mapsymbols_t *mapsymbols, const char* name, uintptr_t addr v->syms[idx].sym.sz = sz; } -int GetSymbolStartEnd(kh_mapsymbols_t* mapsymbols, const char* name, uintptr_t* start, uintptr_t* end, int ver, const char* vername, int local) +int GetSymbolStartEnd(kh_mapsymbols_t* mapsymbols, const char* name, uintptr_t* start, uintptr_t* end, int ver, const char* vername, int local, const char* defver) { if(!mapsymbols) return 0; @@ -206,7 +214,7 @@ int GetSymbolStartEnd(kh_mapsymbols_t* mapsymbols, const char* name, uintptr_t* if(k==kh_end(mapsymbols)) return 0; versymbols_t * v = &kh_val(mapsymbols, k); - versymbol_t* s = MatchVersion(v, ver, vername, local); + versymbol_t* s = MatchVersion(v, ver, vername, local, defver); if(s) { *start = s->sym.offs; *end = *start + s->sym.sz; @@ -231,3 +239,37 @@ const char* GetSymbolName(kh_mapsymbols_t* mapsymbols, void* p, uintptr_t* start ); return NULL; } + + +KHASH_MAP_IMPL_STR(defaultversion, const char*) +kh_defaultversion_t* NewDefaultVersion() +{ + kh_defaultversion_t* ret = kh_init(defaultversion); + return ret; +} + +void FreeDefaultVersion(kh_defaultversion_t** def) +{ + if(!def || !*def) + return; + const char* v; + kh_foreach_value(*def, v, free((char*)v);); + + kh_destroy(defaultversion, *def); + *def = NULL; +} + +void AddDefaultVersion(kh_defaultversion_t* def, const char* symname, const char* vername) +{ + int ret; + khint_t k = kh_put(defaultversion, def, symname, &ret); + if(!ret) return; // already set! + kh_value(def, k) = strdup(vername); +} +const char* GetDefaultVersion(kh_defaultversion_t* def, const char* symname) +{ + khint_t k = kh_get(defaultversion, def, symname); + if(k==kh_end(def)) + return NULL; + return kh_value(def, k); +} diff --git a/src/main.c b/src/main.c index 9e1bb0bd..b522f635 100755 --- a/src/main.c +++ b/src/main.c @@ -900,7 +900,7 @@ void setupTraceInit() if(s_trace_start || s_trace_end) SetTraceEmu(s_trace_start, s_trace_end); } else { - if (GetSymbolStartEnd(GetMapSymbol(my_context->maplib), p, &s_trace_start, &s_trace_end, -1, NULL, -1)) { + if (GetGlobalSymbolStartEnd(my_context->maplib, p, &trace_start, &trace_end, NULL, -1, 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 { @@ -1479,11 +1479,11 @@ int main(int argc, const char **argv, char **env) { setupTraceInit(); // export symbols - AddSymbols(my_context->maplib, GetMapSymbol(my_context->maplib), GetWeakSymbol(my_context->maplib), GetLocalSymbol(my_context->maplib), elf_header); + AddSymbols(my_context->maplib, GetMapSymbols(elf_header), GetWeakSymbols(elf_header), GetLocalSymbols(elf_header), elf_header); if(wine_preloaded) { - uintptr_t wineinfo = FindSymbol(GetMapSymbol(my_context->maplib), "wine_main_preload_info", -1, NULL, 1); - if(!wineinfo) wineinfo = FindSymbol(GetWeakSymbol(my_context->maplib), "wine_main_preload_info", -1, NULL, 1); - if(!wineinfo) wineinfo = FindSymbol(GetLocalSymbol(my_context->maplib), "wine_main_preload_info", -1, NULL, 1); + uintptr_t wineinfo = FindSymbol(GetMapSymbols(elf_header), "wine_main_preload_info", -1, NULL, 1, NULL); + if(!wineinfo) wineinfo = FindSymbol(GetWeakSymbols(elf_header), "wine_main_preload_info", -1, NULL, 1, NULL); + if(!wineinfo) wineinfo = FindSymbol(GetLocalSymbols(elf_header), "wine_main_preload_info", -1, NULL, 1, NULL); if(!wineinfo) {printf_log(LOG_NONE, "Warning, Symbol wine_main_preload_info not found\n");} else { *(void**)wineinfo = get_wine_prereserve(); diff --git a/src/wrapped/wrappedlib_init.h b/src/wrapped/wrappedlib_init.h index b61989b0..2b34acab 100755 --- a/src/wrapped/wrappedlib_init.h +++ b/src/wrapped/wrappedlib_init.h @@ -2,6 +2,8 @@ #error Meh #endif +#include "librarian/library_inner.h" + #define FUNC3(M,N) wrapped##M##N #define FUNC2(M,N) FUNC3(M,N) #define FUNC(N) FUNC2(LIBNAME,N) @@ -111,7 +113,6 @@ static const map_onedata_t MAPNAME(mydatamap)[] = { #undef DOIT #undef _DOIT -void NativeLib_CommonInit(library_t *lib); int FUNC(_init)(library_t* lib, box64context_t* box64) { (void)box64; @@ -140,7 +141,7 @@ int FUNC(_init)(library_t* lib, box64context_t* box64) #endif } else lib->path = strdup(MAPNAME(Name)); } - NativeLib_CommonInit(lib); + WrappedLib_CommonInit(lib); khint_t k; int ret; @@ -201,51 +202,11 @@ int FUNC(_init)(library_t* lib, box64context_t* box64) return 0; } -void NativeLib_FinishFini(library_t* lib); void FUNC(_fini)(library_t* lib) { #ifdef CUSTOM_FINI CUSTOM_FINI #endif - NativeLib_FinishFini(lib); -} - -int WrappedLib_defget(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, int version, const char* vername, int local); -int FUNC(_get)(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, int version, const char* vername, int local) -{ -#ifdef CUSTOM_FAIL - uintptr_t addr = 0; - uintptr_t size = 0; - void* symbol = NULL; - if (!getSymbolInMaps(lib, name, 0, &addr, &size, version, vername, local)) { - CUSTOM_FAIL - } - if(!addr && !size) - return 0; - *offs = addr; - *sz = size; - return 1; -#else - return WrappedLib_defget(lib, name, offs, sz, version, vername, local); -#endif + WrappedLib_FinishFini(lib); } -int WrappedLib_defgetnoweak(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, int version, const char* vername, int local); -int FUNC(_getnoweak)(library_t* lib, const char* name, uintptr_t *offs, uintptr_t *sz, int version, const char* vername, int local) -{ -#ifdef CUSTOM_FAIL - uintptr_t addr = 0; - uintptr_t size = 0; - void* symbol = NULL; - if (!getSymbolInMaps(lib, name, 1, &addr, &size, version, vername, local)) { - CUSTOM_FAIL - } - if(!addr && !size) - return 0; - *offs = addr; - *sz = size; - return 1; -#else - return WrappedLib_defgetnoweak(lib, name, offs, sz, version, vername, local); -#endif -} diff --git a/src/wrapped/wrappedlibdl.c b/src/wrapped/wrappedlibdl.c index 6360cf34..d452a8d8 100755 --- a/src/wrapped/wrappedlibdl.c +++ b/src/wrapped/wrappedlibdl.c @@ -129,7 +129,7 @@ void* my_dlopen(x64emu_t* emu, void *filename, int flag) const char* libs[] = {rfilename}; my_context->deferedInit = 1; int bindnow = (!box64_musl && (flag&0x2))?1:0; - if(AddNeededLib(NULL, NULL, NULL, is_local, bindnow, libs, 1, emu->context, emu)) { + if(AddNeededLib(NULL, NULL, NULL, is_local, bindnow, libs, 1, my_context, emu)) { printf_dlsym(strchr(rfilename,'/')?LOG_DEBUG:LOG_INFO, "Warning: Cannot dlopen(\"%s\"/%p, %X)\n", rfilename, filename, flag); if(!dl->last_error) dl->last_error = box_malloc(129); @@ -175,7 +175,7 @@ void* my_dlmopen(x64emu_t* emu, void* lmid, void *filename, int flag) } char* my_dlerror(x64emu_t* emu) { - dlprivate_t *dl = emu->context->dlprivate; + dlprivate_t *dl = my_context->dlprivate; return dl->last_error; } @@ -190,8 +190,12 @@ int recursive_dlsym_lib(kh_libs_t* collection, library_t* lib, const char* rsymb return 0; int ret; kh_put(libs, collection, (uintptr_t)lib, &ret); + // TODO: should use librarian functions instead! + int weak; // look in the library itself - if(lib->get(lib, rsymbol, start, end, version, vername, 1)) + if(lib->getglobal(lib, rsymbol, start, end, &weak, version, vername, 1)) + return 1; + if(lib->getweak(lib, rsymbol, start, end, &weak, version, vername, 1)) return 1; // look in other libs int n = GetNeededLibN(lib); @@ -215,14 +219,14 @@ int my_dlsym_lib(library_t* lib, const char* rsymbol, uintptr_t *start, uintptr_ void* my_dlsym(x64emu_t* emu, void *handle, void *symbol) { (void)emu; - dlprivate_t *dl = emu->context->dlprivate; + dlprivate_t *dl = my_context->dlprivate; uintptr_t start = 0, end = 0; char* rsymbol = (char*)symbol; CLEARERR printf_dlsym(LOG_DEBUG, "Call to dlsym(%p, \"%s\")%s", handle, rsymbol, dlsym_error?"":"\n"); if(handle==NULL) { // special case, look globably - if(GetGlobalSymbolStartEnd(emu->context->maplib, rsymbol, &start, &end, NULL, -1, NULL)) { + if(GetGlobalSymbolStartEnd(my_context->maplib, rsymbol, &start, &end, NULL, -1, NULL)) { printf_dlsym(LOG_NEVER, "%p\n", (void*)start); return (void*)start; } @@ -234,8 +238,8 @@ void* my_dlsym(x64emu_t* emu, void *handle, void *symbol) } if(handle==(void*)~0LL) { // 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, -1, NULL)) { + 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, -1, NULL)) { printf_dlsym(LOG_NEVER, "%p\n", (void*)start); return (void*)start; } @@ -275,7 +279,9 @@ void* my_dlsym(x64emu_t* emu, void *handle, void *symbol) } else { // still usefull? // => look globably - if(GetGlobalSymbolStartEnd(emu->context->maplib, rsymbol, &start, &end, NULL, -1, NULL)) { + 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)) { printf_dlsym(LOG_NEVER, "%p\n", (void*)start); return (void*)start; } @@ -292,7 +298,7 @@ int my_dlclose(x64emu_t* emu, void *handle) { (void)emu; printf_dlsym(LOG_DEBUG, "Call to dlclose(%p)\n", handle); - dlprivate_t *dl = emu->context->dlprivate; + dlprivate_t *dl = my_context->dlprivate; CLEARERR size_t nlib = (size_t)handle; --nlib; @@ -316,7 +322,7 @@ int my_dlclose(x64emu_t* emu, void *handle) int idx = GetElfIndex(dl->libs[nlib]); if(idx!=-1) { printf_dlsym(LOG_DEBUG, "dlclose: Call to Fini for %p\n", handle); - RunElfFini(emu->context->elfs[idx], emu); + RunElfFini(my_context->elfs[idx], emu); InactiveLibrary(dl->libs[nlib]); } } @@ -325,7 +331,7 @@ int my_dlclose(x64emu_t* emu, void *handle) int my_dladdr1(x64emu_t* emu, void *addr, void *i, void** extra_info, int flags) { //int dladdr(void *addr, Dl_info *info); - dlprivate_t *dl = emu->context->dlprivate; + dlprivate_t *dl = my_context->dlprivate; CLEARERR Dl_info *info = (Dl_info*)i; printf_log(LOG_DEBUG, "Warning: partially unimplement call to dladdr/dladdr1(%p, %p, %p, %d)\n", addr, info, extra_info, flags); @@ -334,7 +340,7 @@ int my_dladdr1(x64emu_t* emu, void *addr, void *i, void** extra_info, int flags) library_t* lib = NULL; info->dli_saddr = NULL; info->dli_fname = NULL; - info->dli_sname = FindSymbolName(emu->context->maplib, addr, &info->dli_saddr, NULL, &info->dli_fname, &info->dli_fbase, &lib); + info->dli_sname = FindSymbolName(my_context->maplib, addr, &info->dli_saddr, NULL, &info->dli_fname, &info->dli_fbase, &lib); 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:""); if(flags==RTLD_DL_SYMENT) { printf_log(LOG_INFO, "Warning, unimplement call to dladdr1 with RTLD_DL_SYMENT flags\n"); @@ -350,7 +356,7 @@ int my_dladdr(x64emu_t* emu, void *addr, void *i) } void* my_dlvsym(x64emu_t* emu, void *handle, void *symbol, const char *vername) { - dlprivate_t *dl = emu->context->dlprivate; + dlprivate_t *dl = my_context->dlprivate; int version = (vername)?2:-1; uintptr_t start, end; char* rsymbol = (char*)symbol; @@ -358,7 +364,7 @@ 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(emu->context->maplib, rsymbol, &start, &end, NULL, version, vername)) { + if(GetGlobalSymbolStartEnd(my_context->maplib, rsymbol, &start, &end, NULL, version, vername)) { printf_dlsym(LOG_NEVER, "%p\n", (void*)start); return (void*)start; } @@ -370,8 +376,8 @@ 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) - 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)) { + 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, version, vername)) { printf_dlsym(LOG_NEVER, "%p\n", (void*)start); return (void*)start; } @@ -410,16 +416,10 @@ void* my_dlvsym(x64emu_t* emu, void *handle, void *symbol, const char *vername) } } else { // still usefull? - if(GetSymbolStartEnd(GetLocalSymbol(emu->context->maplib), rsymbol, &start, &end, version, vername, 1)) { - printf_dlsym(LOG_NEVER, "%p\n", (void*)start); - return (void*)start; - } - if(GetSymbolStartEnd(GetWeakSymbol(emu->context->maplib), rsymbol, &start, &end, version, vername, 1)) { - printf_dlsym(LOG_NEVER, "%p\n", (void*)start); - return (void*)start; - } - if(GetSymbolStartEnd(GetMapSymbol(emu->context->maplib), rsymbol, &start, &end, version, vername, 1)) { - printf_dlsym(LOG_NEVER, "%p\n", (void*)start); + 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)) { + printf_dlsym(LOG_NEVER, "%p\n", (void*)start); return (void*)start; } // not found @@ -438,7 +438,7 @@ int my_dlinfo(x64emu_t* emu, void* handle, int request, void* info) { (void)emu; printf_dlsym(LOG_DEBUG, "Call to dlinfo(%p, %d, %p)\n", handle, request, info); - dlprivate_t *dl = emu->context->dlprivate; + dlprivate_t *dl = my_context->dlprivate; CLEARERR size_t nlib = (size_t)handle; --nlib; -- cgit 1.4.1