about summary refs log tree commit diff stats
path: root/src/elfs/elfloader.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/elfs/elfloader.c')
-rw-r--r--src/elfs/elfloader.c56
1 files changed, 44 insertions, 12 deletions
diff --git a/src/elfs/elfloader.c b/src/elfs/elfloader.c
index 37de9dc2..5a0890cf 100644
--- a/src/elfs/elfloader.c
+++ b/src/elfs/elfloader.c
@@ -37,6 +37,7 @@
 #include "dynablock.h"
 #endif
 #include "../emu/x64emu_private.h"
+#include "../emu/x64run_private.h"
 #include "x64tls.h"
 
 void* my__IO_2_1_stderr_ = NULL;
@@ -258,7 +259,7 @@ int AllocElfMemory(box64context_t* context, elfheader_t* head, int mainbin)
     } else {
         // vaddr is 0, load everything has a One block
         uintptr_t old_offs = offs;
-        if(!offs && box64_wine)
+        if(!offs /*&& box64_wine*/)
             offs = (uintptr_t)find47bitBlock(head->memsz); // limit to 47bits...
         printf_log(log_level, "Allocating 0x%zx memory @%p for Elf \"%s\"\n", head->memsz, (void*)offs, head->name);
         void* p = mmap((void*)offs, head->memsz
@@ -373,6 +374,23 @@ int LoadElfMemory(FILE* f, box64context_t* context, elfheader_t* head)
     return 0;
 }
 
+int isElfHasNeededVer(elfheader_t* head, const char* libname, elfheader_t* verneeded)
+{
+    if(!verneeded || !head)
+        return 1;
+    if(!head->VerDef || !verneeded->VerNeed)
+        return 1;
+    int cnt = GetNeededVersionCnt(verneeded, libname);
+    for (int i=0; i<cnt; ++i) {
+        const char* vername = GetNeededVersionString(verneeded, libname, i);
+        if(vername && !GetVersionIndice(head, vername)) {
+            printf_log(/*LOG_DEBUG*/LOG_INFO, "Discarding %s for missing version %s\n", head->path, vername);
+            return 0;   // missing version
+        }
+    }
+    return 1;
+}
+
 int ReloadElfMemory(FILE* f, box64context_t* context, elfheader_t* head)
 {
     (void)context;
@@ -502,7 +520,8 @@ int RelocateElfREL(lib_t *maplib, lib_t *local_maplib, int bindnow, elfheader_t*
                     if(sym->st_size && offs) {
                         printf_dump(LOG_NEVER, "Apply %s R_X86_64_GLOB_DAT with R_X86_64_COPY @%p/%p (%p/%p -> %p/%p) size=%ld on sym=%s \n", (bind==STB_LOCAL)?"Local":"Global", p, globp, (void*)(p?(*p):0), (void*)(globp?(*globp):0), (void*)(offs + head->delta), (void*)globoffs, sym->st_size, symname);
                         memmove((void*)globoffs, (void*)offs, sym->st_size);   // preapply to copy part from lib to main elf
-                        AddUniqueSymbol(GetGlobalData(maplib), symname, offs + head->delta, sym->st_size, version, vername);
+                        AddUniqueSymbol(GetGlobalData(maplib), symname, globoffs, sym->st_size, version, vername);
+                        AddUniqueSymbol(my_context->globdata, symname, offs + head->delta, sym->st_size, version, vername);
                     } else {
                         printf_dump(LOG_NEVER, "Apply %s R_X86_64_GLOB_DAT with R_X86_64_COPY @%p/%p (%p/%p -> %p/%p) null sized on sym=%s \n", (bind==STB_LOCAL)?"Local":"Global", p, globp, (void*)(p?(*p):0), (void*)(globp?(*globp):0), (void*)offs, (void*)globoffs, symname);
                     }
@@ -527,7 +546,7 @@ int RelocateElfREL(lib_t *maplib, lib_t *local_maplib, int bindnow, elfheader_t*
                     uintptr_t old_offs = offs;
                     uintptr_t old_end = end;
                     offs = 0;
-                    GetSizedSymbolStartEnd(GetGlobalData(maplib), symname, &offs, &end, size, version, vername, 1, globdefver); // try globaldata symbols first
+                    GetSizedSymbolStartEnd(my_context->globdata, symname, &offs, &end, size, version, vername, 1, globdefver); // try globaldata symbols first
                     if(offs==0) {
                         GetNoSelfSymbolStartEnd(maplib, symname, &offs, &end, head, size, version, vername, globdefver, weakdefver);   // get original copy if any
                         if(!offs && local_maplib)
@@ -711,7 +730,7 @@ int RelocateElfRELA(lib_t *maplib, lib_t *local_maplib, int bindnow, elfheader_t
                 globoffs = offs;
                 globend = end;
                 offs = end = 0;
-                GetSizedSymbolStartEnd(GetGlobalData(maplib), symname, &offs, &end, size, version, vername, 1, globdefver); // try globaldata symbols first
+                GetSizedSymbolStartEnd(my_context->globdata, symname, &offs, &end, size, version, vername, 1, globdefver); // try globaldata symbols first
                 if(!offs && local_maplib)
                     GetNoSelfSymbolStartEnd(local_maplib, symname, &offs, &end, head, size, version, vername, globdefver, weakdefver);
                 if(!offs)
@@ -736,7 +755,8 @@ int RelocateElfRELA(lib_t *maplib, lib_t *local_maplib, int bindnow, elfheader_t
                             (bind==STB_LOCAL)?"Local":"Global", p, globp, (void*)(p?(*p):0), 
                             (void*)(globp?(*globp):0), (void*)offs, (void*)globoffs, sym->st_size, symname, version, vername?vername:"(none)");
                         //memmove((void*)globoffs, (void*)offs, sym->st_size);   // preapply to copy part from lib to main elf
-                        AddUniqueSymbol(GetGlobalData(maplib), symname, offs, sym->st_size, version, vername);
+                        AddUniqueSymbol(GetGlobalData(maplib), symname, globoffs, sym->st_size, version, vername);
+                        AddUniqueSymbol(my_context->globdata, symname, offs, sym->st_size, version, vername);
                     } else {
                         printf_dump(LOG_NEVER, "Apply %s R_X86_64_GLOB_DAT with R_X86_64_COPY @%p/%p (%p/%p -> %p/%p) null sized on sym=%s (ver=%d/%s)\n", 
                             (bind==STB_LOCAL)?"Local":"Global", p, globp, (void*)(p?(*p):0), 
@@ -890,7 +910,6 @@ int RelocateElfRELA(lib_t *maplib, lib_t *local_maplib, int bindnow, elfheader_t
     }
     return bindnow?ret_ok:0;
 }
-void checkHookedSymbols(lib_t *maplib, elfheader_t* h); // in mallochook.c
 int RelocateElf(lib_t *maplib, lib_t *local_maplib, int bindnow, elfheader_t* head)
 {
     if((head->flags&DF_BIND_NOW) && !bindnow) {
@@ -911,7 +930,6 @@ int RelocateElf(lib_t *maplib, lib_t *local_maplib, int bindnow, elfheader_t* he
         if(RelocateElfRELA(maplib, local_maplib, bindnow, head, cnt, (Elf64_Rela *)(head->rela + head->delta), NULL))
             return -1;
     }
-    checkHookedSymbols(maplib, head);
     return 0;
 }
 
@@ -1020,6 +1038,7 @@ uintptr_t GetLastByte(elfheader_t* h)
     return (uintptr_t)h->memory/* + h->delta*/ + h->memsz;
 }
 
+void checkHookedSymbols(elfheader_t* h); // in mallochook.c
 void AddSymbols(lib_t *maplib, kh_mapsymbols_t* mapsymbols, kh_mapsymbols_t* weaksymbols, kh_mapsymbols_t* localsymbols, elfheader_t* h)
 {
     if(box64_dump && h->DynSym) DumpDynSym(h);
@@ -1104,6 +1123,7 @@ void AddSymbols(lib_t *maplib, kh_mapsymbols_t* mapsymbols, kh_mapsymbols_t* wea
                 }
         }
     }
+    checkHookedSymbols(h);
 }
 
 /*
@@ -1184,9 +1204,13 @@ int LoadNeededLibs(elfheader_t* h, lib_t *maplib, int local, int bindnow, box64c
 
     DumpDynamicNeeded(h);
     int cnt = 0;
-    for (int i=0; i<h->numDynamic; ++i)
+    // count the number of needed libs, and also grab soname
+    for (int i=0; i<h->numDynamic; ++i) {
         if(h->Dynamic[i].d_tag==DT_NEEDED)
             ++cnt;
+        if(h->Dynamic[i].d_tag==DT_SONAME)
+            h->soname = h->DynStrTab+h->delta+h->Dynamic[i].d_un.d_val;
+    }
     h->needed = new_neededlib(cnt);
     if(h == my_context->elfs[0])
         my_context->neededlibs = h->needed;
@@ -1196,7 +1220,7 @@ int LoadNeededLibs(elfheader_t* h, lib_t *maplib, int local, int bindnow, box64c
             h->needed->names[j++] = h->DynStrTab+h->delta+h->Dynamic[i].d_un.d_val;
 
     // TODO: Add LD_LIBRARY_PATH and RPATH handling
-    if(AddNeededLib(maplib, local, bindnow, h->needed, box64, emu)) {
+    if(AddNeededLib(maplib, local, bindnow, h->needed, h, box64, emu)) {
         printf_log(LOG_INFO, "Error loading one of needed lib\n");
         if(!allow_missing_libs)
             return 1;   //error...
@@ -1241,6 +1265,7 @@ void MarkElfInitDone(elfheader_t* h)
     if(h)
         h->init_done = 1;
 }
+void startMallocHook();
 void RunElfInitPltResolver(elfheader_t* h, x64emu_t *emu)
 {
     if(!h || h->init_done)
@@ -1255,17 +1280,20 @@ void RunElfInitPltResolver(elfheader_t* h, x64emu_t *emu)
     }
     printf_dump(LOG_DEBUG, "Calling Init for %s @%p\n", ElfName(h), (void*)p);
     if(h->initentry)
-        RunSafeFunction(my_context, p, 3, my_context->argc, my_context->argv, my_context->envv);
+        RunSafeFunction(p, 3, my_context->argc, my_context->argv, my_context->envv);
     printf_dump(LOG_DEBUG, "Done Init for %s\n", ElfName(h));
     // and check init array now
     Elf64_Addr *addr = (Elf64_Addr*)(h->initarray + h->delta);
     for (size_t i=0; i<h->initarray_sz; ++i) {
         if(addr[i]) {
             printf_dump(LOG_DEBUG, "Calling Init[%zu] for %s @%p\n", i, ElfName(h), (void*)addr[i]);
-            RunSafeFunction(my_context, (uintptr_t)addr[i], 3, my_context->argc, my_context->argv, my_context->envv);
+            RunSafeFunction((uintptr_t)addr[i], 3, my_context->argc, my_context->argv, my_context->envv);
         }
     }
 
+    if(h->malloc_hook_2)
+        startMallocHook();
+
     h->fini_done = 0;   // can be fini'd now (in case it was re-inited)
     printf_dump(LOG_DEBUG, "All Init Done for %s\n", ElfName(h));
     return;
@@ -1310,6 +1338,9 @@ void RunElfInit(elfheader_t* h, x64emu_t *emu)
         }
     }
 
+    if(h->malloc_hook_2)
+        startMallocHook();
+
     h->fini_done = 0;   // can be fini'd now (in case it was re-inited)
     printf_dump(LOG_DEBUG, "All Init Done for %s\n", ElfName(h));
     return;
@@ -1582,7 +1613,7 @@ static int my_dl_iterate_phdr_##A(struct dl_phdr_info* a, size_t b, void* c)
         return 0;                                                                   \
     if(!a->dlpi_name[0]) /*don't send informations about box64 itself*/             \
         return 0;                                                                   \
-    return (int)RunFunction(my_context, my_dl_iterate_phdr_fct_##A, 3, a, b, c);    \
+    return (int)RunFunction(my_dl_iterate_phdr_fct_##A, 3, a, b, c);                \
 }
 SUPER()
 #undef GO
@@ -1855,6 +1886,7 @@ EXPORT void PltResolver(x64emu_t* emu)
             printf_dump(LOG_DEBUG, "symbol %s from %s but elf not initialized yet, run Init now (from %s)\n", symname, ElfName(sym_elf), ElfName(h));
             RunElfInitPltResolver(sym_elf, emu);
         }
+        offs = (uintptr_t)getAlternate((void*)offs);
 
         if(p) {
             printf_dump(LOG_DEBUG, "            Apply %s R_X86_64_JUMP_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(sym_elf));