about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2022-06-06 17:02:41 +0200
committerptitSeb <sebastien.chev@gmail.com>2022-06-06 17:02:41 +0200
commit1057b88ba72c8c0cd241a7f4de3308a91fe321f9 (patch)
tree6d288c51e5455a3a74daca075386518345f433fd /src
parentde21088bc4d7bcfc97a5cf12fbe22d02ec8c3641 (diff)
downloadbox64-1057b88ba72c8c0cd241a7f4de3308a91fe321f9.tar.gz
box64-1057b88ba72c8c0cd241a7f4de3308a91fe321f9.zip
Fixed some issue with TLS data not beeing updated correctly after ElfInit (fixes Steam version of Ion Fury)
Diffstat (limited to 'src')
-rwxr-xr-xsrc/elfs/elfloader.c34
-rwxr-xr-xsrc/include/elfloader.h1
-rwxr-xr-xsrc/main.c2
3 files changed, 23 insertions, 14 deletions
diff --git a/src/elfs/elfloader.c b/src/elfs/elfloader.c
index 3bbd2206..fc58a502 100755
--- a/src/elfs/elfloader.c
+++ b/src/elfs/elfloader.c
@@ -1146,6 +1146,23 @@ int ElfCheckIfUseTCMallocMinimal(elfheader_t* h)
     return 0;
 }
 
+void RefreshElfTLS(elfheader_t* h)
+{
+    if(h->tlsfilesize) {
+        char* dest = (char*)(my_context->tlsdata+my_context->tlssize+h->tlsbase);
+        printf_dump(LOG_DEBUG, "Refreshing main TLS block @%p from %p:0x%lx\n", dest, (void*)h->tlsaddr, h->tlsfilesize);
+        memcpy(dest, (void*)(h->tlsaddr+h->delta), h->tlsfilesize);
+        tlsdatasize_t* ptr;
+        if ((ptr = (tlsdatasize_t*)pthread_getspecific(my_context->tlskey)) != NULL)
+            if(ptr->tlssize==my_context->tlssize) {
+                // refresh in tlsdata too
+                dest = (char*)(ptr->tlsdata+ptr->tlssize+h->tlsbase);
+                printf_dump(LOG_DEBUG, "Refreshing active TLS block @%p from %p:0x%lx\n", dest, (void*)h->tlsaddr, h->tlssize-h->tlsfilesize);
+                memcpy(dest, (void*)(h->tlsaddr+h->delta), h->tlsfilesize);
+            }
+    }
+}
+
 void RunElfInit(elfheader_t* h, x64emu_t *emu)
 {
     if(!h || h->init_done)
@@ -1154,6 +1171,9 @@ void RunElfInit(elfheader_t* h, x64emu_t *emu)
     memset(emu->segs_serial, 0, sizeof(emu->segs_serial));
     uintptr_t p = h->initentry + h->delta;
     box64context_t* context = GetEmuContext(emu);
+    // Refresh no-file part of TLS in case default value changed
+    RefreshElfTLS(h);
+    // check if in deferedInit
     if(context->deferedInit) {
         if(context->deferedInitSz==context->deferedInitCap) {
             context->deferedInitCap += 4;
@@ -1162,20 +1182,6 @@ void RunElfInit(elfheader_t* h, x64emu_t *emu)
         context->deferedInitList[context->deferedInitSz++] = h;
         return;
     }
-    // Refresh no-file part of TLS in case default value changed
-    if(h->tlsfilesize) {
-        char* dest = (char*)(my_context->tlsdata+my_context->tlssize+h->tlsbase);
-        printf_dump(LOG_DEBUG, "Refreshing main TLS block @%p from %p:0x%lx\n", dest, (void*)h->tlsaddr, h->tlsfilesize);
-        memcpy(dest, (void*)(h->tlsaddr+h->delta), h->tlsfilesize);
-        tlsdatasize_t* ptr;
-        if ((ptr = (tlsdatasize_t*)pthread_getspecific(my_context->tlskey)) != NULL)
-            if(ptr->tlssize==my_context->tlssize) {
-                // refresh in tlsdata too
-                dest = (char*)(ptr->tlsdata+ptr->tlssize+h->tlsbase);
-                printf_dump(LOG_DEBUG, "Refreshing active TLS block @%p from %p:0x%lx\n", dest, (void*)h->tlsaddr, h->tlssize-h->tlsfilesize);
-                memcpy(dest, (void*)(h->tlsaddr+h->delta), h->tlsfilesize);
-            }
-    }
     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);
diff --git a/src/include/elfloader.h b/src/include/elfloader.h
index 2cb90df4..ca7a6621 100755
--- a/src/include/elfloader.h
+++ b/src/include/elfloader.h
@@ -34,6 +34,7 @@ void AddSymbols(lib_t *maplib, kh_mapsymbols_t* mapsymbols, kh_mapsymbols_t* wea
 int LoadNeededLibs(elfheader_t* h, lib_t *maplib, needed_libs_t* neededlibs, library_t *deplib, int local, int bindnow, box64context_t *box64, x64emu_t* emu);
 uintptr_t GetElfInit(elfheader_t* h);
 uintptr_t GetElfFini(elfheader_t* h);
+void RefreshElfTLS(elfheader_t* h);
 void RunElfInit(elfheader_t* h, x64emu_t *emu);
 void RunElfFini(elfheader_t* h, x64emu_t *emu);
 void RunDeferedElfInit(x64emu_t *emu);
diff --git a/src/main.c b/src/main.c
index 42b2e600..9a75ee07 100755
--- a/src/main.c
+++ b/src/main.c
@@ -1356,6 +1356,8 @@ int main(int argc, const char **argv, char **env) {
     RelocateElfPlt(my_context->maplib, NULL, 0, elf_header);
     // defered init
     RunDeferedElfInit(emu);
+    // update TLS of main elf
+    RefreshElfTLS(elf_header);
     // do some special case check, _IO_2_1_stderr_ and friends, that are setup by libc, but it's already done here, so need to do a copy
     ResetSpecialCaseMainElf(elf_header);
     // init...