vg_assert(VG_(is_valid_tid)(tid));
tst = & VG_(threads)[tid];
-
+ if (0)
+ VG_(printf)("set_thread_shadow_archreg(%d, %d, 0x%x)\n",
+ tid, archreg, val);
switch (archreg) {
- case R_EAX: tst->arch.sh_eax = val; break;
- case R_ECX: tst->arch.sh_ecx = val; break;
- case R_EDX: tst->arch.sh_edx = val; break;
- case R_EBX: tst->arch.sh_ebx = val; break;
- case R_ESP: tst->arch.sh_esp = val; break;
- case R_EBP: tst->arch.sh_ebp = val; break;
- case R_ESI: tst->arch.sh_esi = val; break;
- case R_EDI: tst->arch.sh_edi = val; break;
+ case R_EAX: tst->arch.vex_shadow.guest_EAX = val; break;
+ case R_ECX: tst->arch.vex_shadow.guest_ECX = val; break;
+ case R_EDX: tst->arch.vex_shadow.guest_EDX = val; break;
+ case R_EBX: tst->arch.vex_shadow.guest_EBX = val; break;
+ case R_ESP: tst->arch.vex_shadow.guest_ESP = val; break;
+ case R_EBP: tst->arch.vex_shadow.guest_EBP = val; break;
+ case R_ESI: tst->arch.vex_shadow.guest_ESI = val; break;
+ case R_EDI: tst->arch.vex_shadow.guest_EDI = val; break;
default: VG_(core_panic)( "set_thread_shadow_archreg");
}
}
vg_assert(VG_(is_valid_tid)(tid));
tst = & VG_(threads)[tid];
+ VG_(printf)("get_thread_shadow_archreg(%d, %d)\n",
+ tid, archreg);
+
switch (archreg) {
- case R_EAX: return tst->arch.sh_eax;
- case R_ECX: return tst->arch.sh_ecx;
- case R_EDX: return tst->arch.sh_edx;
- case R_EBX: return tst->arch.sh_ebx;
- case R_ESP: return tst->arch.sh_esp;
- case R_EBP: return tst->arch.sh_ebp;
- case R_ESI: return tst->arch.sh_esi;
- case R_EDI: return tst->arch.sh_edi;
+ case R_EAX: return tst->arch.vex_shadow.guest_EAX;
+ case R_ECX: return tst->arch.vex_shadow.guest_ECX;
+ case R_EDX: return tst->arch.vex_shadow.guest_EDX;
+ case R_EBX: return tst->arch.vex_shadow.guest_EBX;
+ case R_ESP: return tst->arch.vex_shadow.guest_ESP;
+ case R_EBP: return tst->arch.vex_shadow.guest_EBP;
+ case R_ESI: return tst->arch.vex_shadow.guest_ESI;
+ case R_EDI: return tst->arch.vex_shadow.guest_EDI;
default: VG_(core_panic)( "get_thread_shadow_archreg");
}
}
/* Return the baseBlock index for the specified shadow register */
static Int shadow_reg_index ( Int arch )
{
+ VG_(printf)("shadow_reg_index(%d)\n",
+ arch);
switch (arch) {
- case R_EAX: return VGOFF_(sh_eax);
- case R_ECX: return VGOFF_(sh_ecx);
- case R_EDX: return VGOFF_(sh_edx);
- case R_EBX: return VGOFF_(sh_ebx);
- case R_ESP: return VGOFF_(sh_esp);
- case R_EBP: return VGOFF_(sh_ebp);
- case R_ESI: return VGOFF_(sh_esi);
- case R_EDI: return VGOFF_(sh_edi);
+ case R_EAX: return VGOFF_(m_vex_shadow) + offsetof(VexGuestX86State,guest_EAX)/4;
+ case R_ECX: return VGOFF_(m_vex_shadow) + offsetof(VexGuestX86State,guest_ECX)/4;
+ case R_EDX: return VGOFF_(m_vex_shadow) + offsetof(VexGuestX86State,guest_EDX)/4;
+ case R_EBX: return VGOFF_(m_vex_shadow) + offsetof(VexGuestX86State,guest_EBX)/4;
+ case R_ESP: return VGOFF_(m_vex_shadow) + offsetof(VexGuestX86State,guest_ESP)/4;
+ case R_EBP: return VGOFF_(m_vex_shadow) + offsetof(VexGuestX86State,guest_EBP)/4;
+ case R_ESI: return VGOFF_(m_vex_shadow) + offsetof(VexGuestX86State,guest_ESI)/4;
+ case R_EDI: return VGOFF_(m_vex_shadow) + offsetof(VexGuestX86State,guest_EDI)/4;
default: VG_(core_panic)( "shadow_reg_index");
}
}
#define BASEBLOCK_VEX \
((VexGuestX86State*)(&VG_(baseBlock)[VGOFF_(m_vex)]))
+/* Ditto the Vex shadow guest state. */
+#define BASEBLOCK_VEX_SHADOW \
+ ((VexGuestX86State*)(&VG_(baseBlock)[VGOFF_(m_vex_shadow)]))
+
// Accessors for the arch_thread_t
#define ARCH_INSTR_PTR(regs) ((regs).vex.guest_EIP)
#define ARCH_STACK_PTR(regs) ((regs).vex.guest_ESP)
/* State of the simulated CPU. */
extern Int VGOFF_(m_vex);
+extern Int VGOFF_(m_vex_shadow);
/* Reg-alloc spill area (VG_MAX_SPILLSLOTS words long). */
extern Int VGOFF_(spillslots);
-/* Records the valid bits for the 8 integer regs & flags reg. */
-extern Int VGOFF_(sh_eax);
-extern Int VGOFF_(sh_ecx);
-extern Int VGOFF_(sh_edx);
-extern Int VGOFF_(sh_ebx);
-extern Int VGOFF_(sh_esp);
-extern Int VGOFF_(sh_ebp);
-extern Int VGOFF_(sh_esi);
-extern Int VGOFF_(sh_edi);
-extern Int VGOFF_(sh_eflags);
/* -----------------------------------------------------
Read-only parts of baseBlock.
/* Saved machine context. */
VexGuestX86State vex;
- UInt sh_eax;
- UInt sh_ebx;
- UInt sh_ecx;
- UInt sh_edx;
- UInt sh_esi;
- UInt sh_edi;
- UInt sh_ebp;
- UInt sh_esp;
- UInt sh_eflags;
+ /* Saved shadow context. */
+ VexGuestX86State vex_shadow;
}
arch_thread_t;
/* Safely-saved version of sigNo, as described above. */
Int sigNo_private;
/* Saved processor state. */
- VexGuestX86State vex;
-
- UInt sh_eax;
- UInt sh_ebx;
- UInt sh_ecx;
- UInt sh_edx;
- UInt sh_esi;
- UInt sh_edi;
- UInt sh_ebp;
- UInt sh_esp;
- UInt sh_eflags;
+ VexGuestX86State vex;
+ VexGuestX86State vex_shadow;
/* saved signal mask to be restored when handler returns */
vki_ksigset_t mask;
frame->vex = tst->arch.vex;
- if (VG_(needs).shadow_regs) {
- frame->sh_eax = tst->arch.sh_eax;
- frame->sh_ecx = tst->arch.sh_ecx;
- frame->sh_edx = tst->arch.sh_edx;
- frame->sh_ebx = tst->arch.sh_ebx;
- frame->sh_ebp = tst->arch.sh_ebp;
- frame->sh_esp = tst->arch.sh_esp;
- frame->sh_esi = tst->arch.sh_esi;
- frame->sh_edi = tst->arch.sh_edi;
- frame->sh_eflags = tst->arch.sh_eflags;
- }
+ if (VG_(needs).shadow_regs)
+ frame->vex_shadow = tst->arch.vex_shadow;
frame->mask = tst->sig_mask;
// tst->arch.m_sse[i] = frame->m_sse[i];
tst->arch.vex = frame->vex;
-
- if (VG_(needs).shadow_regs) {
- tst->arch.sh_eax = frame->sh_eax;
- tst->arch.sh_ecx = frame->sh_ecx;
- tst->arch.sh_edx = frame->sh_edx;
- tst->arch.sh_ebx = frame->sh_ebx;
- tst->arch.sh_ebp = frame->sh_ebp;
- tst->arch.sh_esp = frame->sh_esp;
- tst->arch.sh_esi = frame->sh_esi;
- tst->arch.sh_edi = frame->sh_edi;
- tst->arch.sh_eflags = frame->sh_eflags;
- }
+ if (VG_(needs).shadow_regs)
+ tst->arch.vex_shadow = frame->vex_shadow;
/* And restore the thread's status to what it was before the signal
was delivered. */
/* The variables storing offsets. */
Int VGOFF_(m_vex) = INVALID_OFFSET;
+Int VGOFF_(m_vex_shadow) = INVALID_OFFSET;
Int VGOFF_(ldt) = INVALID_OFFSET;
Int VGOFF_(tls_ptr) = INVALID_OFFSET;
Int VGOFF_(m_eip) = INVALID_OFFSET;
Int VGOFF_(spillslots) = INVALID_OFFSET;
-Int VGOFF_(sh_eax) = INVALID_OFFSET;
-Int VGOFF_(sh_ecx) = INVALID_OFFSET;
-Int VGOFF_(sh_edx) = INVALID_OFFSET;
-Int VGOFF_(sh_ebx) = INVALID_OFFSET;
-Int VGOFF_(sh_esp) = INVALID_OFFSET;
-Int VGOFF_(sh_ebp) = INVALID_OFFSET;
-Int VGOFF_(sh_esi) = INVALID_OFFSET;
-Int VGOFF_(sh_edi) = INVALID_OFFSET;
-Int VGOFF_(sh_eflags) = INVALID_OFFSET;
-
-Int VGOFF_(helper_idiv_64_32) = INVALID_OFFSET;
-Int VGOFF_(helper_div_64_32) = INVALID_OFFSET;
-Int VGOFF_(helper_idiv_32_16) = INVALID_OFFSET;
-Int VGOFF_(helper_div_32_16) = INVALID_OFFSET;
-Int VGOFF_(helper_idiv_16_8) = INVALID_OFFSET;
-Int VGOFF_(helper_div_16_8) = INVALID_OFFSET;
-Int VGOFF_(helper_imul_32_64) = INVALID_OFFSET;
-Int VGOFF_(helper_mul_32_64) = INVALID_OFFSET;
-Int VGOFF_(helper_imul_16_32) = INVALID_OFFSET;
-Int VGOFF_(helper_mul_16_32) = INVALID_OFFSET;
-Int VGOFF_(helper_imul_8_16) = INVALID_OFFSET;
-Int VGOFF_(helper_mul_8_16) = INVALID_OFFSET;
-Int VGOFF_(helper_CLD) = INVALID_OFFSET;
-Int VGOFF_(helper_STD) = INVALID_OFFSET;
-Int VGOFF_(helper_get_dirflag) = INVALID_OFFSET;
-Int VGOFF_(helper_CLC) = INVALID_OFFSET;
-Int VGOFF_(helper_STC) = INVALID_OFFSET;
-Int VGOFF_(helper_CMC) = INVALID_OFFSET;
-Int VGOFF_(helper_shldl) = INVALID_OFFSET;
-Int VGOFF_(helper_shldw) = INVALID_OFFSET;
-Int VGOFF_(helper_shrdl) = INVALID_OFFSET;
-Int VGOFF_(helper_shrdw) = INVALID_OFFSET;
-Int VGOFF_(helper_IN) = INVALID_OFFSET;
-Int VGOFF_(helper_OUT) = INVALID_OFFSET;
-Int VGOFF_(helper_RDTSC) = INVALID_OFFSET;
-Int VGOFF_(helper_CPUID) = INVALID_OFFSET;
-Int VGOFF_(helper_BSWAP) = INVALID_OFFSET;
-Int VGOFF_(helper_bsfw) = INVALID_OFFSET;
-Int VGOFF_(helper_bsfl) = INVALID_OFFSET;
-Int VGOFF_(helper_bsrw) = INVALID_OFFSET;
-Int VGOFF_(helper_bsrl) = INVALID_OFFSET;
-Int VGOFF_(helper_fstsw_AX) = INVALID_OFFSET;
-Int VGOFF_(helper_SAHF) = INVALID_OFFSET;
-Int VGOFF_(helper_LAHF) = INVALID_OFFSET;
-Int VGOFF_(helper_DAS) = INVALID_OFFSET;
-Int VGOFF_(helper_DAA) = INVALID_OFFSET;
-Int VGOFF_(helper_AAS) = INVALID_OFFSET;
-Int VGOFF_(helper_AAA) = INVALID_OFFSET;
-Int VGOFF_(helper_AAD) = INVALID_OFFSET;
-Int VGOFF_(helper_AAM) = INVALID_OFFSET;
-Int VGOFF_(helper_cmpxchg8b) = INVALID_OFFSET;
/* Here we assign actual offsets. It's important on x86 to get the most
size of translations. */
void VGA_(init_low_baseBlock) ( Addr client_eip, Addr esp_at_startup )
{
- Int shadow_off;
- /* Those with offsets under 128 are carefully chosen. */
-
- /* WORD offsets in this column */
vg_assert(0 == sizeof(VexGuestX86State) % 8);
/* First the guest state. */
VGOFF_(m_vex) = VG_(alloc_BaB)( sizeof(VexGuestX86State) / 4 );
/* Then equal sized shadow state. */
- shadow_off = VG_(alloc_BaB)( sizeof(VexGuestX86State) / 4 );
+ VGOFF_(m_vex_shadow) = VG_(alloc_BaB)( sizeof(VexGuestX86State) / 4 );
/* Finally the spill area. */
VGOFF_(spillslots) = VG_(alloc_BaB)( LibVEX_N_SPILL_BYTES/4 );
sane way. */
LibVEX_GuestX86_initialise(BASEBLOCK_VEX);
+ /* Zero out the shadow area. */
+ VG_(memset)(BASEBLOCK_VEX_SHADOW, 0, sizeof(VexGuestX86State));
+
/* Put essential stuff into the new state. */
BASEBLOCK_VEX->guest_ESP = esp_at_startup;
BASEBLOCK_VEX->guest_EIP = client_eip;
= VGOFF_(m_vex) + offsetof(VexGuestX86State,guest_EIP)/4;
if (VG_(needs).shadow_regs) {
- /* 9 */ VGOFF_(sh_eax) = shadow_off+0;
- /* 10 */ VGOFF_(sh_ecx) = shadow_off+1;
- /* 11 */ VGOFF_(sh_edx) = shadow_off+2;
- /* 12 */ VGOFF_(sh_ebx) = shadow_off+3;
- /* 13 */ VGOFF_(sh_esp) = shadow_off+4;
- /* 14 */ VGOFF_(sh_ebp) = shadow_off+5;
- /* 15 */ VGOFF_(sh_esi) = shadow_off+6;
- /* 16 */ VGOFF_(sh_edi) = shadow_off+7;
- /* 17 */ VGOFF_(sh_eflags) = shadow_off+8;
VG_TRACK( post_regs_write_init );
}
-
- /* 9,10,11 or 18,19,20... depends on number whether shadow regs are used
- * and on compact helpers registered */
-
- /* Make these most-frequently-called specialised ones compact, if they
- are used. */
- if (VG_(defined_new_mem_stack_4)())
- VG_(register_compact_helper)( (Addr) VG_(tool_interface).track_new_mem_stack_4);
-
- if (VG_(defined_die_mem_stack_4)())
- VG_(register_compact_helper)( (Addr) VG_(tool_interface).track_die_mem_stack_4);
-
}
void VGA_(init_high_baseBlock)( Addr client_eip, Addr esp_at_startup )
asm volatile("movw %%ss, %0"
:
: "m" (BASEBLOCK_VEX->guest_SS));
-
- VG_(register_noncompact_helper)( (Addr) & VG_(do_useseg) );
-
-# define HELPER(name) \
- VGOFF_(helper_##name) = VG_(alloc_BaB_1_set)( (Addr) & VG_(helper_##name))
-
- /* Helper functions. */
-
- HELPER(RDTSC); HELPER(CPUID);
-
- HELPER(DAS); HELPER(DAA);
- HELPER(AAS); HELPER(AAA);
- HELPER(AAD); HELPER(AAM);
- HELPER(IN); HELPER(OUT);
- HELPER(cmpxchg8b);
-
- HELPER(undefined_instruction);
-
-# undef HELPER
}
/* Junk to fill up a thread's shadow regs with when shadow regs aren't
*BASEBLOCK_VEX = arch->vex;
if (VG_(needs).shadow_regs) {
- VG_(baseBlock)[VGOFF_(sh_eax)] = arch->sh_eax;
- VG_(baseBlock)[VGOFF_(sh_ebx)] = arch->sh_ebx;
- VG_(baseBlock)[VGOFF_(sh_ecx)] = arch->sh_ecx;
- VG_(baseBlock)[VGOFF_(sh_edx)] = arch->sh_edx;
- VG_(baseBlock)[VGOFF_(sh_esi)] = arch->sh_esi;
- VG_(baseBlock)[VGOFF_(sh_edi)] = arch->sh_edi;
- VG_(baseBlock)[VGOFF_(sh_ebp)] = arch->sh_ebp;
- VG_(baseBlock)[VGOFF_(sh_esp)] = arch->sh_esp;
- VG_(baseBlock)[VGOFF_(sh_eflags)] = arch->sh_eflags;
+ *BASEBLOCK_VEX_SHADOW = arch->vex_shadow;
} else {
/* Fields shouldn't be used -- check their values haven't changed. */
+ /* ummm ...
vg_assert(
VG_UNUSED_SHADOW_REG_VALUE == arch->sh_eax &&
VG_UNUSED_SHADOW_REG_VALUE == arch->sh_ebx &&
VG_UNUSED_SHADOW_REG_VALUE == arch->sh_ebp &&
VG_UNUSED_SHADOW_REG_VALUE == arch->sh_esp &&
VG_UNUSED_SHADOW_REG_VALUE == arch->sh_eflags);
+ */
}
}
arch->vex = *BASEBLOCK_VEX;
if (VG_(needs).shadow_regs) {
- arch->sh_eax = VG_(baseBlock)[VGOFF_(sh_eax)];
- arch->sh_ebx = VG_(baseBlock)[VGOFF_(sh_ebx)];
- arch->sh_ecx = VG_(baseBlock)[VGOFF_(sh_ecx)];
- arch->sh_edx = VG_(baseBlock)[VGOFF_(sh_edx)];
- arch->sh_esi = VG_(baseBlock)[VGOFF_(sh_esi)];
- arch->sh_edi = VG_(baseBlock)[VGOFF_(sh_edi)];
- arch->sh_ebp = VG_(baseBlock)[VGOFF_(sh_ebp)];
- arch->sh_esp = VG_(baseBlock)[VGOFF_(sh_esp)];
- arch->sh_eflags = VG_(baseBlock)[VGOFF_(sh_eflags)];
+ arch->vex_shadow = *BASEBLOCK_VEX_SHADOW;
} else {
/* Fill with recognisable junk */
+ /* can't easily do this ...
arch->sh_eax =
arch->sh_ebx =
arch->sh_ecx =
arch->sh_ebp =
arch->sh_esp =
arch->sh_eflags = VG_UNUSED_SHADOW_REG_VALUE;
+ */
}
/* Fill it up with junk. */
VG_(baseBlock)[VGOFF_(ldt)] = junk;
// tools, and the IR should provide a better way than this to see what the
// original instruction was.
-extern Int VGOFF_(helper_idiv_64_32);
-extern Int VGOFF_(helper_div_64_32);
-extern Int VGOFF_(helper_idiv_32_16);
-extern Int VGOFF_(helper_div_32_16);
-extern Int VGOFF_(helper_idiv_16_8);
-extern Int VGOFF_(helper_div_16_8);
-
-extern Int VGOFF_(helper_imul_32_64);
-extern Int VGOFF_(helper_mul_32_64);
-extern Int VGOFF_(helper_imul_16_32);
-extern Int VGOFF_(helper_mul_16_32);
-extern Int VGOFF_(helper_imul_8_16);
-extern Int VGOFF_(helper_mul_8_16);
-
-extern Int VGOFF_(helper_CLD);
-extern Int VGOFF_(helper_STD);
-extern Int VGOFF_(helper_get_dirflag);
-
-extern Int VGOFF_(helper_CLC);
-extern Int VGOFF_(helper_STC);
-extern Int VGOFF_(helper_CMC);
-
-extern Int VGOFF_(helper_shldl);
-extern Int VGOFF_(helper_shldw);
-extern Int VGOFF_(helper_shrdl);
-extern Int VGOFF_(helper_shrdw);
-
-extern Int VGOFF_(helper_RDTSC);
-extern Int VGOFF_(helper_CPUID);
-
-extern Int VGOFF_(helper_IN);
-extern Int VGOFF_(helper_OUT);
-
-extern Int VGOFF_(helper_bsfw);
-extern Int VGOFF_(helper_bsfl);
-extern Int VGOFF_(helper_bsrw);
-extern Int VGOFF_(helper_bsrl);
-
-extern Int VGOFF_(helper_fstsw_AX);
-extern Int VGOFF_(helper_SAHF);
-extern Int VGOFF_(helper_LAHF);
-extern Int VGOFF_(helper_DAS);
-extern Int VGOFF_(helper_DAA);
-extern Int VGOFF_(helper_AAS);
-extern Int VGOFF_(helper_AAA);
-extern Int VGOFF_(helper_AAD);
-extern Int VGOFF_(helper_AAM);
-
-extern Int VGOFF_(helper_cmpxchg8b);
-
#endif // __X86_TOOL_ARCH_H