]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Move x86-TLS specific stuff out of x86/state.c, back into
authorJulian Seward <jseward@acm.org>
Mon, 13 Dec 2004 13:14:05 +0000 (13:14 +0000)
committerJulian Seward <jseward@acm.org>
Mon, 13 Dec 2004 13:14:05 +0000 (13:14 +0000)
x86-linux/tls.c.  Also some other cleanups.

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@3194

coregrind/x86-linux/ldt.c
coregrind/x86/core_arch.h
coregrind/x86/state.c
coregrind/x86/x86_private.h

index 8ad94057200599352ddb2dce8f40c9f478714e70..a89aea57223d1731f4b070a3df980e64a2f029f0 100644 (file)
    am not sure what is and isn't allowed in user-mode.
 */
 
-/* 13 Dec 04: all this stuff has been moved into
-   coregrind/x86/state.c. */
+#include "core.h"
+#include "x86_private.h"
+#include "libvex_guest_x86.h"
+
+
+/* Translate a struct modify_ldt_ldt_s to a VexGuestX86SegDescr, using
+   the Linux kernel's logic (cut-n-paste of code in
+   linux/kernel/ldt.c).  */
+
+static
+void translate_to_hw_format ( /* IN  */ vki_modify_ldt_t* inn,
+                             /* OUT */ VexGuestX86SegDescr* out,
+                                        Int oldmode )
+{
+   UInt entry_1, entry_2;
+   vg_assert(8 == sizeof(VexGuestX86SegDescr));
+
+   if (0)
+      VG_(printf)("translate_to_hw_format: base %p, limit %d\n", 
+                  inn->base_addr, inn->limit );
+
+   /* Allow LDTs to be cleared by the user. */
+   if (inn->base_addr == 0 && inn->limit == 0) {
+      if (oldmode ||
+          (inn->contents == 0      &&
+           inn->read_exec_only == 1   &&
+           inn->seg_32bit == 0      &&
+           inn->limit_in_pages == 0   &&
+           inn->seg_not_present == 1   &&
+           inn->useable == 0 )) {
+         entry_1 = 0;
+         entry_2 = 0;
+         goto install;
+      }
+   }
+
+   entry_1 = ((inn->base_addr & 0x0000ffff) << 16) |
+             (inn->limit & 0x0ffff);
+   entry_2 = (inn->base_addr & 0xff000000) |
+             ((inn->base_addr & 0x00ff0000) >> 16) |
+             (inn->limit & 0xf0000) |
+             ((inn->read_exec_only ^ 1) << 9) |
+             (inn->contents << 10) |
+             ((inn->seg_not_present ^ 1) << 15) |
+             (inn->seg_32bit << 22) |
+             (inn->limit_in_pages << 23) |
+             0x7000;
+   if (!oldmode)
+      entry_2 |= (inn->useable << 20);
+
+   /* Install the new entry ...  */
+  install:
+   out->LdtEnt.Words.word1 = entry_1;
+   out->LdtEnt.Words.word2 = entry_2;
+}
+
+
+/*
+ * linux/kernel/ldt.c
+ *
+ * Copyright (C) 1992 Krishna Balasubramanian and Linus Torvalds
+ * Copyright (C) 1999 Ingo Molnar <mingo@redhat.com>
+ */
+
+/*
+ * read_ldt() is not really atomic - this is not a problem since
+ * synchronization of reads and writes done to the LDT has to be
+ * assured by user-space anyway. Writes are atomic, to protect
+ * the security checks done on new descriptors.
+ */
+static
+Int read_ldt ( ThreadId tid, UChar* ptr, UInt bytecount )
+{
+   Int    err;
+   UInt   i, size;
+   UChar* ldt;
+
+   if (0)
+      VG_(printf)("read_ldt: tid = %d, ptr = %p, bytecount = %d\n",
+                  tid, ptr, bytecount );
+
+   vg_assert(sizeof(HWord) == sizeof(VexGuestX86SegDescr*));
+   vg_assert(8 == sizeof(VexGuestX86SegDescr));
+
+   ldt = (Char*)(VG_(threads)[tid].arch.vex.guest_LDT);
+   err = 0;
+   if (ldt == NULL)
+      /* LDT not allocated, meaning all entries are null */
+      goto out;
+
+   size = VEX_GUEST_X86_LDT_NENT * sizeof(VexGuestX86SegDescr);
+   if (size > bytecount)
+      size = bytecount;
+
+   err = size;
+   for (i = 0; i < size; i++)
+      ptr[i] = ldt[i];
+
+  out:
+   return err;
+}
+
+
+static
+Int write_ldt ( ThreadId tid, void* ptr, UInt bytecount, Int oldmode )
+{
+   Int error;
+   VexGuestX86SegDescr* ldt;
+   vki_modify_ldt_t* ldt_info; 
+
+   if (0)
+      VG_(printf)("write_ldt: tid = %d, ptr = %p, "
+                  "bytecount = %d, oldmode = %d\n",
+                  tid, ptr, bytecount, oldmode );
+
+   vg_assert(8 == sizeof(VexGuestX86SegDescr));
+   vg_assert(sizeof(HWord) == sizeof(VexGuestX86SegDescr*));
+
+   ldt      = (VexGuestX86SegDescr*)VG_(threads)[tid].arch.vex.guest_LDT;
+   ldt_info = (vki_modify_ldt_t*)ptr;
+
+   error = -VKI_EINVAL;
+   if (bytecount != sizeof(vki_modify_ldt_t))
+      goto out;
+
+   error = -VKI_EINVAL;
+   if (ldt_info->entry_number >= VEX_GUEST_X86_LDT_NENT)
+      goto out;
+   if (ldt_info->contents == 3) {
+      if (oldmode)
+         goto out;
+      if (ldt_info->seg_not_present == 0)
+         goto out;
+   }
+
+   /* If this thread doesn't have an LDT, we'd better allocate it
+      now. */
+   if (ldt == (HWord)NULL) {
+      ldt = VG_(alloc_zeroed_x86_LDT)();
+      VG_(threads)[tid].arch.vex.guest_LDT = (HWord)ldt;
+   }
+
+   /* Install the new entry ...  */
+   translate_to_hw_format ( ldt_info, &ldt[ldt_info->entry_number], oldmode );
+   error = 0;
+
+  out:
+   return error;
+}
+
+
+Int VG_(sys_modify_ldt) ( ThreadId tid,
+                          Int func, void* ptr, UInt bytecount )
+{
+   Int ret = -VKI_ENOSYS;
+
+   switch (func) {
+   case 0:
+      ret = read_ldt(tid, ptr, bytecount);
+      break;
+   case 1:
+      ret = write_ldt(tid, ptr, bytecount, 1);
+      break;
+   case 2:
+      VG_(unimplemented)("sys_modify_ldt: func == 2");
+      /* god knows what this is about */
+      /* ret = read_default_ldt(ptr, bytecount); */
+      /*UNREACHED*/
+      break;
+   case 0x11:
+      ret = write_ldt(tid, ptr, bytecount, 0);
+      break;
+   }
+   return ret;
+}
+
+
+Int VG_(sys_set_thread_area) ( ThreadId tid,
+                               vki_modify_ldt_t* info )
+{
+   Int idx;
+   VexGuestX86SegDescr* gdt;
+
+   vg_assert(8 == sizeof(VexGuestX86SegDescr));
+   vg_assert(sizeof(HWord) == sizeof(VexGuestX86SegDescr*));
+
+   if (info == NULL)
+      return -VKI_EFAULT;
+
+   gdt = (VexGuestX86SegDescr*)VG_(threads)[tid].arch.vex.guest_GDT;
+
+   /* If the thread doesn't have a GDT, allocate it now. */
+   if (!gdt) {
+      gdt = VG_(alloc_zeroed_x86_GDT)();
+      VG_(threads)[tid].arch.vex.guest_GDT = (HWord)gdt;
+   }
+
+   idx = info->entry_number;
+
+   if (idx == -1) {
+      /* Find and use the first free entry. */
+      for (idx = 0; idx < VEX_GUEST_X86_GDT_NENT; idx++) {
+         if (gdt[idx].LdtEnt.Words.word1 == 0 
+             && gdt[idx].LdtEnt.Words.word2 == 0)
+            break;
+      }
+
+      if (idx == VEX_GUEST_X86_GDT_NENT)
+         return -VKI_ESRCH;
+   } else if (idx < 0 || idx >= VEX_GUEST_X86_GDT_NENT) {
+      return -VKI_EINVAL;
+   }
+
+   translate_to_hw_format(info, &gdt[idx], 0);
+
+   VG_TRACK( pre_mem_write, Vg_CoreSysCall, tid,
+             "set_thread_area(info->entry)",
+             (Addr) & info->entry_number, sizeof(unsigned int) );
+   info->entry_number = idx;
+   VG_TRACK( post_mem_write, Vg_CoreSysCall, tid,
+             (Addr) & info->entry_number, sizeof(unsigned int) );
+
+   return 0;
+}
+
+
+Int VG_(sys_get_thread_area) ( ThreadId tid,
+                               vki_modify_ldt_t* info )
+{
+   Int idx;
+   VexGuestX86SegDescr* gdt;
+
+   vg_assert(sizeof(HWord) == sizeof(VexGuestX86SegDescr*));
+   vg_assert(8 == sizeof(VexGuestX86SegDescr));
+
+   if (info == NULL)
+      return -VKI_EFAULT;
+
+   idx = info->entry_number;
+
+   if (idx < 0 || idx >= VEX_GUEST_X86_GDT_NENT)
+      return -VKI_EINVAL;
+
+   gdt = (VexGuestX86SegDescr*)VG_(threads)[tid].arch.vex.guest_GDT;
+
+   /* If the thread doesn't have a GDT, allocate it now. */
+   if (!gdt) {
+      gdt = VG_(alloc_zeroed_x86_GDT)();
+      VG_(threads)[tid].arch.vex.guest_GDT = (HWord)gdt;
+   }
+
+   info->base_addr = ( gdt[idx].LdtEnt.Bits.BaseHi << 24 ) |
+                     ( gdt[idx].LdtEnt.Bits.BaseMid << 16 ) |
+                     gdt[idx].LdtEnt.Bits.BaseLow;
+   info->limit = ( gdt[idx].LdtEnt.Bits.LimitHi << 16 ) |
+                   gdt[idx].LdtEnt.Bits.LimitLow;
+   info->seg_32bit = gdt[idx].LdtEnt.Bits.Default_Big;
+   info->contents = ( gdt[idx].LdtEnt.Bits.Type >> 2 ) & 0x3;
+   info->read_exec_only = ( gdt[idx].LdtEnt.Bits.Type & 0x1 ) ^ 0x1;
+   info->limit_in_pages = gdt[idx].LdtEnt.Bits.Granularity;
+   info->seg_not_present = gdt[idx].LdtEnt.Bits.Pres ^ 0x1;
+   info->useable = gdt[idx].LdtEnt.Bits.Sys;
+   info->reserved = 0;
+
+   return 0;
+}
+
 
 /*--------------------------------------------------------------------*/
 /*--- end                                                          ---*/
