diff options
Diffstat (limited to 'src/emu/x64tls.c')
| -rw-r--r-- | src/emu/x64tls.c | 71 |
1 files changed, 32 insertions, 39 deletions
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 |