p = (Addr)VG_(malloc_aligned)(VG_AR_CLIENT, align, size);
sc = VG_(malloc)(VG_AR_PRIVATE, sizeof(ShadowChunk));
- sc->where = VG_(get_ExeContext)(False, tst->m_eip, tst->m_ebp);
+ sc->where = VG_(get_ExeContext)(False, tst->vex.guest_EIP,
+ tst->vex.guest_EBP);
sc->size = size;
sc->allockind = kind;
sc->data = p;
VGM_(make_noaccess) ( sc->data - VG_AR_CLIENT_REDZONE_SZB,
sc->size + 2*VG_AR_CLIENT_REDZONE_SZB );
VGM_(make_noaccess) ( (Addr)sc, sizeof(ShadowChunk) );
- sc->where = VG_(get_ExeContext)(False, tst->m_eip, tst->m_ebp);
+ sc->where = VG_(get_ExeContext)(False, tst->vex.guest_EIP,
+ tst->vex.guest_EBP);
/* Put it out of harm's way for a while. */
add_to_freed_queue ( sc );
else
p = (Addr)VG_(malloc_aligned)(VG_AR_CLIENT, VG_(clo_alignment), size);
sc = VG_(malloc)(VG_AR_PRIVATE, sizeof(ShadowChunk));
- sc->where = VG_(get_ExeContext)(False, tst->m_eip, tst->m_ebp);
+ sc->where = VG_(get_ExeContext)(False, tst->vex.guest_EIP,
+ tst->vex.guest_EBP);
sc->size = size;
sc->allockind = Vg_AllocMalloc; /* its a lie - but true. eat this :) */
sc->data = p;
vg_csbs[vg_csb_used].size = sz;
/* Actually running a thread at this point. */
vg_csbs[vg_csb_used].where
- = VG_(get_ExeContext) ( False, tst->m_eip, tst->m_ebp );
+ = VG_(get_ExeContext) ( False, tst->vex.guest_EIP, tst->vex.guest_EBP );
vg_csb_used++;
if (vg_csb_used > vg_csb_used_MAX)
void VG_(delete_client_stack_blocks_following_ESP_change) ( void )
{
Addr newESP;
- newESP = VG_(baseBlock)[VGOFF_(m_esp)];
+ newESP
+ = ((VexGuestX86State*)(&VG_(baseBlock)[VGOFF_(m_vex)]))->guest_ESP;
while (vg_csb_used > 0
&& vg_csbs[vg_csb_used-1].start + vg_csbs[vg_csb_used-1].size
<= newESP) {
vg_cgbs[i].start = arg[1];
vg_cgbs[i].size = arg[2];
vg_cgbs[i].where
- = VG_(get_ExeContext) ( False, tst->m_eip, tst->m_ebp );
+ = VG_(get_ExeContext) ( False, tst->vex.guest_EIP, tst->vex.guest_EBP );
VGM_(make_noaccess) ( arg[1], arg[2] );
return i;
case VG_USERREQ__MAKE_WRITABLE: /* make writable */
vg_cgbs[i].start = arg[1];
vg_cgbs[i].size = arg[2];
vg_cgbs[i].where
- = VG_(get_ExeContext) ( False, tst->m_eip, tst->m_ebp );
+ = VG_(get_ExeContext) ( False, tst->vex.guest_EIP, tst->vex.guest_EBP );
VGM_(make_writable) ( arg[1], arg[2] );
return i;
case VG_USERREQ__MAKE_READABLE: /* make readable */
vg_cgbs[i].start = arg[1];
vg_cgbs[i].size = arg[2];
vg_cgbs[i].where
- = VG_(get_ExeContext) ( False, tst->m_eip, tst->m_ebp );
+ = VG_(get_ExeContext) ( False, tst->vex.guest_EIP, tst->vex.guest_EBP );
VGM_(make_readable) ( arg[1], arg[2] );
return i;
/* The C world needs a way to get started simulating. So we provide
a function void vg_run_innerloop ( void ), which starts running
- from vg_m_eip, and exits when the counter reaches zero. This loop
+ from vg_m_eipS, and exits when the counter reaches zero. This loop
can also exit if vg_oursignalhandler() catches a non-resumable
signal, for example SIGSEGV. It then longjmp()s back past here.
*/
# Set up the baseBlock pointer
movl $VG_(baseBlock), %ebp
- # fetch m_eip into %eax
- movl VGOFF_(m_eip), %esi
+ # fetch m_eipS into %eax
+ movl VGOFF_(m_eipS), %esi
movl (%ebp, %esi, 4), %eax
# Start off dispatching paranoically, since we no longer have
jnz dispatch_exceptional
dispatch_boring:
- # save the jump address at VG_(baseBlock)[VGOFF_(m_eip)],
- movl VGOFF_(m_eip), %esi
+ # save the jump address at VG_(baseBlock)[VGOFF_(m_eipS)],
+ movl VGOFF_(m_eipS), %esi
movl %eax, (%ebp, %esi, 4)
# do a timeslice check.
dispatch_syscall:
# save %eax in %EIP and defer to sched
movl $VG_(baseBlock), %ebp
- movl VGOFF_(m_eip), %esi
+ movl VGOFF_(m_eipS), %esi
movl %eax, (%ebp, %esi, 4)
movl $VG_TRC_EBP_JMP_SYSCALL, %eax
jmp run_innerloop_exit
dispatch_clientreq:
# save %eax in %EIP and defer to sched
movl $VG_(baseBlock), %ebp
- movl VGOFF_(m_eip), %esi
+ movl VGOFF_(m_eipS), %esi
movl %eax, (%ebp, %esi, 4)
movl $VG_TRC_EBP_JMP_CLIENTREQ, %eax
jmp run_innerloop_exit
dispatch_stkadj:
# save %eax in %EIP
movl $VG_(baseBlock), %ebp
- movl VGOFF_(m_eip), %esi
+ movl VGOFF_(m_eipS), %esi
movl %eax, (%ebp, %esi, 4)
# see if we need to mess with stack blocks
clear_ErrContext( &ec );
ec.count = 1;
ec.next = NULL;
- ec.where = VG_(get_ExeContext)( False, VG_(baseBlock)[VGOFF_(m_eip)],
- VG_(baseBlock)[VGOFF_(m_ebp)] );
+ ec.where
+ = VG_(get_ExeContext)( False,
+ ((VexGuestX86State*)(&VG_(baseBlock)[VGOFF_(m_vex)]))->guest_EIP,
+ ((VexGuestX86State*)(&VG_(baseBlock)[VGOFF_(m_vex)]))->guest_EBP );
ec.ekind = ValueErr;
ec.size = size;
ec.tid = VG_(get_current_tid)();
- ec.m_eip = VG_(baseBlock)[VGOFF_(m_eip)];
- ec.m_esp = VG_(baseBlock)[VGOFF_(m_esp)];
- ec.m_ebp = VG_(baseBlock)[VGOFF_(m_ebp)];
+ ec.m_eip = ((VexGuestX86State*)(&VG_(baseBlock)[VGOFF_(m_vex)]))->guest_EIP;
+ ec.m_esp = ((VexGuestX86State*)(&VG_(baseBlock)[VGOFF_(m_vex)]))->guest_ESP;
+ ec.m_ebp = ((VexGuestX86State*)(&VG_(baseBlock)[VGOFF_(m_vex)]))->guest_EBP;
VG_(maybe_add_context) ( &ec );
}
if (vg_ignore_errors) return;
just_below_esp
- = VG_(is_just_below_ESP)( VG_(baseBlock)[VGOFF_(m_esp)], a );
+ = VG_(is_just_below_ESP)( ((VexGuestX86State*)(&VG_(baseBlock)[VGOFF_(m_vex)]))->guest_ESP, a );
/* If this is caused by an access immediately below %ESP, and the
user asks nicely, we just ignore it. */
clear_ErrContext( &ec );
ec.count = 1;
ec.next = NULL;
- ec.where = VG_(get_ExeContext)( False, VG_(baseBlock)[VGOFF_(m_eip)],
- VG_(baseBlock)[VGOFF_(m_ebp)] );
+ ec.where
+ = VG_(get_ExeContext)( False,
+ ((VexGuestX86State*)(&VG_(baseBlock)[VGOFF_(m_vex)]))->guest_EIP,
+ ((VexGuestX86State*)(&VG_(baseBlock)[VGOFF_(m_vex)]))->guest_EBP );
ec.ekind = AddrErr;
ec.axskind = isWrite ? WriteAxs : ReadAxs;
ec.size = size;
ec.addr = a;
ec.tid = VG_(get_current_tid)();
- ec.m_eip = VG_(baseBlock)[VGOFF_(m_eip)];
- ec.m_esp = VG_(baseBlock)[VGOFF_(m_esp)];
- ec.m_ebp = VG_(baseBlock)[VGOFF_(m_ebp)];
+ ec.m_eip = ((VexGuestX86State*)(&VG_(baseBlock)[VGOFF_(m_vex)]))->guest_EIP;
+ ec.m_esp = ((VexGuestX86State*)(&VG_(baseBlock)[VGOFF_(m_vex)]))->guest_ESP;
+ ec.m_ebp = ((VexGuestX86State*)(&VG_(baseBlock)[VGOFF_(m_vex)]))->guest_EBP;
ec.addrinfo.akind = Undescribed;
ec.addrinfo.maybe_gcc = just_below_esp;
VG_(maybe_add_context) ( &ec );
clear_ErrContext( &ec );
ec.count = 1;
ec.next = NULL;
- ec.where = VG_(get_ExeContext)( False, tst->m_eip, tst->m_ebp );
+ ec.where = VG_(get_ExeContext)( False, tst->vex.guest_EIP, tst->vex.guest_EBP );
ec.ekind = FreeErr;
ec.addr = a;
ec.tid = tst->tid;
- ec.m_eip = tst->m_eip;
- ec.m_esp = tst->m_esp;
- ec.m_ebp = tst->m_ebp;
+ ec.m_eip = tst->vex.guest_EIP;
+ ec.m_esp = tst->vex.guest_ESP;
+ ec.m_ebp = tst->vex.guest_EBP;
ec.addrinfo.akind = Undescribed;
VG_(maybe_add_context) ( &ec );
}
clear_ErrContext( &ec );
ec.count = 1;
ec.next = NULL;
- ec.where = VG_(get_ExeContext)( False, tst->m_eip, tst->m_ebp );
+ ec.where = VG_(get_ExeContext)( False, tst->vex.guest_EIP, tst->vex.guest_EBP );
ec.ekind = FreeMismatchErr;
ec.addr = a;
ec.tid = tst->tid;
- ec.m_eip = tst->m_eip;
- ec.m_esp = tst->m_esp;
- ec.m_ebp = tst->m_ebp;
+ ec.m_eip = tst->vex.guest_EIP;
+ ec.m_esp = tst->vex.guest_ESP;
+ ec.m_ebp = tst->vex.guest_EBP;
ec.addrinfo.akind = Undescribed;
VG_(maybe_add_context) ( &ec );
}
clear_ErrContext( &ec );
ec.count = 1;
ec.next = NULL;
- ec.where = VG_(get_ExeContext)( False, tst->m_eip, tst->m_ebp );
+ ec.where = VG_(get_ExeContext)( False, tst->vex.guest_EIP, tst->vex.guest_EBP );
ec.ekind = AddrErr;
ec.axskind = ExecAxs;
ec.addr = a;
ec.tid = tst->tid;
- ec.m_eip = tst->m_eip;
- ec.m_esp = tst->m_esp;
- ec.m_ebp = tst->m_ebp;
+ ec.m_eip = tst->vex.guest_EIP;
+ ec.m_esp = tst->vex.guest_ESP;
+ ec.m_ebp = tst->vex.guest_EBP;
ec.addrinfo.akind = Undescribed;
VG_(maybe_add_context) ( &ec );
}
clear_ErrContext( &ec );
ec.count = 1;
ec.next = NULL;
- ec.where = VG_(get_ExeContext)( False, tst->m_eip, tst->m_ebp );
+ ec.where = VG_(get_ExeContext)( False, tst->vex.guest_EIP, tst->vex.guest_EBP );
ec.ekind = ParamErr;
ec.addr = a;
ec.tid = tst->tid;
- ec.m_eip = tst->m_eip;
- ec.m_esp = tst->m_esp;
- ec.m_ebp = tst->m_ebp;
+ ec.m_eip = tst->vex.guest_EIP;
+ ec.m_esp = tst->vex.guest_ESP;
+ ec.m_ebp = tst->vex.guest_EBP;
ec.addrinfo.akind = Undescribed;
ec.syscall_param = msg;
ec.isWriteableLack = isWriteLack;
clear_ErrContext( &ec );
ec.count = 1;
ec.next = NULL;
- ec.where = VG_(get_ExeContext)( False, tst->m_eip, tst->m_ebp );
+ ec.where = VG_(get_ExeContext)( False, tst->vex.guest_EIP, tst->vex.guest_EBP );
ec.ekind = UserErr;
ec.addr = a;
ec.tid = tst->tid;
- ec.m_eip = tst->m_eip;
- ec.m_esp = tst->m_esp;
- ec.m_ebp = tst->m_ebp;
+ ec.m_eip = tst->vex.guest_EIP;
+ ec.m_esp = tst->vex.guest_ESP;
+ ec.m_ebp = tst->vex.guest_EBP;
ec.addrinfo.akind = Undescribed;
ec.isWriteableLack = isWriteLack;
VG_(maybe_add_context) ( &ec );
clear_ErrContext( &ec );
ec.count = 1;
ec.next = NULL;
- ec.where = VG_(get_ExeContext)( False, VG_(threads)[tid].m_eip,
- VG_(threads)[tid].m_ebp );
+ ec.where = VG_(get_ExeContext)( False, VG_(threads)[tid].vex.guest_EIP,
+ VG_(threads)[tid].vex.guest_EBP );
ec.ekind = PThreadErr;
ec.tid = tid;
ec.syscall_param = msg;
- ec.m_eip = VG_(threads)[tid].m_eip;
- ec.m_esp = VG_(threads)[tid].m_esp;
- ec.m_ebp = VG_(threads)[tid].m_ebp;
+ ec.m_eip = VG_(threads)[tid].vex.guest_EIP;
+ ec.m_esp = VG_(threads)[tid].vex.guest_ESP;
+ ec.m_ebp = VG_(threads)[tid].vex.guest_EBP;
VG_(maybe_add_context) ( &ec );
}
VG_(printf)( "\n\t\tcall * %d(%%ebp)\n", byte_off );
}
-
+#if 0
static void emit_addlit8_offregmem ( Int lit8, Int regmem, Int off )
{
vg_assert(lit8 >= -128 && lit8 < 128);
VG_(printf)( "\n\t\taddl $%d, %d(%s)\n", lit8, off,
nameIReg(4,regmem));
}
-
+#endif
static void emit_add_lit_to_esp ( Int lit )
{
vg_assert(value >= 0 && value < VG_MAX_SPILLSLOTS);
return 4 * (value + VGOFF_(spillslots));
}
+#if 0
if (tag == ArchReg) {
switch (value) {
case R_EAX: return 4 * VGOFF_(m_eax);
else return 4 * VGOFF_(m_edi);
}
}
+#endif
VG_(panic)("spillOrArchOffset");
}
case INCEIP: {
vg_assert(u->tag1 == Lit16);
- emit_addlit8_offregmem ( u->val1, R_EBP, 4 * VGOFF_(m_eip) );
+ //emit_addlit8_offregmem ( u->val1, R_EBP, 4 * VGOFF_(m_eip) );
break;
}
#include <stdarg.h> /* ANSI varargs stuff */
#include <setjmp.h> /* for jmp_buf */
+#include "../pub/libvex_guest_x86.h"
+
/* ---------------------------------------------------------------------
Where to send bug reports to.
Addr stack_highest_word;
/* Saved machine context. */
- UInt m_eax;
- UInt m_ebx;
- UInt m_ecx;
- UInt m_edx;
- UInt m_esi;
- UInt m_edi;
- UInt m_ebp;
- UInt m_esp;
-
- UInt m_cc_op;
- UInt m_cc_src;
- UInt m_cc_dst;
- UInt m_cc_dflag;
-
- UInt m_eip;
-
- ULong m_f0, m_f1, m_f2, m_f3, m_f4, m_f5, m_f6, m_f7;
- UInt m_ftop;
- UInt m_fpucw;
- UInt m_ftag74;
- UInt m_ftag30;
- UInt m_fc3210;
+ VexGuestX86State vex;
UInt sh_eax;
UInt sh_ebx;
/* Write a value to the client's %EDX (request return value register)
and set the shadow to indicate it is defined. */
-#define SET_EDX(zztid, zzval) \
- do { VG_(threads)[zztid].m_edx = (zzval); \
+#define SET_EDX(zztid, zzval) \
+ do { VG_(threads)[zztid].vex.guest_EDX = (zzval); \
VG_(threads)[zztid].sh_edx = VGM_WORD_VALID; \
} while (0)
-#define SET_EAX(zztid, zzval) \
- do { VG_(threads)[zztid].m_eax = (zzval); \
+#define SET_EAX(zztid, zzval) \
+ do { VG_(threads)[zztid].vex.guest_EAX = (zzval); \
VG_(threads)[zztid].sh_eax = VGM_WORD_VALID; \
} while (0)
VG_(copy_m_state_static_to_baseBlock)(); \
VG_(save_thread_state)(thread_id); \
VG_(threads)[thread_id].sh_eax = VGM_WORD_VALID; \
- result_lvalue = VG_(threads)[thread_id].m_eax;
+ result_lvalue = VG_(threads)[thread_id].vex.guest_EAX;
/* ---------------------------------------------------------------------
-------------------------------------------------- */
/* State of the simulated CPU. */
-extern Int VGOFF_(m_eax);
-extern Int VGOFF_(m_ecx);
-extern Int VGOFF_(m_edx);
-extern Int VGOFF_(m_ebx);
-extern Int VGOFF_(m_esp);
-extern Int VGOFF_(m_ebp);
-extern Int VGOFF_(m_esi);
-extern Int VGOFF_(m_edi);
-
-extern Int VGOFF_(m_cc_op);
-extern Int VGOFF_(m_cc_src);
-extern Int VGOFF_(m_cc_dst);
-extern Int VGOFF_(m_cc_dflag);
-
-extern Int VGOFF_(m_eip);
-
-extern Int VGOFF_(m_ftop);
-extern Int VGOFF_(m_f0);
-extern Int VGOFF_(m_f1);
-extern Int VGOFF_(m_f2);
-extern Int VGOFF_(m_f3);
-extern Int VGOFF_(m_f4);
-extern Int VGOFF_(m_f5);
-extern Int VGOFF_(m_f6);
-extern Int VGOFF_(m_f7);
-extern Int VGOFF_(m_ftag0);
-extern Int VGOFF_(m_fpucw);
-extern Int VGOFF_(m_fc3210);
+extern Int VGOFF_(m_vex);
+extern Int VGOFF_(m_eipS);
/* Reg-alloc spill area (VG_MAX_SPILLSLOTS words long). */
extern Int VGOFF_(spillslots);
#define INVALID_OFFSET (-1)
-Int VGOFF_(m_eax) = INVALID_OFFSET;
-Int VGOFF_(m_ecx) = INVALID_OFFSET;
-Int VGOFF_(m_edx) = INVALID_OFFSET;
-Int VGOFF_(m_ebx) = INVALID_OFFSET;
-Int VGOFF_(m_esp) = INVALID_OFFSET;
-Int VGOFF_(m_ebp) = INVALID_OFFSET;
-Int VGOFF_(m_esi) = INVALID_OFFSET;
-Int VGOFF_(m_edi) = INVALID_OFFSET;
-
-Int VGOFF_(m_cc_op) = INVALID_OFFSET;
-Int VGOFF_(m_cc_src) = INVALID_OFFSET;
-Int VGOFF_(m_cc_dst) = INVALID_OFFSET;
-Int VGOFF_(m_cc_dflag) = INVALID_OFFSET;
-
-Int VGOFF_(m_eip) = INVALID_OFFSET;
-
-Int VGOFF_(m_ftop) = INVALID_OFFSET;
-Int VGOFF_(m_f0) = INVALID_OFFSET;
-Int VGOFF_(m_f1) = INVALID_OFFSET;
-Int VGOFF_(m_f2) = INVALID_OFFSET;
-Int VGOFF_(m_f3) = INVALID_OFFSET;
-Int VGOFF_(m_f4) = INVALID_OFFSET;
-Int VGOFF_(m_f5) = INVALID_OFFSET;
-Int VGOFF_(m_f6) = INVALID_OFFSET;
-Int VGOFF_(m_f7) = INVALID_OFFSET;
-Int VGOFF_(m_ftag0) = INVALID_OFFSET;
-Int VGOFF_(m_fpucw) = INVALID_OFFSET;
-Int VGOFF_(m_fc3210) = INVALID_OFFSET;
+Int VGOFF_(m_vex) = INVALID_OFFSET;
+Int VGOFF_(m_eipS) = INVALID_OFFSET;
Int VGOFF_(spillslots) = INVALID_OFFSET;
Int VGOFF_(sh_eax) = INVALID_OFFSET;
/* Those with offsets under 128 are carefully chosen. */
+#define offsetof(type,memb) ((Int)&((type*)0)->memb)
+
/* WORD offsets in this column */
- /* 0 */ VGOFF_(m_eax) = alloc_BaB(1);
- /* 1 */ VGOFF_(m_ecx) = alloc_BaB(1);
- /* 2 */ VGOFF_(m_edx) = alloc_BaB(1);
- /* 3 */ VGOFF_(m_ebx) = alloc_BaB(1);
- /* 4 */ VGOFF_(m_esp) = alloc_BaB(1);
- /* 5 */ VGOFF_(m_ebp) = alloc_BaB(1);
- /* 6 */ VGOFF_(m_esi) = alloc_BaB(1);
- /* 7 */ VGOFF_(m_edi) = alloc_BaB(1);
-
- /* 8 */ VGOFF_(m_cc_op) = alloc_BaB(1);
- /* 9 */ VGOFF_(m_cc_src) = alloc_BaB(1);
- /* 10 */ VGOFF_(m_cc_dst) = alloc_BaB(1);
- /* 11 */ VGOFF_(m_cc_dflag) = alloc_BaB(1);
-
- /* 12 */ VGOFF_(m_eip) = alloc_BaB(1);
-
- /* 13 */ VGOFF_(m_ftop) = alloc_BaB(1);
- /* 14 */ VGOFF_(m_f0) = alloc_BaB(2);
- /* 16 */ VGOFF_(m_f1) = alloc_BaB(2);
- /* 18 */ VGOFF_(m_f2) = alloc_BaB(2);
- /* 20 */ VGOFF_(m_f3) = alloc_BaB(2);
- /* 22 */ VGOFF_(m_f4) = alloc_BaB(2);
- /* 24 */ VGOFF_(m_f5) = alloc_BaB(2);
- /* 26 */ VGOFF_(m_f6) = alloc_BaB(2);
- /* 28 */ VGOFF_(m_f7) = alloc_BaB(2);
- /* 30 */ VGOFF_(m_ftag0) = alloc_BaB(2);
- /* 32 */ VGOFF_(m_fpucw) = alloc_BaB(1);
- /* 33 */ VGOFF_(m_fc3210) = alloc_BaB(1);
+ VGOFF_(m_vex) = alloc_BaB( (3 + sizeof(VexGuestX86State)) / 4 );
+ VGOFF_(m_eipS) = VGOFF_(m_vex) + offsetof(VexGuestX86State,guest_EIP)/4;
+
+#undef offsetof
/* 34 */ VGOFF_(sh_eax) = alloc_BaB(1);
/* 35 */ VGOFF_(sh_ecx) = alloc_BaB(1);
void VG_(copy_baseBlock_to_m_state_static) ( void )
{
- VG_(m_state_static)[ 0/4] = VG_(baseBlock)[VGOFF_(m_eax)];
- VG_(m_state_static)[ 4/4] = VG_(baseBlock)[VGOFF_(m_ecx)];
- VG_(m_state_static)[ 8/4] = VG_(baseBlock)[VGOFF_(m_edx)];
- VG_(m_state_static)[12/4] = VG_(baseBlock)[VGOFF_(m_ebx)];
- VG_(m_state_static)[16/4] = VG_(baseBlock)[VGOFF_(m_esp)];
- VG_(m_state_static)[20/4] = VG_(baseBlock)[VGOFF_(m_ebp)];
- VG_(m_state_static)[24/4] = VG_(baseBlock)[VGOFF_(m_esi)];
- VG_(m_state_static)[28/4] = VG_(baseBlock)[VGOFF_(m_edi)];
-
- { extern UInt calculate_eflags_all(UInt,UInt,UInt);
- UInt eflags = calculate_eflags_all(
- VG_(baseBlock)[VGOFF_(m_cc_op)],
- VG_(baseBlock)[VGOFF_(m_cc_src)],
- VG_(baseBlock)[VGOFF_(m_cc_dst)]
- );
- UInt dflag = VG_(baseBlock)[VGOFF_(m_cc_dflag)];
- vg_assert(dflag == 1 || dflag == 0xFFFFFFFF);
- if (dflag == 0xFFFFFFFF)
- eflags |= (1<<10);
-
- VG_(m_state_static)[32/4] = eflags;
- }
-
- VG_(m_state_static)[36/4] = VG_(baseBlock)[VGOFF_(m_eip)];
-
- /* Copy FPU state */
- vex_to_x87( (UChar*)&VG_(baseBlock)[0],
- (UChar*)&VG_(m_state_static)[40/4] );
+ VexGuestX86State* vex
+ = (VexGuestX86State*)(&VG_(baseBlock)[VGOFF_(m_vex)]);
+ VG_(m_state_static)[ 0/4] = vex->guest_EAX;
+ VG_(m_state_static)[ 4/4] = vex->guest_ECX;
+ VG_(m_state_static)[ 8/4] = vex->guest_EDX;
+ VG_(m_state_static)[12/4] = vex->guest_EBX;
+ VG_(m_state_static)[16/4] = vex->guest_ESP;
+ VG_(m_state_static)[20/4] = vex->guest_EBP;
+ VG_(m_state_static)[24/4] = vex->guest_ESI;
+ VG_(m_state_static)[28/4] = vex->guest_EDI;
+ VG_(m_state_static)[32/4] = vex_to_eflags( vex );
+ VG_(m_state_static)[36/4] = vex->guest_EIP;
+ vex_to_x87( vex, (UChar*)&VG_(m_state_static)[40/4] );
}
void VG_(copy_m_state_static_to_baseBlock) ( void )
{
- VG_(baseBlock)[VGOFF_(m_eax)] = VG_(m_state_static)[ 0/4];
- VG_(baseBlock)[VGOFF_(m_ecx)] = VG_(m_state_static)[ 4/4];
- VG_(baseBlock)[VGOFF_(m_edx)] = VG_(m_state_static)[ 8/4];
- VG_(baseBlock)[VGOFF_(m_ebx)] = VG_(m_state_static)[12/4];
- VG_(baseBlock)[VGOFF_(m_esp)] = VG_(m_state_static)[16/4];
- VG_(baseBlock)[VGOFF_(m_ebp)] = VG_(m_state_static)[20/4];
- VG_(baseBlock)[VGOFF_(m_esi)] = VG_(m_state_static)[24/4];
- VG_(baseBlock)[VGOFF_(m_edi)] = VG_(m_state_static)[28/4];
-
- VG_(baseBlock)[VGOFF_(m_cc_op)] = 0; // CC_OP_COPY
- VG_(baseBlock)[VGOFF_(m_cc_src)] = VG_(m_state_static)[32/4];
- VG_(baseBlock)[VGOFF_(m_cc_dst)] = 0;
- VG_(baseBlock)[VGOFF_(m_cc_dflag)]
- = (VG_(m_state_static)[32/4] & (1<<10))
- ? 0xFFFFFFFF
- : 0x00000001;
- /* Mask out everything except O S Z A C P. */
- VG_(baseBlock)[VGOFF_(m_cc_src)]
- &= (0x0001 | 0x0004 | 0x0010 | 0x0040 | 0x0080 | 0x0800);
-
- VG_(baseBlock)[VGOFF_(m_eip)] = VG_(m_state_static)[36/4];
-
- /* Make the FPU register stack appear to be empty. */
- *(ULong*)(&VG_(baseBlock)[VGOFF_(m_f0)]) = 0;
- *(ULong*)(&VG_(baseBlock)[VGOFF_(m_f1)]) = 0;
- *(ULong*)(&VG_(baseBlock)[VGOFF_(m_f2)]) = 0;
- *(ULong*)(&VG_(baseBlock)[VGOFF_(m_f3)]) = 0;
- *(ULong*)(&VG_(baseBlock)[VGOFF_(m_f4)]) = 0;
- *(ULong*)(&VG_(baseBlock)[VGOFF_(m_f5)]) = 0;
- *(ULong*)(&VG_(baseBlock)[VGOFF_(m_f6)]) = 0;
- *(ULong*)(&VG_(baseBlock)[VGOFF_(m_f7)]) = 0;
-
- /* Copy FPU state. */
- x87_to_vex( (UChar*)&VG_(m_state_static)[40/4],
- (UChar*)&VG_(baseBlock)[0] );
+ VexGuestX86State* vex
+ = (VexGuestX86State*)(&VG_(baseBlock)[VGOFF_(m_vex)]);
+ vex->guest_EAX = VG_(m_state_static)[ 0/4];
+ vex->guest_ECX = VG_(m_state_static)[ 4/4];
+ vex->guest_EDX = VG_(m_state_static)[ 8/4];
+ vex->guest_EBX = VG_(m_state_static)[12/4];
+ vex->guest_ESP = VG_(m_state_static)[16/4];
+ vex->guest_EBP = VG_(m_state_static)[20/4];
+ vex->guest_ESI = VG_(m_state_static)[24/4];
+ vex->guest_EDI = VG_(m_state_static)[28/4];
+ eflags_to_vex( VG_(m_state_static)[32/4], vex );
+ vex->guest_EIP = VG_(m_state_static)[36/4];
+ x87_to_vex( (UChar*)&VG_(m_state_static)[40/4], vex );
}
void VGM_(handle_esp_assignment) ( Addr new_espA )
{
- UInt old_esp = VG_(baseBlock)[VGOFF_(m_esp)];
+ UInt old_esp = ((VexGuestX86State*)(&VG_(baseBlock)[VGOFF_(m_vex)]))->guest_ESP;
UInt new_esp = (UInt)new_espA;
Int delta = ((Int)new_esp) - ((Int)old_esp);
static void vg_handle_esp_assignment_SLOWLY ( Addr new_espA )
{
- UInt old_esp = VG_(baseBlock)[VGOFF_(m_esp)];
+ UInt old_esp = ((VexGuestX86State*)(&VG_(baseBlock)[VGOFF_(m_vex)]))->guest_ESP;
UInt new_esp = (UInt)new_espA;
Int delta = ((Int)new_esp) - ((Int)old_esp);
// VG_(printf)("%d ", delta);
start,start+size,rr,ww,xx,foffset,
size, filename?filename:(UChar*)"NULL");
- r_esp = VG_(baseBlock)[VGOFF_(m_esp)];
+ r_esp = ((VexGuestX86State*)(&VG_(baseBlock)[VGOFF_(m_vex)]))->guest_ESP;
is_stack_segment = start <= r_esp && r_esp < start+size;
/* Figure out the segment's permissions.
VG_(baseBlock). */
if (vg_tid_currently_in_baseBlock != VG_INVALID_THREADID) {
tid = vg_tid_currently_in_baseBlock;
- if (VG_(baseBlock)[VGOFF_(m_esp)] <= a
+ if ( ((VexGuestX86State*)(&VG_(baseBlock)[VGOFF_(m_vex)]))->guest_ESP <= a
&& a <= VG_(threads)[tid].stack_highest_word)
return tid;
else
for (tid = 1; tid < VG_N_THREADS; tid++) {
if (VG_(threads)[tid].status == VgTs_Empty) continue;
if (tid == tid_to_skip) continue;
- if (VG_(threads)[tid].m_esp <= a
+ if (VG_(threads)[tid].vex.guest_ESP <= a
&& a <= VG_(threads)[tid].stack_highest_word)
return tid;
}
VG_(threads)[i].associated_mx,
VG_(threads)[i].associated_cv );
VG_(pp_ExeContext)(
- VG_(get_ExeContext)( False, VG_(threads)[i].m_eip,
- VG_(threads)[i].m_ebp ));
+ VG_(get_ExeContext)( False, VG_(threads)[i].vex.guest_EIP,
+ VG_(threads)[i].vex.guest_EBP ));
}
VG_(printf)("\n");
}
{
vg_assert(vg_tid_currently_in_baseBlock == VG_INVALID_THREADID);
- VG_(baseBlock)[VGOFF_(m_eax)] = VG_(threads)[tid].m_eax;
- VG_(baseBlock)[VGOFF_(m_ebx)] = VG_(threads)[tid].m_ebx;
- VG_(baseBlock)[VGOFF_(m_ecx)] = VG_(threads)[tid].m_ecx;
- VG_(baseBlock)[VGOFF_(m_edx)] = VG_(threads)[tid].m_edx;
- VG_(baseBlock)[VGOFF_(m_esi)] = VG_(threads)[tid].m_esi;
- VG_(baseBlock)[VGOFF_(m_edi)] = VG_(threads)[tid].m_edi;
- VG_(baseBlock)[VGOFF_(m_ebp)] = VG_(threads)[tid].m_ebp;
- VG_(baseBlock)[VGOFF_(m_esp)] = VG_(threads)[tid].m_esp;
-
- VG_(baseBlock)[VGOFF_(m_cc_op)] = VG_(threads)[tid].m_cc_op;
- VG_(baseBlock)[VGOFF_(m_cc_src)] = VG_(threads)[tid].m_cc_src;
- VG_(baseBlock)[VGOFF_(m_cc_dst)] = VG_(threads)[tid].m_cc_dst;
- VG_(baseBlock)[VGOFF_(m_cc_dflag)] = VG_(threads)[tid].m_cc_dflag;
-
- VG_(baseBlock)[VGOFF_(m_eip)] = VG_(threads)[tid].m_eip;
-
- *(ULong*)(&VG_(baseBlock)[VGOFF_(m_f0)]) = VG_(threads)[tid].m_f0;
- *(ULong*)(&VG_(baseBlock)[VGOFF_(m_f1)]) = VG_(threads)[tid].m_f1;
- *(ULong*)(&VG_(baseBlock)[VGOFF_(m_f2)]) = VG_(threads)[tid].m_f2;
- *(ULong*)(&VG_(baseBlock)[VGOFF_(m_f3)]) = VG_(threads)[tid].m_f3;
- *(ULong*)(&VG_(baseBlock)[VGOFF_(m_f4)]) = VG_(threads)[tid].m_f4;
- *(ULong*)(&VG_(baseBlock)[VGOFF_(m_f5)]) = VG_(threads)[tid].m_f5;
- *(ULong*)(&VG_(baseBlock)[VGOFF_(m_f6)]) = VG_(threads)[tid].m_f6;
- *(ULong*)(&VG_(baseBlock)[VGOFF_(m_f7)]) = VG_(threads)[tid].m_f7;
- VG_(baseBlock)[VGOFF_(m_ftop)] = VG_(threads)[tid].m_ftop;
- VG_(baseBlock)[VGOFF_(m_fpucw)] = VG_(threads)[tid].m_fpucw;
- VG_(baseBlock)[VGOFF_(m_fc3210)] = VG_(threads)[tid].m_fc3210;
- VG_(baseBlock)[VGOFF_(m_ftag0)+0] = VG_(threads)[tid].m_ftag30;
- VG_(baseBlock)[VGOFF_(m_ftag0)+1] = VG_(threads)[tid].m_ftag74;
+ *(VexGuestX86State*)(&VG_(baseBlock)[VGOFF_(m_vex)])
+ = VG_(threads)[tid].vex;
VG_(baseBlock)[VGOFF_(sh_eax)] = VG_(threads)[tid].sh_eax;
VG_(baseBlock)[VGOFF_(sh_ebx)] = VG_(threads)[tid].sh_ebx;
__inline__
void VG_(save_thread_state) ( ThreadId tid )
{
- const UInt junk = 0xDEADBEEF;
- const ULong junk64 = 0xDEADBEEFDEADBEEFLL;
+ Int i;
+ const UInt junk = 0xDEADBEEF;
vg_assert(vg_tid_currently_in_baseBlock != VG_INVALID_THREADID);
-
- VG_(threads)[tid].m_eax = VG_(baseBlock)[VGOFF_(m_eax)];
- VG_(threads)[tid].m_ebx = VG_(baseBlock)[VGOFF_(m_ebx)];
- VG_(threads)[tid].m_ecx = VG_(baseBlock)[VGOFF_(m_ecx)];
- VG_(threads)[tid].m_edx = VG_(baseBlock)[VGOFF_(m_edx)];
- VG_(threads)[tid].m_esi = VG_(baseBlock)[VGOFF_(m_esi)];
- VG_(threads)[tid].m_edi = VG_(baseBlock)[VGOFF_(m_edi)];
- VG_(threads)[tid].m_ebp = VG_(baseBlock)[VGOFF_(m_ebp)];
- VG_(threads)[tid].m_esp = VG_(baseBlock)[VGOFF_(m_esp)];
-
- VG_(threads)[tid].m_cc_op = VG_(baseBlock)[VGOFF_(m_cc_op)];
- VG_(threads)[tid].m_cc_src = VG_(baseBlock)[VGOFF_(m_cc_src)];
- VG_(threads)[tid].m_cc_dst = VG_(baseBlock)[VGOFF_(m_cc_dst)];
- VG_(threads)[tid].m_cc_dflag = VG_(baseBlock)[VGOFF_(m_cc_dflag)];
-
- VG_(threads)[tid].m_eip = VG_(baseBlock)[VGOFF_(m_eip)];
-
- VG_(threads)[tid].m_f0 = *(ULong*)(&VG_(baseBlock)[VGOFF_(m_f0)]);
- VG_(threads)[tid].m_f1 = *(ULong*)(&VG_(baseBlock)[VGOFF_(m_f1)]);
- VG_(threads)[tid].m_f2 = *(ULong*)(&VG_(baseBlock)[VGOFF_(m_f2)]);
- VG_(threads)[tid].m_f3 = *(ULong*)(&VG_(baseBlock)[VGOFF_(m_f3)]);
- VG_(threads)[tid].m_f4 = *(ULong*)(&VG_(baseBlock)[VGOFF_(m_f4)]);
- VG_(threads)[tid].m_f5 = *(ULong*)(&VG_(baseBlock)[VGOFF_(m_f5)]);
- VG_(threads)[tid].m_f6 = *(ULong*)(&VG_(baseBlock)[VGOFF_(m_f6)]);
- VG_(threads)[tid].m_f7 = *(ULong*)(&VG_(baseBlock)[VGOFF_(m_f7)]);
- VG_(threads)[tid].m_ftop = VG_(baseBlock)[VGOFF_(m_ftop)];
- VG_(threads)[tid].m_fpucw = VG_(baseBlock)[VGOFF_(m_fpucw)];
- VG_(threads)[tid].m_fc3210 = VG_(baseBlock)[VGOFF_(m_fc3210)];
- VG_(threads)[tid].m_ftag30 = VG_(baseBlock)[VGOFF_(m_ftag0)+0];
- VG_(threads)[tid].m_ftag74 = VG_(baseBlock)[VGOFF_(m_ftag0)+1];
+ VG_(threads)[tid].vex
+ = *(VexGuestX86State*)(&VG_(baseBlock)[VGOFF_(m_vex)]) ;
VG_(threads)[tid].sh_eax = VG_(baseBlock)[VGOFF_(sh_eax)];
VG_(threads)[tid].sh_ebx = VG_(baseBlock)[VGOFF_(sh_ebx)];
VG_(threads)[tid].sh_eflags = VG_(baseBlock)[VGOFF_(sh_eflags)];
/* Fill it up with junk. */
- VG_(baseBlock)[VGOFF_(m_eax)] = junk;
- VG_(baseBlock)[VGOFF_(m_ebx)] = junk;
- VG_(baseBlock)[VGOFF_(m_ecx)] = junk;
- VG_(baseBlock)[VGOFF_(m_edx)] = junk;
- VG_(baseBlock)[VGOFF_(m_esi)] = junk;
- VG_(baseBlock)[VGOFF_(m_edi)] = junk;
- VG_(baseBlock)[VGOFF_(m_ebp)] = junk;
- VG_(baseBlock)[VGOFF_(m_esp)] = junk;
- VG_(baseBlock)[VGOFF_(m_cc_op)] = junk;
- VG_(baseBlock)[VGOFF_(m_cc_src)] = junk;
- VG_(baseBlock)[VGOFF_(m_cc_dst)] = junk;
- VG_(baseBlock)[VGOFF_(m_cc_dflag)] = junk;
- VG_(baseBlock)[VGOFF_(m_eip)] = junk;
-
- *(ULong*)(&VG_(baseBlock)[VGOFF_(m_f0)]) = junk64;
- *(ULong*)(&VG_(baseBlock)[VGOFF_(m_f1)]) = junk64;
- *(ULong*)(&VG_(baseBlock)[VGOFF_(m_f2)]) = junk64;
- *(ULong*)(&VG_(baseBlock)[VGOFF_(m_f3)]) = junk64;
- *(ULong*)(&VG_(baseBlock)[VGOFF_(m_f4)]) = junk64;
- *(ULong*)(&VG_(baseBlock)[VGOFF_(m_f5)]) = junk64;
- *(ULong*)(&VG_(baseBlock)[VGOFF_(m_f6)]) = junk64;
- *(ULong*)(&VG_(baseBlock)[VGOFF_(m_f7)]) = junk64;
- VG_(baseBlock)[VGOFF_(m_ftop)] = junk;
- VG_(baseBlock)[VGOFF_(m_fpucw)] = junk;
- VG_(baseBlock)[VGOFF_(m_fc3210)] = junk;
- VG_(baseBlock)[VGOFF_(m_ftag0)+0] = junk;
- VG_(baseBlock)[VGOFF_(m_ftag0)+1] = junk;
+ for (i = 0; i < (3 + sizeof(VexGuestX86State)) / 4; i++)
+ VG_(baseBlock)[VGOFF_(m_vex) + i] = junk;
vg_tid_currently_in_baseBlock = VG_INVALID_THREADID;
}
Addr startup_esp;
ThreadId tid_main;
- startup_esp = VG_(baseBlock)[VGOFF_(m_esp)];
+ startup_esp
+ = ((VexGuestX86State*)(&VG_(baseBlock)[VGOFF_(m_vex)]))->guest_ESP;
if (VG_STACK_MATCHES_BASE(startup_esp, VG_STARTUP_STACK_BASE_1)
|| VG_STACK_MATCHES_BASE(startup_esp, VG_STARTUP_STACK_BASE_2)
VG_(save_thread_state) ( tid_main );
VG_(threads)[tid_main].stack_highest_word
- = VG_(threads)[tid_main].m_esp /* -4 ??? */;
+ = VG_(threads)[tid_main].vex.guest_ESP /* -4 ??? */;
/* So now ... */
vg_assert(vg_tid_currently_in_baseBlock == VG_INVALID_THREADID);
vg_assert(VG_(is_valid_tid)(tid));
vg_assert(VG_(threads)[tid].status == VgTs_WaitFD);
- vg_assert(VG_(threads)[tid].m_eax == __NR_read
- || VG_(threads)[tid].m_eax == __NR_write);
+ vg_assert(VG_(threads)[tid].vex.guest_EAX == __NR_read
+ || VG_(threads)[tid].vex.guest_EAX == __NR_write);
/* Excessively paranoidly ... find the fd this op was waiting
for, and mark it as not being waited on. */
for (i = 0; i < VG_N_WAITING_FDS; i++) {
if (vg_waiting_fds[i].tid == tid) {
waiters++;
- vg_assert(vg_waiting_fds[i].syscall_no == VG_(threads)[tid].m_eax);
+ vg_assert(vg_waiting_fds[i].syscall_no == VG_(threads)[tid].vex.guest_EAX);
}
}
vg_assert(waiters == 1);
return;
if (VG_(threads)[tid].status == VgTs_WaitFD
- && (VG_(threads)[tid].m_eax == __NR_read
- || VG_(threads)[tid].m_eax == __NR_write)) {
+ && (VG_(threads)[tid].vex.guest_EAX == __NR_read
+ || VG_(threads)[tid].vex.guest_EAX == __NR_write)) {
/* read() or write() interrupted. Force a return with EINTR. */
cleanup_waiting_fd_table(tid);
- VG_(threads)[tid].m_eax = -VKI_EINTR;
+ VG_(threads)[tid].vex.guest_EAX = -VKI_EINTR;
VG_(threads)[tid].status = VgTs_Runnable;
if (VG_(clo_trace_sched)) {
}
if (VG_(threads)[tid].status == VgTs_Sleeping
- && VG_(threads)[tid].m_eax == __NR_nanosleep) {
+ && VG_(threads)[tid].vex.guest_EAX == __NR_nanosleep) {
/* We interrupted a nanosleep(). The right thing to do is to
write the unused time to nanosleep's second param, but that's
too much effort ... we just say that 1 nanosecond was not
used, and return EINTR. */
- rem = (struct vki_timespec *)VG_(threads)[tid].m_ecx; /* arg2 */
+ rem = (struct vki_timespec *)VG_(threads)[tid].vex.guest_ECX; /* arg2 */
if (rem != NULL) {
rem->tv_sec = 0;
rem->tv_nsec = 1;
vg_assert(VG_(is_valid_tid)(tid));
vg_assert(VG_(threads)[tid].status == VgTs_Runnable);
- syscall_no = VG_(threads)[tid].m_eax; /* syscall number */
+ syscall_no = VG_(threads)[tid].vex.guest_EAX; /* syscall number */
if (syscall_no == __NR_nanosleep) {
UInt t_now, t_awaken;
struct vki_timespec* req;
- req = (struct vki_timespec*)VG_(threads)[tid].m_ebx; /* arg1 */
+ req = (struct vki_timespec*)VG_(threads)[tid].vex.guest_EBX; /* arg1 */
t_now = VG_(read_millisecond_timer)();
t_awaken
= t_now
immediately, in order to lodge a request with the Linux kernel.
We later poll for I/O completion using select(). */
- fd = VG_(threads)[tid].m_ebx /* arg1 */;
+ fd = VG_(threads)[tid].vex.guest_EBX /* arg1 */;
/* Deal with error case immediately. */
if (!fd_is_valid(fd)) {
VG_(check_known_blocking_syscall)(tid, syscall_no, NULL /* PRE */);
/* This trashes the thread's %eax; we have to preserve it. */
- saved_eax = VG_(threads)[tid].m_eax;
+ saved_eax = VG_(threads)[tid].vex.guest_EAX;
KERNEL_DO_SYSCALL(tid,res);
/* Restore original blockfulness of the fd. */
/* It would have blocked. First, restore %EAX to what it was
before our speculative call. */
- VG_(threads)[tid].m_eax = saved_eax;
+ VG_(threads)[tid].vex.guest_EAX = saved_eax;
/* Put this fd in a table of fds on which we are waiting for
completion. The arguments for select() later are constructed
from this table. */
/* Resume this thread. Set to zero the remaining-time
(second) arg of nanosleep, since it's used up all its
time. */
- vg_assert(VG_(threads)[tid].m_eax == __NR_nanosleep);
- rem = (struct vki_timespec *)VG_(threads)[tid].m_ecx; /* arg2 */
+ vg_assert(VG_(threads)[tid].vex.guest_EAX == __NR_nanosleep);
+ rem = (struct vki_timespec *)VG_(threads)[tid].vex.guest_ECX; /* arg2 */
if (rem != NULL) {
rem->tv_sec = 0;
rem->tv_nsec = 0;
}
/* Make the syscall return 0 (success). */
- VG_(threads)[tid].m_eax = 0;
+ VG_(threads)[tid].vex.guest_EAX = 0;
/* Reschedule this thread. */
VG_(threads)[tid].status = VgTs_Runnable;
if (VG_(clo_trace_sched)) {
sched_do_syscall() doesn't change %EAX in the case where the
call would have blocked. */
syscall_no = vg_waiting_fds[i].syscall_no;
- vg_assert(syscall_no == VG_(threads)[tid].m_eax);
+ vg_assert(syscall_no == VG_(threads)[tid].vex.guest_EAX);
/* In a rare case pertaining to writing into a pipe, write()
will block when asked to write > 4096 bytes even though the
the short write. That shoulds dubious to me, so we don't do
it by default. */
if (syscall_no == __NR_write
- && VG_(threads)[tid].m_edx /* arg3, count */ > 4096
+ && VG_(threads)[tid].vex.guest_EDX /* arg3, count */ > 4096
&& VG_(strstr)(VG_(clo_weird_hacks), "truncate-writes") != NULL) {
/* VG_(printf)("truncate write from %d to 4096\n",
- VG_(threads)[tid].m_edx ); */
- VG_(threads)[tid].m_edx = 4096;
+ VG_(threads)[tid].vex.guest_EDX ); */
+ VG_(threads)[tid].vex.guest_EDX = 4096;
}
KERNEL_DO_SYSCALL(tid,res);
/* Trivial event. Miss in the fast-cache. Do a full
lookup for it. */
trans_addr
- = VG_(search_transtab) ( VG_(threads)[tid].m_eip );
+ = VG_(search_transtab) ( VG_(threads)[tid].vex.guest_EIP );
if (trans_addr == (Addr)0) {
/* Not found; we need to request a translation. */
- create_translation_for( tid, VG_(threads)[tid].m_eip );
- trans_addr = VG_(search_transtab) ( VG_(threads)[tid].m_eip );
+ create_translation_for( tid, VG_(threads)[tid].vex.guest_EIP );
+ trans_addr = VG_(search_transtab) ( VG_(threads)[tid].vex.guest_EIP );
if (trans_addr == (Addr)0)
VG_(panic)("VG_TRC_INNER_FASTMISS: missing tt_fast entry");
}
}
if (trc == VG_TRC_EBP_JMP_CLIENTREQ) {
- UInt reqno = *(UInt*)(VG_(threads)[tid].m_eax);
+ UInt reqno = *(UInt*)(VG_(threads)[tid].vex.guest_EAX);
/* VG_(printf)("request 0x%x\n", reqno); */
/* Are we really absolutely totally quitting? */
to exit. */
# if 0
{ UInt* esp; Int i;
- esp=(UInt*)VG_(threads)[tid].m_esp;
+ esp=(UInt*)VG_(threads)[tid].vex.guest_ESP;
VG_(printf)("\nBEFORE\n");
for (i = 10; i >= -10; i--)
VG_(printf)("%2d %p = 0x%x\n", i, &esp[i], esp[i]);
the unprotected malloc/free system. */
/* If __NR_exit, remember the supplied argument. */
- if (VG_(threads)[tid].m_eax == __NR_exit)
- VG_(exitcode) = VG_(threads)[tid].m_ebx; /* syscall arg1 */
+ if (VG_(threads)[tid].vex.guest_EAX == __NR_exit)
+ VG_(exitcode) = VG_(threads)[tid].vex.guest_EBX; /* syscall arg1 */
- if (VG_(threads)[tid].m_eax == __NR_exit
+ if (VG_(threads)[tid].vex.guest_EAX == __NR_exit
&& !VG_(clo_instrument)) {
if (VG_(clo_trace_syscalls) || VG_(clo_trace_sched)) {
VG_(message)(Vg_DebugMsg,
return VgSrc_ExitSyscall;
}
- if (VG_(threads)[tid].m_eax == __NR_exit) {
+ if (VG_(threads)[tid].vex.guest_EAX == __NR_exit) {
vg_assert(VG_(clo_instrument));
if (0 || VG_(clo_trace_syscalls) || VG_(clo_trace_sched)) {
VG_(message)(Vg_DebugMsg,
"Caught __NR_exit; running __libc_freeres()");
}
VG_(nuke_all_threads_except) ( tid );
- VG_(threads)[tid].m_eip = (UInt)(&VG_(__libc_freeres_wrapper));
+ VG_(threads)[tid].vex.guest_EIP = (UInt)(&VG_(__libc_freeres_wrapper));
vg_assert(VG_(threads)[tid].status == VgTs_Runnable);
goto stage1; /* party on, dudes (but not for much longer :) */
}
/* Trap syscalls to __NR_sched_yield and just have this
thread yield instead. Not essential, just an
optimisation. */
- if (VG_(threads)[tid].m_eax == __NR_sched_yield) {
+ if (VG_(threads)[tid].vex.guest_EAX == __NR_sched_yield) {
SET_EAX(tid, 0); /* syscall returns with success */
goto stage1; /* find a new thread to run */
}
# if 0
{ UInt* esp; Int i;
- esp=(UInt*)VG_(threads)[tid].m_esp;
+ esp=(UInt*)VG_(threads)[tid].vex.guest_ESP;
VG_(printf)("AFTER\n");
for (i = 10; i >= -10; i--)
VG_(printf)("%2d %p = 0x%x\n", i, &esp[i], esp[i]);
VG_(printf)(
"======vvvvvvvv====== LAST TRANSLATION ======vvvvvvvv======\n");
VG_(translate)( &VG_(threads)[tid],
- VG_(threads)[tid].m_eip, NULL, NULL, NULL );
+ VG_(threads)[tid].vex.guest_EIP, NULL, NULL, NULL );
VG_(printf)("\n");
VG_(printf)(
"======^^^^^^^^====== LAST TRANSLATION ======^^^^^^^^======\n");
handler -- which is really thread_exit_wrapper() in
vg_libpthread.c. */
vg_assert(VG_(threads)[tid].cancel_pend != NULL);
- VG_(threads)[tid].m_esp -= 4;
- * (UInt*)(VG_(threads)[tid].m_esp) = (UInt)PTHREAD_CANCELED;
- VG_(threads)[tid].m_eip = (UInt)VG_(threads)[tid].cancel_pend;
+ VG_(threads)[tid].vex.guest_ESP -= 4;
+ * (UInt*)(VG_(threads)[tid].vex.guest_ESP) = (UInt)PTHREAD_CANCELED;
+ VG_(threads)[tid].vex.guest_EIP = (UInt)VG_(threads)[tid].cancel_pend;
VG_(threads)[tid].status = VgTs_Runnable;
/* Make sure we aren't cancelled again whilst handling this
cancellation. */
- VG_AR_CLIENT_STACKBASE_REDZONE_SZB; /* -4 ??? */;
}
- VG_(threads)[tid].m_esp
+ VG_(threads)[tid].vex.guest_ESP
= VG_(threads)[tid].stack_base
+ VG_(threads)[tid].stack_size
- VG_AR_CLIENT_STACKBASE_REDZONE_SZB;
if (VG_(clo_instrument))
- VGM_(make_noaccess)( VG_(threads)[tid].m_esp,
+ VGM_(make_noaccess)( VG_(threads)[tid].vex.guest_ESP,
VG_AR_CLIENT_STACKBASE_REDZONE_SZB );
/* push arg */
- VG_(threads)[tid].m_esp -= 4;
- * (UInt*)(VG_(threads)[tid].m_esp) = (UInt)arg;
+ VG_(threads)[tid].vex.guest_ESP -= 4;
+ * (UInt*)(VG_(threads)[tid].vex.guest_ESP) = (UInt)arg;
/* push (bogus) return address */
- VG_(threads)[tid].m_esp -= 4;
- * (UInt*)(VG_(threads)[tid].m_esp)
+ VG_(threads)[tid].vex.guest_ESP -= 4;
+ * (UInt*)(VG_(threads)[tid].vex.guest_ESP)
= (UInt)&do__apply_in_new_thread_bogusRA;
if (VG_(clo_instrument))
- VGM_(make_readable)( VG_(threads)[tid].m_esp, 2 * 4 );
+ VGM_(make_readable)( VG_(threads)[tid].vex.guest_ESP, 2 * 4 );
/* this is where we start */
- VG_(threads)[tid].m_eip = (UInt)fn;
+ VG_(threads)[tid].vex.guest_EIP = (UInt)fn;
if (VG_(clo_trace_sched)) {
VG_(sprintf)(msg_buf,
void do_client_request ( ThreadId tid )
{
# define RETURN_WITH(vvv) \
- { tst->m_edx = (vvv); \
+ { tst->vex.guest_EDX = (vvv); \
tst->sh_edx = VGM_WORD_VALID; \
}
ThreadState* tst = &VG_(threads)[tid];
- UInt* arg = (UInt*)(VG_(threads)[tid].m_eax);
+ UInt* arg = (UInt*)(tst->vex.guest_EAX);
UInt req_no = arg[0];
/* VG_(printf)("req no = 0x%x\n", req_no); */
if (VG_(threads)[i].status != VgTs_Empty) {
Int
stack_used = (Addr)VG_(threads)[i].stack_highest_word
- - (Addr)VG_(threads)[i].m_esp;
+ - (Addr)VG_(threads)[i].vex.guest_ESP;
if (i > 1 /* not the root thread */
&& stack_used
>= (VG_PTHREAD_STACK_MIN - 1000 /* paranoia */)) {
#include "vg_unsafe.h"
#include "valgrind.h" /* for VALGRIND_MAGIC_SEQUENCE */
+#include "../pub/libvex_guest_x86.h"
+
/* Define to give more sanity checking for signals. */
#define DEBUG_SIGNALS
Addr m_esp;
vg_assert(VG_(is_valid_tid)(tid));
- ss = (vki_kstack_t*)(VG_(threads)[tid].m_ebx);
- oss = (vki_kstack_t*)(VG_(threads)[tid].m_ecx);
- m_esp = VG_(threads)[tid].m_esp;
+ ss = (vki_kstack_t*)(VG_(threads)[tid].vex.guest_EBX);
+ oss = (vki_kstack_t*)(VG_(threads)[tid].vex.guest_ECX);
+ m_esp = VG_(threads)[tid].vex.guest_ESP;
if (VG_(clo_trace_signals))
VG_(message)(Vg_DebugExtraMsg,
}
if (ss != NULL) {
- if (on_sig_stack(VG_(threads)[tid].m_esp)) {
+ if (on_sig_stack(VG_(threads)[tid].vex.guest_ESP)) {
SET_EAX(tid, -VKI_EPERM);
return;
}
vki_ksigset_t irrelevant_sigmask;
vg_assert(VG_(is_valid_tid)(tid));
- signo = VG_(threads)[tid].m_ebx; /* int sigNo */
- new_act = (vki_ksigaction*)(VG_(threads)[tid].m_ecx);
- old_act = (vki_ksigaction*)(VG_(threads)[tid].m_edx);
+ signo = VG_(threads)[tid].vex.guest_EBX; /* int sigNo */
+ new_act = (vki_ksigaction*)(VG_(threads)[tid].vex.guest_ECX);
+ old_act = (vki_ksigaction*)(VG_(threads)[tid].vex.guest_EDX);
if (VG_(clo_trace_signals))
VG_(message)(Vg_DebugExtraMsg,
/* Safely-saved version of sigNo, as described above. */
Int sigNo_private;
/* Saved processor state. */
- UInt eax;
- UInt ecx;
- UInt edx;
- UInt ebx;
- UInt ebp;
- UInt esp;
- UInt esi;
- UInt edi;
- Addr eip;
- UInt cc_op;
- UInt cc_src;
- UInt cc_dst;
- UInt cc_dflag;
- ULong f0, f1, f2, f3, f4, f5, f6, f7;
- UInt ftop;
+ VexGuestX86State vex;
/* Scheduler-private stuff: what was the thread's status prior to
delivering this signal? */
ThreadStatus status;
&& /* there is a defined and enabled alt stack, which we're not
already using. Logic from get_sigframe in
arch/i386/kernel/signal.c. */
- sas_ss_flags(tst->m_esp) == 0
+ sas_ss_flags(tst->vex.guest_ESP) == 0
) {
esp_top_of_frame
= (Addr)(vg_scss.altstack.ss_sp) + vg_scss.altstack.ss_size;
"delivering signal %d to thread %d: on ALT STACK",
sigNo, tid );
} else {
- esp_top_of_frame = tst->m_esp;
+ esp_top_of_frame = tst->vex.guest_ESP;
}
esp = esp_top_of_frame;
frame->puContext = (Addr)NULL;
frame->magicPI = 0x31415927;
- frame->f0 = tst->m_f0;
- frame->f1 = tst->m_f1;
- frame->f2 = tst->m_f2;
- frame->f3 = tst->m_f3;
- frame->f4 = tst->m_f4;
- frame->f5 = tst->m_f5;
- frame->f6 = tst->m_f6;
- frame->f7 = tst->m_f7;
- frame->ftop = tst->m_ftop;
-
- frame->eax = tst->m_eax;
- frame->ecx = tst->m_ecx;
- frame->edx = tst->m_edx;
- frame->ebx = tst->m_ebx;
- frame->ebp = tst->m_ebp;
- frame->esp = tst->m_esp;
- frame->esi = tst->m_esi;
- frame->edi = tst->m_edi;
- frame->eip = tst->m_eip;
-
- frame->cc_op = tst->m_cc_op;
- frame->cc_src = tst->m_cc_src;
- frame->cc_dst = tst->m_cc_dst;
- frame->cc_dflag = tst->m_cc_dflag;
+ frame->vex = tst->vex;
frame->status = tst->status;
frame->magicE = 0x27182818;
/* Set the thread so it will next run the handler. */
- tst->m_esp = esp;
- tst->m_eip = (Addr)vg_scss.scss_per_sig[sigNo].scss_handler;
+ tst->vex.guest_ESP = esp;
+ tst->vex.guest_EIP = (Addr)vg_scss.scss_per_sig[sigNo].scss_handler;
/* This thread needs to be marked runnable, but we leave that the
caller to do. */
tst = & VG_(threads)[tid];
/* Correctly reestablish the frame base address. */
- esp = tst->m_esp;
+ esp = tst->vex.guest_ESP;
frame = (VgSigFrame*)
(esp -4 /* because the handler's RET pops the RA */
+20 /* because signalreturn_bogusRA pushes 5 words */);
"vg_pop_signal_frame (thread %d): valid magic", tid);
/* restore machine state */
- tst->m_f0 = frame->f0;
- tst->m_f1 = frame->f1;
- tst->m_f2 = frame->f2;
- tst->m_f3 = frame->f3;
- tst->m_f4 = frame->f4;
- tst->m_f5 = frame->f5;
- tst->m_f6 = frame->f6;
- tst->m_f7 = frame->f7;
- tst->m_ftop = frame->ftop;
+ tst->vex = frame->vex;
/* Mark the frame structure as nonaccessible. */
if (VG_(clo_instrument))
VGM_(make_noaccess)( (Addr)frame, sizeof(VgSigFrame) );
- /* Restore machine state from the saved context. */
- tst->m_eax = frame->eax;
- tst->m_ecx = frame->ecx;
- tst->m_edx = frame->edx;
- tst->m_ebx = frame->ebx;
- tst->m_ebp = frame->ebp;
- tst->m_esp = frame->esp;
- tst->m_esi = frame->esi;
- tst->m_edi = frame->edi;
-
- tst->m_cc_op = frame->cc_op;
- tst->m_cc_src = frame->cc_src;
- tst->m_cc_dst = frame->cc_dst;
- tst->m_cc_dflag = frame->cc_dflag;
-
- tst->m_eip = frame->eip;
-
/* don't use the copy exposed to the handler; it might have changed
it. */
- sigNo = frame->sigNo_private;
+ sigNo = frame->sigNo_private;
/* And restore the thread's status to what it was before the signal
was delivered. */
VG_(message)(Vg_DebugMsg,
"releasing thread %d from sigwait() due to signal %d",
tid, sigNo );
- sigwait_args = (UInt*)(tst->m_eax);
+ sigwait_args = (UInt*)(tst->vex.guest_EAX);
if (NULL != (UInt*)(sigwait_args[2])) {
*(Int*)(sigwait_args[2]) = sigNo;
if (VG_(clo_instrument))
sane_before_call = True;
sane_after_call = True;
tst = & VG_(threads)[tid];
- syscallno = tst->m_eax;
- arg1 = tst->m_ebx;
- arg2 = tst->m_ecx;
- arg3 = tst->m_edx;
- arg4 = tst->m_esi;
- arg5 = tst->m_edi;
+ syscallno = tst->vex.guest_EAX;
+ arg1 = tst->vex.guest_EBX;
+ arg2 = tst->vex.guest_ECX;
+ arg3 = tst->vex.guest_EDX;
+ arg4 = tst->vex.guest_ESI;
+ arg5 = tst->vex.guest_EDI;
/* Since buggy syscall wrappers sometimes break this, we may as well
check ourselves. */
/* KLUDGE: we prefer to do a fork rather than vfork.
vfork gives a SIGSEGV, and the stated semantics looks
pretty much impossible for us. */
- tst->m_eax = __NR_fork;
+ tst->vex.guest_EAX = __NR_fork;
/* fall through ... */
case __NR_fork: /* syscall 2 */
/* pid_t fork(void); */
/* int ipc ( unsigned int call, int first, int second,
int third, void *ptr, long fifth); */
{
- UInt arg6 = tst->m_ebp;
+ UInt arg6 = tst->vex.guest_EBP;
if (VG_(clo_trace_syscalls))
VG_(printf)("ipc ( %d, %d, %d, %d, %p, %d )\n",
int flags, int fd, off_t offset);
*/
{
- UInt arg6 = tst->m_ebp;
+ UInt arg6 = tst->vex.guest_EBP;
if (VG_(clo_trace_syscalls))
VG_(printf)("mmap2 ( %p, %d, %d, %d, %d, %d )\n",
arg1, arg2, arg3, arg4, arg5, arg6 );
}
# if SIGNAL_SIMULATION
VG_(do__NR_sigaltstack) (tid);
- res = tst->m_eax;
+ res = tst->vex.guest_EAX;
# else
KERNEL_DO_SYSCALL(tid,res);
# endif
/* We do this one ourselves! */
# if SIGNAL_SIMULATION
VG_(do__NR_sigaction)(tid);
- res = tst->m_eax;
+ res = tst->vex.guest_EAX;
# else
/* debugging signals; when we don't handle them. */
KERNEL_DO_SYSCALL(tid,res);
arg1 /*how*/,
(vki_ksigset_t*) arg2,
(vki_ksigset_t*) arg3 );
- res = tst->m_eax;
+ res = tst->vex.guest_EAX;
# else
KERNEL_DO_SYSCALL(tid,res);
# endif
sane_before_post = True;
sane_after_post = True;
tst = & VG_(threads)[tid];
- arg1 = tst->m_ebx;
- arg2 = tst->m_ecx;
- arg3 = tst->m_edx;
+ arg1 = tst->vex.guest_EBX;
+ arg2 = tst->vex.guest_ECX;
+ arg3 = tst->vex.guest_EDX;
/*
- arg4 = tst->m_esi;
- arg5 = tst->m_edi;
+ arg4 = tst->vex.guest_ESI;
+ arg5 = tst->vex.guest_EDI;
*/
if (res != NULL