|
From: <sv...@va...> - 2005-11-04 14:18:35
|
Author: sewardj
Date: 2005-11-04 14:18:31 +0000 (Fri, 04 Nov 2005)
New Revision: 1432
Log:
Handle address-size overrides in the common case (explicit memory referen=
ces).
Modified:
trunk/priv/guest-amd64/toIR.c
Modified: trunk/priv/guest-amd64/toIR.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/priv/guest-amd64/toIR.c 2005-11-03 14:00:57 UTC (rev 1431)
+++ trunk/priv/guest-amd64/toIR.c 2005-11-04 14:18:31 UTC (rev 1432)
@@ -93,6 +93,35 @@
//.. should ever become relevant).
*/
=20
+/* Notes re address size overrides (0x67).
+
+ According to the AMD documentation (24594 Rev 3.09, Sept 2003,
+ "AMD64 Architecture Programmer's Manual Volume 3: General-Purpose
+ and System Instructions"), Section 1.2.3 ("Address-Size Override
+ Prefix"):
+
+ 0x67 applies to all explicit memory references, causing the top
+ 32 bits of the effective address to become zero.
+
+ 0x67 has no effect on stack references (push/pop); these always
+ use a 64-bit address.
+
+ 0x67 changes the interpretation of instructions which implicitly
+ reference RCX/RSI/RDI, so that in fact ECX/ESI/EDI are used
+ instead. These are:
+
+ cmp{s,sb,sw,sd,sq}
+ in{s,sb,sw,sd}
+ jcxz, jecxz, jrcxz
+ lod{s,sb,sw,sd,sq}
+ loop{,e,bz,be,z}
+ mov{s,sb,sw,sd,sq}
+ out{s,sb,sw,sd}
+ rep{,e,ne,nz}
+ sca{s,sb,sw,sd,sq}
+ sto{s,sb,sw,sd,sq}
+ xlat{,b} */
+
/* Translates AMD64 code to IR. */
=20
#include "libvex_basictypes.h"
@@ -1900,15 +1929,18 @@
=20
/* 'virtual' is an IRExpr* holding a virtual address. Convert it to a
linear address by adding any required segment override as indicated
- by sorb. */
+ by sorb, and also dealing with any address size override
+ present. */
static
-IRExpr* handleSegOverride ( Prefix pfx, IRExpr* virtual )
+IRExpr* handleAddrOverrides ( Prefix pfx, IRExpr* virtual )
{
+ /* --- segment overrides --- */
+
if (pfx & PFX_FS) {
/* Note that this is a linux-kernel specific hack that relies
on the assumption that %fs is always zero. */
/* return virtual + guest_FS_ZERO. */
- return binop(Iop_Add64, virtual, IRExpr_Get(OFFB_FS_ZERO, Ity_I64)=
);
+ virtual =3D binop(Iop_Add64, virtual, IRExpr_Get(OFFB_FS_ZERO, Ity=
_I64));
}
=20
if (pfx & PFX_GS) {
@@ -1916,6 +1948,11 @@
}
=20
/* cs, ds, es and ss are simply ignored in 64-bit mode. */
+
+ /* --- address size override --- */
+ if (haveASO(pfx))
+ virtual =3D unop(Iop_32Uto64, unop(Iop_64to32, virtual));
+
return virtual;
}
=20
@@ -1933,7 +1970,7 @@
//.. case 0x26: sreg =3D R_ES; break;
//.. case 0x64: sreg =3D R_FS; break;
//.. case 0x65: sreg =3D R_GS; break;
-//.. default: vpanic("handleSegOverride(x86,guest)");
+//.. default: vpanic("handleAddrOverrides(x86,guest)");
//.. }
//..=20
//.. hWordTy =3D sizeof(HWord)=3D=3D4 ? Ity_I32 : Ity_I64;
@@ -2033,7 +2070,7 @@
DIS(buf, "%s(%s)", sorbTxt(pfx), nameIRegRexB(8,pfx,rm));
*len =3D 1;
return disAMode_copy2tmp(
- handleSegOverride(pfx, getIRegRexB(8,pfx,rm)));
+ handleAddrOverrides(pfx, getIRegRexB(8,pfx,rm)));
}
=20
/* REX.B=3D=3D0: d8(%rax) ... d8(%rdi), not including d8(%rsp)=20
@@ -2050,7 +2087,7 @@
}
*len =3D 2;
return disAMode_copy2tmp(
- handleSegOverride(pfx,
+ handleAddrOverrides(pfx,
binop(Iop_Add64,getIRegRexB(8,pfx,rm),mkU64(d))));
}
=20
@@ -2064,7 +2101,7 @@
DIS(buf, "%s%lld(%s)", sorbTxt(pfx), d, nameIRegRexB(8,pfx,rm=
));
*len =3D 5;
return disAMode_copy2tmp(
- handleSegOverride(pfx,
+ handleAddrOverrides(pfx,
binop(Iop_Add64,getIRegRexB(8,pfx,rm),mkU64(d))));
}
=20
@@ -2089,7 +2126,7 @@
guest_RIP_next_assumed =3D guest_RIP_bbstart=20
+ delta+4 + extra_bytes;
return disAMode_copy2tmp(=20
- handleSegOverride(pfx,=20
+ handleAddrOverrides(pfx,=20
binop(Iop_Add64, mkU64(guest_RIP_next_assumed),=20
mkU64(d))));
}
@@ -2133,7 +2170,7 @@
*len =3D 2;
return
disAMode_copy2tmp(=20
- handleSegOverride(pfx,
+ handleAddrOverrides(pfx,
binop(Iop_Add64,=20
getIRegRexB(8,pfx,base_r),
binop(Iop_Shl64, getIReg64rexX(pfx,index_r),
@@ -2147,7 +2184,7 @@
*len =3D 6;
return
disAMode_copy2tmp(
- handleSegOverride(pfx,=20
+ handleAddrOverrides(pfx,=20
binop(Iop_Add64,
binop(Iop_Shl64, getIReg64rexX(pfx,index_r),=20
mkU8(scale)),
@@ -2158,7 +2195,7 @@
DIS(buf, "%s(%s)", sorbTxt(pfx), nameIRegRexB(8,pfx,base_r))=
;
*len =3D 2;
return disAMode_copy2tmp(
- handleSegOverride(pfx, getIRegRexB(8,pfx,base_r)));
+ handleAddrOverrides(pfx, getIRegRexB(8,pfx,base_r)));
}
=20
if (index_is_SP && base_is_BPor13) {
@@ -2166,7 +2203,7 @@
DIS(buf, "%s%lld", sorbTxt(pfx), d);
*len =3D 6;
return disAMode_copy2tmp(
- handleSegOverride(pfx, mkU64(d)));
+ handleAddrOverrides(pfx, mkU64(d)));
}
=20
vassert(0);
@@ -2193,7 +2230,7 @@
d, nameIRegRexB(8,pfx,base_r));
*len =3D 3;
return disAMode_copy2tmp(
- handleSegOverride(pfx,=20
+ handleAddrOverrides(pfx,=20
binop(Iop_Add64, getIRegRexB(8,pfx,base_r), mkU64(=
d)) ));
} else {
if (scale =3D=3D 0) {
@@ -2208,7 +2245,7 @@
*len =3D 3;
return=20
disAMode_copy2tmp(
- handleSegOverride(pfx,
+ handleAddrOverrides(pfx,
binop(Iop_Add64,
binop(Iop_Add64,=20
getIRegRexB(8,pfx,base_r),=20
@@ -2240,7 +2277,7 @@
d, nameIRegRexB(8,pfx,base_r));
*len =3D 6;
return disAMode_copy2tmp(
- handleSegOverride(pfx,=20
+ handleAddrOverrides(pfx,=20
binop(Iop_Add64, getIRegRexB(8,pfx,base_r), mkU64(=
d)) ));
} else {
if (scale =3D=3D 0) {
@@ -2255,7 +2292,7 @@
*len =3D 6;
return=20
disAMode_copy2tmp(
- handleSegOverride(pfx,
+ handleAddrOverrides(pfx,
binop(Iop_Add64,
binop(Iop_Add64,=20
getIRegRexB(8,pfx,base_r),=20
@@ -7870,10 +7907,8 @@
}
=20
not_a_prefix:
+
/* Dump invalid combinations */
- if (pfx & PFX_ASO)=20
- goto decode_failure; /* don't support address-size override */
-
n =3D 0;
if (pfx & PFX_F2) n++;
if (pfx & PFX_F3) n++;
@@ -7890,6 +7925,9 @@
if (n > 1)=20
goto decode_failure; /* multiple seg overrides =3D=3D illegal */
=20
+ if (pfx & PFX_GS)
+ goto decode_failure; /* legal, but unsupported right now */
+
/* Set up sz. */
sz =3D 4;
if (pfx & PFX_66) sz =3D 2;
@@ -11728,7 +11766,7 @@
delta +=3D 8;
ty =3D szToITy(sz);
addr =3D newTemp(Ity_I64);
- assign( addr, handleSegOverride(pfx, mkU64(d64)) );
+ assign( addr, handleAddrOverrides(pfx, mkU64(d64)) );
putIRegRAX(sz, loadLE( ty, mkexpr(addr) ));
DIP("mov%c %s0x%llx, %s\n", nameISize(sz),=20
sorbTxt(pfx), d64,
@@ -11746,7 +11784,7 @@
delta +=3D 8;
ty =3D szToITy(sz);
addr =3D newTemp(Ity_I64);
- assign( addr, handleSegOverride(pfx, mkU64(d64)) );
+ assign( addr, handleAddrOverrides(pfx, mkU64(d64)) );
storeLE( mkexpr(addr), getIRegRAX(sz) );
DIP("mov%c %s, %s0x%llx\n", nameISize(sz), nameIRegRAX(sz),
sorbTxt(pfx), d64);
@@ -12475,6 +12513,8 @@
case 0xAE:
case 0xAF:
/* F2 AE/AF: repne scasb/repne scas{w,l,q} */
+ if (haveASO(pfx))=20
+ goto decode_failure;
if (haveF2(pfx) && !haveF3(pfx)) {
if (opc =3D=3D 0xAE)
sz =3D 1;
@@ -12497,6 +12537,8 @@
case 0xA6:
case 0xA7:
/* F3 A6/A7: repe cmps/rep cmps{w,l,q} */
+ if (haveASO(pfx))=20
+ goto decode_failure;
if (haveF3(pfx) && !haveF2(pfx)) {
if (opc =3D=3D 0xA6)
sz =3D 1;
@@ -12512,6 +12554,8 @@
case 0xAA:
case 0xAB:
/* F3 AA/AB: rep stosb/rep stos{w,l,q} */
+ if (haveASO(pfx))=20
+ goto decode_failure;
if (haveF3(pfx) && !haveF2(pfx)) {
if (opc =3D=3D 0xAA)
sz =3D 1;
@@ -12534,6 +12578,8 @@
case 0xA4:
case 0xA5:
/* F3 A4: rep movsb */
+ if (haveASO(pfx))=20
+ goto decode_failure;
if (haveF3(pfx) && !haveF2(pfx)) {
if (opc =3D=3D 0xA4)
sz =3D 1;
@@ -12625,7 +12671,7 @@
//.. //-- case 0xD7: /* XLAT */
//.. //-- t1 =3D newTemp(cb); t2 =3D newTemp(cb);
//.. //-- uInstr2(cb, GET, sz, ArchReg, R_EBX, TempReg, t1); /* ge=
t eBX */
-//.. //-- handleSegOverride( cb, sorb, t1 ); /* make=
t1 DS:eBX */
+//.. //-- handleAddrOverrides( cb, sorb, t1 ); /* ma=
ke t1 DS:eBX */
//.. //-- uInstr2(cb, GET, 1, ArchReg, R_AL, TempReg, t2); /* get =
AL */
//.. //-- /* Widen %AL to 32 bits, so it's all defined when we add=
it. */
//.. //-- uInstr1(cb, WIDEN, 4, TempReg, t2);
|