diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2022-11-01 10:37:44 +0100 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2022-11-01 10:37:44 +0100 |
| commit | 24cc0c8422f4917fc8d0d03044d930ee91163674 (patch) | |
| tree | aa36455ad4889d1d1a72cc7fd27e256d7e375c64 /src | |
| parent | 8459ea0d31a851e847318273233c9a8b2b079eae (diff) | |
| download | box64-24cc0c8422f4917fc8d0d03044d930ee91163674.tar.gz box64-24cc0c8422f4917fc8d0d03044d930ee91163674.zip | |
Detect when program is linked with glibc 2.34+ to workaround the default libc libs to load
Diffstat (limited to 'src')
| -rwxr-xr-x | src/elfs/elfparser.c | 28 | ||||
| -rwxr-xr-x | src/include/debug.h | 1 | ||||
| -rwxr-xr-x | src/include/elfloader.h | 1 | ||||
| -rwxr-xr-x | src/main.c | 4 | ||||
| -rwxr-xr-x | src/wrapped/wrappedlibc.c | 16 | ||||
| -rwxr-xr-x | src/wrapped/wrappedlibdl.c | 2 |
6 files changed, 47 insertions, 5 deletions
diff --git a/src/elfs/elfparser.c b/src/elfs/elfparser.c index 9607efd9..1fd3ca01 100755 --- a/src/elfs/elfparser.c +++ b/src/elfs/elfparser.c @@ -407,3 +407,31 @@ const char* GetParentSymbolVersion(elfheader_t* h, int index) } return NULL; } + +int GetVersionIndice(elfheader_t* h, const char* vername) +{ + if(!vername) + return 0; + if(h->VerNeed) { + Elf64_Verneed *ver = (Elf64_Verneed*)((uintptr_t)h->VerNeed + h->delta); + while(ver) { + Elf64_Vernaux *aux = (Elf64_Vernaux*)((uintptr_t)ver + ver->vn_aux); + for(int j=0; j<ver->vn_cnt; ++j) { + if(!strcmp(h->DynStr+aux->vna_name, vername)) + return aux->vna_other; + aux = (Elf64_Vernaux*)((uintptr_t)aux + aux->vna_next); + } + ver = ver->vn_next?((Elf64_Verneed*)((uintptr_t)ver + ver->vn_next)):NULL; + } + } + if(h->VerDef) { + Elf64_Verdef *def = (Elf64_Verdef*)((uintptr_t)h->VerDef + h->delta); + while(def) { + Elf64_Verdaux *aux = (Elf64_Verdaux*)((uintptr_t)def + def->vd_aux); + if(!strcmp(h->DynStr+aux->vda_name, vername)) + return def->vd_ndx; + def = def->vd_next?((Elf64_Verdef*)((uintptr_t)def + def->vd_next)):NULL; + } + } + return 0; +} \ No newline at end of file diff --git a/src/include/debug.h b/src/include/debug.h index 7c14a6ee..43a3e2ad 100755 --- a/src/include/debug.h +++ b/src/include/debug.h @@ -48,6 +48,7 @@ extern int box64_nogtk; // disabling the use of wrapped gtk extern int box64_novulkan; // disabling the use of wrapped vulkan extern int box64_showsegv; // show sigv, even if a signal handler is present extern int box64_showbt; // show a backtrace if a signal is caught +extern int box64_isglibc234; // is the program linked with glibc 2.34+ extern uintptr_t fmod_smc_start, fmod_smc_end; // to handle libfmod (from Unreal) SMC (self modifying code) extern uint32_t default_gs; extern int jit_gdb; // launch gdb when a segfault is trapped diff --git a/src/include/elfloader.h b/src/include/elfloader.h index 579c98bd..891a62ac 100755 --- a/src/include/elfloader.h +++ b/src/include/elfloader.h @@ -62,6 +62,7 @@ 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); +int GetVersionIndice(elfheader_t* h, const char* vername); kh_mapsymbols_t* GetMapSymbols(elfheader_t* h); kh_mapsymbols_t* GetWeakSymbols(elfheader_t* h); diff --git a/src/main.c b/src/main.c index 5f081257..a8f3eb9f 100755 --- a/src/main.c +++ b/src/main.c @@ -91,6 +91,7 @@ int box64_nogtk = 0; int box64_novulkan = 0; int box64_showsegv = 0; int box64_showbt = 0; +int box64_isglibc234 = 0; char* libGL = NULL; uintptr_t fmod_smc_start = 0; uintptr_t fmod_smc_end = 0; @@ -1491,6 +1492,9 @@ int main(int argc, const char **argv, char **env) { setupTraceInit(); // export symbols AddSymbols(my_context->maplib, GetMapSymbols(elf_header), GetWeakSymbols(elf_header), GetLocalSymbols(elf_header), elf_header); + box64_isglibc234 = GetVersionIndice(elf_header, "GLIBC_2.34")?1:0; + if(box64_isglibc234) + printf_log(LOG_DEBUG, "Program linked with GLIBC 2.34+\n"); if(wine_preloaded) { uintptr_t wineinfo = FindSymbol(GetMapSymbols(elf_header), "wine_main_preload_info", -1, NULL, 1, NULL); if(!wineinfo) wineinfo = FindSymbol(GetWeakSymbols(elf_header), "wine_main_preload_info", -1, NULL, 1, NULL); diff --git a/src/wrapped/wrappedlibc.c b/src/wrapped/wrappedlibc.c index 690fa66f..8f8f3881 100755 --- a/src/wrapped/wrappedlibc.c +++ b/src/wrapped/wrappedlibc.c @@ -2964,10 +2964,18 @@ EXPORT char my___libc_single_threaded = 0; my___progname = my_program_invocation_short_name = \ strrchr(box64->argv[0], '/') + 1; \ getMy(lib); \ - setNeededLibs(lib, 3, \ - "ld-linux-x86-64.so.2", \ - "libpthread.so.0", \ - "librt.so.1"); + if(box64_isglibc234) \ + setNeededLibs(lib, 5, \ + "ld-linux-x86-64.so.2", \ + "libpthread.so.0", \ + "libdl.so.2", \ + "libutil.so.1", \ + "librt.so.1"); \ + else \ + setNeededLibs(lib, 3, \ + "ld-linux-x86-64.so.2", \ + "libpthread.so.0", \ + "librt.so.1"); #define CUSTOM_FINI \ freeMy(); diff --git a/src/wrapped/wrappedlibdl.c b/src/wrapped/wrappedlibdl.c index 3a6d505d..4cd70df4 100755 --- a/src/wrapped/wrappedlibdl.c +++ b/src/wrapped/wrappedlibdl.c @@ -474,7 +474,7 @@ int my_dlinfo(x64emu_t* emu, void* handle, int request, void* info) } #define CUSTOM_INIT\ - setNeededLibs(lib, 1, "libc.so.6"); + if(!box64_isglibc234) setNeededLibs(lib, 1, "libc.so.6"); // define all standard library functions |