about summary refs log tree commit diff stats
path: root/src/emu/x64tls.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/emu/x64tls.c')
-rw-r--r--src/emu/x64tls.c71
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