First half of the long-overdue support for segment override prefixes,
LDTs and __NR_modify_ldt.

- Each thread has its own LDT.  Usually NULL, but if we need to
  change an entry, it is allocated.  LDTs are inherited from parents
  as one would expect.

- We intercept __NR_modify_ldt and update the calling thread's LDT
  accordingly.  This is done in coregrind/vg_ldt.c.  The kernel
  never sees these syscalls.

- New architectural state for %cs, %ss, %ds, %es, %fs and %gs.
  Probably overkill including %cs and %ss.  These are saved and
  restored in the usual way, _except_ at syscalls -- there's no
  point, since we are hiding all LDT operations from the kernel now.
  This does assume that no syscall implicitly looks at the
  segment registers, but I think that's safe.

Still only halfway there.  JITter is still unaware of seg regs
and override prefixes.


git-svn-id: svn://svn.valgrind.org/valgrind/trunk@1133 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/coregrind/vg_startup.S b/coregrind/vg_startup.S
index d6c202e..ae6bf94 100644
--- a/coregrind/vg_startup.S
+++ b/coregrind/vg_startup.S
@@ -85,21 +85,27 @@
 	# have not yet been set up.  Instead, they are copied to a
 	# temporary place (m_state_static).  In vg_main.c, once the
 	# baseBlock offsets are set up, values are copied into baseBlock.
-	movl	%eax, VG_(m_state_static)+0
-	movl	%ecx, VG_(m_state_static)+4
-	movl	%edx, VG_(m_state_static)+8
-	movl	%ebx, VG_(m_state_static)+12
-	movl	%esp, VG_(m_state_static)+16
-	movl	%ebp, VG_(m_state_static)+20
-	movl	%esi, VG_(m_state_static)+24
-	movl	%edi, VG_(m_state_static)+28
+	movw	%cs, VG_(m_state_static)+0
+	movw	%ss, VG_(m_state_static)+4
+	movw	%ds, VG_(m_state_static)+8
+	movw	%es, VG_(m_state_static)+12
+	movw	%fs, VG_(m_state_static)+16
+	movw	%gs, VG_(m_state_static)+20
+	movl	%eax, VG_(m_state_static)+24
+	movl	%ecx, VG_(m_state_static)+28
+	movl	%edx, VG_(m_state_static)+32
+	movl	%ebx, VG_(m_state_static)+36
+	movl	%esp, VG_(m_state_static)+40
+	movl	%ebp, VG_(m_state_static)+44
+	movl	%esi, VG_(m_state_static)+48
+	movl	%edi, VG_(m_state_static)+52
 	pushfl
 	popl	%eax
-	movl	%eax, VG_(m_state_static)+32
+	movl	%eax, VG_(m_state_static)+56
 	fwait
-	fnsave	VG_(m_state_static)+40
-	frstor	VG_(m_state_static)+40
-
+	fnsave	VG_(m_state_static)+64
+	frstor	VG_(m_state_static)+64
+	
 	# keep the first and last 10 words free to check for overruns	
 	movl	$VG_(stack)+39996 -40, %esp
 
@@ -108,7 +114,7 @@
 	# simulator.  So vg_main starts the simulator running at
 	# the insn labelled first_insn_to_simulate.
 
-	movl	$first_insn_to_simulate, VG_(m_state_static)+36
+	movl	$first_insn_to_simulate, VG_(m_state_static)+60
 	jmp	VG_(main)
 first_insn_to_simulate:
 	# Nothing else to do -- just return in the "normal" way.
@@ -136,18 +142,24 @@
 	# of the rest of the program continues on the real CPU,
 	# and there is no way for the simulator to regain control
 	# after this point.
-	frstor	VG_(m_state_static)+40
-	movl	VG_(m_state_static)+32, %eax
+	frstor	VG_(m_state_static)+64
+	movl	VG_(m_state_static)+56, %eax
 	pushl	%eax
 	popfl
-	movl	VG_(m_state_static)+0, %eax
-	movl	VG_(m_state_static)+4, %ecx
-	movl	VG_(m_state_static)+8, %edx
-	movl	VG_(m_state_static)+12, %ebx
-	movl	VG_(m_state_static)+16, %esp
-	movl	VG_(m_state_static)+20, %ebp
-	movl	VG_(m_state_static)+24, %esi
-	movl	VG_(m_state_static)+28, %edi
+	movw	VG_(m_state_static)+0, %cs
+	movw	VG_(m_state_static)+4, %ss
+	movw	VG_(m_state_static)+8, %ds
+	movw	VG_(m_state_static)+12, %es
+	movw	VG_(m_state_static)+16, %fs
+	movw	VG_(m_state_static)+20, %gs
+	movl	VG_(m_state_static)+24, %eax
+	movl	VG_(m_state_static)+28, %ecx
+	movl	VG_(m_state_static)+32, %edx
+	movl	VG_(m_state_static)+36, %ebx
+	movl	VG_(m_state_static)+40, %esp
+	movl	VG_(m_state_static)+44, %ebp
+	movl	VG_(m_state_static)+48, %esi
+	movl	VG_(m_state_static)+52, %edi
 
 	pushal
 	pushfl
@@ -157,8 +169,8 @@
 	popfl
 	popal
 	# re-restore the FPU state anyway ...
-	frstor	VG_(m_state_static)+40	
-	jmp	*VG_(m_state_static)+36
+	frstor	VG_(m_state_static)+64
+	jmp	*VG_(m_state_static)+60