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