volatile UInt sz_vex = (UInt) sizeof VG_(threads)[tid].arch.vex;
volatile UInt sz_vexsh = (UInt) sizeof VG_(threads)[tid].arch.vex_shadow;
volatile UInt sz_spill = (UInt) sizeof VG_(threads)[tid].arch.vex_spill;
+ /* volatile UInt zz = VG_(threads)[tid].arch.vex.guest_EIP; */
/* Paranoia */
vg_assert(VG_(is_valid_tid)(tid));
vg_assert(!scheduler_jmpbuf_valid);
+ if (trc == VG_TRC_INVARIANT_FAILED) {
+ /* To see the bb causing this to fail, set VG_SCHEDULING_QUANTUM to 1,
+ and make zz be the program counter at entry to this fn. */
+ /* VG_(translate)(tid,zz,True); */
+ VG_(core_panic)
+ ("host invariant state failure in VEX-generated code");
+ }
+
done_this_time = (Int)dispatch_ctr_SAVED - (Int)VG_(dispatch_ctr) - 0;
vg_assert(done_this_time >= 0);
movl (%ebp, %esi, 1), %eax
/* set host FPU control word to the default mode expected
- by VEX-generated code. */
+ by VEX-generated code. See comments in libvex.h for
+ more info. */
finit
- pushl $0x037F
+ pushl $0x027F
fldcw (%esp)
addl $4, %esp
jmp dispatch_exceptional
-fast_lookup_failed:
- /* %EIP is up to date here since dispatch_boring dominates */
- addl $1, VG_(dispatch_ctr)
- movl $VG_TRC_INNER_FASTMISS, %eax
- jmp run_innerloop_exit
-counter_is_zero:
- /* %EIP is up to date here since dispatch_boring dominates */
- addl $1, VG_(dispatch_ctr)
- movl $VG_TRC_INNER_COUNTERZERO, %eax
- jmp run_innerloop_exit
-
-run_innerloop_exit:
+/* All exits from the dispatcher go through here. %eax holds
+ the return value.
+*/
+run_innerloop_exit:
+ /* We're leaving. Check that nobody messed with
+ %mxcsr or %fpucw. We can't mess with %eax here as it
+ holds the tentative return value, but any other is OK. */
+ pushl $0
+ fstcw (%esp)
+ cmpl $0x027F, (%esp)
+ popl %esi /* get rid of the word without trashing %eflags */
+ jnz invariant_violation
+ pushl $0
+ stmxcsr (%esp)
+ andl $0xFFFFFFC0, (%esp) /* mask out status flags */
+ cmpl $0x1F80, (%esp)
+ popl %esi
+ jnz invariant_violation
+ /* otherwise we're OK */
+ jmp run_innerloop_exit_REALLY
+
+invariant_violation:
+ movl $VG_TRC_INVARIANT_FAILED, %eax
+ jmp run_innerloop_exit_REALLY
+
+run_innerloop_exit_REALLY:
popl %ebp
popl %edi
popl %esi
movl %ebp, %eax
jmp run_innerloop_exit
+fast_lookup_failed:
+ /* %EIP is up to date here since dispatch_boring dominates */
+ addl $1, VG_(dispatch_ctr)
+ movl $VG_TRC_INNER_FASTMISS, %eax
+ jmp run_innerloop_exit
+
+counter_is_zero:
+ /* %EIP is up to date here since dispatch_boring dominates */
+ addl $1, VG_(dispatch_ctr)
+ movl $VG_TRC_INNER_COUNTERZERO, %eax
+ jmp run_innerloop_exit
+
/* Let the linker know we don't need an executable stack */
.section .note.GNU-stack,"",@progbits