|
From: <sv...@va...> - 2005-05-12 17:55:04
|
Author: sewardj
Date: 2005-05-12 18:55:01 +0100 (Thu, 12 May 2005)
New Revision: 1193
Modified:
trunk/priv/guest-amd64/toIR.c
trunk/priv/host-amd64/isel.c
trunk/priv/ir/irdefs.c
trunk/priv/ir/iropt.c
trunk/pub/libvex_ir.h
Log:
Add the beginnings of what might be a general mechanism to pass
ABI-specific knowledge through the IR compilation pipeline. This
entails a new IR construction, AbiHint.
Currently there is only one kind of hint, and it is generated by the
amd64 front end. This tells whoever wants to know that a function
call or return has happened, and so the 128 bytes below %rsp should be
considered undefined.
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-05-12 02:14:52 UTC (rev 1192)
+++ trunk/priv/guest-amd64/toIR.c 2005-05-12 17:55:01 UTC (rev 1193)
@@ -2077,7 +2077,21 @@
}
}
=20
+/* Let new_rsp be the %rsp value after a call/return. This function
+ generates an AbiHint to say that -128(%rsp) .. -1(%rsp) should now
+ be regarded as uninitialised.
+*/
+static void make_redzone_AbiHint ( IRTemp new_rsp, HChar* who )
+{
+ if (0) vex_printf("AbiHint: %s\n", who);
+ vassert(typeOfIRTemp(irbb->tyenv, new_rsp) =3D=3D Ity_I64);
+ stmt( IRStmt_AbiHint(=20
+ binop(Iop_Sub64, mkexpr(new_rsp), mkU64(128)),=20
+ 128=20
+ ));
+}
=20
+
/*------------------------------------------------------------*/
/*--- Disassembling addressing modes ---*/
/*------------------------------------------------------------*/
@@ -3758,6 +3772,7 @@
assign(t2, binop(Iop_Sub64, getIReg64(R_RSP), mkU64(8)));
putIReg64(R_RSP, mkexpr(t2));
storeLE( mkexpr(t2), mkU64(guest_rip_bbstart+delta+1));
+ make_redzone_AbiHint(t2, "call-Ev(reg)");
jmp_treg(Ijk_Call,t3);
*whatNext =3D Dis_StopHere;
showSz =3D False;
@@ -3812,6 +3827,7 @@
assign(t2, binop(Iop_Sub64, getIReg64(R_RSP), mkU64(8)));
putIReg64(R_RSP, mkexpr(t2));
storeLE( mkexpr(t2), mkU64(guest_rip_bbstart+delta+len));
+ make_redzone_AbiHint(t2, "call-Ev(mem)");
jmp_treg(Ijk_Call,t3);
*whatNext =3D Dis_StopHere;
showSz =3D False;
@@ -7266,9 +7282,12 @@
{
IRTemp t1 =3D newTemp(Ity_I64);=20
IRTemp t2 =3D newTemp(Ity_I64);
+ IRTemp t3 =3D newTemp(Ity_I64);
assign(t1, getIReg64(R_RSP));
assign(t2, loadLE(Ity_I64,mkexpr(t1)));
- putIReg64(R_RSP, binop(Iop_Add64, mkexpr(t1), mkU64(8+d64)));
+ assign(t3, binop(Iop_Add64, mkexpr(t1), mkU64(8+d64)));
+ putIReg64(R_RSP, mkexpr(t3));
+ make_redzone_AbiHint(t3, "ret");
jmp_treg(Ijk_Ret,t2);
}
=20
@@ -11490,6 +11509,7 @@
assign(t1, binop(Iop_Sub64, getIReg64(R_RSP), mkU64(8)));
putIReg64(R_RSP, mkexpr(t1));
storeLE( mkexpr(t1), mkU64(guest_rip_bbstart+delta));
+ make_redzone_AbiHint(t1, "call-d32");
if (resteerOK && resteerOkFn((Addr64)d64)) {
/* follow into the call target. */
whatNext =3D Dis_Resteer;
Modified: trunk/priv/host-amd64/isel.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/host-amd64/isel.c 2005-05-12 02:14:52 UTC (rev 1192)
+++ trunk/priv/host-amd64/isel.c 2005-05-12 17:55:01 UTC (rev 1193)
@@ -3696,6 +3696,12 @@
case Ist_IMark:
return;
=20
+ /* --------- ABI HINT --------- */
+ /* These have no meaning (denotation in the IR) and so we ignore
+ them ... if any actually made it this far. */
+ case Ist_AbiHint:
+ return;
+
/* --------- NO-OP --------- */
case Ist_NoOp:
return;
Modified: trunk/priv/ir/irdefs.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/ir/irdefs.c 2005-05-12 02:14:52 UTC (rev 1192)
+++ trunk/priv/ir/irdefs.c 2005-05-12 17:55:01 UTC (rev 1193)
@@ -613,6 +613,11 @@
vex_printf( "------ IMark(0x%llx, %d) ------",=20
s->Ist.IMark.addr, s->Ist.IMark.len);
break;
+ case Ist_AbiHint:
+ vex_printf("=3D=3D=3D=3D=3D=3D AbiHint(");
+ ppIRExpr(s->Ist.AbiHint.base);
+ vex_printf(", %d) =3D=3D=3D=3D=3D=3D", s->Ist.AbiHint.len);
+ break;
case Ist_Put:
vex_printf( "PUT(%d) =3D ", s->Ist.Put.offset);
ppIRExpr(s->Ist.Put.data);
@@ -948,6 +953,13 @@
s->Ist.IMark.len =3D len;
return s;
}
+IRStmt* IRStmt_AbiHint ( IRExpr* base, Int len ) {
+ IRStmt* s =3D LibVEX_Alloc(sizeof(IRStmt));
+ s->tag =3D Ist_AbiHint;
+ s->Ist.AbiHint.base =3D base;
+ s->Ist.AbiHint.len =3D len;
+ return s;
+}
IRStmt* IRStmt_Put ( Int off, IRExpr* data ) {
IRStmt* s =3D LibVEX_Alloc(sizeof(IRStmt));
s->tag =3D Ist_Put;
@@ -1153,6 +1165,9 @@
switch (s->tag) {
case Ist_NoOp:
return IRStmt_NoOp();
+ case Ist_AbiHint:
+ return IRStmt_AbiHint(dopyIRExpr(s->Ist.AbiHint.base),
+ s->Ist.AbiHint.len);
case Ist_IMark:
return IRStmt_IMark(s->Ist.IMark.addr, s->Ist.IMark.len);
case Ist_Put:=20
@@ -1648,6 +1663,8 @@
IRDirty* di;
=20
switch (st->tag) {
+ case Ist_AbiHint:
+ return isIRAtom(st->Ist.AbiHint.base);
case Ist_Put:
return isIRAtom(st->Ist.Put.data);
case Ist_PutI:
@@ -1835,6 +1852,9 @@
switch (stmt->tag) {
case Ist_IMark:
break;
+ case Ist_AbiHint:
+ useBeforeDef_Expr(bb,stmt,stmt->Ist.AbiHint.base,def_counts);
+ break;
case Ist_Put:
useBeforeDef_Expr(bb,stmt,stmt->Ist.Put.data,def_counts);
break;
@@ -1982,6 +2002,11 @@
if (stmt->Ist.IMark.len < 0 || stmt->Ist.IMark.len > 20)
sanityCheckFail(bb,stmt,"IRStmt.IMark.len: implausible");
break;
+ case Ist_AbiHint:
+ if (typeOfIRExpr(tyenv, stmt->Ist.AbiHint.base) !=3D gWordTy)
+ sanityCheckFail(bb,stmt,"IRStmt.AbiHint.base: "
+ "not :: guest word type");
+ break;
case Ist_Put:
tcExpr( bb, stmt, stmt->Ist.Put.data, gWordTy );
if (typeOfIRExpr(tyenv,stmt->Ist.Put.data) =3D=3D Ity_I1)
Modified: trunk/priv/ir/iropt.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/ir/iropt.c 2005-05-12 02:14:52 UTC (rev 1192)
+++ trunk/priv/ir/iropt.c 2005-05-12 17:55:01 UTC (rev 1193)
@@ -414,6 +414,10 @@
case Ist_IMark:
addStmtToIRBB(bb, st);
break;
+ case Ist_AbiHint:
+ e1 =3D flatten_Expr(bb, st->Ist.AbiHint.base);
+ addStmtToIRBB(bb, IRStmt_AbiHint(e1, st->Ist.AbiHint.len));
+ break;
case Ist_Exit:
e1 =3D flatten_Expr(bb, st->Ist.Exit.guard);
addStmtToIRBB(bb, IRStmt_Exit(e1, st->Ist.Exit.jk,
@@ -671,7 +675,10 @@
crude solution is just to flush everything; we could easily
enough do a lot better if needed. */
/* Probably also overly-conservative, but also dump everything
- if we hit a memory fence. */
+ if we hit a memory fence. Ditto AbiHints.*/
+ case Ist_AbiHint:
+ vassert(isIRAtom(st->Ist.AbiHint.base));
+ /* fall through */
case Ist_MFence:
case Ist_Dirty:
for (j =3D 0; j < env->used; j++)
@@ -1507,6 +1514,12 @@
# endif
=20
switch (st->tag) {
+ case Ist_AbiHint:
+ vassert(isIRAtom(st->Ist.AbiHint.base));
+ return IRStmt_AbiHint(
+ fold_Expr(subst_Expr(env, st->Ist.AbiHint.base)),
+ st->Ist.AbiHint.len
+ );
case Ist_Put:
vassert(isIRAtom(st->Ist.Put.data));
return IRStmt_Put(
@@ -1732,6 +1745,9 @@
Int i;
IRDirty* d;
switch (st->tag) {
+ case Ist_AbiHint:
+ addUses_Expr(set, st->Ist.AbiHint.base);
+ return;
case Ist_PutI:
addUses_Expr(set, st->Ist.PutI.ix);
addUses_Expr(set, st->Ist.PutI.data);
@@ -2573,7 +2589,8 @@
return False;
=20
case Ist_MFence:
- /* just be paranoid ... this should be rare. */
+ case Ist_AbiHint:
+ /* just be paranoid ... these should be rare. */
return True;
=20
case Ist_Dirty:
@@ -2804,6 +2821,9 @@
case Ist_NoOp:
case Ist_IMark:
break;
+ case Ist_AbiHint:
+ deltaIRExpr(st->Ist.AbiHint.base, delta);
+ break;
case Ist_Put:
deltaIRExpr(st->Ist.Put.data, delta);
break;
@@ -3166,6 +3186,9 @@
Int i;
IRDirty* d;
switch (st->tag) {
+ case Ist_AbiHint:
+ occCount_Expr(env, st->Ist.AbiHint.base);
+ return;
case Ist_Tmp:=20
occCount_Expr(env, st->Ist.Tmp.data);=20
return;=20
@@ -3293,6 +3316,11 @@
IRDirty* d;
IRDirty* d2;
switch (st->tag) {
+ case Ist_AbiHint:
+ return IRStmt_AbiHint(
+ tbSubst_Expr(env, st->Ist.AbiHint.base),
+ st->Ist.AbiHint.len
+ );
case Ist_STle:
return IRStmt_STle(
tbSubst_Expr(env, st->Ist.STle.addr),
@@ -3580,6 +3608,8 @@
computation prior to it is forced to complete before
proceeding with the fence. */
|| st->tag =3D=3D Ist_MFence
+ /* also be (probably overly) paranoid re AbiHints */
+ || st->tag =3D=3D Ist_AbiHint
);
/*
if (ti->invalidateMe)
@@ -3691,6 +3721,9 @@
for (i =3D 0; i < bb->stmts_used; i++) {
st =3D bb->stmts[i];
switch (st->tag) {
+ case Ist_AbiHint:
+ vassert(isIRAtom(st->Ist.AbiHint.base));
+ break;
case Ist_PutI:=20
return True;
case Ist_Tmp: =20
Modified: trunk/pub/libvex_ir.h
=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/pub/libvex_ir.h 2005-05-12 02:14:52 UTC (rev 1192)
+++ trunk/pub/libvex_ir.h 2005-05-12 17:55:01 UTC (rev 1193)
@@ -896,19 +896,32 @@
=20
/* ------------------ Statements ------------------ */
=20
-/* The possible kinds of statements are as follows: */
+/* The possible kinds of statements are as follows. Those marked
+ OPTIONAL are hints of one kind or another, and as such do not
+ denote any change in the guest state or of IR temporaries. They
+ can therefore be omitted without changing the meaning denoted by
+ the IR.=20
+
+ At the moment, the only AbiHint is one which indicates that a given
+ chunk of address space has become undefined. This is used on
+ amd64-linux to pass stack-redzoning hints to whoever wants to see
+ them.
+*/
typedef=20
enum {
- Ist_NoOp, /* no-op (usually resulting from IR optimisation) */
- Ist_IMark, /* instruction mark: describe addr/len of guest insn
- whose IR follows */
- Ist_Put, /* write guest state, fixed offset */
- Ist_PutI, /* write guest state, run-time offset */
- Ist_Tmp, /* assign value to temporary */
- Ist_STle, /* little-endian write to memory */
- Ist_Dirty, /* call complex ("dirty") helper function */
- Ist_MFence, /* memory fence */
- Ist_Exit /* conditional exit from BB */
+ Ist_NoOp, /* OPTIONAL: no-op (usually resulting from IR
+ optimisation) */
+ Ist_IMark, /* OPTIONAL: instruction mark: describe addr/len of
+ guest insn whose IR follows. */
+ Ist_AbiHint, /* OPTIONAL: tell me something about this
+ platform's ABI */
+ Ist_Put, /* write guest state, fixed offset */
+ Ist_PutI, /* write guest state, run-time offset */
+ Ist_Tmp, /* assign value to temporary */
+ Ist_STle, /* little-endian write to memory */
+ Ist_Dirty, /* call complex ("dirty") helper function */
+ Ist_MFence, /* memory fence */
+ Ist_Exit /* conditional exit from BB */
}=20
IRStmtTag;
=20
@@ -923,6 +936,11 @@
Int len;
} IMark;
struct {
+ /* [base .. base+len-1] has become uninitialised */
+ IRExpr* base;
+ Int len;
+ } AbiHint;
+ struct {
Int offset;
IRExpr* data;
} Put;
@@ -954,16 +972,17 @@
}
IRStmt;
=20
-extern IRStmt* IRStmt_NoOp ( void );
-extern IRStmt* IRStmt_IMark ( Addr64 addr, Int len );
-extern IRStmt* IRStmt_Put ( Int off, IRExpr* data );
-extern IRStmt* IRStmt_PutI ( IRArray* descr, IRExpr* ix, Int bias,=20
- IRExpr* data );
-extern IRStmt* IRStmt_Tmp ( IRTemp tmp, IRExpr* data );
-extern IRStmt* IRStmt_STle ( IRExpr* addr, IRExpr* data );
-extern IRStmt* IRStmt_Dirty ( IRDirty* details );
-extern IRStmt* IRStmt_MFence ( void );
-extern IRStmt* IRStmt_Exit ( IRExpr* guard, IRJumpKind jk, IRConst* ds=
t );
+extern IRStmt* IRStmt_NoOp ( void );
+extern IRStmt* IRStmt_IMark ( Addr64 addr, Int len );
+extern IRStmt* IRStmt_AbiHint ( IRExpr* base, Int len );
+extern IRStmt* IRStmt_Put ( Int off, IRExpr* data );
+extern IRStmt* IRStmt_PutI ( IRArray* descr, IRExpr* ix, Int bias,=20
+ IRExpr* data );
+extern IRStmt* IRStmt_Tmp ( IRTemp tmp, IRExpr* data );
+extern IRStmt* IRStmt_STle ( IRExpr* addr, IRExpr* data );
+extern IRStmt* IRStmt_Dirty ( IRDirty* details );
+extern IRStmt* IRStmt_MFence ( void );
+extern IRStmt* IRStmt_Exit ( IRExpr* guard, IRJumpKind jk, IRConst* d=
st );
=20
extern IRStmt* dopyIRStmt ( IRStmt* );
=20
|