diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2025-10-15 20:52:16 +0200 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2025-10-15 20:52:16 +0200 |
| commit | d0045b158b30434c2077693d970e2167a1089e84 (patch) | |
| tree | b2951427e4870055cf79f6388d9755a227e843f7 /src | |
| parent | 1d4a9e8863d7e32f0bb1472674a94f05df1409b5 (diff) | |
| download | box64-d0045b158b30434c2077693d970e2167a1089e84.tar.gz box64-d0045b158b30434c2077693d970e2167a1089e84.zip | |
Some Segments/Selector handling refactoring , removing some pthread_getspecific use
Diffstat (limited to 'src')
| -rw-r--r-- | src/box64context.c | 44 | ||||
| -rw-r--r-- | src/core.c | 5 | ||||
| -rw-r--r-- | src/elfs/elfloader.c | 29 | ||||
| -rw-r--r-- | src/emu/x64emu.c | 22 | ||||
| -rw-r--r-- | src/emu/x64emu_private.h | 7 | ||||
| -rw-r--r-- | src/emu/x64run0f.c | 5 | ||||
| -rw-r--r-- | src/emu/x64tls.c | 71 | ||||
| -rw-r--r-- | src/include/box64context.h | 5 | ||||
| -rw-r--r-- | src/include/debug.h | 1 | ||||
| -rw-r--r-- | src/include/elfloader.h | 7 | ||||
| -rw-r--r-- | src/include/os.h | 4 | ||||
| -rw-r--r-- | src/include/x64tls.h | 2 | ||||
| -rw-r--r-- | src/libtools/threads.c | 3 | ||||
| -rwxr-xr-x | src/libtools/threads32.c | 2 | ||||
| -rw-r--r-- | src/os/os_linux.c | 25 | ||||
| -rw-r--r-- | src/os/os_wine.c | 4 | ||||
| -rw-r--r-- | src/wrapped/wrappedldlinux.c | 4 | ||||
| -rw-r--r-- | src/wrapped/wrappedldlinux_private.h | 2 | ||||
| -rwxr-xr-x | src/wrapped32/wrappedldlinux.c | 4 |
19 files changed, 133 insertions, 113 deletions
diff --git a/src/box64context.c b/src/box64context.c index 444a76a8..cbc92283 100644 --- a/src/box64context.c +++ b/src/box64context.c @@ -72,17 +72,6 @@ int getrand(int maxval) } -void free_tlsdatasize(void* p) -{ - if(!p) - return; - tlsdatasize_t *data = (tlsdatasize_t*)p; - actual_free(data->ptr); - actual_free(p); - if(my_context) - pthread_setspecific(my_context->tlskey, NULL); -} - void x64Syscall(x64emu_t *emu); void x86Syscall(x64emu_t *emu); @@ -217,28 +206,25 @@ box64context_t *NewBox64Context(int argc) init_mutexes(context); pthread_atfork(NULL, NULL, atfork_child_box64context); - pthread_key_create(&context->tlskey, free_tlsdatasize); - - for (int i=0; i<8; ++i) context->canary[i] = 1 + getrand(255); context->canary[getrand(4)] = 0; printf_log(LOG_DEBUG, "Setting up canary (for Stack protector) at FS:0x28, value:%08X\n", *(uint32_t*)context->canary); // init segments for(int i=0; i<16; i++) { - context->segtls[i].limit = (uintptr_t)-1LL; + context->seggdt[i].limit = (uintptr_t)-1LL; } - context->segtls[10].key_init = 0; // 0x53 selector - context->segtls[10].present = 1; - context->segtls[8].key_init = 0; // 0x43 selector - context->segtls[8].present = 1; - context->segtls[6].key_init = 0; // 0x33 selector - context->segtls[6].present = 1; - context->segtls[5].key_init = 0; // 0x2b selector - context->segtls[5].present = 1; - context->segtls[4].key_init = 0; // 0x23 selector - context->segtls[4].present = 1; - context->segtls[4].is32bits = 1; + // 0x53 selector + context->seggdt[10].present = 1; + // 0x43 selector + context->seggdt[8].present = 1; + // 0x33 selector + context->seggdt[6].present = 1; + // 0x2b selector + context->seggdt[5].present = 1; + // 0x23 selector + context->seggdt[4].present = 1; + context->seggdt[4].is32bits = 1; context->globdata = NewMapSymbols(); context->uniques = NewMapSymbols(); @@ -330,12 +316,6 @@ void FreeBox64Context(box64context_t** context) box_free(ctx->stack_clone); - void* ptr; - if ((ptr = pthread_getspecific(ctx->tlskey)) != NULL) { - free_tlsdatasize(ptr); - } - pthread_key_delete(ctx->tlskey); - if(ctx->tlsdata) box_free(ctx->tlsdata); diff --git a/src/core.c b/src/core.c index 20a6df56..14d0c26a 100644 --- a/src/core.c +++ b/src/core.c @@ -67,6 +67,7 @@ int box64_zoom = 0; int box64_steam = 0; int box64_steamcmd = 0; int box64_musl = 0; +int box64_nolibs = 0; char* box64_custom_gstreamer = NULL; int box64_tcmalloc_minimal = 0; uintptr_t fmod_smc_start = 0; @@ -1322,6 +1323,8 @@ int initialize(int argc, const char **argv, char** env, x64emu_t** emulator, elf my_context->orig_argc = argc; my_context->orig_argv = (char**)argv; } + box64_nolibs = (NeededLibs(elf_header)==0); + if(box64_nolibs) printf_log(LOG_INFO, "Warning, box64 is not really compatible with staticaly linked binaries. Expect crash!\n"); box64_isglibc234 = GetNeededVersionForLib(elf_header, "libc.so.6", "GLIBC_2.34"); if(box64_isglibc234) printf_log(LOG_DEBUG, "Program linked with GLIBC 2.34+\n"); @@ -1405,7 +1408,7 @@ int initialize(int argc, const char **argv, char** env, x64emu_t** emulator, elf setupTraceInit(); RunDeferredElfInit(emu); // update TLS of main elf - RefreshElfTLS(elf_header); + RefreshElfTLS(elf_header, emu); // 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... diff --git a/src/elfs/elfloader.c b/src/elfs/elfloader.c index 7cc6b490..2c860cac 100644 --- a/src/elfs/elfloader.c +++ b/src/elfs/elfloader.c @@ -1133,14 +1133,14 @@ int ElfCheckIfUseTCMallocMinimal(elfheader_t* h) return 0; } -void RefreshElfTLS(elfheader_t* h) +void RefreshElfTLS(elfheader_t* h, x64emu_t* emu) { 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); - if (pthread_getspecific(my_context->tlskey)) { - tlsdatasize_t* ptr = getTLSData(my_context); + if (emu->tlsdata) { + tlsdatasize_t* ptr = getTLSData(emu); // refresh in tlsdata too dest = (char*)(ptr->data+h->tlsbase); printf_dump(LOG_DEBUG, "Refreshing active TLS block @%p from %p:0x%lx\n", dest, (void*)h->tlsaddr, h->tlssize-h->tlsfilesize); @@ -1166,7 +1166,7 @@ void RunElfInit(elfheader_t* h, x64emu_t *emu) memset(emu->segs_serial, 0, sizeof(emu->segs_serial)); uintptr_t p = h->initentry + h->delta; // Refresh no-file part of TLS in case default value changed - RefreshElfTLS(h); + RefreshElfTLS(h, emu); // check if in deferredInit if(my_context->deferredInit) { if(my_context->deferredInitSz==my_context->deferredInitCap) { @@ -1438,9 +1438,9 @@ int SameVersionedSymbol(const char* name1, int ver1, const char* vername1, int v return 0; } -void* GetDTatOffset(box64context_t* context, unsigned long int index, unsigned long int offset) +void* GetDTatOffset(x64emu_t* emu, unsigned long int index, unsigned long int offset) { - return (void*)((char*)GetTLSPointer(context, context->elfs[index])+offset); + return (void*)((char*)GetTLSPointer(emu, emu->context->elfs[index])+offset); } int32_t GetTLSBase(elfheader_t* h) @@ -1453,11 +1453,11 @@ uint32_t GetTLSSize(elfheader_t* h) return h?h->tlssize:0; } -void* GetTLSPointer(box64context_t* context, elfheader_t* h) +void* GetTLSPointer(x64emu_t* emu, elfheader_t* h) { if(!h || !h->tlssize) return NULL; - tlsdatasize_t* ptr = getTLSData(context); + tlsdatasize_t* ptr = getTLSData(emu); return ptr->data+h->tlsbase; } @@ -1776,6 +1776,19 @@ int ElfGetSymTabStartEnd(elfheader_t* head, uintptr_t *offs, uintptr_t *end, con return box64_is32bits?ElfGetSymTabStartEnd32(head, offs, end, symname):ElfGetSymTabStartEnd64(head, offs, end, symname); } +int NeededLibs(elfheader_t* h) +{ + if(!h) return 0; + int cnt = 0; + // count the number of needed libs, and also grab soname + for (size_t i=0; i<h->numDynamic; ++i) { + int tag = box64_is32bits?h->Dynamic._32[i].d_tag:h->Dynamic._64[i].d_tag; + if(tag==DT_NEEDED) + ++cnt; + } + return cnt; +} + typedef struct search_symbol_s{ const char* name; void* addr; diff --git a/src/emu/x64emu.c b/src/emu/x64emu.c index e32ce693..f4fa700b 100644 --- a/src/emu/x64emu.c +++ b/src/emu/x64emu.c @@ -80,6 +80,11 @@ static void internalX64Setup(x64emu_t* emu, box64context_t *context, uintptr_t s emu->segs[_FS] = 0x43; emu->segs[_GS] = default_gs; } + // init segments + for(int i=0; i<16; i++) { + emu->segldt[i].limit = (uintptr_t)-1LL; + } + memcpy(emu->seggdt, context->seggdt, sizeof(emu->seggdt)); // setup fpu regs reset_fpu(emu); emu->mxcsr.x32 = 0x1f80; @@ -149,6 +154,10 @@ static void internalFreeX64(x64emu_t* emu) actual_free(emu->res_state_32); emu->res_state_32 = NULL; #endif + if(emu->tlsdata) { + free_tlsdatasize(emu->tlsdata); + emu->tlsdata = NULL; + } } EXPORTDYN @@ -186,6 +195,8 @@ void CloneEmu(x64emu_t *newemu, const x64emu_t* emu) newemu->old_ip = emu->old_ip; memcpy(newemu->segs, emu->segs, sizeof(emu->segs)); memset(newemu->segs_serial, 0, sizeof(newemu->segs_serial)); + memcpy(newemu->seggdt, emu->seggdt, sizeof(newemu->seggdt)); + memcpy(newemu->segldt, emu->segldt, sizeof(newemu->segldt)); memcpy(newemu->x87, emu->x87, sizeof(emu->x87)); memcpy(newemu->mmx, emu->mmx, sizeof(emu->mmx)); memcpy(newemu->fpu_ld, emu->fpu_ld, sizeof(emu->fpu_ld)); @@ -1585,10 +1596,19 @@ void UpdateFlags(x64emu_t* emu) RESET_FLAGS(emu); } +void free_tlsdatasize(void* p) +{ + if(!p) + return; + tlsdatasize_t *data = (tlsdatasize_t*)p; + actual_free(data->ptr); + actual_free(p); +} + uintptr_t GetSegmentBaseEmu(x64emu_t* emu, int seg) { if (emu->segs_serial[seg] != emu->context->sel_serial) { - emu->segs_offs[seg] = (uintptr_t)GetSegmentBase(emu->segs[seg]); + emu->segs_offs[seg] = (uintptr_t)GetSegmentBase(emu, emu->segs[seg]); emu->segs_serial[seg] = emu->context->sel_serial; } return emu->segs_offs[seg]; diff --git a/src/emu/x64emu_private.h b/src/emu/x64emu_private.h index aba2b3ed..bd76c047 100644 --- a/src/emu/x64emu_private.h +++ b/src/emu/x64emu_private.h @@ -3,8 +3,8 @@ #include "regs.h" #include "os.h" +#include "box64context.h" -typedef struct box64context_s box64context_t; typedef struct x64_ucontext_s x64_ucontext_t; #ifdef BOX32 typedef struct i386_ucontext_s i386_ucontext_t; @@ -127,6 +127,11 @@ typedef struct x64emu_s { #ifdef _WIN32 uint64_t win64_teb; #endif + // local selector handling + base_segment_t segldt[16]; + base_segment_t seggdt[16]; // hacky + tlsdatasize_t *tlsdata; + // other informations int type; // EMUTYPE_xxx define #ifdef BOX32 int libc_err; // copy of errno from libc diff --git a/src/emu/x64run0f.c b/src/emu/x64run0f.c index aff7419e..caba2238 100644 --- a/src/emu/x64run0f.c +++ b/src/emu/x64run0f.c @@ -168,10 +168,11 @@ uintptr_t Run0F(x64emu_t *emu, rex_t rex, uintptr_t addr, int *step) GETGD; CHECK_FLAGS(emu); tmp8u = ED->word[0]>>3; - if (tmp8u>0x10 || !my_context->segtls[tmp8u].present) { + tmp8s = !!(ED->word[0]&2); + if (tmp8u>0x10 || !tmp8s?emu->segldt[tmp8u].present:my_context->seggdt[tmp8u].present) { CLEAR_FLAG(F_ZF); } else { - GD->dword[0] = my_context->segtls[tmp8u].limit; + GD->dword[0] = tmp8s?emu->segldt[tmp8u].limit:my_context->seggdt[tmp8u].limit; SET_FLAG(F_ZF); } break; diff --git a/src/emu/x64tls.c b/src/emu/x64tls.c index 4c17dda8..80aef6ae 100644 --- a/src/emu/x64tls.c +++ b/src/emu/x64tls.c @@ -62,7 +62,7 @@ uint32_t my_set_thread_area_32(x64emu_t* emu, thread_area_32_t* td) if(idx==-1) { // find a free one for (int i=9; i<15 && idx==-1; ++i) - if(!my_context->segtls[i].present) + if(!my_context->seggdt[i].present) idx=i; if(idx==-1) { errno = ESRCH; @@ -75,7 +75,7 @@ uint32_t my_set_thread_area_32(x64emu_t* emu, thread_area_32_t* td) return (uint32_t)-1; } if(isempty) { - memset(&my_context->segtls[td->entry_number], 0, sizeof(base_segment_t)); + memset(&my_context->seggdt[td->entry_number], 0, sizeof(base_segment_t)); return 0; } if((idx<9 || idx>15)) { @@ -83,17 +83,17 @@ uint32_t my_set_thread_area_32(x64emu_t* emu, thread_area_32_t* td) return (uint32_t)-1; } - my_context->segtls[idx].base = td->base_addr; - my_context->segtls[idx].limit = td->limit; - my_context->segtls[idx].present = 1; - my_context->segtls[idx].is32bits = 1; - if(!my_context->segtls[idx].key_init) { - pthread_key_create(&my_context->segtls[idx].key, NULL); - my_context->segtls[idx].key_init = 1; + my_context->seggdt[idx].base = td->base_addr; + my_context->seggdt[idx].limit = td->limit; + my_context->seggdt[idx].present = 1; + my_context->seggdt[idx].is32bits = 1; + if(idx>5) { + emu->seggdt[idx].base = td->base_addr; + emu->seggdt[idx].limit = td->limit; + emu->seggdt[idx].present = 1; + emu->seggdt[idx].is32bits = 1; } - pthread_setspecific(my_context->segtls[idx].key, (void*)my_context->segtls[idx].base); - ResetSegmentsCache(emu); return 0; @@ -124,15 +124,9 @@ uint32_t my_modify_ldt(x64emu_t* emu, int op, thread_area_t* td, int size) if(box64_is32bits) { emu->segs_serial[_GS] = 0; - my_context->segtls[idx].base = td->base_addr; - my_context->segtls[idx].limit = td->limit; - my_context->segtls[idx].present = 1; - if(idx>8 && !my_context->segtls[idx].key_init) { - pthread_key_create(&my_context->segtls[idx].key, NULL); - my_context->segtls[idx].key_init = 1; - } - if(my_context->segtls[idx].key_init) - pthread_setspecific(my_context->segtls[idx].key, (void*)my_context->segtls[idx].base); + emu->segldt[idx].base = td->base_addr; + emu->segldt[idx].limit = td->limit; + emu->segldt[idx].present = 1; } ResetSegmentsCache(emu); @@ -172,21 +166,21 @@ int my_arch_prctl(x64emu_t *emu, int code, void* addr) errno = 0; switch(code) { case ARCH_GET_GS: - *(void**)addr = GetSegmentBase(emu->segs[_GS]); + *(void**)addr = GetSegmentBase(emu, emu->segs[_GS]); return 0; case ARCH_GET_FS: - *(void**)addr = GetSegmentBase(emu->segs[_FS]); + *(void**)addr = GetSegmentBase(emu, emu->segs[_FS]); return 0; case ARCH_SET_FS: case ARCH_SET_GS: seg=(code==ARCH_SET_FS)?_FS:_GS; int idx = -1; // search if it's a TLS base - if(GetSeg43Base()==addr) + if(GetSeg43Base(emu)==addr) idx = 0x43>>3; // Is this search only occurs when seg==0? for (int i=9; i<15 && idx==-1; ++i) - if(my_context->segtls[i].present && my_context->segtls[i].base==(uintptr_t)addr) + if(my_context->seggdt[i].present && my_context->seggdt[i].base==(uintptr_t)addr) idx=i; // found... if(idx!=-1) { @@ -204,15 +198,14 @@ int my_arch_prctl(x64emu_t *emu, int code, void* addr) return -1; } emu->segs_serial[seg] = 0; - my_context->segtls[idx].base = (uintptr_t)addr; - my_context->segtls[idx].limit = 0; - my_context->segtls[idx].present = 1; - if(idx>8 && !my_context->segtls[idx].key_init) { - pthread_key_create(&my_context->segtls[idx].key, NULL); - my_context->segtls[idx].key_init = 1; + my_context->seggdt[idx].base = (uintptr_t)addr; + my_context->seggdt[idx].limit = 0; + my_context->seggdt[idx].present = 1; + if(idx>5) { + emu->seggdt[idx].base = (uintptr_t)addr; + emu->seggdt[idx].limit = 0; + emu->seggdt[idx].present = 1; } - if(my_context->segtls[idx].key_init) - pthread_setspecific(my_context->segtls[idx].key, addr); ResetSegmentsCache(emu); return 0; case ARCH_GET_XCOMP_SUPP: @@ -234,7 +227,7 @@ int my_arch_prctl(x64emu_t *emu, int code, void* addr) /* tls record should looks like: void* tcb 0x00 - void* dtv 0x08 + void* dts 0x08 void* self 0x10 int multiple 0x18 int gscope 0x1c @@ -274,7 +267,6 @@ static tlsdatasize_t* setupTLSData(box64context_t* context) data->tlssize = context->tlssize; data->ptr = ptr_oversized; data->n_elfs = context->elfsize; - pthread_setspecific(context->tlskey, data); #ifdef BOX32 if(box64_is32bits) { // copy canary... @@ -364,14 +356,15 @@ static void* resizeTLSData(box64context_t *context, void* oldptr) } } -tlsdatasize_t* getTLSData(box64context_t *context) +tlsdatasize_t* getTLSData(x64emu_t* emu) { tlsdatasize_t* ptr = NULL; if(!ptr) - if ((ptr = (tlsdatasize_t*)pthread_getspecific(context->tlskey)) == NULL) { - ptr = (tlsdatasize_t*)fillTLSData(context); + if ((ptr = emu->tlsdata) == NULL) { + ptr = (tlsdatasize_t*)fillTLSData(emu->context); } - if(ptr->tlssize != context->tlssize) - ptr = (tlsdatasize_t*)resizeTLSData(context, ptr); + if(ptr->tlssize != emu->context->tlssize) + ptr = (tlsdatasize_t*)resizeTLSData(emu->context, ptr); + emu->tlsdata = ptr; return ptr; } \ No newline at end of file diff --git a/src/include/box64context.h b/src/include/box64context.h index 910b0e8a..419599c6 100644 --- a/src/include/box64context.h +++ b/src/include/box64context.h @@ -88,10 +88,8 @@ void add1libref_neededlib(needed_libs_t* needed, library_t* lib); typedef struct base_segment_s { uintptr_t base; uint64_t limit; - pthread_key_t key; uint8_t present; uint8_t is32bits; - uint8_t key_init; } base_segment_t; typedef struct box64context_s { @@ -202,10 +200,9 @@ typedef struct box64context_s { int deferredInitSz; int deferredInitCap; - pthread_key_t tlskey; // then tls key to have actual tlsdata void* tlsdata; // the initial global tlsdata int64_t tlssize; // wanted size of tlsdata - base_segment_t segtls[16]; + base_segment_t seggdt[16]; uintptr_t *auxval_start; diff --git a/src/include/debug.h b/src/include/debug.h index 2c7e1a62..556c7e37 100644 --- a/src/include/debug.h +++ b/src/include/debug.h @@ -15,6 +15,7 @@ extern int box64_rdtsc; extern uint8_t box64_rdtsc_shift; extern int box64_is32bits; extern int box64_isAddressSpace32; +extern int box64_nolibs; #ifdef DYNAREC extern cpu_ext_t cpuext; #endif diff --git a/src/include/elfloader.h b/src/include/elfloader.h index 56a0571e..c2cc529d 100644 --- a/src/include/elfloader.h +++ b/src/include/elfloader.h @@ -51,10 +51,11 @@ void CalcStack(elfheader_t* h, uint64_t* stacksz, size_t* stackalign); uintptr_t GetEntryPoint(lib_t* maplib, elfheader_t* h); uintptr_t GetLastByte(elfheader_t* h); void AddSymbols(lib_t *maplib, elfheader_t* h); +int NeededLibs(elfheader_t* h); int LoadNeededLibs(elfheader_t* h, lib_t *maplib, int local, int bindnow, int deepbind, box64context_t *box64, x64emu_t* emu); uintptr_t GetElfInit(elfheader_t* h); uintptr_t GetElfFini(elfheader_t* h); -void RefreshElfTLS(elfheader_t* h); +void RefreshElfTLS(elfheader_t* h, x64emu_t* emu); void RunElfInit(elfheader_t* h, x64emu_t *emu); void RunElfFini(elfheader_t* h, x64emu_t *emu); void RunDeferredElfInit(x64emu_t *emu); @@ -67,8 +68,8 @@ elfheader_t* FindElfAddress(box64context_t *context, uintptr_t addr); const char* FindNearestSymbolName(elfheader_t* h, void* p, uintptr_t* start, uint64_t* sz); int32_t GetTLSBase(elfheader_t* h); uint32_t GetTLSSize(elfheader_t* h); -void* GetTLSPointer(box64context_t* context, elfheader_t* h); -void* GetDTatOffset(box64context_t* context, unsigned long int index, unsigned long int offset); +void* GetTLSPointer(x64emu_t* emu, elfheader_t* h); +void* GetDTatOffset(x64emu_t* emu, unsigned long int index, unsigned long int offset); void ResetSpecialCaseMainElf(elfheader_t* h); void CreateMemorymapFile(box64context_t* context, int fd); void* GetDynamicSection(elfheader_t* h); diff --git a/src/include/os.h b/src/include/os.h index fc778928..60be6195 100644 --- a/src/include/os.h +++ b/src/include/os.h @@ -45,8 +45,8 @@ int SchedYield(void); void EmuX64Syscall(void* emu); void EmuX86Syscall(void* emu); -void* GetSeg43Base(); -void* GetSegmentBase(uint32_t desc); +void* GetSeg43Base(void* emu); +void* GetSegmentBase(void* emu, uint32_t desc); // These functions only applies to Linux -------------------------- int IsBridgeSignature(char s, char c); diff --git a/src/include/x64tls.h b/src/include/x64tls.h index e8eefd31..112cc59a 100644 --- a/src/include/x64tls.h +++ b/src/include/x64tls.h @@ -7,7 +7,7 @@ typedef struct thread_area_32_s thread_area_32_t; uint32_t my_set_thread_area_32(x64emu_t* emu, thread_area_32_t* td); uint32_t my_modify_ldt(x64emu_t* emu, int op, thread_area_t* td, int size); -tlsdatasize_t* getTLSData(box64context_t* context); +tlsdatasize_t* getTLSData(x64emu_t* emu); int my_arch_prctl(x64emu_t *emu, int code, void* addr); diff --git a/src/libtools/threads.c b/src/libtools/threads.c index 6fd7ffe6..1076b3e2 100644 --- a/src/libtools/threads.c +++ b/src/libtools/threads.c @@ -24,6 +24,7 @@ #include "x64trace.h" #include "bridge.h" #include "myalign.h" +#include "x64tls.h" #ifdef DYNAREC #include "dynablock.h" #include "dynarec/native_lock.h" @@ -215,6 +216,7 @@ x64emu_t* thread_get_emu() setProtection_stack((uintptr_t)stack, stacksize, PROT_READ|PROT_WRITE); x64emu_t *emu = NewX64Emu(my_context, my_context->exit_bridge, (uintptr_t)stack, stacksize, 1); SetupX64Emu(emu, NULL); + getTLSData(emu); thread_set_emu(emu); return emu; } @@ -248,6 +250,7 @@ static void* pthread_routine(void* p) et->emu->type = EMUTYPE_MAIN; // setup callstack and run... x64emu_t* emu = et->emu; + getTLSData(emu); ResetSegmentsCache(emu); Push64(emu, 0); // PUSH 0 (backtrace marker: return address is 0) Push64(emu, 0); // PUSH BP diff --git a/src/libtools/threads32.c b/src/libtools/threads32.c index ce5a4579..4d614b93 100755 --- a/src/libtools/threads32.c +++ b/src/libtools/threads32.c @@ -27,6 +27,7 @@ #include "x64trace.h" #include "bridge.h" #include "threads32.h" +#include "x64tls.h" #ifdef DYNAREC #include "dynablock.h" #endif @@ -112,6 +113,7 @@ static void* pthread_routine(void* p) et->hself = to_hash(et->self); // setup callstack and run... x64emu_t* emu = et->emu; + getTLSData(emu); Push_32(emu, 0); // PUSH 0 (backtrace marker: return address is 0) Push_32(emu, 0); // PUSH BP R_EBP = R_ESP; // MOV BP, SP diff --git a/src/os/os_linux.c b/src/os/os_linux.c index 235d43ee..17ba33cc 100644 --- a/src/os/os_linux.c +++ b/src/os/os_linux.c @@ -22,6 +22,7 @@ #include "debug.h" #include "x64tls.h" #include "librarian.h" +#include "emu/x64emu_private.h" int GetTID(void) { @@ -65,33 +66,33 @@ void EmuX86Syscall(void* emu) extern int box64_is32bits; -void* GetSeg43Base() +void* GetSeg43Base(void* emu) { - tlsdatasize_t* ptr = getTLSData(my_context); + tlsdatasize_t* ptr = getTLSData((x64emu_t*)emu); return ptr->data; } -void* GetSegmentBase(uint32_t desc) +void* GetSegmentBase(void* emu, uint32_t desc) { if (!desc) { printf_log(LOG_NONE, "Warning, accessing segment NULL\n"); return NULL; } int base = desc >> 3; - if (!box64_is32bits && base == 0x8 && !my_context->segtls[base].key_init) - return GetSeg43Base(); - if (box64_is32bits && (base == 0x6)) - return GetSeg43Base(); + int is_ldt = !!(desc&4); + base_segment_t* segs = is_ldt?((x64emu_t*)emu)->segldt:((base>5)?((x64emu_t*)emu)->seggdt:my_context->seggdt); + if(!box64_nolibs) { + if (!box64_is32bits && (base == 0x8) ) + return GetSeg43Base((x64emu_t*)emu); + if (box64_is32bits && (base == 0x6)) + return GetSeg43Base((x64emu_t*)emu); + } if (base > 15) { printf_log(LOG_NONE, "Warning, accessing segment unknown 0x%x or unset\n", desc); return NULL; } - if (my_context->segtls[base].key_init) { - void* ptr = pthread_getspecific(my_context->segtls[base].key); - return ptr; - } - void* ptr = (void*)my_context->segtls[base].base; + void* ptr = (void*)segs[base].base; return ptr; } diff --git a/src/os/os_wine.c b/src/os/os_wine.c index edae6e07..4693295d 100644 --- a/src/os/os_wine.c +++ b/src/os/os_wine.c @@ -30,12 +30,12 @@ int IsBridgeSignature(char s, char c) return FALSE; } -void* GetSeg43Base() +void* GetSeg43Base(void* emu) { return NULL; } -void* GetSegmentBase(uint32_t desc) +void* GetSegmentBase(void* emu, uint32_t desc) { printf_log(LOG_NONE, "GetSegmentBase does not apply to Wine dlls\n"); return NULL; diff --git a/src/wrapped/wrappedldlinux.c b/src/wrapped/wrappedldlinux.c index cd2ee420..acb69a8d 100644 --- a/src/wrapped/wrappedldlinux.c +++ b/src/wrapped/wrappedldlinux.c @@ -21,10 +21,10 @@ typedef struct my_tls_s { unsigned long int o; } my_tls_t; -EXPORT void* my___tls_get_addr(void* p) +EXPORT void* my___tls_get_addr(x64emu_t* emu, void* p) { my_tls_t *t = (my_tls_t*)p; - tlsdatasize_t* ptr = getTLSData(my_context); + tlsdatasize_t* ptr = getTLSData(emu); return ptr->data+GetTLSBase(my_context->elfs[t->i])+t->o; } diff --git a/src/wrapped/wrappedldlinux_private.h b/src/wrapped/wrappedldlinux_private.h index bbfe723c..6e2b6fe5 100644 --- a/src/wrapped/wrappedldlinux_private.h +++ b/src/wrapped/wrappedldlinux_private.h @@ -27,4 +27,4 @@ DATA(_rtld_global, sizeof(void*)) DATA(_rtld_global_ro, sizeof(void*)) #endif DATA(__stack_chk_guard, sizeof(void*)) -GOM(__tls_get_addr, pFp) //%NoE +GOM(__tls_get_addr, pFEp) diff --git a/src/wrapped32/wrappedldlinux.c b/src/wrapped32/wrappedldlinux.c index b83e3559..bb138d52 100755 --- a/src/wrapped32/wrappedldlinux.c +++ b/src/wrapped32/wrappedldlinux.c @@ -23,14 +23,14 @@ typedef struct __attribute__((packed, aligned(4))) my32_tls_s { EXPORT void* my32___tls_get_addr(x64emu_t* emu, void* p) { my32_tls_t *t = (my32_tls_t*)p; - return GetDTatOffset(emu->context, t->i, t->o); + return GetDTatOffset(emu, t->i, t->o); } EXPORT void* my32____tls_get_addr(x64emu_t* emu) { // the GNU version (with 3 '_') use register for the parameter! my32_tls_t *t = (my32_tls_t*)from_ptrv(R_EAX); - return GetDTatOffset(emu->context, t->i, t->o); + return GetDTatOffset(emu, t->i, t->o); } EXPORT ptr_t my32___libc_stack_end; |