From 1057b88ba72c8c0cd241a7f4de3308a91fe321f9 Mon Sep 17 00:00:00 2001 From: ptitSeb Date: Mon, 6 Jun 2022 17:02:41 +0200 Subject: [PATCH] Fixed some issue with TLS data not beeing updated correctly after ElfInit (fixes Steam version of Ion Fury) --- src/elfs/elfloader.c | 38 ++++++++++++++++++++++---------------- src/include/elfloader.h | 1 + src/main.c | 2 ++ 3 files changed, 25 insertions(+), 16 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,23 +1146,8 @@ int ElfCheckIfUseTCMallocMinimal(elfheader_t* h) return 0; } -void RunElfInit(elfheader_t* h, x64emu_t *emu) +void RefreshElfTLS(elfheader_t* h) { - if(!h || h->init_done) - return; - // reset Segs Cache - memset(emu->segs_serial, 0, sizeof(emu->segs_serial)); - uintptr_t p = h->initentry + h->delta; - box64context_t* context = GetEmuContext(emu); - if(context->deferedInit) { - if(context->deferedInitSz==context->deferedInitCap) { - context->deferedInitCap += 4; - context->deferedInitList = (elfheader_t**)realloc(context->deferedInitList, context->deferedInitCap*sizeof(elfheader_t*)); - } - 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); @@ -1176,6 +1161,27 @@ void RunElfInit(elfheader_t* h, x64emu_t *emu) memcpy(dest, (void*)(h->tlsaddr+h->delta), h->tlsfilesize); } } +} + +void RunElfInit(elfheader_t* h, x64emu_t *emu) +{ + if(!h || h->init_done) + return; + // reset Segs Cache + 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; + context->deferedInitList = (elfheader_t**)realloc(context->deferedInitList, context->deferedInitCap*sizeof(elfheader_t*)); + } + context->deferedInitList[context->deferedInitSz++] = h; + return; + } 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...