From: Julian Seward Date: Wed, 26 Jan 2005 01:19:35 +0000 (+0000) Subject: Try and get the amd64 address mode mess sorted out a bit. X-Git-Tag: svn/VALGRIND_3_0_1^2~585 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=7f75b9a2aec8ba2fb459911f52d38f74c39c166c;p=thirdparty%2Fvalgrind.git Try and get the amd64 address mode mess sorted out a bit. git-svn-id: svn://svn.valgrind.org/vex/trunk@749 --- diff --git a/VEX/priv/guest-amd64/ghelpers.c b/VEX/priv/guest-amd64/ghelpers.c index d25436d521..15184a2ae2 100644 --- a/VEX/priv/guest-amd64/ghelpers.c +++ b/VEX/priv/guest-amd64/ghelpers.c @@ -59,12 +59,37 @@ IRExpr* guest_amd64_spechelper ( Char* function_name, return NULL; } +/* Figure out if any part of the guest state contained in minoff + .. maxoff requires precise memory exceptions. If in doubt return + True (but this is generates significantly slower code). + + We enforce precise exns for guest %RSP and %RIP only. +*/ Bool guest_amd64_state_requires_precise_mem_exns ( Int minoff, Int maxoff) { - vassert(0); - return False; + Int rsp_min = offsetof(VexGuestAMD64State, guest_RSP); + Int rsp_max = rsp_min + 8 - 1; + Int rip_min = offsetof(VexGuestAMD64State, guest_RIP); + Int rip_max = rip_min + 8 - 1; + + if (maxoff < rsp_min || minoff > rsp_max) { + /* no overlap with rsp */ + } else { + return True; + } + + if (maxoff < rip_min || minoff > rip_max) { + /* no overlap with eip */ + } else { + return True; + } + + return False; } + + + #define ALWAYSDEFD(field) \ { offsetof(VexGuestX86State, field), \ (sizeof ((VexGuestX86State*)0)->field) } diff --git a/VEX/priv/guest-amd64/toIR.c b/VEX/priv/guest-amd64/toIR.c index 26f426f745..6a81fae643 100644 --- a/VEX/priv/guest-amd64/toIR.c +++ b/VEX/priv/guest-amd64/toIR.c @@ -648,8 +648,7 @@ typedef /* Fetches the relevant reg field extension bit from pfx. Returns 1 or 0. */ -static -UInt getRX ( Prefix pfx, RegField rf ) { +static UInt getRX ( Prefix pfx, RegField rf ) { switch (rf) { case RegR: return (pfx & PFX_REXR) ? 1 : 0; case RegX: return (pfx & PFX_REXX) ? 1 : 0; @@ -657,7 +656,10 @@ UInt getRX ( Prefix pfx, RegField rf ) { default: vpanic("getRFExpr(amd64)"); } } - +static UInt getRexX ( Prefix pfx ) +{ + return haveREX(pfx) ? getRX(pfx,RegX) : 0; +} static IRType szToITy ( UInt n ) { @@ -795,12 +797,15 @@ HChar* nameIReg ( Prefix pfx, RegField rf, Int sz, UInt lo3bits ) return NULL; /*notreached*/ } -static HChar* nameIRegB ( Prefix pfx, Int sz, UInt lo3bits ) { - return nameIReg ( pfx, RegB, sz, lo3bits ); -} static HChar* nameIRegR ( Prefix pfx, Int sz, UInt lo3bits ) { return nameIReg ( pfx, RegR, sz, lo3bits ); } +static HChar* nameIRegX ( Prefix pfx, Int sz, UInt lo3bits ) { + return nameIReg ( pfx, RegX, sz, lo3bits ); +} +static HChar* nameIRegB ( Prefix pfx, Int sz, UInt lo3bits ) { + return nameIReg ( pfx, RegB, sz, lo3bits ); +} /* Generate an IR expression to fetch the guest state corresponding to @@ -863,6 +868,12 @@ static IRExpr* getIReg64 ( UInt regno ) Ity_I64 ); } +static void putIReg64 ( UInt regno, IRExpr* e ) +{ + vassert(typeOfIRExpr(irbb->tyenv,e) == Ity_I64); + stmt( IRStmt_Put( integerGuestReg64Offset(regno), e ) ); +} + static HChar* nameIReg64 ( UInt regno ) { static HChar* ireg64_names[16] @@ -1557,12 +1568,12 @@ static void jmp_lit( IRJumpKind kind, Addr64 d64 ) irbb->jumpkind = kind; } -//.. static void jmp_treg( IRJumpKind kind, IRTemp t ) -//.. { -//.. irbb->next = mkexpr(t); -//.. irbb->jumpkind = kind; -//.. } -//.. +static void jmp_treg( IRJumpKind kind, IRTemp t ) +{ + irbb->next = mkexpr(t); + irbb->jumpkind = kind; +} + //.. static //.. void jcc_01( X86Condcode cond, Addr32 d32_false, Addr32 d32_true ) //.. { @@ -1723,6 +1734,7 @@ IRTemp disAMode ( Int* len, Prefix pfx, UInt delta, UChar* buf ) { UChar rm = mod_reg_rm & 7; DIS(buf, "%s(%s)", sorbTxt(pfx), nameIRegB(pfx,8,rm)); *len = 1; + vpanic("disAMode(amd64):untested amode: 1"); return disAMode_copy2tmp( handleSegOverride(pfx, getIRegB(pfx,8,rm))); } @@ -1750,6 +1762,7 @@ IRTemp disAMode ( Int* len, Prefix pfx, UInt delta, UChar* buf ) ULong d = getSDisp32(delta); DIS(buf, "%s0x%llx(%s)", sorbTxt(pfx), d, nameIRegB(pfx,8,rm)); *len = 5; + vpanic("disAMode(amd64):untested amode: 3"); return disAMode_copy2tmp( handleSegOverride(pfx, binop(Iop_Add64,getIRegB(pfx,8,rm),mkU64(d)))); @@ -1767,12 +1780,171 @@ IRTemp disAMode ( Int* len, Prefix pfx, UInt delta, UChar* buf ) { ULong d = getSDisp32(delta); *len = 5; DIS(buf, "%s(0x%llx)", sorbTxt(pfx), d); + vpanic("disAMode(amd64):untested amode: 4"); return disAMode_copy2tmp( handleSegOverride(pfx, binop(Iop_Add64, mkU64(guest_rip_curr_instr), mkU64(d)))); } +#if 0 + case 0x04: { + /* SIB, with no displacement. Special cases: + -- %esp cannot act as an index value. + If index_r indicates %esp, zero is used for the index. + -- when mod is zero and base indicates EBP, base is instead + a 32-bit literal. + It's all madness, I tell you. Extract %index, %base and + scale from the SIB byte. The value denoted is then: + | %index == %ESP && %base == %EBP + = d32 following SIB byte + | %index == %ESP && %base != %EBP + = %base + | %index != %ESP && %base == %EBP + = d32 following SIB byte + (%index << scale) + | %index != %ESP && %base != %ESP + = %base + (%index << scale) + */ + UChar sib = getIByte(delta); + UChar scale = (sib >> 6) & 3; + UChar index_r = (sib >> 3) & 7; + UChar base_r = sib & 7; + delta++; + + if (index_r != R_ESP && base_r != R_EBP) { + DIS(buf, "%s(%s,%s,%d)", sorbTxt(sorb), + nameIReg(4,base_r), nameIReg(4,index_r), 1<> 6) & 3; + UChar index_r = (sib >> 3) & 7; + UChar base_r = sib & 7; + UInt d = getSDisp8(delta+1); + + if (index_r == R_ESP) { + DIS(buf, "%s%d(%s,,)", sorbTxt(sorb), d, nameIReg(4,base_r)); + *len = 3; + vpanic("disAMode(amd64):untested amode: 9"); + return disAMode_copy2tmp( + handleSegOverride(sorb, + binop(Iop_Add32, getIReg(4,base_r), mkU32(d)) )); + } else { + DIS(buf, "%s%d(%s,%s,%d)", sorbTxt(sorb), d, + nameIReg(4,base_r), nameIReg(4,index_r), 1<> 6) & 3; + UChar index_r = (sib >> 3) & 7; + UChar base_r = sib & 7; + ULong d = getSDisp32(delta+1); + + if (index_r == R_RSP && 0==getRexX(pfx)) { + DIS(buf, "%s%lld(%s,,)", sorbTxt(pfx), + d, nameIRegB(pfx,8,base_r)); + *len = 6; + vpanic("disAMode(amd64):untested amode: 11"); + return disAMode_copy2tmp( + handleSegOverride(pfx, + binop(Iop_Add64, getIRegB(pfx,8,base_r), mkU64(d)) )); + } else { + DIS(buf, "%s%lld(%s,%s,%d)", sorbTxt(pfx), d, + nameIRegB(pfx,8,base_r), + nameIRegX(pfx,8,index_r), 1<