index b56ebbc6eb1ae1be0baf00ddfc03e6798cab09f6..62958f1a35dbf928d95812e790c7f064a2ecbd21 100644 (file)
    asm("movl %%ebp, %0" : "=r" (ebp));       \
 } while (0)
 
-/* ---------------------------------------------------------------------
-   LDT type             
-   ------------------------------------------------------------------ */
-
-// XXX: eventually this will be x86-private, not seen by the core(?)
-
-/* This is the hardware-format for a segment descriptor, ie what the
-   x86 actually deals with.  It is 8 bytes long.  It's ugly.  */
-#if 0
-typedef struct _LDT_ENTRY {
-    union {
-       struct {
-          UShort      LimitLow;
-          UShort      BaseLow;
-          unsigned    BaseMid         : 8;
-          unsigned    Type            : 5;
-          unsigned    Dpl             : 2;
-          unsigned    Pres            : 1;
-          unsigned    LimitHi         : 4;
-          unsigned    Sys             : 1;
-          unsigned    Reserved_0      : 1;
-          unsigned    Default_Big     : 1;
-          unsigned    Granularity     : 1;
-          unsigned    BaseHi          : 8;
-       } Bits;
-       struct {
-          UInt word1;
-          UInt word2;
-       } Words;
-    } 
-    LdtEnt;
-} VgLdtEntry;
-#endif
-
 /* ---------------------------------------------------------------------
    Architecture-specific part of a ThreadState
    ------------------------------------------------------------------ */
 
 // Architecture-specific part of a ThreadState
 // XXX: eventually this should be made abstract, ie. the fields not visible
