Fixed some issue with TLS data not beeing updated correctly after ElfInit (fixes Steam version of Ion Fury)

This commit is contained in:
ptitSeb 2022-06-06 17:02:41 +02:00
parent de21088bc4
commit 1057b88ba7
3 changed files with 25 additions and 16 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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...