diff --git a/CMakeLists.txt b/CMakeLists.txt index aee628950e..4f55a3a72c 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -216,6 +216,8 @@ set(ELFLOADER_SRC "${BOX86_ROOT}/src/elfs/elfload_dump.c" "${BOX86_ROOT}/src/librarian/library.c" "${BOX86_ROOT}/src/librarian/librarian.c" + "${BOX86_ROOT}/src/librarian/dictionnary.c" + "${BOX86_ROOT}/src/librarian/symbols.c" "${BOX86_ROOT}/src/emu/x86emu.c" "${BOX86_ROOT}/src/emu/x86run.c" "${BOX86_ROOT}/src/emu/x86run66.c" @@ -647,16 +649,15 @@ add_test(NAME conditionalThreads COMMAND ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAK -D TEST_REFERENCE=${CMAKE_SOURCE_DIR}/tests/ref14.txt -P ${CMAKE_SOURCE_DIR}/runTest.cmake ) -# WIP -#add_test(NAME linkingIndirectNoversion COMMAND ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX86} -# -D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests/test15 -D TEST_OUTPUT=tmpfile.txt -# -D TEST_REFERENCE=${CMAKE_SOURCE_DIR}/tests/ref15.txt -# -P ${CMAKE_SOURCE_DIR}/runTest.cmake ) -# -#add_test(NAME linkingIndirectVersion COMMAND ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX86} -# -D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests/test16 -D TEST_OUTPUT=tmpfile.txt -# -D TEST_REFERENCE=${CMAKE_SOURCE_DIR}/tests/ref16.txt -# -P ${CMAKE_SOURCE_DIR}/runTest.cmake ) +add_test(NAME linkingIndirectNoversion COMMAND ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX86} + -D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests/test15 -D TEST_OUTPUT=tmpfile.txt + -D TEST_REFERENCE=${CMAKE_SOURCE_DIR}/tests/ref15.txt + -P ${CMAKE_SOURCE_DIR}/runTest.cmake ) + +add_test(NAME linkingIndirectVersion COMMAND ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX86} + -D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests/test16 -D TEST_OUTPUT=tmpfile.txt + -D TEST_REFERENCE=${CMAKE_SOURCE_DIR}/tests/ref16.txt + -P ${CMAKE_SOURCE_DIR}/runTest.cmake ) file(GLOB extension_tests "${CMAKE_SOURCE_DIR}/tests/extensions/*.c") foreach(file ${extension_tests}) diff --git a/src/box86context.c b/src/box86context.c index 8b64ab6c78..da2e87c6d9 100755 --- a/src/box86context.c +++ b/src/box86context.c @@ -21,6 +21,7 @@ #include "signals.h" #include #include "custommem.h" +#include "dictionnary.h" #ifdef DYNAREC #include "dynablock.h" #include "dynarec/arm_lock_helper.h" @@ -129,10 +130,10 @@ static void init_mutexes(box86context_t* context) pthread_mutex_init(&context->mutex_once, &attr); pthread_mutex_init(&context->mutex_once2, &attr); pthread_mutex_init(&context->mutex_trace, &attr); -#ifndef DYNAREC - pthread_mutex_init(&context->mutex_lock, &attr); -#else +#ifdef DYNAREC pthread_mutex_init(&context->mutex_dyndump, &attr); +#else + pthread_mutex_init(&context->mutex_lock, &attr); #endif pthread_mutex_init(&context->mutex_tls, &attr); pthread_mutex_init(&context->mutex_thread, &attr); @@ -169,6 +170,7 @@ box86context_t *NewBox86Context(int argc) context->maplib = NewLibrarian(context, 1); context->local_maplib = NewLibrarian(context, 1); + context->versym = NewDictionnary(); context->system = NewBridge(); // create vsyscall context->vsyscall = AddBridge(context->system, vFv, x86Syscall, 0); @@ -217,6 +219,7 @@ void FreeBox86Context(box86context_t** context) FreeLibrarian(&ctx->local_maplib, NULL); if(ctx->maplib) FreeLibrarian(&ctx->maplib, NULL); + FreeDictionnary(&ctx->versym); for(int i=0; ielfsize; ++i) { FreeElfHeader(&ctx->elfs[i]); @@ -295,10 +298,10 @@ void FreeBox86Context(box86context_t** context) pthread_mutex_destroy(&ctx->mutex_once); pthread_mutex_destroy(&ctx->mutex_once2); pthread_mutex_destroy(&ctx->mutex_trace); -#ifndef DYNAREC - pthread_mutex_destroy(&ctx->mutex_lock); -#else +#ifdef DYNAREC pthread_mutex_destroy(&ctx->mutex_dyndump); +#else + pthread_mutex_destroy(&ctx->mutex_lock); #endif pthread_mutex_destroy(&ctx->mutex_tls); pthread_mutex_destroy(&ctx->mutex_thread); diff --git a/src/dynarec/dynablock.c b/src/dynarec/dynablock.c index ec747044c1..2a03d3f59a 100755 --- a/src/dynarec/dynablock.c +++ b/src/dynarec/dynablock.c @@ -258,7 +258,7 @@ dynablock_t *AddNewDynablock(dynablocklist_t* dynablocks, uintptr_t addr, int* c if(dynablocks->direct) { block = dynablocks->direct[addr-dynablocks->text]; if(block) { - dynarec_log(LOG_DUMP, "Block already exist in Direct Map\n"); + dynarec_log(LOG_VERBOSE, "Block already exist in Direct Map\n"); *created = 0; return block; } @@ -274,7 +274,7 @@ dynablock_t *AddNewDynablock(dynablocklist_t* dynablocks, uintptr_t addr, int* c } // create and add new block - dynarec_log(LOG_DUMP, "Ask for DynaRec Block creation @%p\n", (void*)addr); + dynarec_log(LOG_VERBOSE, "Ask for DynaRec Block creation @%p\n", (void*)addr); block = (dynablock_t*)calloc(1, sizeof(dynablock_t)); block->parent = dynablocks; diff --git a/src/elfs/elfload_dump.c b/src/elfs/elfload_dump.c index e3de6d53a9..c1bc9e4bc7 100755 --- a/src/elfs/elfload_dump.c +++ b/src/elfs/elfload_dump.c @@ -200,13 +200,14 @@ const char* DumpRelType(int t) return buff; } -const char* DumpSym(elfheader_t *h, Elf32_Sym* sym) +const char* DumpSym(elfheader_t *h, Elf32_Sym* sym, int version) { static char buff[4096]; + const char* vername = (version==-1)?"(none)":((version==0)?"*local*":((version==1)?"*global*":GetSymbolVersion(h, version))); memset(buff, 0, sizeof(buff)); - sprintf(buff, "\"%s\", value=%p, size=%d, info/other=%d/%d index=%d", + sprintf(buff, "\"%s\", value=%p, size=%d, info/other=%d/%d index=%d (ver=%d/%s)", h->DynStr+sym->st_name, (void*)sym->st_value, sym->st_size, - sym->st_info, sym->st_other, sym->st_shndx); + sym->st_info, sym->st_other, sym->st_shndx, version, vername); return buff; } @@ -221,116 +222,118 @@ const char* IdxSymName(elfheader_t *h, int sym) void DumpMainHeader(Elf32_Ehdr *header, elfheader_t *h) { - if(box86_log>=LOG_DUMP) { - printf_log(LOG_DUMP, "ELF Dump main header\n"); - printf_log(LOG_DUMP, " Entry point = %p\n", (void*)header->e_entry); - printf_log(LOG_DUMP, " Program Header table offset = %p\n", (void*)header->e_phoff); - printf_log(LOG_DUMP, " Section Header table offset = %p\n", (void*)header->e_shoff); - printf_log(LOG_DUMP, " Flags = 0x%X\n", header->e_flags); - printf_log(LOG_DUMP, " ELF Header size = %d\n", header->e_ehsize); - printf_log(LOG_DUMP, " Program Header Entry num/size = %d(%d)/%d\n", h->numPHEntries, header->e_phnum, header->e_phentsize); - printf_log(LOG_DUMP, " Section Header Entry num/size = %d(%d)/%d\n", h->numSHEntries, header->e_shnum, header->e_shentsize); - printf_log(LOG_DUMP, " Section Header index num = %d(%d)\n", h->SHIdx, header->e_shstrndx); - printf_log(LOG_DUMP, "ELF Dump ==========\n"); + if(box86_dump) { + printf_dump(LOG_NEVER, "ELF Dump main header\n"); + printf_dump(LOG_NEVER, " Entry point = %p\n", (void*)header->e_entry); + printf_dump(LOG_NEVER, " Program Header table offset = %p\n", (void*)header->e_phoff); + printf_dump(LOG_NEVER, " Section Header table offset = %p\n", (void*)header->e_shoff); + printf_dump(LOG_NEVER, " Flags = 0x%X\n", header->e_flags); + printf_dump(LOG_NEVER, " ELF Header size = %d\n", header->e_ehsize); + printf_dump(LOG_NEVER, " Program Header Entry num/size = %d(%d)/%d\n", h->numPHEntries, header->e_phnum, header->e_phentsize); + printf_dump(LOG_NEVER, " Section Header Entry num/size = %d(%d)/%d\n", h->numSHEntries, header->e_shnum, header->e_shentsize); + printf_dump(LOG_NEVER, " Section Header index num = %d(%d)\n", h->SHIdx, header->e_shstrndx); + printf_dump(LOG_NEVER, "ELF Dump ==========\n"); - printf_log(LOG_DUMP, "ELF Dump PEntries (%d)\n", h->numSHEntries); + printf_dump(LOG_NEVER, "ELF Dump PEntries (%d)\n", h->numSHEntries); for (int i=0; inumPHEntries; ++i) - printf_log(LOG_DUMP, " PHEntry %04d : %s\n", i, DumpPHEntry(h->PHEntries+i)); - printf_log(LOG_DUMP, "ELF Dump PEntries ====\n"); + printf_dump(LOG_NEVER, " PHEntry %04d : %s\n", i, DumpPHEntry(h->PHEntries+i)); + printf_dump(LOG_NEVER, "ELF Dump PEntries ====\n"); - printf_log(LOG_DUMP, "ELF Dump Sections (%d)\n", h->numSHEntries); + printf_dump(LOG_NEVER, "ELF Dump Sections (%d)\n", h->numSHEntries); for (int i=0; inumSHEntries; ++i) - printf_log(LOG_DUMP, " Section %04d : %s\n", i, DumpSection(h->SHEntries+i, h->SHStrTab)); - printf_log(LOG_DUMP, "ELF Dump Sections ====\n"); + printf_dump(LOG_NEVER, " Section %04d : %s\n", i, DumpSection(h->SHEntries+i, h->SHStrTab)); + printf_dump(LOG_NEVER, "ELF Dump Sections ====\n"); } } void DumpSymTab(elfheader_t *h) { - if(box86_log>=LOG_DUMP && h->SymTab) { + if(box86_dump && h->SymTab) { const char* name = ElfName(h); - printf_log(LOG_DUMP, "ELF Dump SymTab(%d)=\n", h->numSymTab); + printf_dump(LOG_NEVER, "ELF Dump SymTab(%d)=\n", h->numSymTab); for (int i=0; inumSymTab; ++i) - printf_log(LOG_DUMP, " %s:SymTab[%d] = \"%s\", value=%p, size=%d, info/other=%d/%d index=%d\n", name, + printf_dump(LOG_NEVER, " %s:SymTab[%d] = \"%s\", value=%p, size=%d, info/other=%d/%d index=%d\n", name, i, h->StrTab+h->SymTab[i].st_name, (void*)h->SymTab[i].st_value, h->SymTab[i].st_size, h->SymTab[i].st_info, h->SymTab[i].st_other, h->SymTab[i].st_shndx); - printf_log(LOG_DUMP, "ELF Dump SymTab=====\n"); + printf_dump(LOG_NEVER, "ELF Dump SymTab=====\n"); } } void DumpDynamicSections(elfheader_t *h) { - if(box86_log>=LOG_DUMP && h->Dynamic) { - printf_log(LOG_DUMP, "ELF Dump Dynamic(%d)=\n", h->numDynamic); + if(box86_dump && h->Dynamic) { + printf_dump(LOG_NEVER, "ELF Dump Dynamic(%d)=\n", h->numDynamic); for (int i=0; inumDynamic; ++i) - printf_log(LOG_DUMP, " Dynamic %04d : %s\n", i, DumpDynamic(h->Dynamic+i)); - printf_log(LOG_DUMP, "ELF Dump Dynamic=====\n"); + printf_dump(LOG_NEVER, " Dynamic %04d : %s\n", i, DumpDynamic(h->Dynamic+i)); + printf_dump(LOG_NEVER, "ELF Dump Dynamic=====\n"); } } void DumpDynSym(elfheader_t *h) { - if(box86_log>=LOG_DUMP && h->DynSym) { + if(box86_dump && h->DynSym) { const char* name = ElfName(h); - printf_log(LOG_DUMP, "ELF Dump DynSym(%d)=\n", h->numDynSym); - for (int i=0; inumDynSym; ++i) - printf_log(LOG_DUMP, " %s:DynSym[%d] = %s\n", name, i, DumpSym(h, h->DynSym+i)); - printf_log(LOG_DUMP, "ELF Dump DynSym=====\n"); + printf_dump(LOG_NEVER, "ELF Dump DynSym(%d)=\n", h->numDynSym); + for (int i=0; inumDynSym; ++i) { + int version = h->VerSym?((Elf32_Half*)((uintptr_t)h->VerSym+h->delta))[i]:-1; + printf_dump(LOG_NEVER, " %s:DynSym[%d] = %s\n", name, i, DumpSym(h, h->DynSym+i, version)); + } + printf_dump(LOG_NEVER, "ELF Dump DynSym=====\n"); } } void DumpDynamicNeeded(elfheader_t *h) { - if(box86_log>=LOG_DUMP && h->DynStrTab) { - printf_log(LOG_DUMP, "ELF Dump DT_NEEDED=====\n"); + if(box86_dump && h->DynStrTab) { + printf_dump(LOG_NEVER, "ELF Dump DT_NEEDED=====\n"); for (int i=0; inumDynamic; ++i) if(h->Dynamic[i].d_tag==DT_NEEDED) { - printf_log(LOG_DUMP, " Needed : %s\n", h->DynStrTab+h->Dynamic[i].d_un.d_val + h->delta); + printf_dump(LOG_NEVER, " Needed : %s\n", h->DynStrTab+h->Dynamic[i].d_un.d_val + h->delta); } - printf_log(LOG_DUMP, "ELF Dump DT_NEEDED=====\n"); + printf_dump(LOG_NEVER, "ELF Dump DT_NEEDED=====\n"); } } void DumpDynamicRPath(elfheader_t *h) { - if(box86_log>=LOG_DUMP && h->DynStrTab) { - printf_log(LOG_DUMP, "ELF Dump DT_RPATH/DT_RUNPATH=====\n"); + if(box86_dump && h->DynStrTab) { + printf_dump(LOG_NEVER, "ELF Dump DT_RPATH/DT_RUNPATH=====\n"); for (int i=0; inumDynamic; ++i) { if(h->Dynamic[i].d_tag==DT_RPATH) { - printf_log(LOG_DUMP, " RPATH : %s\n", h->DynStrTab+h->Dynamic[i].d_un.d_val + h->delta); + printf_dump(LOG_NEVER, " RPATH : %s\n", h->DynStrTab+h->Dynamic[i].d_un.d_val + h->delta); } if(h->Dynamic[i].d_tag==DT_RUNPATH) { - printf_log(LOG_DUMP, " RUNPATH : %s\n", h->DynStrTab+h->Dynamic[i].d_un.d_val + h->delta); + printf_dump(LOG_NEVER, " RUNPATH : %s\n", h->DynStrTab+h->Dynamic[i].d_un.d_val + h->delta); } } - printf_log(LOG_DUMP, "=====ELF Dump DT_RPATH/DT_RUNPATH\n"); + printf_dump(LOG_NEVER, "=====ELF Dump DT_RPATH/DT_RUNPATH\n"); } } void DumpRelTable(elfheader_t *h, int cnt, Elf32_Rel *rel, const char* name) { - if(box86_log>=LOG_DUMP) { + if(box86_dump) { const char* elfname = ElfName(h); - printf_log(LOG_DUMP, "ELF Dump %s Table(%d) @%p\n", name, cnt, rel); + printf_dump(LOG_NEVER, "ELF Dump %s Table(%d) @%p\n", name, cnt, rel); for (int i = 0; i=LOG_DUMP && h->rela) { + if(box86_dump && h->rela) { const char* elfname = ElfName(h); - printf_log(LOG_DUMP, "ELF Dump %s Table(%d) @%p\n", name, cnt, rela); + printf_dump(LOG_NEVER, "ELF Dump %s Table(%d) @%p\n", name, cnt, rela); for (int i = 0; isz) n = sz; int fill = 16-sz; for (int j = 0; j127)?'.':d[j]); + printf_dump(LOG_NEVER, "%c", (d[j]<32 || d[j]>127)?'.':d[j]); for (int j = 0; jmultiblock_n = n; // might be less in fact for (int i=0; imultiblock_n; ++i) { - printf_log(LOG_DEBUG, "Allocating 0x%x memory @%p for Elf \"%s\"\n", head->multiblock_size[i], (void*)head->multiblock_offs[i], head->name); + printf_log(LOG_DEBUG, "Allocating 0x%x memory %p for Elf \"%s\"\n", head->multiblock_size[i], (void*)head->multiblock_offs[i], head->name); void* p = mmap((void*)head->multiblock_offs[i], head->multiblock_size[i] , PROT_READ | PROT_WRITE | PROT_EXEC , MAP_PRIVATE | MAP_ANONYMOUS /*| ((wine_preloaded)?MAP_FIXED:0)*/ , -1, 0); if(p==MAP_FAILED) { - printf_log(LOG_NONE, "Cannot create memory map (@%p 0x%x/0x%x) for elf \"%s\"\n", (void*)head->multiblock_offs[i], head->multiblock_size[i], head->align, head->name); + printf_log(LOG_NONE, "Cannot create memory map (%p 0x%x/0x%x) for elf \"%s\"\n", (void*)head->multiblock_offs[i], head->multiblock_size[i], head->align, head->name); return 1; } if(head->multiblock_offs[i] &&( p!=(void*)head->multiblock_offs[i])) { if((head->e_type!=ET_DYN)) { - printf_log(LOG_NONE, "Error, memory map (@%p 0x%x/0x%x) for elf \"%s\" allocated @%p\n", (void*)head->multiblock_offs[i], head->multiblock_size[i], head->align, head->name, p); + printf_log(LOG_NONE, "Error, memory map (%p 0x%x/0x%x) for elf \"%s\" allocated %p\n", (void*)head->multiblock_offs[i], head->multiblock_size[i], head->align, head->name, p); return 1; } else { printf_log(LOG_INFO, "Allocated memory is not at hinted %p but %p (size %p) \"%s\"\n", (void*)head->multiblock_offs[i], p, (void*)head->multiblock_size[i], head->name); @@ -236,17 +238,17 @@ int AllocElfMemory(box86context_t* context, elfheader_t* head, int mainbin) } } else { // vaddr is 0, load everything has a One block - printf_log(LOG_DEBUG, "Allocating 0x%x memory @%p for Elf \"%s\"\n", head->memsz, (void*)offs, head->name); + printf_log(LOG_DEBUG, "Allocating 0x%x memory %p for Elf \"%s\"\n", head->memsz, (void*)offs, head->name); void* p = mmap((void*)offs, head->memsz , PROT_READ | PROT_WRITE | PROT_EXEC , MAP_PRIVATE | MAP_ANONYMOUS /*| (((offs&&wine_preloaded)?MAP_FIXED:0))*/ , -1, 0); if(p==MAP_FAILED) { - printf_log(LOG_NONE, "Cannot create memory map (@%p 0x%x/0x%x) for elf \"%s\"\n", (void*)offs, head->memsz, head->align, head->name); + printf_log(LOG_NONE, "Cannot create memory map (%p 0x%x/0x%x) for elf \"%s\"\n", (void*)offs, head->memsz, head->align, head->name); return 1; } if(offs && (p!=(void*)offs) && (head->e_type!=ET_DYN)) { - printf_log(LOG_NONE, "Error, memory map (@%p 0x%x/0x%x) for elf \"%s\" allocated @%p\n", (void*)offs, head->memsz, head->align, head->name, p); + printf_log(LOG_NONE, "Error, memory map (%p 0x%x/0x%x) for elf \"%s\" allocated %p\n", (void*)offs, head->memsz, head->align, head->name, p); return 1; } setProtection((uintptr_t)p, head->memsz, PROT_READ | PROT_WRITE | PROT_EXEC); @@ -286,7 +288,7 @@ int LoadElfMemory(FILE* f, box86context_t* context, elfheader_t* head) if(head->PHEntries[i].p_type == PT_LOAD) { Elf32_Phdr * e = &head->PHEntries[i]; char* dest = (char*)e->p_paddr + head->delta; - printf_log(LOG_DEBUG, "Loading block #%i @%p (0x%x/0x%x)\n", i, dest, e->p_filesz, e->p_memsz); + printf_log(LOG_DEBUG, "Loading block #%i %p (0x%x/0x%x)\n", i, dest, e->p_filesz, e->p_memsz); fseeko64(f, e->p_offset, SEEK_SET); if(e->p_filesz) { if(fread(dest, e->p_filesz, 1, f)!=1) { @@ -308,7 +310,7 @@ int LoadElfMemory(FILE* f, box86context_t* context, elfheader_t* head) if(head->PHEntries[i].p_type == PT_TLS) { Elf32_Phdr * e = &head->PHEntries[i]; char* dest = (char*)(context->tlsdata+context->tlssize+head->tlsbase); - printf_log(LOG_DEBUG, "Loading TLS block #%i @%p (0x%x/0x%x)\n", i, dest, e->p_filesz, e->p_memsz); + printf_log(LOG_DEBUG, "Loading TLS block #%i %p (0x%x/0x%x)\n", i, dest, e->p_filesz, e->p_memsz); if(e->p_filesz) { fseeko64(f, e->p_offset, SEEK_SET); if(fread(dest, e->p_filesz, 1, f)!=1) { @@ -330,7 +332,7 @@ int ReloadElfMemory(FILE* f, box86context_t* context, elfheader_t* head) if(head->PHEntries[i].p_type == PT_LOAD) { Elf32_Phdr * e = &head->PHEntries[i]; char* dest = (char*)e->p_paddr + head->delta; - printf_log(LOG_DEBUG, "Re-loading block #%i @%p (0x%x/0x%x)\n", i, dest, e->p_filesz, e->p_memsz); + printf_log(LOG_DEBUG, "Re-loading block #%i %p (0x%x/0x%x)\n", i, dest, e->p_filesz, e->p_memsz); int ret = fseeko64(f, e->p_offset, SEEK_SET); if(ret==-1) {printf_log(LOG_NONE, "Fail to (re)seek PT_LOAD part #%d (offset=%d, errno=%d/%s)\n", i, e->p_offset, errno, strerror(errno)); return 1;} #ifdef DYNAREC @@ -353,7 +355,7 @@ int ReloadElfMemory(FILE* f, box86context_t* context, elfheader_t* head) // TLS data are just a copy, no need to re-load it return 0; } -int FindR386COPYRel(elfheader_t* h, const char* name, uintptr_t *offs, uint32_t** p) +int FindR386COPYRel(elfheader_t* h, const char* name, uintptr_t *offs, uint32_t** p, int version, const char* vername) { if(!h) return 0; @@ -365,7 +367,10 @@ int FindR386COPYRel(elfheader_t* h, const char* name, uintptr_t *offs, uint32_t* int t = ELF32_R_TYPE(rel[i].r_info); Elf32_Sym *sym = &h->DynSym[ELF32_R_SYM(rel[i].r_info)]; const char* symname = SymName(h, sym); - if(!strcmp(symname, name) && t==R_386_COPY) { + int version2 = h->VerSym?((Elf32_Half*)((uintptr_t)h->VerSym+h->delta))[ELF32_R_SYM(rel[i].r_info)]:-1; + if(version2!=-1) version2 &= 0x7fff; + const char* vername2 = GetSymbolVersion(h, version2); + if(SameVersionnedSymbol(name, version, vername, symname, version2, vername2) && t==R_386_COPY) { *offs = sym->st_value + h->delta; *p = (uint32_t*)(rel[i].r_offset + h->delta); return 1; @@ -386,14 +391,9 @@ int RelocateElfREL(lib_t *maplib, lib_t *local_maplib, elfheader_t* head, int cn uintptr_t offs = 0; uintptr_t end = 0; uintptr_t tmp = 0; - int version = head->VerSym?((Elf32_Half*)((uintptr_t)head->VerSym+head->delta))[ELF32_R_SYM(rel[i].r_info)]:0; - const char* ver = GetSymbolVersion(head, version); - char SymbolVersionned[501]; - strncpy(SymbolVersionned, symname, 500); - if(ver) { - strncat(SymbolVersionned, "@", 500); - strncat(SymbolVersionned, ver, 500); - } + int version = head->VerSym?((Elf32_Half*)((uintptr_t)head->VerSym+head->delta))[ELF32_R_SYM(rel[i].r_info)]:-1; + if(version!=-1) version &=0x7fff; + const char* vername = GetSymbolVersion(head, version); elfheader_t* h_tls = head; if(bind==STB_LOCAL) { offs = sym->st_value + head->delta; @@ -401,22 +401,16 @@ int RelocateElfREL(lib_t *maplib, lib_t *local_maplib, elfheader_t* head, int cn } else { // this is probably very very wrong. A proprer way to get reloc need to be writen, but this hack seems ok for now // at least it work for half-life, unreal, ut99, zsnes, Undertale, ColinMcRae Remake, FTL, ShovelKnight... - if(bind==STB_GLOBAL && (ndx==10 || ndx==19) && t!=R_386_GLOB_DAT) { + /*if(bind==STB_GLOBAL && (ndx==10 || ndx==19) && t!=R_386_GLOB_DAT) { offs = sym->st_value + head->delta; end = offs + sym->st_size; - } + }*/ // so weak symbol are the one left, and try versionned symbol first if(!offs && !end) { h_tls = NULL; - if(local_maplib) { - GetGlobalSymbolStartEnd(local_maplib, SymbolVersionned, &offs, &end); - if(!offs && !end) - GetGlobalSymbolStartEnd(local_maplib, symname, &offs, &end); - } - if(!offs && !end) { - GetGlobalSymbolStartEnd(maplib, SymbolVersionned, &offs, &end); - if(!offs && !end) - GetGlobalSymbolStartEnd(maplib, symname, &offs, &end); + GetGlobalSymbolStartEnd(maplib, symname, &offs, &end, head, version, vername); + if(!offs && !end && local_maplib) { + GetGlobalSymbolStartEnd(local_maplib, symname, &offs, &end, head, version, vername); } } } @@ -426,7 +420,7 @@ int RelocateElfREL(lib_t *maplib, lib_t *local_maplib, elfheader_t* head, int cn switch(t) { case R_386_NONE: // can be ignored - printf_log(LOG_DUMP, "Ignoring %s @%p (%p)\n", DumpRelType(t), p, (void*)(p?(*p):0)); + printf_dump(LOG_NEVER, "Ignoring [%d] %s %p (%p)\n", i, DumpRelType(t), p, (void*)(p?(*p):0)); break; case R_386_TLS_TPOFF: // Negated offset in static TLS block @@ -435,16 +429,16 @@ int RelocateElfREL(lib_t *maplib, lib_t *local_maplib, elfheader_t* head, int cn offs = sym->st_value; else { if(local_maplib) - h_tls = GetGlobalSymbolElf(local_maplib, symname); + h_tls = GetGlobalSymbolElf(local_maplib, symname, version, vername); if(!h_tls) - h_tls = GetGlobalSymbolElf(maplib, symname); + h_tls = GetGlobalSymbolElf(maplib, symname, version, vername); } if(h_tls) { delta = *(int*)p; - printf_log(LOG_DUMP, "Applying %s %s on %s @%p (%d -> %d)\n", (bind==STB_LOCAL)?"Local":"Global", DumpRelType(t), symname, p, delta, (int32_t)offs + h_tls->tlsbase); + printf_dump(LOG_NEVER, "Applying [%d] %s %s on %s %p (%d -> %d)\n", i, (bind==STB_LOCAL)?"Local":"Global", DumpRelType(t), symname, p, delta, (int32_t)offs + h_tls->tlsbase); *p = (uint32_t)((int32_t)offs + h_tls->tlsbase); } else { - printf_log(LOG_INFO, "Warning, cannot apply %s %s on %s @%p (%d), no elf_header found\n", (bind==STB_LOCAL)?"Local":"Global", DumpRelType(t), symname, p, (int32_t)offs); + printf_log(LOG_INFO, "Warning, cannot apply %s %s on %s %p (%d), no elf_header found\n", (bind==STB_LOCAL)?"Local":"Global", DumpRelType(t), symname, p, (int32_t)offs); } } break; @@ -455,52 +449,52 @@ int RelocateElfREL(lib_t *maplib, lib_t *local_maplib, elfheader_t* head, int cn offs = sym->st_value; else { if(local_maplib) - h_tls = GetGlobalSymbolElf(local_maplib, symname); + h_tls = GetGlobalSymbolElf(local_maplib, symname, version, vername); if(!h_tls) - h_tls = GetGlobalSymbolElf(maplib, symname); + h_tls = GetGlobalSymbolElf(maplib, symname, version, vername); } if(h_tls) { delta = *(int*)p; - printf_log(LOG_DUMP, "Applying %s %s on %s @%p (%d -> %d)\n", (bind==STB_LOCAL)?"Local":"Global", DumpRelType(t), symname, p, delta, (int32_t)offs + h_tls->tlsbase); + printf_dump(LOG_NEVER, "Applying %s %s on %s %p (%d -> %d)\n", (bind==STB_LOCAL)?"Local":"Global", DumpRelType(t), symname, p, delta, (int32_t)offs + h_tls->tlsbase); *p = (uint32_t)(-((int32_t)offs + h_tls->tlsbase)); } else { - printf_log(LOG_INFO, "Warning, cannot apply %s %s on %s @%p (%d), no elf_header found\n", (bind==STB_LOCAL)?"Local":"Global", DumpRelType(t), symname, p, (int32_t)offs); + printf_log(LOG_INFO, "Warning, cannot apply %s %s on %s %p (%d), no elf_header found\n", (bind==STB_LOCAL)?"Local":"Global", DumpRelType(t), symname, p, (int32_t)offs); } } break; case R_386_PC32: if (!offs) { - printf_log(LOG_NONE, "Error: Global Symbol %s not found, cannot apply R_386_PC32 @%p (%p) in %s\n", symname, p, *(void**)p, head->name); + printf_log(LOG_NONE, "Error: Global Symbol %s not found, cannot apply R_386_PC32 %p (%p) in %s\n", symname, p, *(void**)p, head->name); } + if(offs) + printf_dump(LOG_NEVER, "Apply [%d] %s R_386_PC32 %p with sym=%s (%p -> %p/%p)\n", i, (bind==STB_LOCAL)?"Local":"Global", p, symname, *(void**)p, (void*)(*(uintptr_t*)p+(offs-(uintptr_t)p)), (void*)offs); offs = (offs - (uintptr_t)p); - if(!offs) - printf_log(LOG_DUMP, "Apply %s R_386_PC32 @%p with sym=%s (%p -> %p)\n", (bind==STB_LOCAL)?"Local":"Global", p, symname, *(void**)p, (void*)(*(uintptr_t*)p+offs)); *p += offs; break; case R_386_GLOB_DAT: - if(head!=my_context->elfs[0] && !IsGlobalNoWeakSymbolInNative(maplib, symname) && FindR386COPYRel(my_context->elfs[0], symname, &globoffs, &globp)) { + if(head!=my_context->elfs[0] && !IsGlobalNoWeakSymbolInNative(maplib, symname, version, vername) && FindR386COPYRel(my_context->elfs[0], symname, &globoffs, &globp, version, vername)) { // set global offs / size for the symbol offs = sym->st_value + head->delta; end = offs + sym->st_size; if(sym->st_size) { - printf_log(LOG_DUMP, "Apply %s R_386_GLOB_DAT with R_386_COPY @%p/%p (%p/%p -> %p/%p) size=%d on sym=%s \n", (bind==STB_LOCAL)?"Local":"Global", p, globp, (void*)(p?(*p):0), (void*)(globp?(*globp):0), (void*)offs, (void*)globoffs, sym->st_size, symname); + printf_dump(LOG_NEVER, "Apply %s R_386_GLOB_DAT with R_386_COPY %p/%p (%p/%p -> %p/%p) size=%d on sym=%s (ver %d/%s) \n", (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); + AddWeakSymbol(GetGlobalData(maplib), symname, offs, sym->st_size, version, vername); } else { - printf_log(LOG_DUMP, "Apply %s R_386_GLOB_DAT with R_386_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); + printf_dump(LOG_NEVER, "Apply %s R_386_GLOB_DAT with R_386_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), (void*)(globp?(*globp):0), (void*)offs, (void*)globoffs, symname, version, vername?vername:"(none)"); } *p = globoffs; } else { // Look for same symbol already loaded but not in self (so no need for local_maplib here) - if (GetGlobalNoWeakSymbolStartEnd(maplib, symname, &globoffs, &globend)) { + if (GetGlobalNoWeakSymbolStartEnd(maplib, symname, &globoffs, &globend, version, vername)) { offs = globoffs; end = globend; } if (!offs) { if(strcmp(symname, "__gmon_start__")) - printf_log(LOG_NONE, "Error: Global Symbol %s not found, cannot apply R_386_GLOB_DAT @%p (%p) in %s\n", symname, p, *(void**)p, head->name); + printf_log(LOG_NONE, "Error: Global Symbol %s version %d/%s not found, cannot apply R_386_GLOB_DAT %p (%p) in %s\n", symname, version, vername?vername:"(none)", p, *(void**)p, head->name); } else { - printf_log(LOG_DUMP, "Apply %s R_386_GLOB_DAT @%p (%p -> %p) on sym=%s\n", (bind==STB_LOCAL)?"Local":"Global", p, (void*)(p?(*p):0), (void*)offs, symname); + printf_dump(LOG_NEVER, "Apply %s R_386_GLOB_DAT %p (%p -> %p) on sym=%s (ver %d/%s)\n", (bind==STB_LOCAL)?"Local":"Global", p, (void*)(p?(*p):0), (void*)offs, symname, version, vername?vername:"(none)"); *p = offs; } } @@ -510,39 +504,38 @@ int RelocateElfREL(lib_t *maplib, lib_t *local_maplib, elfheader_t* head, int cn uintptr_t old_offs = offs; uintptr_t old_end = end; offs = 0; - GetSymbolStartEnd(GetGlobalData(maplib), symname, &offs, &end); // try globaldata symbols first + GetSymbolStartEnd(GetGlobalData(maplib), symname, &offs, &end, version, vername, 1); // try globaldata symbols first, with exact version (enabling local symbol) if(offs==0) { if(local_maplib) - GetNoSelfSymbolStartEnd(local_maplib, symname, &offs, &end, head); + GetNoSelfSymbolStartEnd(local_maplib, symname, &offs, &end, head, version, vername); if(!offs) - GetNoSelfSymbolStartEnd(maplib, symname, &offs, &end, head); // get original copy if any + GetNoSelfSymbolStartEnd(maplib, symname, &offs, &end, head, version, vername); // get original copy if any } if(!offs) { offs = old_offs; end = old_end; } - printf_log(LOG_DUMP, "Apply %s R_386_COPY @%p with sym=%s, @%p size=%d (", (bind==STB_LOCAL)?"Local":"Global", p, symname, (void*)offs, sym->st_size); + printf_dump(LOG_NEVER, "Apply %s R_386_COPY %p with sym=%s (ver %d/%s), %p size=%d (", (bind==STB_LOCAL)?"Local":"Global", p, symname, version, vername?vername:"(none)", (void*)offs, sym->st_size); memmove(p, (void*)offs, sym->st_size); - if(LOG_DUMP<=box86_log) { + if(box86_dump) { uint32_t*k = (uint32_t*)p; for (int i=0; i<((sym->st_size>128)?128:sym->st_size); i+=4, ++k) - printf_log(LOG_DUMP, "%s0x%08X", i?" ":"", *k); - printf_log(LOG_DUMP, "%s)\n", (sym->st_size>128)?" ...":""); + printf_dump(LOG_NEVER, "%s0x%08X", i?" ":"", *k); + printf_dump(LOG_NEVER, "%s)\n", (sym->st_size>128)?" ...":""); } } else { - printf_log(LOG_NONE, "Error: Symbol %s not found, cannot apply R_386_COPY @%p (%p) in %s\n", symname, p, *(void**)p, head->name); + printf_log(LOG_NONE, "Error: Symbol %s not found, cannot apply R_386_COPY %p (%p) in %s\n", symname, p, *(void**)p, head->name); } break; case R_386_RELATIVE: - printf_log(LOG_DUMP, "Apply %s R_386_RELATIVE @%p (%p -> %p)\n", (bind==STB_LOCAL)?"Local":"Global", p, *(void**)p, (void*)((*p)+head->delta)); + printf_dump(LOG_NEVER, "Apply [%d] %s R_386_RELATIVE %p (%p -> %p)\n", i, (bind==STB_LOCAL)?"Local":"Global", p, *(void**)p, (void*)((*p)+head->delta)); *p += head->delta; break; case R_386_32: if (!offs) { - printf_log(LOG_NONE, "Error: Symbol %s not found, cannot apply R_386_32 @%p (%p) in %s\n", symname, p, *(void**)p, head->name); -// return -1; + printf_log(LOG_NONE, "Error: Symbol %s not found, cannot apply R_386_32 %p (%p) in %s\n", symname, p, *(void**)p, head->name); } else { - printf_log(LOG_DUMP, "Apply %s R_386_32 @%p with sym=%s (%p -> %p)\n", (bind==STB_LOCAL)?"Local":"Global", p, symname, *(void**)p, (void*)(offs+*(uint32_t*)p)); + printf_dump(LOG_NEVER, "Apply %s R_386_32 %p with sym=%s (ver=%d/%s) (%p -> %p)\n", (bind==STB_LOCAL)?"Local":"Global", p, symname, version, vername?vername:"(none)", *(void**)p, (void*)(offs+*(uint32_t*)p)); *p += offs; } break; @@ -553,14 +546,14 @@ int RelocateElfREL(lib_t *maplib, lib_t *local_maplib, elfheader_t* head, int cn else { if(!h_tls) { if(local_maplib) - h_tls = GetGlobalSymbolElf(local_maplib, symname); + h_tls = GetGlobalSymbolElf(local_maplib, symname, version, vername); if(!h_tls) - h_tls = GetGlobalSymbolElf(maplib, symname); + h_tls = GetGlobalSymbolElf(maplib, symname, version, vername); } offs = getElfIndex(my_context, h_tls); } if(p) { - printf_log(LOG_DUMP, "Apply %s %s @%p with sym=%s (%p -> %p)\n", "R_386_TLS_DTPMOD32", (bind==STB_LOCAL)?"Local":"Global", p, symname, *(void**)p, (void*)offs); + printf_dump(LOG_NEVER, "Apply %s %s %p with sym=%s (%p -> %p)\n", "R_386_TLS_DTPMOD32", (bind==STB_LOCAL)?"Local":"Global", p, symname, *(void**)p, (void*)offs); *p = offs; } else { printf_log(LOG_NONE, "Warning, Symbol %s or Elf not found, but R_386_TLS_DTPMOD32 Slot Offset is NULL \n", symname); @@ -570,17 +563,16 @@ int RelocateElfREL(lib_t *maplib, lib_t *local_maplib, elfheader_t* head, int cn // Offset in TLS block if (!offs && !end) { if(bind==STB_WEAK) { - printf_log(LOG_INFO, "Warning: Weak Symbol %s not found, cannot apply R_386_TLS_DTPOFF32 @%p (%p)\n", symname, p, *(void**)p); + printf_log(LOG_INFO, "Warning: Weak Symbol %s not found, cannot apply R_386_TLS_DTPOFF32 %p (%p)\n", symname, p, *(void**)p); } else { - printf_log(LOG_NONE, "Error: Symbol %s not found, cannot apply R_386_TLS_DTPOFF32 @%p (%p) in %s\n", symname, p, *(void**)p, head->name); + printf_log(LOG_NONE, "Error: Symbol %s not found, cannot apply R_386_TLS_DTPOFF32 %p (%p) in %s\n", symname, p, *(void**)p, head->name); } -// return -1; } else { if(h_tls) offs = sym->st_value; if(p) { int tlsoffset = offs; // it's not an offset in elf memory - printf_log(LOG_DUMP, "Apply %s R_386_TLS_DTPOFF32 @%p with sym=%s (%p -> %p)\n", (bind==STB_LOCAL)?"Local":"Global", p, symname, (void*)tlsoffset, (void*)offs); + printf_dump(LOG_NEVER, "Apply %s R_386_TLS_DTPOFF32 %p with sym=%s (%p -> %p)\n", (bind==STB_LOCAL)?"Local":"Global", p, symname, (void*)tlsoffset, (void*)offs); *p = tlsoffset; } else { printf_log(LOG_NONE, "Warning, Symbol %s found, but R_386_TLS_DTPOFF32 Slot Offset is NULL \n", symname); @@ -598,21 +590,20 @@ int RelocateElfREL(lib_t *maplib, lib_t *local_maplib, elfheader_t* head, int cn ) { if (!offs) { if(bind==STB_WEAK) { - printf_log(LOG_INFO, "Warning: Weak Symbol %s not found, cannot apply R_386_JMP_SLOT @%p (%p)\n", symname, p, *(void**)p); + printf_log(LOG_INFO, "Warning: Weak Symbol %s not found, cannot apply R_386_JMP_SLOT %p (%p)\n", symname, p, *(void**)p); } else { - printf_log(LOG_NONE, "Error: Symbol %s not found, cannot apply R_386_JMP_SLOT @%p (%p) in %s\n", symname, p, *(void**)p, head->name); + printf_log(LOG_NONE, "Error: Symbol %s not found, cannot apply R_386_JMP_SLOT %p (%p) in %s\n", symname, p, *(void**)p, head->name); } - // return -1; } else { if(p) { - printf_log(LOG_DUMP, "Apply %s R_386_JMP_SLOT @%p with sym=%s(%s) (%p -> %p)\n", (bind==STB_LOCAL)?"Local":"Global", p, symname, SymbolVersionned, *(void**)p, (void*)offs); + printf_dump(LOG_NEVER, "Apply %s R_386_JMP_SLOT %p with sym=%s(%s%s%s) (%p -> %p)\n", (bind==STB_LOCAL)?"Local":"Global", p, symname, symname, vername?"@":"", vername?vername:"", *(void**)p, (void*)offs); *p = offs; } else { printf_log(LOG_NONE, "Warning, Symbol %s found, but Jump Slot Offset is NULL \n", symname); } } } else { - printf_log(LOG_DUMP, "Preparing (if needed) %s R_386_JMP_SLOT @%p (0x%x->0x%0x) with sym=%s(%s/version %d) to be apply later\n", (bind==STB_LOCAL)?"Local":"Global", p, *p, *p+head->delta, symname, SymbolVersionned, version); + printf_dump(LOG_NEVER, "Preparing (if needed) %s R_386_JMP_SLOT %p (0x%x->0x%0x) with sym=%s(%s%s%s/version %d) to be apply later\n", (bind==STB_LOCAL)?"Local":"Global", p, *p, *p+head->delta, symname, symname, vername?"@":"", vername?vername:"", version); *p += head->delta; } break; @@ -627,7 +618,11 @@ int RelocateElfRELA(lib_t *maplib, lib_t *local_maplib, elfheader_t* head, int c { for (int i=0; iDynSym[ELF32_R_SYM(rela[i].r_info)]; + int bind = ELF32_ST_BIND(sym->st_info); const char* symname = SymName(head, sym); + int version = head->VerSym?((Elf32_Half*)((uintptr_t)head->VerSym+head->delta))[ELF32_R_SYM(rela[i].r_info)]:-1; + if(version!=-1) version &=0x7fff; + const char* vername = GetSymbolVersion(head, version); uint32_t *p = (uint32_t*)(rela[i].r_offset + head->delta); uintptr_t offs = 0; uintptr_t end = 0; @@ -638,15 +633,15 @@ int RelocateElfRELA(lib_t *maplib, lib_t *local_maplib, elfheader_t* head, int c break; case R_386_COPY: if(local_maplib) - GetNoSelfSymbolStartEnd(local_maplib, symname, &offs, &end, head); + GetNoSelfSymbolStartEnd(local_maplib, symname, &offs, &end, head, version, vername); if(!offs) - GetNoSelfSymbolStartEnd(maplib, symname, &offs, &end, head); + GetNoSelfSymbolStartEnd(maplib, symname, &offs, &end, head, version, vername); if(offs) { // add r_addend to p? - printf_log(LOG_DUMP, "Apply R_386_COPY @%p with sym=%s, @%p size=%d\n", p, symname, (void*)offs, sym->st_size); + printf_dump(LOG_NEVER, "Apply R_386_COPY %p with sym=%s, %p size=%d\n", p, symname, (void*)offs, sym->st_size); memcpy(p, (void*)(offs+rela[i].r_addend), sym->st_size); } else { - printf_log(LOG_NONE, "Error: Symbol %s not found, cannot apply RELA R_386_COPY @%p (%p) in %s\n", symname, p, *(void**)p, head->name); + printf_log(LOG_NONE, "Error: Symbol %s not found, cannot apply RELA R_386_COPY %p (%p) in %s\n", symname, p, *(void**)p, head->name); } break; default: @@ -756,30 +751,14 @@ uintptr_t GetEntryPoint(lib_t* maplib, elfheader_t* h) { uintptr_t ep = h->entrypoint + h->delta; printf_log(LOG_DEBUG, "Entry Point is %p\n", (void*)ep); - if(box86_log>=LOG_DUMP) { - printf_log(LOG_DUMP, "(short) Dump of Entry point\n"); + if(box86_dump) { + printf_dump(LOG_NEVER, "(short) Dump of Entry point\n"); int sz = 64; uintptr_t lastbyte = GetLastByte(h); if (ep + sz > lastbyte) sz = lastbyte - ep; DumpBinary((char*)ep, sz); } - /* - // but instead of regular entrypoint, lets grab "main", it will be easier to manage I guess - uintptr_t m = FindSymbol(maplib, "main"); - if(m) { - ep = m; - printf_log(LOG_DEBUG, "Using \"main\" as Entry Point @%p\n", ep); - if(box86_log>=LOG_DUMP) { - printf_log(LOG_DUMP, "(short) Dump of Entry point\n"); - int sz = 64; - uintptr_t lastbyte = GetLastByte(h); - if (ep + sz > lastbyte) - sz = lastbyte - ep; - DumpBinary((char*)ep, sz); - } - } - */ return ep; } @@ -790,31 +769,83 @@ uintptr_t GetLastByte(elfheader_t* h) void AddSymbols(lib_t *maplib, kh_mapsymbols_t* mapsymbols, kh_mapsymbols_t* weaksymbols, kh_mapsymbols_t* localsymbols, elfheader_t* h) { - printf_log(LOG_DUMP, "Will look for Symbol to add in SymTable(%d)\n", h->numSymTab); + if(box86_dump && h->DynSym) DumpDynSym(h); + printf_dump(LOG_NEVER, "Will look for Symbol to add in SymTable(%d)\n", h->numSymTab); for (int i=0; inumSymTab; ++i) { const char * symname = h->StrTab+h->SymTab[i].st_name; int bind = ELF32_ST_BIND(h->SymTab[i].st_info); int type = ELF32_ST_TYPE(h->SymTab[i].st_info); int vis = h->SymTab[i].st_other&0x3; + uint32_t sz = h->SymTab[i].st_size; if((type==STT_OBJECT || type==STT_FUNC || type==STT_COMMON || type==STT_TLS || type==STT_NOTYPE) && (vis==STV_DEFAULT || vis==STV_PROTECTED) && (h->SymTab[i].st_shndx!=0)) { - if((bind==STB_GNU_UNIQUE /*|| (bind==STB_GLOBAL && type==STT_FUNC)*/) && FindGlobalSymbol(maplib, symname)) - continue; - uintptr_t offs = (type==STT_TLS)?h->SymTab[i].st_value:(h->SymTab[i].st_value + h->delta); - uint32_t sz = h->SymTab[i].st_size; - printf_log(LOG_DUMP, "Adding Symbol(bind=%s) \"%s\" with offset=%p sz=%d\n", (bind==STB_LOCAL)?"LOCAL":((bind==STB_WEAK)?"WEAK":"GLOBAL"), symname, (void*)offs, sz); - if(bind==STB_LOCAL) - AddSymbol(localsymbols, symname, offs, sz); - else // add in local and global map - if(bind==STB_WEAK) { - AddSymbol(weaksymbols, symname, offs, sz); - } else { - AddSymbol(mapsymbols, symname, offs, sz); + if(sz && strstr(symname, "@@")) { + char symnameversionned[strlen(symname)+1]; + strcpy(symnameversionned, symname); + // extact symname@@vername + char* p = strchr(symnameversionned, '@'); + *p=0; + p+=2; + symname = AddDictionnary(my_context->versym, symnameversionned); + const char* vername = AddDictionnary(my_context->versym, p); + 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); + printf_dump(LOG_NEVER, "Adding Default Versionned Symbol(bind=%s) \"%s@%s\" with offset=%p sz=%d\n", (bind==STB_LOCAL)?"LOCAL":((bind==STB_WEAK)?"WEAK":"GLOBAL"), symname, vername, (void*)offs, sz); + if(bind==STB_LOCAL) + AddSymbol(localsymbols, symname, offs, sz, 2, vername); + else // add in local and global map + if(bind==STB_WEAK) { + AddSymbol(weaksymbols, symname, offs, sz, 2, vername); + } else { + AddSymbol(mapsymbols, symname, offs, sz, 2, vername); + } + } else { + if((bind==STB_GNU_UNIQUE /*|| (bind==STB_GLOBAL && type==STT_FUNC)*/) && FindGlobalSymbol(maplib, symname, -1, NULL)) + continue; + uintptr_t offs = (type==STT_TLS)?h->SymTab[i].st_value:(h->SymTab[i].st_value + h->delta); + printf_dump(LOG_NEVER, "Adding Symbol(bind=%s) \"%s\" with offset=%p sz=%d\n", (bind==STB_LOCAL)?"LOCAL":((bind==STB_WEAK)?"WEAK":"GLOBAL"), symname, (void*)offs, sz); + if(bind==STB_LOCAL) + AddSymbol(localsymbols, symname, offs, sz, 1, NULL); + else // add in local and global map + if(bind==STB_WEAK) { + AddSymbol(weaksymbols, symname, offs, sz, 1, NULL); + } else { + AddSymbol(mapsymbols, symname, offs, sz, 1, NULL); + } + } + } + } + + printf_dump(LOG_NEVER, "Will look for Symbol to add in DynSym (%d)\n", h->numDynSym); + for (int i=0; inumDynSym; ++i) { + const char * symname = h->DynStr+h->DynSym[i].st_name; + int bind = ELF32_ST_BIND(h->DynSym[i].st_info); + int type = ELF32_ST_TYPE(h->DynSym[i].st_info); + int vis = h->DynSym[i].st_other&0x3; + if((type==STT_OBJECT || type==STT_FUNC || type==STT_COMMON || type==STT_TLS || type==STT_NOTYPE) + && (vis==STV_DEFAULT || vis==STV_PROTECTED) && (h->DynSym[i].st_shndx!=0 && h->DynSym[i].st_shndx<=65521)) { + uint32_t sz = h->DynSym[i].st_size; + uintptr_t offs = (type==STT_TLS)?h->DynSym[i].st_value:(h->DynSym[i].st_value + h->delta); + int version = h->VerSym?((Elf32_Half*)((uintptr_t)h->VerSym+h->delta))[i]:-1; + if(version!=-1) version &= 0x7fff; + const char* vername = GetSymbolVersion(h, version); + if(!((bind==STB_GNU_UNIQUE /*|| (bind==STB_GLOBAL && type==STT_FUNC)*/) && FindGlobalSymbol(maplib, symname, version, vername))) { + printf_dump(LOG_NEVER, "Adding Versionned Symbol(bind=%s) \"%s\" (ver=%d/%s) with offset=%p sz=%d\n", (bind==STB_LOCAL)?"LOCAL":((bind==STB_WEAK)?"WEAK":"GLOBAL"), symname, version, vername?vername:"(none)", (void*)offs, sz); + if(bind==STB_LOCAL) { + AddSymbol(localsymbols, symname, offs, sz, version, vername); + } else { // add in local and global map + if(bind==STB_WEAK) { + AddSymbol(weaksymbols, symname, offs, sz, version, vername); + } else { + AddSymbol(mapsymbols, symname, offs, sz, version, vername); + } } + } } } - - printf_log(LOG_DUMP, "Will look for Symbol to add in DynSym (%d)\n", h->numDynSym); + #if 0 + printf_dump(LOG_NEVER, "Will look for Symbol to add in DynSym (%d)\n", h->numDynSym); for (int i=0; inumDynSym; ++i) { const char * symname = h->DynStr+h->DynSym[i].st_name; int bind = ELF32_ST_BIND(h->DynSym[i].st_info); @@ -827,7 +858,7 @@ void AddSymbols(lib_t *maplib, kh_mapsymbols_t* mapsymbols, kh_mapsymbols_t* wea continue; uintptr_t offs = (type==STT_TLS)?h->DynSym[i].st_value:(h->DynSym[i].st_value + h->delta); uint32_t sz = h->DynSym[i].st_size; - printf_log(LOG_DUMP, "Adding Symbol(bind=%s) \"%s\" with offset=%p sz=%d\n", (bind==STB_LOCAL)?"LOCAL":((bind==STB_WEAK)?"WEAK":"GLOBAL"), symname, (void*)offs, sz); + printf_dump(LOG_NEVER, "Adding Symbol(bind=%s) \"%s\" with offset=%p sz=%d\n", (bind==STB_LOCAL)?"LOCAL":((bind==STB_WEAK)?"WEAK":"GLOBAL"), symname, (void*)offs, sz); if(bind==STB_LOCAL) AddSymbol(localsymbols, symname, offs, sz); else // add in local and global map @@ -838,7 +869,7 @@ void AddSymbols(lib_t *maplib, kh_mapsymbols_t* mapsymbols, kh_mapsymbols_t* wea } } } - + #endif } /* @@ -905,16 +936,22 @@ int LoadNeededLibs(elfheader_t* h, lib_t* maplib, needed_libs_t* neededlibs, lib h->neededlibs = neededlibs; DumpDynamicNeeded(h); + int cnt = 0; for (int i=0; inumDynamic; ++i) - if(h->Dynamic[i].d_tag==DT_NEEDED) { - char *needed = h->DynStrTab+h->delta+h->Dynamic[i].d_un.d_val; - // TODO: Add LD_LIBRARY_PATH and RPATH handling - if(AddNeededLib(maplib, neededlibs, deplib, local, needed, box86, emu)) { - printf_log(LOG_INFO, "Error loading needed lib: \"%s\"\n", needed); - if(!allow_missing_libs) - return 1; //error... - } - } + if(h->Dynamic[i].d_tag==DT_NEEDED) + ++cnt; + const char* nlibs[cnt]; + int j=0; + for (int i=0; inumDynamic; ++i) + if(h->Dynamic[i].d_tag==DT_NEEDED) + nlibs[j++] = h->DynStrTab+h->delta+h->Dynamic[i].d_un.d_val; + + // TODO: Add LD_LIBRARY_PATH and RPATH handling + if(AddNeededLib(maplib, neededlibs, deplib, local, nlibs, cnt, box86, emu)) { + printf_log(LOG_INFO, "Error loading one of needed lib\n"); + if(!allow_missing_libs) + return 1; //error... + } return 0; } @@ -949,14 +986,14 @@ void RunElfInit(elfheader_t* h, x86emu_t *emu) context->deferedInitList[context->deferedInitSz++] = h; return; } - printf_log(LOG_DEBUG, "Calling Init for %s @%p\n", ElfName(h), (void*)p); + printf_log(LOG_DEBUG, "Calling Init for %s %p\n", ElfName(h), (void*)p); if(h->initentry) RunFunctionWithEmu(emu, 0, p, 3, context->argc, context->argv, context->envv); printf_log(LOG_DEBUG, "Done Init for %s\n", ElfName(h)); // and check init array now Elf32_Addr *addr = (Elf32_Addr*)(h->initarray + h->delta); for (int i=0; iinitarray_sz; ++i) { - printf_log(LOG_DEBUG, "Calling Init[%d] for %s @%p\n", i, ElfName(h), (void*)addr[i]); + printf_log(LOG_DEBUG, "Calling Init[%d] for %s %p\n", i, ElfName(h), (void*)addr[i]); RunFunctionWithEmu(emu, 0, (uintptr_t)addr[i], 3, context->argc, context->argv, context->envv); } @@ -994,13 +1031,13 @@ void RunElfFini(elfheader_t* h, x86emu_t *emu) // first check fini array Elf32_Addr *addr = (Elf32_Addr*)(h->finiarray + h->delta); for (int i=h->finiarray_sz-1; i>=0; --i) { - printf_log(LOG_DEBUG, "Calling Fini[%d] for %s @%p\n", i, ElfName(h), (void*)addr[i]); + printf_log(LOG_DEBUG, "Calling Fini[%d] for %s %p\n", i, ElfName(h), (void*)addr[i]); RunFunctionWithEmu(emu, 0, (uintptr_t)addr[i], 0); } // then the "old-style" fini if(h->finientry) { uintptr_t p = h->finientry + h->delta; - printf_log(LOG_DEBUG, "Calling Fini for %s @%p\n", ElfName(h), (void*)p); + printf_log(LOG_DEBUG, "Calling Fini for %s %p\n", ElfName(h), (void*)p); RunFunctionWithEmu(emu, 0, p, 0); } h->init_done = 0; // can be re-inited again... @@ -1099,6 +1136,43 @@ const char* FindNearestSymbolName(elfheader_t* h, void* p, uintptr_t* start, uin return ret; } +const char* VersionnedName(const char* name, int ver, const char* vername) +{ + if(ver==-1) + return name; + const char *v=NULL; + if(ver==0) + v=""; + if(ver==1) + v="*"; + if(!v && !vername) + return name; + if(ver>1) + v = vername; + char buf[strlen(name)+strlen(v)+1+1]; + strcpy(buf, name); + strcat(buf, "@"); + strcat(buf, v); + return AddDictionnary(my_context->versym, buf); +} + +int SameVersionnedSymbol(const char* name1, int ver1, const char* vername1, const char* name2, int ver2, const char* vername2) +{ + if(strcmp(name1, name2)) //name are different, no need to go further + return 0; + if(ver1==-1 || ver2==-1) // don't check version, so ok + return 1; + if(ver1==ver2 && ver1<2) // same ver (local or global), ok + return 1; + if(ver1==0 || ver2==0) // one is local, the other is not, no match + return 0; + if(ver1==1 || ver2==1) // one if global, ok + return 1; + if(!strcmp(vername1, vername2)) // same vername + return 1; + return 0; +} + void* GetDTatOffset(box86context_t* context, int index, int offset) { return (void*)((char*)GetTLSPointer(context, context->elfs[index])+offset); @@ -1288,48 +1362,36 @@ EXPORT void PltResolver(x86emu_t* emu) uintptr_t addr = Pop32(emu); int slot = (int)Pop32(emu); elfheader_t *h = (elfheader_t*)addr; - printf_log(LOG_DEBUG, "PltResolver: Addr=%p, Slot=%d Return=%p: elf is %s (VerSym=%p)\n", (void*)addr, slot, *(void**)(R_ESP), h->name, h->VerSym); - + printf_dump(LOG_DEBUG, "PltResolver: Addr=%p, Slot=%d Return=%p: elf is %s (VerSym=%p)\n", (void*)addr, slot, *(void**)(R_ESP), h->name, h->VerSym); Elf32_Rel * rel = (Elf32_Rel *)(h->jmprel + h->delta + slot); Elf32_Sym *sym = &h->DynSym[ELF32_R_SYM(rel->r_info)]; int bind = ELF32_ST_BIND(sym->st_info); const char* symname = SymName(h, sym); - int version = h->VerSym?((Elf32_Half*)((uintptr_t)h->VerSym+h->delta))[ELF32_R_SYM(rel->r_info)]:0; - const char* ver = GetSymbolVersion(h, version); - char symnameversionned[501]; - strncpy(symnameversionned, symname, 500); - if(ver) { - strncat(symnameversionned, "@", 500); - strncat(symnameversionned, ver, 500); - } + int version = h->VerSym?((Elf32_Half*)((uintptr_t)h->VerSym+h->delta))[ELF32_R_SYM(rel->r_info)]:-1; + if(version!=-1) version &= 0x7fff; + const char* vername = GetSymbolVersion(h, version); uint32_t *p = (uint32_t*)(rel->r_offset + h->delta); uintptr_t offs = 0; uintptr_t end = 0; library_t* lib = h->lib; lib_t* local_maplib = GetMaplib(lib); - if(local_maplib) { - GetGlobalSymbolStartEnd(local_maplib, symnameversionned, &offs, &end); - if(!offs && !end) - GetGlobalSymbolStartEnd(local_maplib, symname, &offs, &end); - } - if(!offs && !end) { - GetGlobalSymbolStartEnd(my_context->maplib, symnameversionned, &offs, &end); - if(!offs && !end) - GetGlobalSymbolStartEnd(my_context->maplib, symname, &offs, &end); + GetGlobalSymbolStartEnd(my_context->maplib, symname, &offs, &end, h, version, vername); + if(!offs && !end && local_maplib) { + GetGlobalSymbolStartEnd(local_maplib, symname, &offs, &end, h, version, vername); } if (!offs) { - printf_log(LOG_NONE, "Error: PltReolver: Symbol %s(%s) not found, cannot apply R_386_JMP_SLOT @%p (%p) in %s\n", symname, symnameversionned, p, *(void**)p, h->name); + printf_log(LOG_NONE, "Error: PltReolver: Symbol %s(ver %d: %s%s%s) not found, cannot apply R_386_JMP_SLOT %p (%p) in %s\n", symname, version, symname, vername?"@":"", vername?vername:"", p, *(void**)p, h->name); emu->quit = 1; return; } else { if(p) { - printf_log(LOG_DEBUG, "PltReolver: Apply %s R_386_JMP_SLOT @%p with sym=%s(%s) (%p -> %p / %s)\n", (bind==STB_LOCAL)?"Local":"Global", p, symname, symnameversionned,*(void**)p, (void*)offs, ElfName(FindElfAddress(my_context, offs))); + printf_dump(LOG_DEBUG, " Apply %s R_386_JMP_SLOT %p with sym=%s(ver %d: %s%s%s) (%p -> %p / %s)\n", (bind==STB_LOCAL)?"Local":"Global", p, symname, version, symname, vername?"@":"", vername?vername:"",*(void**)p, (void*)offs, ElfName(FindElfAddress(my_context, offs))); *p = offs; } else { - printf_log(LOG_NONE, "PltReolver: Warning, Symbol %s(%s) found, but Jump Slot Offset is NULL \n", symname, symnameversionned); + printf_log(LOG_NONE, "PltReolver: Warning, Symbol %s(ver %d: %s%s%s) found, but Jump Slot Offset is NULL \n", symname, version, symname, vername?"@":"", vername?vername:""); } } diff --git a/src/elfs/elfloader_private.h b/src/elfs/elfloader_private.h index 96bd0907f2..c76447e802 100755 --- a/src/elfs/elfloader_private.h +++ b/src/elfs/elfloader_private.h @@ -33,6 +33,8 @@ struct elfheader_s { Elf32_Half* VerSym; Elf32_Verneed* VerNeed; int szVerNeed; + Elf32_Verdef* VerDef; + int szVerDef; int e_type; intptr_t delta; // should be 0 diff --git a/src/elfs/elfparser.c b/src/elfs/elfparser.c index 695683c730..9a82f66923 100755 --- a/src/elfs/elfparser.c +++ b/src/elfs/elfparser.c @@ -177,14 +177,14 @@ elfheader_t* ParseElfHeader(FILE* f, const char* name, int exec) FreeElfHeader(&h); return NULL; } - if(box86_log>=LOG_DUMP) DumpMainHeader(&header, h); + if(box86_dump) DumpMainHeader(&header, h); LoadNamedSection(f, h->SHEntries, h->numSHEntries, h->SHStrTab, ".strtab", "SymTab Strings", SHT_STRTAB, (void**)&h->StrTab, NULL); LoadNamedSection(f, h->SHEntries, h->numSHEntries, h->SHStrTab, ".symtab", "SymTab", SHT_SYMTAB, (void**)&h->SymTab, &h->numSymTab); - if(box86_log>=LOG_DUMP && h->SymTab) DumpSymTab(h); + if(box86_dump && h->SymTab) DumpSymTab(h); LoadNamedSection(f, h->SHEntries, h->numSHEntries, h->SHStrTab, ".dynamic", "Dynamic", SHT_DYNAMIC, (void**)&h->Dynamic, &h->numDynamic); - if(box86_log>=LOG_DUMP && h->Dynamic) DumpDynamicSections(h); + if(box86_dump && h->Dynamic) DumpDynamicSections(h); // grab DT_REL & DT_RELA stuffs // also grab the DT_STRTAB string table { @@ -254,13 +254,21 @@ elfheader_t* ParseElfHeader(FILE* f, const char* name, int exec) printf_log(LOG_DEBUG, "The DT_FINI_ARRAYSZ is %d\n", h->finiarray_sz); break; case DT_VERNEEDNUM: - h->szVerNeed = val / sizeof(Elf32_Verneed); + h->szVerNeed = val; printf_log(LOG_DEBUG, "The DT_VERNEEDNUM is %d\n", h->szVerNeed); break; case DT_VERNEED: h->VerNeed = (Elf32_Verneed*)ptr; printf_log(LOG_DEBUG, "The DT_VERNEED is at address %p\n", h->VerNeed); break; + case DT_VERDEFNUM: + h->szVerDef = val; + printf_log(LOG_DEBUG, "The DT_VERDEFNUM is %d\n", h->szVerDef); + break; + case DT_VERDEF: + h->VerDef = (Elf32_Verdef*)ptr; + printf_log(LOG_DEBUG, "The DT_VERDEF is at address %p\n", h->VerDef); + break; } } if(h->rel) { @@ -335,7 +343,6 @@ elfheader_t* ParseElfHeader(FILE* f, const char* name, int exec) LoadNamedSection(f, h->SHEntries, h->numSHEntries, h->SHStrTab, ".dynstr", "DynSym Strings", SHT_STRTAB, (void**)&h->DynStr, NULL); LoadNamedSection(f, h->SHEntries, h->numSHEntries, h->SHStrTab, ".dynsym", "DynSym", SHT_DYNSYM, (void**)&h->DynSym, &h->numDynSym); - if(box86_log>=LOG_DUMP && h->DynSym) DumpDynSym(h); } return h; @@ -345,6 +352,8 @@ const char* GetSymbolVersion(elfheader_t* h, int version) { if(!h->VerNeed || (version<2)) return NULL; + /*if(version==1) + return "*";*/ Elf32_Verneed *ver = (Elf32_Verneed*)((uintptr_t)h->VerNeed + h->delta); while(ver) { Elf32_Vernaux *aux = (Elf32_Vernaux*)((uintptr_t)ver + ver->vn_aux); @@ -355,5 +364,24 @@ const char* GetSymbolVersion(elfheader_t* h, int version) } ver = ver->vn_next?((Elf32_Verneed*)((uintptr_t)ver + ver->vn_next)):NULL; } + return GetParentSymbolVersion(h, version); // if symbol is "internal", use Def table instead +} + +const char* GetParentSymbolVersion(elfheader_t* h, int index) +{ + if(!h->VerDef || (index<1)) + return NULL; + Elf32_Verdef *def = (Elf32_Verdef*)((uintptr_t)h->VerDef + h->delta); + while(def) { + if(def->vd_ndx==index) { + if(def->vd_cnt<1) + return NULL; + /*if(def->vd_flags&VER_FLG_BASE) + return NULL;*/ + Elf32_Verdaux *aux = (Elf32_Verdaux*)((uintptr_t)def + def->vd_aux); + return h->DynStr+aux->vda_name; // return Parent, so 1st aux + } + def = def->vd_next?((Elf32_Verdef*)((uintptr_t)def + def->vd_next)):NULL; + } return NULL; -} \ No newline at end of file +} diff --git a/src/emu/x86syscall.c b/src/emu/x86syscall.c index d1a2e0502e..32b9dd2f56 100755 --- a/src/emu/x86syscall.c +++ b/src/emu/x86syscall.c @@ -332,7 +332,7 @@ void EXPORT x86Syscall(x86emu_t *emu) switch(syscallwrap[i].nbpars) { case 0: *(int32_t*)&R_EAX = syscall(sc); break; case 1: *(int32_t*)&R_EAX = syscall(sc, R_EBX); break; - case 2: if(s==33) {printf_log(LOG_DUMP, " => sys_access(\"%s\", %d)\n", (char*)R_EBX, R_ECX);}; *(int32_t*)&R_EAX = syscall(sc, R_EBX, R_ECX); break; + case 2: if(s==33) {printf_log(LOG_DEBUG, " => sys_access(\"%s\", %d)\n", (char*)R_EBX, R_ECX);}; *(int32_t*)&R_EAX = syscall(sc, R_EBX, R_ECX); break; case 3: *(int32_t*)&R_EAX = syscall(sc, R_EBX, R_ECX, R_EDX); break; case 4: *(int32_t*)&R_EAX = syscall(sc, R_EBX, R_ECX, R_EDX, R_ESI); break; case 5: *(int32_t*)&R_EAX = syscall(sc, R_EBX, R_ECX, R_EDX, R_ESI, R_EDI); break; @@ -377,7 +377,7 @@ void EXPORT x86Syscall(x86emu_t *emu) char* prog = (char*)R_EBX; char** argv = (char**)R_ECX; char** envv = (char**)R_EDX; - printf_log(LOG_DUMP, " => sys_execve(\"%s\", %p(\"%s\", \"%s\", \"%s\"...), %p)\n", prog, argv, (argv && argv[0])?argv[0]:"nil", (argv && argv[0] && argv[1])?argv[1]:"nil", (argv && argv[0] && argv[1] && argv[2])?argv[2]:"nil", envv); + printf_log(LOG_DEBUG, " => sys_execve(\"%s\", %p(\"%s\", \"%s\", \"%s\"...), %p)\n", prog, argv, (argv && argv[0])?argv[0]:"nil", (argv && argv[0] && argv[1])?argv[1]:"nil", (argv && argv[0] && argv[1] && argv[2])?argv[2]:"nil", envv); R_EAX = my_execve(emu, (const char*)R_EBX, (void*)R_ECX, (void*)R_EDX); } break; @@ -639,7 +639,7 @@ void EXPORT x86Syscall(x86emu_t *emu) uint32_t EXPORT my_syscall(x86emu_t *emu) { uint32_t s = u32(0); - printf_log(LOG_DUMP, "%p: Calling libc syscall 0x%02X (%d) %p %p %p %p %p\n", (void*)R_EIP, s, s, (void*)u32(4), (void*)u32(8), (void*)u32(12), (void*)u32(16), (void*)u32(20)); + printf_log(LOG_DEBUG, "%p: Calling libc syscall 0x%02X (%d) %p %p %p %p %p\n", (void*)R_EIP, s, s, (void*)u32(4), (void*)u32(8), (void*)u32(12), (void*)u32(16), (void*)u32(20)); // check wrapper first int cnt = sizeof(syscallwrap) / sizeof(scwrap_t); for (int i=0; i #include #include "pathcoll.h" +#include "dictionnary.h" typedef struct elfheader_s elfheader_t; typedef struct cleanup_s cleanup_t; @@ -96,6 +97,7 @@ typedef struct box86context_s { lib_t *maplib; // lib and symbols handling lib_t *local_maplib; // libs and symbols openned has local (only collection of libs, no symbols) + dic_t *versym; // dictionnary of versionned symbols kh_threadstack_t *stacksizes; // stack sizes attributes for thread (temporary) bridge_t *system; // other bridges diff --git a/src/include/debug.h b/src/include/debug.h index 8a5fa4b96c..85252af2ba 100755 --- a/src/include/debug.h +++ b/src/include/debug.h @@ -4,6 +4,7 @@ typedef struct box86context_s box86context_t; extern int box86_log; // log level +extern int box86_dump; // dump elf or not extern int box86_dynarec_log; extern int box86_dynarec; extern int box86_pagesize; @@ -36,12 +37,15 @@ extern int box86_tcmalloc_minimal; // when using tcmalloc_minimal #define LOG_NONE 0 #define LOG_INFO 1 #define LOG_DEBUG 2 -#define LOG_DUMP 3 +#define LOG_NEVER 3 +#define LOG_VERBOSE 3 extern FILE* ftrace; #define printf_log(L, ...) do {if(L<=box86_log) {fprintf(ftrace, __VA_ARGS__); fflush(ftrace);}} while(0) +#define printf_dump(L, ...) do {if(box86_dump || (L<=box86_log)) {fprintf(ftrace, __VA_ARGS__); fflush(ftrace);}} while(0) + #define dynarec_log(L, ...) do {if(L<=box86_dynarec_log) {fprintf(ftrace, __VA_ARGS__); fflush(ftrace);}} while(0) #define EXPORT __attribute__((visibility("default"))) diff --git a/src/include/dictionnary.h b/src/include/dictionnary.h new file mode 100755 index 0000000000..e2ec14666b --- /dev/null +++ b/src/include/dictionnary.h @@ -0,0 +1,13 @@ +#ifndef __DICTIONNARY_H_ +#define __DICTIONNARY_H_ +#include + +typedef void dic_t; + +dic_t *NewDictionnary(); +void FreeDictionnary(dic_t **dic); + +const char* AddDictionnary(dic_t* dic, const char* s); +int ExistDictionnary(dic_t* dic, const char* s); + +#endif //__DICTIONNARY_H_ \ No newline at end of file diff --git a/src/include/elfload_dump.h b/src/include/elfload_dump.h index 48e3f9ca97..1d02a06b5e 100755 --- a/src/include/elfload_dump.h +++ b/src/include/elfload_dump.h @@ -6,7 +6,7 @@ typedef struct elfheader_s elfheader_t; const char* DumpSection(Elf32_Shdr *s, char* SST); const char* DumpDynamic(Elf32_Dyn *s); const char* DumpPHEntry(Elf32_Phdr *e); -const char* DumpSym(elfheader_t *h, Elf32_Sym* sym); +const char* DumpSym(elfheader_t *h, Elf32_Sym* sym, int version); const char* DumpRelType(int t); const char* SymName(elfheader_t *h, Elf32_Sym* sym); const char* IdxSymName(elfheader_t *h, int sym); diff --git a/src/include/elfloader.h b/src/include/elfloader.h index 2b48412f30..419a90fd42 100755 --- a/src/include/elfloader.h +++ b/src/include/elfloader.h @@ -56,5 +56,8 @@ void CreateMemorymapFile(box86context_t* context, int fd); int ElfCheckIfUseTCMallocMinimal(elfheader_t* h); // return 1 if tcmalloc is used const char* GetSymbolVersion(elfheader_t* h, int version); +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); #endif //__ELF_LOADER_H_ diff --git a/src/include/librarian.h b/src/include/librarian.h index a378b2d740..a87ceeca53 100755 --- a/src/include/librarian.h +++ b/src/include/librarian.h @@ -25,24 +25,18 @@ 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, const char* path, box86context_t* box86, x86emu_t* emu); // 0=success, 1=error +int AddNeededLib(lib_t* maplib, needed_libs_t* neededlibs, library_t* deplib, int local, const char** paths, int npath, box86context_t* box86, x86emu_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 GetNoSelfSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, elfheader_t* self); -int GetSelfSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, elfheader_t *self); -int GetGlobalSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end); -int GetGlobalNoWeakSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end); -int GetLocalSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, elfheader_t *self); -int GetNoWeakSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, elfheader_t *self); -elfheader_t* GetGlobalSymbolElf(lib_t *maplib, const char* name); -int IsGlobalNoWeakSymbolInNative(lib_t *maplib, const char* name); - -void AddSymbol(kh_mapsymbols_t *mapsymbols, const char* name, uintptr_t addr, uint32_t sz); // replace if already there -uintptr_t FindSymbol(kh_mapsymbols_t *mapsymbols, const char* name); -void AddWeakSymbol(kh_mapsymbols_t *mapsymbols, const char* name, uintptr_t addr, uint32_t sz); // don't add if already there -int GetSymbolStartEnd(kh_mapsymbols_t* mapsymbols, const char* name, uintptr_t* start, uintptr_t* end); -const char* GetSymbolName(kh_mapsymbols_t* mapsymbols, void* p, uintptr_t* offs, uint32_t* sz); +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); const char* FindSymbolName(lib_t *maplib, void* p, void** start, uint32_t* sz, const char** libname, void** base); diff --git a/src/include/library.h b/src/include/library.h index 0fecec58b2..924cec0d66 100755 --- a/src/include/library.h +++ b/src/include/library.h @@ -1,6 +1,7 @@ #ifndef __LIBRARY_H_ #define __LIBRARY_H_ #include +#include "symbols.h" typedef struct library_s library_t; typedef struct lib_s lib_t; @@ -18,9 +19,9 @@ void Free1Library(library_t **lib, x86emu_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 GetLibNoWeakSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start, uintptr_t* end); -int GetLibLocalSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start, uintptr_t* end); +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); void fillGLProcWrapper(box86context_t* context); void freeGLProcWrapper(box86context_t* context); void fillALProcWrapper(box86context_t* context); diff --git a/src/include/symbols.h b/src/include/symbols.h new file mode 100644 index 0000000000..c8403b61df --- /dev/null +++ b/src/include/symbols.h @@ -0,0 +1,24 @@ +#ifndef __SYMBOLS_PRIVATE_H_ +#define __SYMBOLS_PRIVATE_H_ +#include + +#include "custommem.h" +#include "khash.h" + +typedef struct versymbols_s versymbols_t; + +KHASH_MAP_DECLARE_STR(mapsymbols, versymbols_t) + +kh_mapsymbols_t* NewMapSymbols(); +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); +// don't add if already there +#define MAX_STEP 3 +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); +const char* GetSymbolName(kh_mapsymbols_t* mapsymbols, void* p, uintptr_t* offs, uint32_t* sz, const char** vername); + +#endif //__SYMBOLS_PRIVATE_H_ \ No newline at end of file diff --git a/src/include/wrappedlibs.h b/src/include/wrappedlibs.h index 48feda1941..4f32f6d9a2 100755 --- a/src/include/wrappedlibs.h +++ b/src/include/wrappedlibs.h @@ -7,13 +7,13 @@ typedef struct box86context_s box86context_t; typedef int (*wrappedlib_init_t)(library_t * lib, box86context_t* box86); // 0 = success typedef void (*wrappedlib_fini_t)(library_t * lib); -typedef int (*wrappedlib_get_t)(library_t* lib, const char* name, uintptr_t *offs, uint32_t *sz); +typedef int (*wrappedlib_get_t)(library_t* lib, const char* name, uintptr_t *offs, uint32_t *sz, int version, const char* vername, int step); typedef struct wrappedlib_s { const char* name; wrappedlib_init_t init; wrappedlib_fini_t fini; - wrappedlib_get_t get; + wrappedlib_get_t get; wrappedlib_get_t getnoweak; wrappedlib_get_t getlocal; } wrappedlib_t; diff --git a/src/librarian/dictionnary.c b/src/librarian/dictionnary.c new file mode 100755 index 0000000000..9d343e930d --- /dev/null +++ b/src/librarian/dictionnary.c @@ -0,0 +1,48 @@ +#include +#include + +#include "debug.h" +#include "dictionnary.h" +#include "custommem.h" +#include "khash.h" + +KHASH_SET_INIT_STR(dic); + +dic_t *NewDictionnary() +{ + dic_t *dic = kh_init(dic); + return dic; +} + +void FreeDictionnary(dic_t **d) +{ + if(!d || !*d) + return; + kh_dic_t* dic = (kh_dic_t*)*d; + const char* k; + kh_foreach_key(dic, k, free((void*)k)); + kh_destroy(dic, dic); + *d = NULL; +} + +const char* AddDictionnary(dic_t* d, const char* s) +{ + kh_dic_t* dic = (kh_dic_t*)d; + khint_t k = kh_get(dic, dic, s); + if(k!=kh_end(dic)) + return kh_key(dic, k); + char* n = strdup(s); + int ret; + k = kh_put(dic, dic, n, &ret); + return n; +} + +int ExistDictionnary(dic_t* d, const char* s) +{ + kh_dic_t* dic = (kh_dic_t*)d; + khint_t k = kh_get(dic, dic, s); + if(k!=kh_end(dic)) + return 1; + return 0; + +} \ No newline at end of file diff --git a/src/librarian/librarian.c b/src/librarian/librarian.c index 8b87fbc40d..7e24a78741 100755 --- a/src/librarian/librarian.c +++ b/src/librarian/librarian.c @@ -11,21 +11,21 @@ #include "x86emu.h" #include "box86context.h" #include "elfloader.h" +#include "symbols.h" #include "bridge.h" -KHASH_MAP_IMPL_STR(mapsymbols, onesymbol_t); KHASH_MAP_IMPL_INT(mapoffsets, cstr_t); lib_t *NewLibrarian(box86context_t* context, int ownlibs) { lib_t *maplib = (lib_t*)calloc(1, sizeof(lib_t)); - maplib->mapsymbols = kh_init(mapsymbols); - maplib->weaksymbols = kh_init(mapsymbols); - maplib->localsymbols = kh_init(mapsymbols); + maplib->mapsymbols = NewMapSymbols(); + maplib->weaksymbols = NewMapSymbols(); + maplib->localsymbols = NewMapSymbols(); maplib->mapoffsets = kh_init(mapoffsets); - maplib->globaldata = kh_init(mapsymbols); + maplib->globaldata = NewMapSymbols(); maplib->bridge = NewBridge(); maplib->context = context; @@ -62,7 +62,9 @@ static void freeLibraryRecurse(lib_t *maplib, x86emu_t *emu, int idx, char *free } library_t *ptr = maplib->libraries[idx]; - Free1Library(&ptr, emu); + if(maplib->ownlibs && (!maplib->owner || ptr->maplib==maplib)) { + Free1Library(&ptr, emu); + } freed[idx] = 2; } void FreeLibrarian(lib_t **maplib, x86emu_t *emu) @@ -70,6 +72,8 @@ void FreeLibrarian(lib_t **maplib, x86emu_t *emu) // should that be in reverse order? if(!maplib || !*maplib) return; + + (*maplib)->owner = NULL; // too avoid recursive free... if((*maplib)->ownlibs && (*maplib)->libsz) { printf_log(LOG_DEBUG, "Closing %d libs from maplib %p\n", (*maplib)->libsz, *maplib); @@ -92,21 +96,13 @@ void FreeLibrarian(lib_t **maplib, x86emu_t *emu) free((*maplib)->libraries); (*maplib)->libraries = NULL; - if((*maplib)->mapsymbols) { - kh_destroy(mapsymbols, (*maplib)->mapsymbols); - } - if((*maplib)->weaksymbols) { - kh_destroy(mapsymbols, (*maplib)->weaksymbols); - } - if((*maplib)->localsymbols) { - kh_destroy(mapsymbols, (*maplib)->localsymbols); - } + FreeMapSymbols(&(*maplib)->mapsymbols); + FreeMapSymbols(&(*maplib)->weaksymbols); + FreeMapSymbols(&(*maplib)->localsymbols); if((*maplib)->mapoffsets) { kh_destroy(mapoffsets, (*maplib)->mapoffsets); } - if((*maplib)->globaldata) { - kh_destroy(mapsymbols, (*maplib)->globaldata); - } + FreeMapSymbols(&(*maplib)->globaldata); (*maplib)->libsz = (*maplib)->libcap = 0; if((*maplib)->bridge) @@ -173,24 +169,30 @@ void MapLibAddLib(lib_t* maplib, library_t* 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) continue; - if(lib->maplib && src!=lib->maplib) { //TODO: find why is src!=lib->maplib needed - MapLibAddMapLib(dest, lib->maplib); - 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(!libraryInMapLib(dest, lib)) MapLibAddLib(dest, lib); } + 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; @@ -204,8 +206,7 @@ void MapLibRemoveLib(lib_t* maplib, library_t* lib) maplib->libraries[maplib->libsz] = NULL; } -EXPORTDYN -int AddNeededLib(lib_t* maplib, needed_libs_t* neededlibs, library_t* deplib, int local, const char* path, box86context_t* box86, x86emu_t* emu) +int AddNeededLib_add(lib_t* maplib, needed_libs_t* neededlibs, library_t* deplib, int local, const char* path, box86context_t* box86, x86emu_t* emu) { printf_log(LOG_DEBUG, "Trying to add \"%s\" to maplib%s\n", path, local?" (local)":""); // first check if lib is already loaded @@ -224,7 +225,7 @@ int AddNeededLib(lib_t* maplib, needed_libs_t* neededlibs, library_t* deplib, in // 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); @@ -233,9 +234,7 @@ int AddNeededLib(lib_t* maplib, needed_libs_t* neededlibs, library_t* deplib, in // promote lib from local to global... // for add the depending local libs... if(lib->maplib) { - MapLibAddMapLib(my_context->maplib, lib->maplib); - free(lib->maplib); - lib->maplib = NULL; + MapLibAddMapLib(my_context->maplib, lib, lib->maplib); } if(!libraryInMapLib(my_context->maplib, lib)) MapLibAddLib(my_context->maplib, lib); @@ -258,44 +257,51 @@ int AddNeededLib(lib_t* maplib, needed_libs_t* neededlibs, library_t* deplib, in // add lib now if(local) { MapLibAddLib(my_context->local_maplib, lib); - if(maplib) + if(maplib) { MapLibAddLib(maplib, lib); - lib->maplib = NewLibrarian(box86, 0); - MapLibAddLib(lib->maplib, lib); + if(!lib->maplib) + lib->maplib = maplib; + } else { + lib->maplib = NewLibrarian(box86, 0); + MapLibAddLib(lib->maplib, lib); + } } else { MapLibAddLib(my_context->maplib, lib); } + 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; + } +} + +int AddNeededLib_init(lib_t* maplib, needed_libs_t* neededlibs, library_t* deplib, int local, library_t* lib, box86context_t* box86, x86emu_t* emu) +{ if(!maplib) maplib = (local)?lib->maplib:my_context->maplib; int mainelf = GetElfIndex(lib); if(mainelf==-1) { - // It's a native libs, just add wrapped symbols to global map - if(AddSymbolsLibrary(maplib, lib, emu)) { // also add needed libs - printf_log(LOG_DEBUG, "Failure to Add lib => fail\n"); - return 1; - } + // It's a native libs, nothing else to do } else { // it's an emulated lib, - // lets load dependancies before adding symbols and launch init sequence - if(LoadNeededLibs(box86->elfs[mainelf], maplib, &lib->needed, lib, 0, box86, emu)) { + // load dependancies and launch init sequence + if(LoadNeededLibs(box86->elfs[mainelf], maplib, &lib->needed, lib, local, box86, emu)) { printf_log(LOG_DEBUG, "Failure to Add dependant lib => fail\n"); return 1; } // some special case, where dependancies may not be correct if(!strcmp(GetNameLib(lib), "libCgGL.so")) { - AddNeededLib(maplib, &lib->needed, lib, 0, "libGL.so.1", box86, emu); + const char* libs[] = {"libGL.so.1"}; + AddNeededLib(maplib, &lib->needed, lib, 0, libs, 1, box86, emu); } if(!strcmp(GetNameLib(lib), "libmss.so.6")) { - AddNeededLib(maplib, &lib->needed, lib, 0, "libSDL-1.2.so.0", box86, emu); - AddNeededLib(maplib, &lib->needed, lib, 0, "libdl.so.2", box86, emu); - } - // add symbols - if(AddSymbolsLibrary(maplib, lib, emu)) { // also add needed libs - printf_log(LOG_DEBUG, "Failure to Add lib => fail\n"); - return 1; + const char* libs[] = {"libSDL-1.2.so.0", "libdl.so.2"}; + AddNeededLib(maplib, &lib->needed, lib, 0, libs, 2, box86, emu); } // finalize the lib @@ -310,6 +316,26 @@ int AddNeededLib(lib_t* maplib, needed_libs_t* neededlibs, library_t* deplib, in return 0; } +EXPORTDYN +int AddNeededLib(lib_t* maplib, needed_libs_t* neededlibs, library_t* deplib, int local, const char** paths, int npath, box86context_t* box86, x86emu_t* emu) +{ + if(!neededlibs) { + neededlibs = alloca(sizeof(needed_libs_t)); + memset(neededlibs, 0, sizeof(needed_libs_t)); + } + int idx = neededlibs->size; + // Add libs and symbol + for(int i=0; isize; ++i) + if(AddNeededLib_init(maplib, neededlibs, deplib, local, neededlibs->libs[i], box86, emu)) + if(!allow_missing_libs) return 1; + return 0; +} + library_t* GetLibMapLib(lib_t* maplib, const char* name) { printf_log(LOG_DEBUG, "Trying to Get \"%s\" to maplib\n", name); @@ -325,44 +351,53 @@ library_t* GetLibInternal(const char* name) } EXPORTDYN -uintptr_t FindGlobalSymbol(lib_t *maplib, const char* name) +uintptr_t FindGlobalSymbol(lib_t *maplib, const char* name, int version, const char* vername) { uintptr_t start = 0, end = 0; - if(GetGlobalSymbolStartEnd(maplib, name, &start, &end)) + if(GetGlobalSymbolStartEnd(maplib, name, &start, &end, (void*)1, version, vername)) return start; return 0; } -int GetNoSelfSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, elfheader_t* self) +static int isLocal(elfheader_t* self, library_t* l) +{ + if(GetElfIndex(l)==-1) + return 1; + if(my_context->elfs[GetElfIndex(l)]==self) + return 1; + return 0; +} + +int GetNoSelfSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, elfheader_t* self, int version, const char* vername) { //excude self if defined if(maplib->context->elfs[0]!=self) { - if(GetSymbolStartEnd(maplib->mapsymbols, name, start, end)) + if(GetSymbolStartEnd(maplib->mapsymbols, name, start, end, version, vername, 0)) if(*start) return 1; - if(GetSymbolStartEnd(maplib->weaksymbols, name, start, end)) + if(GetSymbolStartEnd(maplib->weaksymbols, name, start, end, version, vername, 0)) if(*start) return 1; } 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)) + if(GetLibSymbolStartEnd(maplib->libraries[i], name, start, end, version, vername, 0)) if(*start) return 1; } // if self defined, give it another chance with self... if(self) { if(maplib->context->elfs[0]==self) { - if(GetSymbolStartEnd(maplib->mapsymbols, name, start, end)) + if(GetSymbolStartEnd(maplib->mapsymbols, name, start, end, version, vername, 1)) if(*start) return 1; - if(GetSymbolStartEnd(maplib->weaksymbols, name, start, end)) + if(GetSymbolStartEnd(maplib->weaksymbols, name, start, end, version, vername, 1)) if(*start) return 1; } 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)) + if(GetLibSymbolStartEnd(maplib->libraries[i], name, start, end, version, vername, 1)) if(*start) return 1; } @@ -370,32 +405,32 @@ int GetNoSelfSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, u // nope, not found return 0; } -static int GetGlobalSymbolStartEnd_internal(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end) +static int GetGlobalSymbolStartEnd_internal(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, elfheader_t* self, int version, const char* vername) { // search non-weak symbol, from older to newer (first GLOBAL object wins) - if(GetSymbolStartEnd(maplib->mapsymbols, name, start, end)) + if(GetSymbolStartEnd(maplib->mapsymbols, name, start, end, version, vername, (maplib->context->elfs[0]==self || !self)?1:0)) 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)) + if(GetLibNoWeakSymbolStartEnd(my_context->neededlibs.libs[i], name, start, end, 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)) + if(GetLibNoWeakSymbolStartEnd(maplib->libraries[i], name, start, end, version, vername, isLocal(self, maplib->libraries[i]))) if(*start) return 1; } // library from newer to older, weak only now for(int i=maplib->libsz-1; i>=0; --i) { - if(GetLibSymbolStartEnd(maplib->libraries[i], name, start, end)) // only weak symbol haven't been found yet + if(GetLibSymbolStartEnd(maplib->libraries[i], name, start, end, version, vername, isLocal(self, maplib->libraries[i]))) // only weak symbol haven't been found yet if(*start) return 1; } - if(GetSymbolStartEnd(maplib->weaksymbols, name, start, end)) + if(GetSymbolStartEnd(maplib->weaksymbols, name, start, end, version, vername, (maplib->context->elfs[0]==self || !self)?1:0)) if(*start) return 1; // nope, not found @@ -403,15 +438,15 @@ static int GetGlobalSymbolStartEnd_internal(lib_t *maplib, const char* name, uin } void** my_GetGTKDisplay(); void** my_GetGthreadsGotInitialized(); -int GetGlobalSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end) +int GetGlobalSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, elfheader_t* self, int version, const char* vername) { - if(GetGlobalSymbolStartEnd_internal(maplib, name, start, end)) { + 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*)malloc(strlen(name) + strlen("_END") + 1); strcpy(buff, name); strcat(buff, "_END"); - if(GetGlobalSymbolStartEnd_internal(maplib, buff, &start2, &end2)) { + if(GetGlobalSymbolStartEnd_internal(maplib, buff, &start2, &end2, self, version, vername)) { if(end2>*end && start2==end2) *end = end2; } @@ -436,16 +471,16 @@ int GetGlobalSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, u return 0; } -elfheader_t* GetGlobalSymbolElf(lib_t *maplib, const char* name) +elfheader_t* GetGlobalSymbolElf(lib_t *maplib, const char* name, int version, const char* vername) { uintptr_t start = 0; uintptr_t end = 0; - if(GetSymbolStartEnd(maplib->mapsymbols, name, &start, &end)) + if(GetSymbolStartEnd(maplib->mapsymbols, name, &start, &end, version, vername, 1)) return maplib->context->elfs[0]; - if(GetSymbolStartEnd(maplib->weaksymbols, name, &start, &end)) + if(GetSymbolStartEnd(maplib->weaksymbols, name, &start, &end, version, vername, 1)) return maplib->context->elfs[0]; for(int i=0; ilibsz; ++i) { - if(GetLibSymbolStartEnd(maplib->libraries[i], name, &start, &end)) { + if(GetLibSymbolStartEnd(maplib->libraries[i], name, &start, &end, 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])); @@ -458,25 +493,25 @@ elfheader_t* GetGlobalSymbolElf(lib_t *maplib, const char* name) return NULL; } -int GetGlobalNoWeakSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end) +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)) + if(GetSymbolStartEnd(maplib->mapsymbols, name, start, end, version, vername, 1)) if(*start || *end) return 1; for(int i=0; ilibsz; ++i) - if(GetLibNoWeakSymbolStartEnd(maplib->libraries[i], name, start, end)) + if(GetLibNoWeakSymbolStartEnd(maplib->libraries[i], name, start, end, version, vername, 1)) if(*start || *end) return 1; // nope, not found return 0; } -int IsGlobalNoWeakSymbolInNative(lib_t *maplib, const char* name) +int IsGlobalNoWeakSymbolInNative(lib_t *maplib, const char* name, int version, const char* vername) { uintptr_t start, end; for(int i=0; ilibsz; ++i) if(GetElfIndex(maplib->libraries[i])==-1) - if(GetLibNoWeakSymbolStartEnd(maplib->libraries[i], name, &start, &end)) + if(GetLibNoWeakSymbolStartEnd(maplib->libraries[i], name, &start, &end, version, vername, 1)) if(start || end) return 1; // nope, not found @@ -484,10 +519,10 @@ int IsGlobalNoWeakSymbolInNative(lib_t *maplib, const char* name) } -int GetLocalSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, elfheader_t *self) +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)) + if(GetSymbolStartEnd(maplib->localsymbols, name, start, end, version, vername, 1)) if(*start || *end) return 1; if(self) @@ -495,7 +530,7 @@ int GetLocalSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, ui } 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)) + if(GetLibLocalSymbolStartEnd(maplib->libraries[i], name, start, end, version, vername, 1)) if(*start) return 1; if(self) @@ -505,16 +540,16 @@ int GetLocalSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, ui return 0; } -int GetSelfSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, elfheader_t *self) +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)) + 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)) + if(GetLibSymbolStartEnd(maplib->libraries[i], name, start, end, version, vername, 1)) if(*start || *end) return 1; } @@ -522,16 +557,16 @@ int GetSelfSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uin return 0; } -int GetNoWeakSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, elfheader_t *self) +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)) + 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)) + if(GetLibNoWeakSymbolStartEnd(maplib->libraries[i], name, start, end, version, vername, 1)) if(*start || *end) return 1; } @@ -540,54 +575,6 @@ int GetNoWeakSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, u } -void AddSymbol(kh_mapsymbols_t *mapsymbols, const char* name, uintptr_t addr, uint32_t sz) -{ - int ret; - khint_t k = kh_put(mapsymbols, mapsymbols, name, &ret); - kh_value(mapsymbols, k).offs = addr; - kh_value(mapsymbols, k).sz = sz; -} -uintptr_t FindSymbol(kh_mapsymbols_t *mapsymbols, const char* name) -{ - khint_t k = kh_get(mapsymbols, mapsymbols, name); - if(k==kh_end(mapsymbols)) - return 0; - return kh_val(mapsymbols, k).offs; -} -void AddWeakSymbol(kh_mapsymbols_t *mapsymbols, const char* name, uintptr_t addr, uint32_t sz) -{ - int ret; - khint_t k = kh_put(mapsymbols, mapsymbols, name, &ret); - if(ret==0) - return; // Symbol already there, don't touch it - kh_value(mapsymbols, k).offs = addr; - kh_value(mapsymbols, k).sz = sz; -} - -int GetSymbolStartEnd(kh_mapsymbols_t* mapsymbols, const char* name, uintptr_t* start, uintptr_t* end) -{ - khint_t k = kh_get(mapsymbols, mapsymbols, name); - if(k==kh_end(mapsymbols)) - return 0; - *start = kh_val(mapsymbols, k).offs; - *end = *start + kh_val(mapsymbols, k).sz; - return 1; -} - -const char* GetSymbolName(kh_mapsymbols_t* mapsymbols, void* p, uintptr_t* start, uint32_t* sz) -{ - uintptr_t addr = (uintptr_t)p; - onesymbol_t *one; - kh_foreach_value_ref(mapsymbols, one, - if((one->offs >= addr) && (one->offs+one->szoffs; - *sz = one->sz; - return kh_key(mapsymbols, __i); - } - ); - return NULL; -} - const char* FindSymbolName(lib_t *maplib, void* p, void** start, uint32_t* sz, const char** libname, void** base) { // first, search in self... diff --git a/src/librarian/librarian_private.h b/src/librarian/librarian_private.h index 093a69e85d..41d499cd2a 100755 --- a/src/librarian/librarian_private.h +++ b/src/librarian/librarian_private.h @@ -6,18 +6,10 @@ #include "khash.h" typedef struct box86context_s box86context_t; - -typedef struct onesymbol_s { - uintptr_t offs; - uint32_t sz; - // need to track type of symbol? - // need to track origin? -} onesymbol_t; +typedef struct kh_mapsymbols_s kh_mapsymbols_t; typedef char* cstr_t; -KHASH_MAP_DECLARE_STR(mapsymbols, onesymbol_t) - KHASH_MAP_DECLARE_INT(mapoffsets, cstr_t); typedef struct lib_s { @@ -30,6 +22,7 @@ typedef struct lib_s { int libsz; int libcap; int ownlibs; + library_t *owner; // in case that maplib is owned by a lib box86context_t* context; diff --git a/src/librarian/library.c b/src/librarian/library.c index e99f735fb6..4cf6979088 100755 --- a/src/librarian/library.c +++ b/src/librarian/library.c @@ -22,13 +22,14 @@ #include "librarian_private.h" #include "pathcoll.h" #include "x86emu.h" +#include "symbols.h" #include "wrappedlibs.h" // create the native lib list #define GO(P, N) int wrapped##N##_init(library_t* lib, box86context_t *box86); \ void wrapped##N##_fini(library_t* lib);\ - int wrapped##N##_get(library_t* lib, const char* name, uintptr_t *offs, uint32_t *sz); \ - int wrapped##N##_getnoweak(library_t* lib, const char* name, uintptr_t *offs, uint32_t *sz); + int wrapped##N##_get(library_t* lib, const char* name, uintptr_t *offs, uint32_t *sz, int version, const char* vername, int local); \ + int wrapped##N##_getnoweak(library_t* lib, const char* name, uintptr_t *offs, uint32_t *sz, int version, const char* vername, int local); #include "library_list.h" #undef GO @@ -85,49 +86,49 @@ void EmuLib_Fini(library_t* lib) kh_destroy(mapsymbols, lib->priv.n.localsymbols); } -int EmuLib_Get(library_t* lib, const char* name, uintptr_t *offs, uint32_t *sz) +int EmuLib_Get(library_t* lib, const char* name, uintptr_t *offs, uint32_t *sz, int version, const char* vername, int local) { - khint_t k; // symbols... - k = kh_get(mapsymbols, lib->priv.n.mapsymbols, name); - if(k!=kh_end(lib->priv.n.mapsymbols)) { - *offs = kh_value(lib->priv.n.mapsymbols, k).offs; - *sz = kh_value(lib->priv.n.mapsymbols, k).sz; + uintptr_t start, end; + if(GetSymbolStartEnd(lib->priv.n.mapsymbols, name, &start, &end, version, vername, local)) + { + *offs = start; + *sz = end-start; return 1; } // weak symbols... - k = kh_get(mapsymbols, lib->priv.n.weaksymbols, name); - if(k!=kh_end(lib->priv.n.weaksymbols)) { - *offs = kh_value(lib->priv.n.weaksymbols, k).offs; - *sz = kh_value(lib->priv.n.weaksymbols, k).sz; + if(GetSymbolStartEnd(lib->priv.n.weaksymbols, name, &start, &end, version, vername, local)) + { + *offs = start; + *sz = end-start; return 1; } return 0; } -int EmuLib_GetNoWeak(library_t* lib, const char* name, uintptr_t *offs, uint32_t *sz) +int EmuLib_GetNoWeak(library_t* lib, const char* name, uintptr_t *offs, uint32_t *sz, int version, const char* vername, int local) { - khint_t k; - k = kh_get(mapsymbols, lib->priv.n.mapsymbols, name); - if(k!=kh_end(lib->priv.n.mapsymbols)) { - *offs = kh_value(lib->priv.n.mapsymbols, k).offs; - *sz = kh_value(lib->priv.n.mapsymbols, k).sz; + uintptr_t start, end; + if(GetSymbolStartEnd(lib->priv.n.mapsymbols, name, &start, &end, version, vername, local)) + { + *offs = start; + *sz = end-start; return 1; } return 0; } -int EmuLib_GetLocal(library_t* lib, const char* name, uintptr_t *offs, uint32_t *sz) +int EmuLib_GetLocal(library_t* lib, const char* name, uintptr_t *offs, uint32_t *sz, int version, const char* vername, int local) { - khint_t k; - k = kh_get(mapsymbols, lib->priv.n.localsymbols, name); - if(k!=kh_end(lib->priv.n.localsymbols)) { - *offs = kh_value(lib->priv.n.localsymbols, k).offs; - *sz = kh_value(lib->priv.n.localsymbols, k).sz; + uintptr_t start, end; + if(GetSymbolStartEnd(lib->priv.n.localsymbols, name, &start, &end, version, vername, local)) + { + *offs = start; + *sz = end-start; return 1; } return 0; } -int NativeLib_GetLocal(library_t* lib, const char* name, uintptr_t *offs, uint32_t *sz) +int NativeLib_GetLocal(library_t* lib, const char* name, uintptr_t *offs, uint32_t *sz, int version, const char* vername, int local) { return 0; } @@ -150,11 +151,9 @@ static void initNativeLib(library_t *lib, box86context_t* context) { lib->getlocal = NativeLib_GetLocal; lib->type = 0; // Call librarian to load all dependant elf - for(int i=0; ipriv.w.needed; ++i) { - if(AddNeededLib(context->maplib, &lib->needed, lib, 0, lib->priv.w.neededlibs[i], context, NULL)) { // probably all native, not emulated, so that's fine - printf_log(LOG_NONE, "Error: loading needed libs in elf %s\n", lib->priv.w.neededlibs[i]); - return; - } + if(AddNeededLib(context->maplib, &lib->needed, lib, 0, (const char**)lib->priv.w.neededlibs, lib->priv.w.needed, context, NULL)) { // probably all native, not emulated, so that's fine + printf_log(LOG_NONE, "Error: loading a needed libs in elf %s\n", lib->name); + return; } break; } @@ -304,12 +303,12 @@ int FinalizeLibrary(library_t* lib, lib_t* local_maplib, x86emu_t* emu) } RelocateElfPlt(my_context->maplib, local_maplib, elf_header); if(trace_func) { - if (GetGlobalSymbolStartEnd(my_context->maplib, trace_func, &trace_start, &trace_end)) { + if (GetGlobalSymbolStartEnd(my_context->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); free(trace_func); trace_func = NULL; - } else if(GetLibLocalSymbolStartEnd(lib, trace_func, &trace_start, &trace_end)) { + } else if(GetLibLocalSymbolStartEnd(lib, trace_func, &trace_start, &trace_end, -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); free(trace_func); @@ -380,7 +379,7 @@ void Free1Library(library_t **lib, x86emu_t* emu) RunElfFini(elf_header, emu); } - if((*lib)->maplib) + if((*lib)->maplib && ((*lib)->maplib->owner==(*lib))) FreeLibrarian(&(*lib)->maplib, emu); if((*lib)->type!=-1 && (*lib)->fini) { @@ -442,22 +441,22 @@ int IsSameLib(library_t* lib, const char* path) free(name); return ret; } -int GetLibSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start, uintptr_t* end) +int GetLibSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start, uintptr_t* end, 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, name); + 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; return 1; } // get a new symbol - if(lib->get(lib, name, start, end)) { + if(lib->get(lib, name, start, end, version, vername, local)) { *end += *start; // lib->get(...) gives size, not end - char* symbol = strdup(name); + char* symbol = strdup(VersionnedName(name, version, vername)); int ret; k = kh_put(bridgemap, lib->bridgemap, symbol, &ret); kh_value(lib->bridgemap, k).name = symbol; @@ -468,22 +467,22 @@ int GetLibSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start, uin // nope return 0; } -int GetLibNoWeakSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start, uintptr_t* end) +int GetLibNoWeakSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start, uintptr_t* end, 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)) { + if(lib->getnoweak(lib, name, start, end, version, vername, local)) { *end += *start; // lib->get(...) gives size, not end // check if already in the map - k = kh_get(bridgemap, lib->bridgemap, name); + 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; return 1; } - char* symbol = strdup(name); + char* symbol = strdup(VersionnedName(name, version, vername)); int ret; k = kh_put(bridgemap, lib->bridgemap, symbol, &ret); kh_value(lib->bridgemap, k).name = symbol; @@ -494,22 +493,22 @@ int GetLibNoWeakSymbolStartEnd(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 GetLibLocalSymbolStartEnd(library_t* lib, const char* name, uintptr_t* start, uintptr_t* end, 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, name); + 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; return 1; } // get a new symbol - if(lib->getlocal(lib, name, start, end)) { + if(lib->getlocal(lib, name, start, end, version, vername, local)) { *end += *start; // lib->get(...) gives size, not end - char* symbol = strdup(name); + char* symbol = strdup(VersionnedName(name, version, vername)); int ret; k = kh_put(bridgemap, lib->bridgemap, symbol, &ret); kh_value(lib->bridgemap, k).name = symbol; @@ -527,14 +526,10 @@ int GetElfIndex(library_t* lib) return lib->priv.n.elf_index; } -int getSymbolInMaps(library_t*lib, const char* name, int noweak, uintptr_t *addr, uint32_t *size) +static int getSymbolInDataMaps(library_t*lib, const char* name, int noweak, uintptr_t *addr, uint32_t *size) { - if(!lib->active) - return 0; - khint_t k; void* symbol; - // check in datamap - k = kh_get(datamap, lib->datamap, name); + khint_t k = kh_get(datamap, lib->datamap, name); if (k!=kh_end(lib->datamap)) { symbol = dlsym(lib->priv.w.lib, kh_key(lib->datamap, k)); if(symbol) { @@ -575,8 +570,14 @@ int getSymbolInMaps(library_t*lib, const char* name, int noweak, uintptr_t *addr return 1; } } + return 0; +} + +static int getSymbolInSymbolMaps(library_t*lib, const char* name, int noweak, uintptr_t *addr, uint32_t *size) +{ + void* symbol; // check in mysymbolmap - k = kh_get(symbolmap, lib->mysymbolmap, name); + khint_t k = kh_get(symbolmap, lib->mysymbolmap, name); if (k!=kh_end(lib->mysymbolmap)) { char buff[200]; if(lib->altmy) @@ -667,6 +668,25 @@ int getSymbolInMaps(library_t*lib, const char* name, int noweak, uintptr_t *addr *size = sizeof(void*); return 1; } + + return 0; +} + +int getSymbolInMaps(library_t*lib, const char* name, int noweak, uintptr_t *addr, uint32_t *size, int version, const char* vername, int local) +{ + if(!lib->active) + return 0; + khint_t k; + void* symbol; + // check in datamaps (but no version, it's not handled there) + if(getSymbolInDataMaps(lib, name, noweak, addr, size)) + return 1; + + if(getSymbolInSymbolMaps(lib, VersionnedName(name, version, vername), noweak, addr, size)) + return 1; + + if(getSymbolInSymbolMaps(lib, name, noweak, addr, size)) + return 1; return 0; } @@ -701,10 +721,24 @@ lib_t* GetMaplib(library_t* lib) return lib->maplib; } +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*)); @@ -725,6 +759,8 @@ 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*)); diff --git a/src/librarian/library_private.h b/src/librarian/library_private.h index 11d452978b..5b9e21ce7a 100755 --- a/src/librarian/library_private.h +++ b/src/librarian/library_private.h @@ -101,6 +101,6 @@ typedef struct map_onedata_s { int weak; } map_onedata_t; -int getSymbolInMaps(library_t*lib, const char* name, int noweak, uintptr_t *addr, uint32_t *size); // Add bridges to functions +int getSymbolInMaps(library_t*lib, const char* name, int noweak, uintptr_t *addr, uint32_t *size, int vezrsion, const char* vername, int local); // Add bridges to functions #endif //__LIBRARY_PRIVATE_H_ diff --git a/src/librarian/symbols.c b/src/librarian/symbols.c new file mode 100644 index 0000000000..aa3b4bc65e --- /dev/null +++ b/src/librarian/symbols.c @@ -0,0 +1,233 @@ +#include +#include + +#include + +#include "debug.h" +#include "x86emu.h" +#include "box86context.h" +#include "symbols.h" +#include "dictionnary.h" + +typedef struct onesymbol_s { + uintptr_t offs; + uint32_t sz; + // need to track type of symbol? + // need to track origin? +} onesymbol_t; + +typedef struct versymbol_s { + int version; // -1 = no-version, 0=local, 1=global, X=versionned + const char* vername; // NULL or version name if version=X + onesymbol_t sym; +} versymbol_t; + +typedef struct versymbols_s { + int sz; + int cap; + versymbol_t *syms; +} versymbols_t; + +KHASH_MAP_IMPL_STR(mapsymbols, versymbols_t); + +kh_mapsymbols_t* NewMapSymbols() +{ + kh_mapsymbols_t* map = kh_init(mapsymbols); + return map; +} + +void FreeMapSymbols(kh_mapsymbols_t** map) +{ + if(!map || !(*map)) + return; + versymbols_t *v; + kh_foreach_value_ref(*map, v, free(v->syms);); + + kh_destroy(mapsymbols, *map); + *map = NULL; +} + +// Exact same version (ver<2 or vername if ver>=2) +static int SameVersion(versymbol_t* s, int ver, const char* vername) +{ + if(ver<2) + return (s->version == ver)?1:0; + if(s->vername && !strcmp(s->vername, vername)) + return 1; + return 0; + +} + +static versymbol_t* FindVersionLocal(versymbols_t* s) +{ + if(!s || !s->sz) + return NULL; + for (int i=0; isz; ++i) + if(s->syms[i].version==0) + return &s->syms[i]; + return NULL; +} +static versymbol_t* FindNoVersion(versymbols_t* s) +{ + if(!s || !s->sz) + return NULL; + for (int i=0; isz; ++i) + if(s->syms[i].version==-1) + return &s->syms[i]; + return NULL; +} +static versymbol_t* FindVersionGlobal(versymbols_t* s) +{ + if(!s || !s->sz) + return NULL; + for (int i=0; isz; ++i) + if(s->syms[i].version==1) + return &s->syms[i]; + return NULL; +} +static versymbol_t* FindVersion(versymbols_t* s, const char* vername) +{ + if(!s || !s->sz) + return NULL; + for (int i=0; isz; ++i) + if(s->syms[i].vername && !strcmp(s->syms[i].vername, vername)) + return &s->syms[i]; + return NULL; +} +static versymbol_t* FindFirstVersion(versymbols_t* s) +{ + if(!s || !s->sz) + return NULL; + for (int i=0; isz; ++i) + if(s->syms[i].version>1) + 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) +{ + if(!s || !s->sz) + return NULL; + versymbol_t* ret; + if(ver==0) { + if(local) ret = FindVersionLocal(s); + if(!ret) ret = FindNoVersion(s); + if(!ret) ret = FindVersionGlobal(s); + return ret; + } + if(ver==-1) { + if(local) ret = FindVersionLocal(s); + if(!ret) ret = FindNoVersion(s); + if(!ret) ret = FindVersionGlobal(s); + if(!ret) ret = FindFirstVersion(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); + return ret; + } + ret = FindVersion(s, vername); + if(local && !ret) FindVersionLocal(s); + if(!ret) return FindVersionGlobal(s); + return ret; +} + +void AddSymbol(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); + versymbols_t * v = &kh_val(mapsymbols, k); + if(ret) {v->sz = v->cap = 0; v->syms = NULL;} + // now check if that version already exist, and update record and exit if yes + for(int i=0; isz; ++i) + if(SameVersion(&v->syms[i], ver, vername)) { + v->syms[i].sym.offs = addr; + v->syms[i].sym.sz = sz; + return; + } + // add a new record + if(v->sz == v->cap) { + v->cap+=4; + v->syms = (versymbol_t*)realloc(v->syms, v->cap*sizeof(versymbol_t)); + } + int idx = v->sz++; + v->syms[idx].version = ver; + v->syms[idx].vername = vername; + v->syms[idx].sym.offs = addr; + v->syms[idx].sym.sz = sz; +} + +uintptr_t FindSymbol(kh_mapsymbols_t *mapsymbols, const char* name, int ver, const char* vername, int local) +{ + 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, local); + 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) +{ + int ret; + khint_t k = kh_put(mapsymbols, mapsymbols, name, &ret); + versymbols_t * v = &kh_val(mapsymbols, k); + if(ret) {v->sz = v->cap = 0; v->syms = NULL;} + // now check if that version already exist, and exit if yes + for(int i=0; isz; ++i) + if(SameVersion(&v->syms[i], ver, vername)) { + return; + } + // add a new record + if(v->sz == v->cap) { + v->cap+=4; + v->syms = (versymbol_t*)realloc(v->syms, v->cap*sizeof(versymbol_t)); + } + int idx = v->sz++; + v->syms[idx].version = ver; + v->syms[idx].vername = vername; + v->syms[idx].sym.offs = 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) +{ + 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, local); + if(s) { + *start = s->sym.offs; + *end = *start + s->sym.sz; + return 1; + } + return 0; +} + +const char* GetSymbolName(kh_mapsymbols_t* mapsymbols, void* p, uintptr_t* start, uint32_t* sz, const char** vername) +{ + uintptr_t addr = (uintptr_t)p; + versymbols_t *s; + kh_foreach_value_ref(mapsymbols, s, + for(int i=0; isz; ++i) + if((s->syms[i].sym.offs >= addr) && (s->syms[i].sym.offs+s->syms[i].sym.szsyms[i].sym.offs; + *sz = s->syms[i].sym.sz; + if(vername) + *vername = s->syms[i].vername; + return kh_key(mapsymbols, __i); + } + ); + return NULL; +} diff --git a/src/main.c b/src/main.c index 4816876caf..9c201ee84f 100755 --- a/src/main.c +++ b/src/main.c @@ -43,6 +43,7 @@ box86context_t *my_context = NULL; int box86_log = LOG_NONE; +int box86_dump = 0; int box86_nobanner = 0; int box86_dynarec_log = LOG_NONE; int box86_pagesize; @@ -205,8 +206,12 @@ void LoadLogEnv() p = getenv("BOX86_LOG"); if(p) { if(strlen(p)==1) { - if(p[0]>='0'+LOG_NONE && p[1]<='0'+LOG_DEBUG) + if(p[0]>='0'+LOG_NONE && p[1]<='0'+LOG_NEVER) box86_log = p[0]-'0'; + if(box86_log == LOG_NEVER) { + --box86_log; + box86_dump = 1; + } } else { if(!strcasecmp(p, "NONE")) box86_log = LOG_NONE; @@ -214,12 +219,23 @@ void LoadLogEnv() box86_log = LOG_INFO; else if(!strcasecmp(p, "DEBUG")) box86_log = LOG_DEBUG; - else if(!strcasecmp(p, "DUMP")) - box86_log = LOG_DUMP; + else if(!strcasecmp(p, "DUMP")) { + box86_log = LOG_DEBUG; + box86_dump = 1; + } } if(!box86_nobanner) printf_log(LOG_INFO, "Debug level is %d\n", box86_log); } + p = getenv("BOX86_DUMP"); + if(p) { + if(strlen(p)==1) { + if(p[0]>='0' && p[1]<='1') + box86_dump = p[0]-'0'; + } + } + if(!box86_nobanner && box86_dump) + printf_log(LOG_INFO, "Elf Dump if ON\n"); #ifdef DYNAREC p = getenv("BOX86_DYNAREC_DUMP"); if(p) { @@ -232,7 +248,7 @@ void LoadLogEnv() p = getenv("BOX86_DYNAREC_LOG"); if(p) { if(strlen(p)==1) { - if((p[0]>='0'+LOG_NONE) && (p[0]<='0'+LOG_DUMP)) + if((p[0]>='0'+LOG_NONE) && (p[0]<='0'+LOG_VERBOSE)) box86_dynarec_log = p[0]-'0'; } else { if(!strcasecmp(p, "NONE")) @@ -242,7 +258,7 @@ void LoadLogEnv() else if(!strcasecmp(p, "DEBUG")) box86_dynarec_log = LOG_DEBUG; else if(!strcasecmp(p, "VERBOSE")) - box86_dynarec_log = LOG_DUMP; + box86_dynarec_log = LOG_VERBOSE; } printf_log(LOG_INFO, "Dynarec log level is %d\n", box86_dynarec_log); } @@ -584,6 +600,11 @@ void LoadEnvVars(box86context_t *context) printf_log(LOG_INFO, "\n"); } } + // add libssl and libcrypto, prefer emulated version because of multiple version exist + AddPath("libssl.so.1", &context->box86_emulated_libs, 0); + AddPath("libssl.so.1.0.0", &context->box86_emulated_libs, 0); + AddPath("libcrypto.so.1", &context->box86_emulated_libs, 0); + AddPath("libcrypto.so.1.0.0", &context->box86_emulated_libs, 0); if(getenv("BOX86_NOSIGSEGV")) { if (strcmp(getenv("BOX86_NOSIGSEGV"), "1")==0) @@ -643,7 +664,7 @@ void setupTraceInit(box86context_t* context) if(trace_start || trace_end) SetTraceEmu(trace_start, trace_end); } else { - if (GetSymbolStartEnd(GetMapSymbol(my_context->maplib), p, &trace_start, &trace_end)) { + if (GetSymbolStartEnd(GetMapSymbol(my_context->maplib), p, &trace_start, &trace_end, -1, NULL, -1)) { SetTraceEmu(trace_start, trace_end); printf_log(LOG_INFO, "TRACE on %s only (%p-%p)\n", p, (void*)trace_start, (void*)trace_end); } else { @@ -684,10 +705,10 @@ void setupTrace(box86context_t* context) } } } else { - if (GetGlobalSymbolStartEnd(my_context->maplib, p, &trace_start, &trace_end)) { + if (GetGlobalSymbolStartEnd(my_context->maplib, p, &trace_start, &trace_end, NULL, -1, NULL)) { SetTraceEmu(trace_start, trace_end); printf_log(LOG_INFO, "TRACE on %s only (%p-%p)\n", p, (void*)trace_start, (void*)trace_end); - } else if(GetLocalSymbolStartEnd(my_context->maplib, p, &trace_start, &trace_end, NULL)) { + } else if(GetLocalSymbolStartEnd(my_context->maplib, p, &trace_start, &trace_end, NULL, -1, NULL)) { SetTraceEmu(trace_start, trace_end); printf_log(LOG_INFO, "TRACE on %s only (%p-%p)\n", p, (void*)trace_start, (void*)trace_end); } else { @@ -889,9 +910,9 @@ int main(int argc, const char **argv, const char **env) { // allocate extra space for new environment variables such as BOX86_PATH my_context->envv = (char**)calloc(my_context->envc+4, sizeof(char*)); GatherEnv(&my_context->envv, environ?environ:env, my_context->box86path); - if(box86_log>=LOG_DUMP) { + if(box86_dump) { for (int i=0; ienvc; ++i) - printf_log(LOG_DUMP, " Env[%02d]: %s\n", i, my_context->envv[i]); + printf_dump(LOG_NEVER, " Env[%02d]: %s\n", i, my_context->envv[i]); } path_collection_t ld_preload = {0}; @@ -1130,9 +1151,9 @@ int main(int argc, const char **argv, const char **env) { // export symbols AddSymbols(my_context->maplib, GetMapSymbol(my_context->maplib), GetWeakSymbol(my_context->maplib), GetLocalSymbol(my_context->maplib), elf_header); if(wine_preloaded) { - uintptr_t wineinfo = FindSymbol(GetMapSymbol(my_context->maplib), "wine_main_preload_info"); - if(!wineinfo) wineinfo = FindSymbol(GetWeakSymbol(my_context->maplib), "wine_main_preload_info"); - if(!wineinfo) wineinfo = FindSymbol(GetLocalSymbol(my_context->maplib), "wine_main_preload_info"); + 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); if(!wineinfo) {printf_log(LOG_NONE, "Warning, Symbol wine_main_preload_info not found\n");} else { *(void**)wineinfo = get_wine_prereserve(); @@ -1144,11 +1165,9 @@ int main(int argc, const char **argv, const char **env) { } // pre-load lib if needed if(ld_preload.size) { - for (int i=0; imaplib, "gdk_display", &globoffs, &globend)) { + if (GetGlobalNoWeakSymbolStartEnd(my_context->maplib, "gdk_display", &globoffs, &globend, -1, NULL)) { printf_log(LOG_DEBUG, "Global gdk_display workaround, @%p <= %p\n", (void*)globoffs, gdk_display); memcpy((void*)globoffs, &gdk_display, sizeof(gdk_display)); } @@ -1054,7 +1054,7 @@ void my_setGlobalGThreadsInit() // workaround, because gdk_display maybe declared as global in the calling program, but there is no way to send this info to the linker int val = 1; uintptr_t globoffs, globend; - if (GetGlobalNoWeakSymbolStartEnd(my_context->maplib, "g_threads_got_initialized", &globoffs, &globend)) { + if (GetGlobalNoWeakSymbolStartEnd(my_context->maplib, "g_threads_got_initialized", &globoffs, &globend, -1, NULL)) { printf_log(LOG_DEBUG, "Global g_threads_got_initialized workaround, @%p <= %p\n", (void*)globoffs, (void*)val); memcpy((void*)globoffs, &val, sizeof(gdk_display)); } diff --git a/src/wrapped/wrappedgtkx112.c b/src/wrapped/wrappedgtkx112.c index 02c6d35c92..830a71249c 100755 --- a/src/wrapped/wrappedgtkx112.c +++ b/src/wrapped/wrappedgtkx112.c @@ -970,7 +970,7 @@ static void my_gtk_builder_connect_signals_custom(void* builder, uintptr_t offs = 0; uintptr_t end = 0; - GetGlobalSymbolStartEnd(my_context->maplib, handler_name, &offs, &end); + GetGlobalSymbolStartEnd(my_context->maplib, handler_name, &offs, &end, NULL, -1, NULL); if(!offs) { if (args->module == NULL) args->my->g_log("Gtk", 1<<2 ,"gtk_builder_connect_signals() requires working GModule"); diff --git a/src/wrapped/wrappedlib_init.h b/src/wrapped/wrappedlib_init.h index f3d1fb2aab..cdfd35c368 100755 --- a/src/wrapped/wrappedlib_init.h +++ b/src/wrapped/wrappedlib_init.h @@ -128,21 +128,29 @@ int FUNC(_init)(library_t* lib, box86context_t* box86) for (int i=0; isymbolmap, MAPNAME(symbolmap)[i].name, &ret); kh_value(lib->symbolmap, k) = MAPNAME(symbolmap)[i].w; + if(strchr(MAPNAME(symbolmap)[i].name, '@')) + AddDictionnary(box86->versym, MAPNAME(symbolmap)[i].name); } cnt = sizeof(MAPNAME(wsymbolmap))/sizeof(map_onesymbol_t); for (int i=0; iwsymbolmap, MAPNAME(wsymbolmap)[i].name, &ret); kh_value(lib->wsymbolmap, k) = MAPNAME(wsymbolmap)[i].w; + if(strchr(MAPNAME(wsymbolmap)[i].name, '@')) + AddDictionnary(box86->versym, MAPNAME(wsymbolmap)[i].name); } cnt = sizeof(MAPNAME(mysymbolmap))/sizeof(map_onesymbol_t); for (int i=0; imysymbolmap, MAPNAME(mysymbolmap)[i].name, &ret); kh_value(lib->mysymbolmap, k) = MAPNAME(mysymbolmap)[i].w; + if(strchr(MAPNAME(mysymbolmap)[i].name, '@')) + AddDictionnary(box86->versym, MAPNAME(mysymbolmap)[i].name); } cnt = sizeof(MAPNAME(stsymbolmap))/sizeof(map_onesymbol_t); for (int i=0; istsymbolmap, MAPNAME(stsymbolmap)[i].name, &ret); kh_value(lib->stsymbolmap, k) = MAPNAME(stsymbolmap)[i].w; + if(strchr(MAPNAME(stsymbolmap)[i].name, '@')) + AddDictionnary(box86->versym, MAPNAME(stsymbolmap)[i].name); } cnt = sizeof(MAPNAME(symbol2map))/sizeof(map_onesymbol2_t); for (int i=0; isymbol2map, k).name = MAPNAME(symbol2map)[i].name2; kh_value(lib->symbol2map, k).w = MAPNAME(symbol2map)[i].w; kh_value(lib->symbol2map, k).weak = MAPNAME(symbol2map)[i].weak; + if(strchr(MAPNAME(symbol2map)[i].name, '@')) + AddDictionnary(box86->versym, MAPNAME(symbol2map)[i].name); } cnt = sizeof(MAPNAME(datamap))/sizeof(map_onedata_t); for (int i=0; ibox86path); + char* p = strrchr(box64path, '/'); + if(p) { + p[1] = '\0'; + strcat(box64path, "box64"); + if(FileExist(box64path, IS_EXECUTABLE|IS_FILE)) + box64_available = 1; + } + box64_tested = 1; + free(box64path); + }*/ // sizeof(struct utsname)==390 on i686, and also on ARM, so this seem safe int ret = uname(buf); - strcpy(buf->machine, /*(box86_steam)?"x86_64":*/"i686"); + strcpy(buf->machine, (box64_available)?"x86_64":"i686"); return ret; } @@ -580,6 +594,7 @@ int EXPORT my_uname(struct utsname *buf) #define X86_O_NOFOLLOW 0400000 #define X86_O_NOATIME 01000000 #define X86_O_CLOEXEC 02000000 +#define X86_O_PATH 010000000 #define X86_O_TMPFILE 020200000 #ifndef O_TMPFILE @@ -606,6 +621,7 @@ int EXPORT my_uname(struct utsname *buf) GO(O_NOFOLLOW) \ GO(O_NOATIME) \ GO(O_CLOEXEC) \ + GO(O_PATH) \ // x86->arm int of_convert(int a) diff --git a/src/wrapped/wrappedlibdl.c b/src/wrapped/wrappedlibdl.c index feeba7532c..daa975a018 100755 --- a/src/wrapped/wrappedlibdl.c +++ b/src/wrapped/wrappedlibdl.c @@ -42,7 +42,7 @@ char* my_dlerror(x86emu_t* emu) EXPORT; void* my_dlsym(x86emu_t* emu, void *handle, void *symbol) EXPORT; int my_dlclose(x86emu_t* emu, void *handle) EXPORT; int my_dladdr(x86emu_t* emu, void *addr, void *info) EXPORT; -void* my_dlvsym(x86emu_t* emu, void *handle, void *symbol, void *version) EXPORT; +void* my_dlvsym(x86emu_t* emu, void *handle, void *symbol, const char* vername) EXPORT; int my_dlinfo(x86emu_t* emu, void* handle, int request, void* info) EXPORT; #define LIBNAME libdl @@ -69,7 +69,7 @@ void* my_dlopen(x86emu_t* emu, void *filename, int flag) library_t *lib = NULL; dlprivate_t *dl = emu->context->dlprivate; int dlopened = 0; - int is_local = (flag&0x100)?0:1; // if not global, then local, and that means symbols are not put in the global "pot" for pther libs + int is_local = (flag&0x100)?0:1; // if not global, then local, and that means symbols are not put in the global "pot" for other libs CLEARERR if(filename) { char* rfilename = (char*)filename; @@ -103,7 +103,8 @@ void* my_dlopen(x86emu_t* emu, void *filename, int flag) } dlopened = (GetLibInternal(rfilename)==NULL); // Then open the lib - if(AddNeededLib(NULL, NULL, NULL, is_local, rfilename, emu->context, emu)) { + const char* libs[] = {rfilename}; + if(AddNeededLib(NULL, NULL, NULL, is_local, libs, 1, emu->context, emu)) { printf_log(LOG_INFO, "Warning: Cannot dlopen(\"%s\"/%p, %X)\n", rfilename, filename, flag); if(!dl->last_error) dl->last_error = malloc(129); @@ -158,7 +159,7 @@ char* my_dlerror(x86emu_t* emu) KHASH_SET_INIT_INT(libs); -int recursive_dlsym_lib(kh_libs_t* collection, library_t* lib, const char* rsymbol, uintptr_t *start, uintptr_t *end) +int recursive_dlsym_lib(kh_libs_t* collection, library_t* lib, const char* rsymbol, uintptr_t *start, uintptr_t *end, int version, const char* vername) { if(!lib) return 0; @@ -168,23 +169,24 @@ int recursive_dlsym_lib(kh_libs_t* collection, library_t* lib, const char* rsymb int ret; kh_put(libs, collection, (uintptr_t)lib, &ret); // look in the library itself - if(lib->get(lib, rsymbol, start, end)) - return 1; + for(int step=0; step<=MAX_STEP; ++step) + if(lib->get(lib, rsymbol, start, end, version, vername, step)) + return 1; // look in other libs int n = GetNeededLibN(lib); for (int i=0; icontext->maplib, rsymbol, &start, &end)) { + if(GetGlobalSymbolStartEnd(emu->context->maplib, rsymbol, &start, &end, NULL, -1, NULL)) { if(dlsym_error && box86_logcontext, *(uint32_t*)R_ESP); // use return address to guess "self" - if(GetNoSelfSymbolStartEnd(emu->context->maplib, rsymbol, &start, &end, elf)) { + if(GetNoSelfSymbolStartEnd(emu->context->maplib, rsymbol, &start, &end, elf, -1, NULL)) { if(dlsym_error && box86_loglibs[nlib]) { - if(my_dlsym_lib(dl->libs[nlib], rsymbol, &start, &end)==0) { + if(my_dlsym_lib(dl->libs[nlib], rsymbol, &start, &end, -1, NULL)==0) { // not found if(dlsym_error && box86_loglibs[nlib]), rsymbol); @@ -265,20 +267,19 @@ void* my_dlsym(x86emu_t* emu, void *handle, void *symbol) return NULL; } } else { - // still usefull? - if(GetSymbolStartEnd(GetLocalSymbol(emu->context->maplib), rsymbol, &start, &end)) { + if(GetSymbolStartEnd(GetLocalSymbol(emu->context->maplib), rsymbol, &start, &end, -1, NULL, 0)) { if(dlsym_error && box86_logcontext->maplib), rsymbol, &start, &end)) { + if(GetSymbolStartEnd(GetWeakSymbol(emu->context->maplib), rsymbol, &start, &end, -1, NULL, 0)) { if(dlsym_error && box86_logcontext->maplib), rsymbol, &start, &end)) { + if(GetSymbolStartEnd(GetMapSymbol(emu->context->maplib), rsymbol, &start, &end, -1, NULL, 0)) { if(dlsym_error && box86_logdli_saddr, info->dli_sname?info->dli_sname:"", info->dli_fname?info->dli_fname:""); return (info->dli_sname)?1:0; // success is non-null here... } -void* my_dlvsym(x86emu_t* emu, void *handle, void *symbol, void *version) +void* my_dlvsym(x86emu_t* emu, void *handle, void *symbol, const char* vername) { dlprivate_t *dl = emu->context->dlprivate; - CLEARERR - //void *dlvsym(void *handle, char *symbol, char *version); + int version = (vername)?2:-1; + uintptr_t start, end; char* rsymbol = (char*)symbol; - char* rversion = (char*)version; - printf_log(LOG_INFO, "Warning: unimplement call to dlvsym(%p, %s, %s), fallback to dlsym\n", handle, rsymbol, rversion); - - return my_dlsym(emu, handle, symbol); + CLEARERR + if(dlsym_error && box86_logcontext->maplib, rsymbol, &start, &end, NULL, version, vername)) { + if(dlsym_error && box86_loglast_error) + dl->last_error = malloc(129); + snprintf(dl->last_error, 129, "Symbol \"%s\" version %s not found in %p)\n", rsymbol, vername?vername:"(nil)", handle); + if(dlsym_error && box86_logcontext, *(uint32_t*)R_ESP); // use return address to guess "self" + if(GetNoSelfSymbolStartEnd(emu->context->maplib, rsymbol, &start, &end, elf, version, vername)) { + if(dlsym_error && box86_loglast_error) + dl->last_error = malloc(129); + snprintf(dl->last_error, 129, "Symbol \"%s\" version %s not found in %p)\n", rsymbol, vername?vername:"(nil)", handle); + if(dlsym_error && box86_log=dl->lib_sz) { + if(!dl->last_error) + dl->last_error = malloc(129); + snprintf(dl->last_error, 129, "Bad handle %p)\n", handle); + if(dlsym_error && box86_logcount[nlib]==0) { + if(!dl->last_error) + dl->last_error = malloc(129); + snprintf(dl->last_error, 129, "Bad handle %p (already closed))\n", handle); + if(dlsym_error && box86_loglibs[nlib]) { + if(my_dlsym_lib(dl->libs[nlib], rsymbol, &start, &end, version, vername)==0) { + // not found + if(dlsym_error && box86_loglibs[nlib]), rsymbol, vername?vername:"(nil)"); + } + printf_log(LOG_DEBUG, " Symbol not found\n"); + if(!dl->last_error) + dl->last_error = malloc(129); + snprintf(dl->last_error, 129, "Symbol \"%s\" not found in %p(%s)", rsymbol, handle, GetNameLib(dl->libs[nlib])); + return NULL; + } + } else { + // still usefull? + for(int step=0; step<=MAX_STEP; ++step) { + if(GetSymbolStartEnd(GetLocalSymbol(emu->context->maplib), rsymbol, &start, &end, version, vername, step)) { + if(dlsym_error && box86_logcontext->maplib), rsymbol, &start, &end, version, vername, step)) { + if(dlsym_error && box86_logcontext->maplib), rsymbol, &start, &end, version, vername, step)) { + if(dlsym_error && box86_loglast_error) + dl->last_error = malloc(129); + snprintf(dl->last_error, 129, "Symbol \"%s\" version %s not found in %p)\n", rsymbol, vername?vername:"(nil)", handle); + return NULL; + } + if(dlsym_error && box86_log