-//      to the core...  then VgLdtEntry can be made non-visible to the core
-//      also.
+//      to the core...
 typedef 
    struct {
       /* --- BEGIN vex-mandated guest state --- */
index 15aad6b5cd5da3a39bf2c33ad216eeda9930c160..942acaa06fe4726b7386d97ed0e12939bf4fc893 100644 (file)
@@ -111,7 +111,7 @@ void VGA_(init_thread1state) ( Addr client_eip,
 
 /* Create a zeroed-out GDT. */
 
-static VexGuestX86SegDescr* alloc_zeroed_GDT ( void )
+VexGuestX86SegDescr* VG_(alloc_zeroed_x86_GDT) ( void )
 {
    Int nbytes 
       = VEX_GUEST_X86_GDT_NENT * sizeof(VexGuestX86SegDescr);
@@ -121,7 +121,7 @@ static VexGuestX86SegDescr* alloc_zeroed_GDT ( void )
 
 /* Create a zeroed-out LDT. */
 
-static VexGuestX86SegDescr* alloc_zeroed_LDT ( void )
+VexGuestX86SegDescr* VG_(alloc_zeroed_x86_LDT) ( void )
 {
    Int nbytes 
       = VEX_GUEST_X86_LDT_NENT * sizeof(VexGuestX86SegDescr);
@@ -172,269 +172,6 @@ static void deallocate_LGDTs_for_thread ( VexGuestX86State* vex )
 }
 
 
-/* Translate a struct modify_ldt_ldt_s to a VexGuestX86SegDescr, using
-   the Linux kernel's logic (cut-n-paste of code in
-   linux/kernel/ldt.c).  */
-
-static
-void translate_to_hw_format ( /* IN  */ vki_modify_ldt_t* inn,
-                             /* OUT */ VexGuestX86SegDescr* out,
-                                        Int oldmode )
-{
-   UInt entry_1, entry_2;
-   vg_assert(8 == sizeof(VexGuestX86SegDescr));
-
-   if (0)
-      VG_(printf)("translate_to_hw_format: base %p, limit %d\n", 
-                  inn->base_addr, inn->limit );
-
-   /* Allow LDTs to be cleared by the user. */
-   if (inn->base_addr == 0 && inn->limit == 0) {
-      if (oldmode ||
-          (inn->contents == 0      &&
-           inn->read_exec_only == 1   &&
-           inn->seg_32bit == 0      &&
-           inn->limit_in_pages == 0   &&
-           inn->seg_not_present == 1   &&
-           inn->useable == 0 )) {
-         entry_1 = 0;
-         entry_2 = 0;
-         goto install;
-      }
-   }
-
-   entry_1 = ((inn->base_addr & 0x0000ffff) << 16) |
-             (inn->limit & 0x0ffff);
-   entry_2 = (inn->base_addr & 0xff000000) |
-             ((inn->base_addr & 0x00ff0000) >> 16) |
-             (inn->limit & 0xf0000) |
-             ((inn->read_exec_only ^ 1) << 9) |
-             (inn->contents << 10) |
-             ((inn->seg_not_present ^ 1) << 15) |
-             (inn->seg_32bit << 22) |
-             (inn->limit_in_pages << 23) |
-             0x7000;
-   if (!oldmode)
-      entry_2 |= (inn->useable << 20);
-
-   /* Install the new entry ...  */
-  install:
-   out->LdtEnt.Words.word1 = entry_1;
-   out->LdtEnt.Words.word2 = entry_2;
-}
-
-
-/*
- * linux/kernel/ldt.c
- *
- * Copyright (C) 1992 Krishna Balasubramanian and Linus Torvalds
- * Copyright (C) 1999 Ingo Molnar <mingo@redhat.com>
- */
-
-/*
- * read_ldt() is not really atomic - this is not a problem since
- * synchronization of reads and writes done to the LDT has to be
- * assured by user-space anyway. Writes are atomic, to protect
- * the security checks done on new descriptors.
- */
-static
-Int read_ldt ( ThreadId tid, UChar* ptr, UInt bytecount )
-{
-   Int    err;
-   UInt   i, size;
-   UChar* ldt;
-
-   if (0)
-      VG_(printf)("read_ldt: tid = %d, ptr = %p, bytecount = %d\n",
-                  tid, ptr, bytecount );
-
-   vg_assert(sizeof(HWord) == sizeof(VexGuestX86SegDescr*));
-   vg_assert(8 == sizeof(VexGuestX86SegDescr));
-
-   ldt = (Char*)(VG_(threads)[tid].arch.vex.guest_LDT);
-   err = 0;
-   if (ldt == NULL)
-      /* LDT not allocated, meaning all entries are null */
-      goto out;
-
-   size = VEX_GUEST_X86_LDT_NENT * sizeof(VexGuestX86SegDescr);
-   if (size > bytecount)
-      size = bytecount;
-
-   err = size;
-   for (i = 0; i < size; i++)
-      ptr[i] = ldt[i];
-
-  out:
-   return err;
-}
-
-
-static
-Int write_ldt ( ThreadId tid, void* ptr, UInt bytecount, Int oldmode )
-{
-   Int error;
-   VexGuestX86SegDescr* ldt;
-   vki_modify_ldt_t* ldt_info; 
-
-   if (0)
-      VG_(printf)("write_ldt: tid = %d, ptr = %p, "
-                  "bytecount = %d, oldmode = %d\n",
-                  tid, ptr, bytecount, oldmode );
-
-   vg_assert(8 == sizeof(VexGuestX86SegDescr));
-   vg_assert(sizeof(HWord) == sizeof(VexGuestX86SegDescr*));
-
-   ldt      = (VexGuestX86SegDescr*)VG_(threads)[tid].arch.vex.guest_LDT;
-   ldt_info = (vki_modify_ldt_t*)ptr;
-
-   error = -VKI_EINVAL;
-   if (bytecount != sizeof(vki_modify_ldt_t))
-      goto out;
-
-   error = -VKI_EINVAL;
-   if (ldt_info->entry_number >= VEX_GUEST_X86_LDT_NENT)
-      goto out;
-   if (ldt_info->contents == 3) {
-      if (oldmode)
-         goto out;
-      if (ldt_info->seg_not_present == 0)
-         goto out;
-   }
-
-   /* If this thread doesn't have an LDT, we'd better allocate it
-      now. */
-   if (ldt == (HWord)NULL) {
-      ldt = alloc_zeroed_LDT();
-      VG_(threads)[tid].arch.vex.guest_LDT = (HWord)ldt;
-   }
-
-   /* Install the new entry ...  */
-   translate_to_hw_format ( ldt_info, &ldt[ldt_info->entry_number], oldmode );
-   error = 0;
-
-  out:
-   return error;
-}
-
-
-Int VG_(sys_modify_ldt) ( ThreadId tid,
-                          Int func, void* ptr, UInt bytecount )
-{
-   Int ret = -VKI_ENOSYS;
-
-   switch (func) {
-   case 0:
-      ret = read_ldt(tid, ptr, bytecount);
-      break;
-   case 1:
-      ret = write_ldt(tid, ptr, bytecount, 1);
-      break;
-   case 2:
-      VG_(unimplemented)("sys_modify_ldt: func == 2");
-      /* god knows what this is about */
-      /* ret = read_default_ldt(ptr, bytecount); */
-      /*UNREACHED*/
-      break;
-   case 0x11:
-      ret = write_ldt(tid, ptr, bytecount, 0);
-      break;
-   }
-   return ret;
-}
-
-
-Int VG_(sys_set_thread_area) ( ThreadId tid,
-                               vki_modify_ldt_t* info )
-{
-   Int idx;
-   VexGuestX86SegDescr* gdt;
-
-   vg_assert(8 == sizeof(VexGuestX86SegDescr));
-   vg_assert(sizeof(HWord) == sizeof(VexGuestX86SegDescr*));
-
-   if (info == NULL)
-      return -VKI_EFAULT;
-
-   gdt = (VexGuestX86SegDescr*)VG_(threads)[tid].arch.vex.guest_GDT;
-
-   /* If the thread doesn't have a GDT, allocate it now. */
-   if (!gdt) {
-      gdt = alloc_zeroed_GDT();
-      VG_(threads)[tid].arch.vex.guest_GDT = (HWord)gdt;
-   }
-
-   idx = info->entry_number;
-
-   if (idx == -1) {
-      /* Find and use the first free entry. */
-      for (idx = 0; idx < VEX_GUEST_X86_GDT_NENT; idx++) {
-         if (gdt[idx].LdtEnt.Words.word1 == 0 
-             && gdt[idx].LdtEnt.Words.word2 == 0)
-            break;
-      }
-
-      if (idx == VEX_GUEST_X86_GDT_NENT)
-         return -VKI_ESRCH;
-   } else if (idx < 0 || idx >= VEX_GUEST_X86_GDT_NENT) {
-      return -VKI_EINVAL;
-   }
-
-   translate_to_hw_format(info, &gdt[idx], 0);
-
-   VG_TRACK( pre_mem_write, Vg_CoreSysCall, tid,
-             "set_thread_area(info->entry)",
-             (Addr) & info->entry_number, sizeof(unsigned int) );
-   info->entry_number = idx;
-   VG_TRACK( post_mem_write, Vg_CoreSysCall, tid,
-             (Addr) & info->entry_number, sizeof(unsigned int) );
-
-   return 0;
-}
-
-
-Int VG_(sys_get_thread_area) ( ThreadId tid,
-                               vki_modify_ldt_t* info )
-{
-   Int idx;
-   VexGuestX86SegDescr* gdt;
-
-   vg_assert(sizeof(HWord) == sizeof(VexGuestX86SegDescr*));
-   vg_assert(8 == sizeof(VexGuestX86SegDescr));
-
-   if (info == NULL)
-      return -VKI_EFAULT;
-
-   idx = info->entry_number;
-
-   if (idx < 0 || idx >= VEX_GUEST_X86_GDT_NENT)
-      return -VKI_EINVAL;
-
-   gdt = (VexGuestX86SegDescr*)VG_(threads)[tid].arch.vex.guest_GDT;
-
-   /* If the thread doesn't have a GDT, allocate it now. */
-   if (!gdt) {
-      gdt = alloc_zeroed_GDT();
-      VG_(threads)[tid].arch.vex.guest_GDT = (HWord)gdt;
-   }
-
-   info->base_addr = ( gdt[idx].LdtEnt.Bits.BaseHi << 24 ) |
-                     ( gdt[idx].LdtEnt.Bits.BaseMid << 16 ) |
-                     gdt[idx].LdtEnt.Bits.BaseLow;
-   info->limit = ( gdt[idx].LdtEnt.Bits.LimitHi << 16 ) |
-                   gdt[idx].LdtEnt.Bits.LimitLow;
-   info->seg_32bit = gdt[idx].LdtEnt.Bits.Default_Big;
-   info->contents = ( gdt[idx].LdtEnt.Bits.Type >> 2 ) & 0x3;
-   info->read_exec_only = ( gdt[idx].LdtEnt.Bits.Type & 0x1 ) ^ 0x1;
-   info->limit_in_pages = gdt[idx].LdtEnt.Bits.Granularity;
-   info->seg_not_present = gdt[idx].LdtEnt.Bits.Pres ^ 0x1;
-   info->useable = gdt[idx].LdtEnt.Bits.Sys;
-   info->reserved = 0;
-
-   return 0;
-}
-
-
 /*------------------------------------------------------------*/
 /*--- Thread stuff                                         ---*/
 /*------------------------------------------------------------*/
@@ -456,7 +193,7 @@ void VGA_(setup_child) ( /*OUT*/ ThreadArchState *child,
       child->vex.guest_LDT = (HWord)NULL;
    } else {
       /* No luck .. we have to take a copy of the parent's. */
-      child->vex.guest_LDT = (HWord)alloc_zeroed_LDT();
+      child->vex.guest_LDT = (HWord)VG_(alloc_zeroed_x86_LDT)();
       copy_LDT_from_to( (VexGuestX86SegDescr*)parent->vex.guest_LDT, 
                         (VexGuestX86SegDescr*)child->vex.guest_LDT );
    }
index c0846b7822359574a6046343d5be0f909d6f8c95..7197f1f8dc782e9ac8353b3dff70bf01f40a9d7a 100644 (file)
 
 /* Is this a SSE/SSE2-capable CPU?  If so, we had better save/restore
    the SSE state all over the place.  This is set up very early, since we
-   can't even correctly snapshot the startup machine state without it. */
+   can't even correctly snapshot the startup machine state without it. 
+*/
 extern Bool VG_(have_ssestate);
 
-/* ---------------------------------------------------------------------
-   Exports of vg_ldt.c
-   ------------------------------------------------------------------ */
-
-/* Alloc & copy, and dealloc. */
-extern VexGuestX86SegDescr* 
-       VG_(allocate_LDT_for_thread)   ( VexGuestX86SegDescr* parent_ldt );
-extern void
-       VG_(deallocate_LDT_for_thread) ( VexGuestX86SegDescr* ldt );
-extern void
-       VG_(clear_TLS_for_thread)      ( VexGuestX86SegDescr* tls );
+/* Create LDT/GDT arrays, as specified in libvex_guest_x86.h. */
+extern VexGuestX86SegDescr* VG_(alloc_zeroed_x86_GDT) ( void );
+extern VexGuestX86SegDescr* VG_(alloc_zeroed_x86_LDT) ( void );
 
 
 #endif   // __X86_PRIVATE_H