diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2022-11-13 00:04:26 +0100 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2022-11-13 00:04:26 +0100 |
| commit | 3cb7632dc84c954c76b84bb3477de2b6ba3d599c (patch) | |
| tree | e250dc582585fa5abda034c9f654ff8863263af6 /src | |
| parent | cde8e54b513cce726008fecf2bb6b67d81da9a21 (diff) | |
| download | box64-3cb7632dc84c954c76b84bb3477de2b6ba3d599c.tar.gz box64-3cb7632dc84c954c76b84bb3477de2b6ba3d599c.zip | |
Also use size when selecting symbol for R_X86_64_COPY and R_X86_64_GLOB_DAT relocations
Diffstat (limited to 'src')
| -rwxr-xr-x | src/elfs/elfloader.c | 22 | ||||
| -rwxr-xr-x | src/include/librarian.h | 2 | ||||
| -rwxr-xr-x | src/include/library.h | 6 | ||||
| -rw-r--r-- | src/include/symbols.h | 1 | ||||
| -rwxr-xr-x | src/include/wrappedlibs.h | 2 | ||||
| -rwxr-xr-x | src/librarian/librarian.c | 35 | ||||
| -rwxr-xr-x | src/librarian/library.c | 75 | ||||
| -rw-r--r-- | src/librarian/symbols.c | 76 | ||||
| -rwxr-xr-x | src/wrapped/wrappedlibdl.c | 8 |
9 files changed, 124 insertions, 103 deletions
diff --git a/src/elfs/elfloader.c b/src/elfs/elfloader.c index 227ef075..d7f4a530 100755 --- a/src/elfs/elfloader.c +++ b/src/elfs/elfloader.c @@ -382,7 +382,7 @@ int ReloadElfMemory(FILE* f, box64context_t* context, elfheader_t* head) return 0; } -int FindR64COPYRel(elfheader_t* h, const char* name, uintptr_t *offs, uint64_t** p, int version, const char* vername) +int FindR64COPYRel(elfheader_t* h, const char* name, uintptr_t *offs, uint64_t** p, size_t size, int version, const char* vername) { if(!h) return 0; @@ -394,7 +394,7 @@ int FindR64COPYRel(elfheader_t* h, const char* name, uintptr_t *offs, uint64_t** int t = ELF64_R_TYPE(rela[i].r_info); Elf64_Sym *sym = &h->DynSym[ELF64_R_SYM(rela[i].r_info)]; const char* symname = SymName(h, sym); - if(t==R_X86_64_COPY && symname && !strcmp(symname, name)) { + if(t==R_X86_64_COPY && symname && !strcmp(symname, name) && sym->st_size==size) { int version2 = h->VerSym?((Elf64_Half*)((uintptr_t)h->VerSym+h->delta))[ELF64_R_SYM(rela[i].r_info)]:-1; if(version2!=-1) version2 &= 0x7fff; if(version && !version2) version2=-1; // match a versionned symbol against a global "local" symbol @@ -421,6 +421,7 @@ int RelocateElfREL(lib_t *maplib, lib_t *local_maplib, int bindnow, elfheader_t* uint64_t *p = (uint64_t*)(rel[i].r_offset + head->delta); uintptr_t offs = 0; uintptr_t end = 0; + size_t size = sym->st_size; //uintptr_t tmp = 0; 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; @@ -462,7 +463,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, version, vername)) { + if(head!=my_context->elfs[0] && !IsGlobalNoWeakSymbolInNative(maplib, symname, version, vername) && 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; @@ -494,11 +495,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; - GetSymbolStartEnd(GetGlobalData(maplib), symname, &offs, &end, version, vername, 1, defver); // try globaldata symbols first + GetSizedSymbolStartEnd(GetGlobalData(maplib), symname, &offs, &end, size, version, vername, 1, defver); // try globaldata symbols first if(offs==0) { - GetNoSelfSymbolStartEnd(maplib, symname, &offs, &end, head, version, vername); // get original copy if any + GetNoSelfSymbolStartEnd(maplib, symname, &offs, &end, head, size, version, vername); // get original copy if any if(!offs && local_maplib) - GetNoSelfSymbolStartEnd(local_maplib, symname, &offs, &end, head, version, vername); + GetNoSelfSymbolStartEnd(local_maplib, symname, &offs, &end, head, size, version, vername); } if(!offs) { offs = old_offs; @@ -593,6 +594,7 @@ int RelocateElfRELA(lib_t *maplib, lib_t *local_maplib, int bindnow, elfheader_t uint64_t *p = (uint64_t*)(rela[i].r_offset + head->delta); uintptr_t offs = 0; uintptr_t end = 0; + size_t size = sym->st_size; elfheader_t* h_tls = NULL;//head; 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; @@ -643,11 +645,11 @@ 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, defver); // try globaldata symbols first + GetSizedSymbolStartEnd(GetGlobalData(maplib), symname, &offs, &end, size, version, vername, 1, defver); // try globaldata symbols first if(!offs && local_maplib) - GetNoSelfSymbolStartEnd(local_maplib, symname, &offs, &end, head, version, vername); + GetNoSelfSymbolStartEnd(local_maplib, symname, &offs, &end, head, size, version, vername); if(!offs) - GetNoSelfSymbolStartEnd(maplib, symname, &offs, &end, head, version, vername); + GetNoSelfSymbolStartEnd(maplib, symname, &offs, &end, head, size, version, vername); if(!offs) {offs = globoffs; end = globend;} if(offs) { // add r_addend to p? @@ -659,7 +661,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, version, vername)) { + if(head!=my_context->elfs[0] && !IsGlobalNoWeakSymbolInNative(maplib, symname, version, vername) && 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; diff --git a/src/include/librarian.h b/src/include/librarian.h index a3fdfb3d..87a78a34 100755 --- a/src/include/librarian.h +++ b/src/include/librarian.h @@ -25,7 +25,7 @@ int AddNeededLib(lib_t* maplib, needed_libs_t* neededlibs, library_t* deplib, in 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 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); diff --git a/src/include/library.h b/src/include/library.h index b62e122d..b88aaa04 100755 --- a/src/include/library.h +++ b/src/include/library.h @@ -24,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 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); +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); void fillGLProcWrapper(box64context_t* context); void freeGLProcWrapper(box64context_t* context); void fillALProcWrapper(box64context_t* context); diff --git a/src/include/symbols.h b/src/include/symbols.h index 98eb9db7..b00a354b 100644 --- a/src/include/symbols.h +++ b/src/include/symbols.h @@ -19,6 +19,7 @@ uintptr_t FindSymbol(kh_mapsymbols_t *mapsymbols, const char* name, int ver, con 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); +int GetSizedSymbolStartEnd(kh_mapsymbols_t* mapsymbols, const char* name, uintptr_t* start, uintptr_t* end, size_t size, 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 diff --git a/src/include/wrappedlibs.h b/src/include/wrappedlibs.h index 7bb4d5a2..07014e46 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* 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); void setNeededLibs(library_t* lib, int n, ...); #define SETALT(A) lib->w.altmy = box_strdup(#A) diff --git a/src/librarian/librarian.c b/src/librarian/librarian.c index 84b0b9a7..58f21aa6 100755 --- a/src/librarian/librarian.c +++ b/src/librarian/librarian.c @@ -384,7 +384,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, 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) { assert(self); // need self for this one //search for the self, to start "next" @@ -398,13 +398,13 @@ 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, &weak, version, vername, 0)) + if(GetLibGlobalSymbolStartEnd(maplib->libraries[i], name, start, end, size, &weak, version, vername, 0)) 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, &weak, version, vername, 0); + GetLibWeakSymbolStartEnd(maplib->libraries[i], name, start, end, size, &weak, version, vername, 0); // loop done, weak symbol found if(weak && *start) return 1; @@ -412,23 +412,23 @@ int GetNoSelfSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, u if(self) { if(my_context->elfs[0]!=self) { const char* defver = GetDefaultVersion(my_context->globaldefver, name); - if(GetSymbolStartEnd(GetMapSymbols(my_context->elfs[0]), name, start, end, version, vername, 1, defver)) + if(GetSizedSymbolStartEnd(GetMapSymbols(my_context->elfs[0]), name, start, end, size, version, vername, 1, defver)) if(*start) return 1; defver = GetDefaultVersion(my_context->weakdefver, name); - if(GetSymbolStartEnd(GetWeakSymbols(my_context->elfs[0]), name, start, end, version, vername, 1, defver)) + if(GetSizedSymbolStartEnd(GetWeakSymbols(my_context->elfs[0]), name, start, end, size, version, vername, 1, defver)) 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, &weak, version, vername, 1)) + if(GetLibGlobalSymbolStartEnd(maplib->libraries[i], name, start, end, size, &weak, version, vername, 1)) 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, &weak, version, vername, 1); + GetLibWeakSymbolStartEnd(maplib->libraries[i], name, start, end, size, &weak, version, vername, 1); } if(weak && *start) return 1; @@ -439,6 +439,7 @@ 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; + size_t size = 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) @@ -448,12 +449,12 @@ static int GetGlobalSymbolStartEnd_internal(lib_t *maplib, const char* name, uin // 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; i<my_context->neededlibs.size; ++i) - if(GetLibGlobalSymbolStartEnd(my_context->neededlibs.libs[i], name, start, end, &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]))) if(*start) return 1; // search in global symbols for(int i=0; i<maplib->libsz; ++i) { - if(GetLibGlobalSymbolStartEnd(maplib->libraries[i], name, start, end, &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]))) if(*start) return 1; } @@ -467,7 +468,7 @@ static int GetGlobalSymbolStartEnd_internal(lib_t *maplib, const char* name, uin ok = 1; for(int i=0; i<maplib->libsz; ++i) { - if(GetLibWeakSymbolStartEnd(maplib->libraries[i], name, start, end, &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]))) if(*start) ok = 1; } @@ -513,6 +514,7 @@ elfheader_t* GetGlobalSymbolElf(lib_t *maplib, const char* name, int version, co { uintptr_t start = 0; uintptr_t end = 0; + size_t size = 0; int weak = 0; elfheader_t* ret = NULL; // check with default version... @@ -521,7 +523,7 @@ elfheader_t* GetGlobalSymbolElf(lib_t *maplib, const char* name, int version, co 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, &weak, version, vername, 1)) { + if(GetLibGlobalSymbolStartEnd(maplib->libraries[i], name, &start, &end, size, &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])); @@ -538,7 +540,7 @@ elfheader_t* GetGlobalSymbolElf(lib_t *maplib, const char* name, int version, co 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, &weak, version, vername, 1)) { + if(GetLibWeakSymbolStartEnd(maplib->libraries[i], name, &start, &end, size, &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])); @@ -557,6 +559,7 @@ elfheader_t* GetGlobalSymbolElf(lib_t *maplib, const char* name, int version, co int GetGlobalNoWeakSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, int version, const char* vername) { int weak = 0; + size_t size = 0; // check with default version... const char* defver = GetDefaultVersion(my_context->globaldefver, name); @@ -564,7 +567,7 @@ int GetGlobalNoWeakSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* st if(*start || *end) return 1; for(int i=0; i<maplib->libsz; ++i) - if(GetLibGlobalSymbolStartEnd(maplib->libraries[i], name, start, end, &weak, version, vername, 1)) + if(GetLibGlobalSymbolStartEnd(maplib->libraries[i], name, start, end, size, &weak, version, vername, 1)) if(*start || *end) return 1; // nope, not found @@ -574,11 +577,12 @@ 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; + size_t size = 0; int weak; // 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, &weak, version, vername, 1)) + if(GetLibGlobalSymbolStartEnd(maplib->libraries[i], name, &start, &end, size, &weak, version, vername, 1)) if(start || end) return 1; // nope, not found @@ -590,6 +594,7 @@ int GetLocalSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, ui { // check with default version... int weak; + size_t size = 0; if(my_context->elfs[0]==self || !self) { if(GetSymbolStartEnd(GetLocalSymbols(my_context->elfs[0]), name, start, end, version, vername, 1, NULL)) @@ -600,7 +605,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, &weak, version, vername, 1)) + if(GetLibLocalSymbolStartEnd(maplib->libraries[i], name, start, end, size, &weak, version, vername, 1)) if(*start) return 1; if(self) diff --git a/src/librarian/library.c b/src/librarian/library.c index 7baceeca..29c595a1 100755 --- a/src/librarian/library.c +++ b/src/librarian/library.c @@ -118,7 +118,9 @@ 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, 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) +{ + // ignoring asked size on wrapped libs uintptr_t addr = 0; uintptr_t size = 0; int wk = 0; @@ -134,13 +136,13 @@ 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, 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) { // symbols... uintptr_t start, end; const char* defver = GetDefaultVersion(my_context->weakdefver, name); // weak symbols... - if(GetSymbolStartEnd(GetWeakSymbols(lib->e.elf), name, &start, &end, version, vername, local, defver)) + if(GetSizedSymbolStartEnd(GetWeakSymbols(lib->e.elf), name, &start, &end, asked_size, version, vername, local, defver)) { *offs = start; *sz = end-start; @@ -149,7 +151,9 @@ 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, 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) +{ + // ignoring asked size on wrapped libs uintptr_t addr = 0; uintptr_t size = 0; int wk = 0; @@ -165,11 +169,11 @@ 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, 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) { uintptr_t start, end; const char* defver = GetDefaultVersion(my_context->globaldefver, name); - if(GetSymbolStartEnd(GetMapSymbols(lib->e.elf), name, &start, &end, version, vername, local, defver)) + if(GetSizedSymbolStartEnd(GetMapSymbols(lib->e.elf), name, &start, &end, asked_size, version, vername, local, defver)) { *offs = start; *sz = end-start; @@ -178,8 +182,9 @@ 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, 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) { + // 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); @@ -193,7 +198,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, 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) { (void)lib; (void)name; (void)offs; (void)sz; (void)version; (void)vername; (void)local; return 0; @@ -448,7 +453,7 @@ int FinalizeLibrary(library_t* lib, lib_t* local_maplib, int bindnow, x64emu_t* 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, &weak, -1, NULL, 0)) { + } else if(GetLibLocalSymbolStartEnd(lib, trace_func, &trace_start, &trace_end, 0, &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); @@ -609,34 +614,24 @@ 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, 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) { if(!name[0] || !lib->active) return 0; khint_t k; - // check first if already in the map - 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->getweak(lib, name, start, end, weak, version, vername, local)) { + if(lib->getweak(lib, name, start, end, size, 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 first if already in the map + 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; - 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; @@ -646,13 +641,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, 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) { if(!name[0] || !lib->active) return 0; khint_t k; // get a new symbol - if(lib->getglobal(lib, name, start, end, weak, version, vername, local)) { + if(lib->getglobal(lib, name, start, end, size, 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 @@ -673,21 +668,21 @@ 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, 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) { if(!name[0] || !lib->active) return 0; khint_t k; - // check first if already in the map - 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, weak, version, vername, local)) { + if(lib->getlocal(lib, name, start, end, size, weak, version, vername, local)) { *end += *start; // lib->get(...) gives size, not end + // check first if already in the map + 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; + } char* symbol = box_strdup(VersionnedName(name, version, vername)); int ret; k = kh_put(bridgemap, lib->lbridgemap, symbol, &ret); diff --git a/src/librarian/symbols.c b/src/librarian/symbols.c index 2fbbf118..83feb019 100644 --- a/src/librarian/symbols.c +++ b/src/librarian/symbols.c @@ -58,88 +58,89 @@ static int SameVersion(versymbol_t* s, int ver, const char* vername) } -static versymbol_t* FindVersionLocal(versymbols_t* s) +static versymbol_t* FindVersionLocal(versymbols_t* s, size_t size) { if(!s || !s->sz) return NULL; for (int i=0; i<s->sz; ++i) - if(s->syms[i].version==0) + if(s->syms[i].version==0 && (!size || (size==s->syms[i].sym.sz))) return &s->syms[i]; return NULL; } -static versymbol_t* FindNoVersion(versymbols_t* s) +static versymbol_t* FindNoVersion(versymbols_t* s, size_t size) { if(!s || !s->sz) return NULL; for (int i=0; i<s->sz; ++i) - if(s->syms[i].version==-1) + if(s->syms[i].version==-1 && (!size || (size==s->syms[i].sym.sz))) return &s->syms[i]; return NULL; } -static versymbol_t* FindVersionGlobal(versymbols_t* s) +static versymbol_t* FindVersionGlobal(versymbols_t* s, size_t size) { if(!s || !s->sz) return NULL; for (int i=0; i<s->sz; ++i) - if(s->syms[i].version==1) + if(s->syms[i].version==1 && (!size || (size==s->syms[i].sym.sz))) return &s->syms[i]; return NULL; } -static versymbol_t* FindVersion(versymbols_t* s, const char* vername) +static versymbol_t* FindVersion(versymbols_t* s, size_t size, const char* vername) { if(!s || !s->sz) return NULL; for (int i=0; i<s->sz; ++i) - if(s->syms[i].vername && !strcmp(s->syms[i].vername, vername)) + if(s->syms[i].vername && !strcmp(s->syms[i].vername, vername) && (!size || (size==s->syms[i].sym.sz))) return &s->syms[i]; return NULL; } -static versymbol_t* FindFirstVersion(versymbols_t* s) +static versymbol_t* FindFirstVersion(versymbols_t* s, size_t size) { if(!s || !s->sz) return NULL; for (int i=0; i<s->sz; ++i) - if(s->syms[i].version>1) + if(s->syms[i].version>1 && (!size || (size==s->syms[i].sym.sz))) return &s->syms[i]; return NULL; } // 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, const char* defver) +static versymbol_t* MatchVersion(versymbols_t* s, int ver, const char* vername, size_t size, int local, const char* defver) { if(!s || !s->sz) return NULL; versymbol_t* ret = NULL; if(ver==0) { - if(local) ret = FindVersionLocal(s); - if(!ret) ret = FindNoVersion(s); - if(!ret) ret = FindVersionGlobal(s); + if(local) ret = FindVersionLocal(s, size); + if(!ret) ret = FindNoVersion(s, size); + if(!ret) ret = FindVersionGlobal(s, size); + if(!ret && defver) ret = FindVersion(s, size, defver); return ret; } if(ver==-1) { - if(local) ret = FindVersionLocal(s); - if(!ret) ret = FindNoVersion(s); - if(!ret) ret = FindVersionGlobal(s); - if(!ret && defver) ret = FindVersion(s, defver); + if(local) ret = FindVersionLocal(s, size); + if(!ret) ret = FindNoVersion(s, size); + if(!ret) ret = FindVersionGlobal(s, size); + if(!ret && defver) ret = FindVersion(s, size, defver); //if(!ret) ret = FindFirstVersion(s); return ret; } if(ver==-2) { - if(local) ret = FindVersionLocal(s); - if(!ret) ret = FindVersionGlobal(s); + if(local) ret = FindVersionLocal(s, size); + if(!ret) ret = FindVersionGlobal(s, size); return ret; } if(ver==1) { - if(local) ret = FindVersionLocal(s); - if(!ret) ret = FindVersionGlobal(s); - if(!ret) ret = FindNoVersion(s); - if(!ret && defver) ret = FindVersion(s, defver); + if(local) ret = FindVersionLocal(s, size); + if(!ret) ret = FindVersionGlobal(s, size); + if(!ret) ret = FindNoVersion(s, size); + if(!ret && defver) ret = FindVersion(s, size, defver); //if(!ret) ret = FindFirstVersion(s); return ret; } - ret = FindVersion(s, vername); - if(local && !ret) ret = FindVersionLocal(s); - if(!ret && defver && vername && !strcmp(defver, vername)) ret = FindVersionGlobal(s); + ret = FindVersion(s, size, vername); + if(local && !ret) ret = FindVersionLocal(s, size); + if(!ret && defver && vername && !strcmp(defver, vername)) ret = FindVersionGlobal(s, size); //if(!ret) return FindVersionGlobal(s); return ret; } @@ -177,7 +178,7 @@ 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, defver); + versymbol_t * s = MatchVersion(v, ver, vername, 0, local, defver); if(s) return s->sym.offs; return 0; @@ -214,7 +215,24 @@ 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, defver); + versymbol_t* s = MatchVersion(v, ver, vername, 0, local, defver); + if(s) { + *start = s->sym.offs; + *end = *start + s->sym.sz; + return 1; + } + return 0; +} + +int GetSizedSymbolStartEnd(kh_mapsymbols_t* mapsymbols, const char* name, uintptr_t* start, uintptr_t* end, size_t size, int ver, const char* vername, int local, const char* defver) +{ + if(!mapsymbols) + return 0; + khint_t k = kh_get(mapsymbols, mapsymbols, name); + if(k==kh_end(mapsymbols)) + return 0; + versymbols_t * v = &kh_val(mapsymbols, k); + versymbol_t* s = MatchVersion(v, ver, vername, size, local, defver); if(s) { *start = s->sym.offs; *end = *start + s->sym.sz; diff --git a/src/wrapped/wrappedlibdl.c b/src/wrapped/wrappedlibdl.c index 4cd70df4..a0f7f4b1 100755 --- a/src/wrapped/wrappedlibdl.c +++ b/src/wrapped/wrappedlibdl.c @@ -192,9 +192,9 @@ 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, &weak, version, vername, 1)) + if(lib->getglobal(lib, rsymbol, start, end, 0, &weak, version, vername, 1)) return 1; - if(lib->getweak(lib, rsymbol, start, end, &weak, version, vername, 1)) + if(lib->getweak(lib, rsymbol, start, end, 0, &weak, version, vername, 1)) return 1; // look in other libs int n = GetNeededLibN(lib); @@ -238,7 +238,7 @@ 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(my_context, *(uintptr_t*)R_RSP); // use return address to guess "self" - if(GetNoSelfSymbolStartEnd(my_context->maplib, rsymbol, &start, &end, elf, -1, NULL)) { + if(GetNoSelfSymbolStartEnd(my_context->maplib, rsymbol, &start, &end, elf, 0, -1, NULL)) { printf_dlsym(LOG_NEVER, "%p\n", (void*)start); return (void*)start; } @@ -376,7 +376,7 @@ 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(my_context, *(uintptr_t*)R_RSP); // use return address to guess "self" - if(GetNoSelfSymbolStartEnd(my_context->maplib, rsymbol, &start, &end, elf, version, vername)) { + if(GetNoSelfSymbolStartEnd(my_context->maplib, rsymbol, &start, &end, elf, 0, version, vername)) { printf_dlsym(LOG_NEVER, "%p\n", (void*)start); return (void*)start; } |