about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2022-11-01 10:37:44 +0100
committerptitSeb <sebastien.chev@gmail.com>2022-11-01 10:37:44 +0100
commit24cc0c8422f4917fc8d0d03044d930ee91163674 (patch)
treeaa36455ad4889d1d1a72cc7fd27e256d7e375c64 /src
parent8459ea0d31a851e847318273233c9a8b2b079eae (diff)
downloadbox64-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-xsrc/elfs/elfparser.c28
-rwxr-xr-xsrc/include/debug.h1
-rwxr-xr-xsrc/include/elfloader.h1
-rwxr-xr-xsrc/main.c4
-rwxr-xr-xsrc/wrapped/wrappedlibc.c16
-rwxr-xr-xsrc/wrapped/wrappedlibdl.c2
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