From: Julian Seward Date: Wed, 3 Nov 2004 09:08:33 +0000 (+0000) Subject: Changes to support Memcheck: X-Git-Tag: svn/VALGRIND_3_0_1^2~856 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e5aed678c71a5b22728ac5266f0bf31cc1b24c6f;p=thirdparty%2Fvalgrind.git Changes to support Memcheck: * Pass host word type to instrumentation functions * irdefs.c: add beginnings of proper sanity checking for flatness * refine guest-state-layout stuff * new primop Iop_1Sto32 git-svn-id: svn://svn.valgrind.org/vex/trunk@478 --- diff --git a/VEX/priv/guest-x86/ghelpers.c b/VEX/priv/guest-x86/ghelpers.c index d2b6fd5c66..d9608a1577 100644 --- a/VEX/priv/guest-x86/ghelpers.c +++ b/VEX/priv/guest-x86/ghelpers.c @@ -1473,10 +1473,9 @@ VexGuestLayout .offset_SP = offsetof(VexGuestX86State,guest_ESP), .sizeof_SP = 4, - /* Describe any indexable sections */ - .n_descrs = 2, - .descrs[0] = { offsetof(VexGuestX86State,guest_FPREG), Ity_F64, 8 }, - .descrs[1] = { offsetof(VexGuestX86State,guest_FPTAG), Ity_I8, 8 }, + /* Describe the instruction pointer. */ + .offset_IP = offsetof(VexGuestX86State,guest_EIP), + .sizeof_IP = 4, /* Describe any sections to be regarded by Memcheck as 'always-defined'. */ diff --git a/VEX/priv/ir/irdefs.c b/VEX/priv/ir/irdefs.c index a956975728..e76f77ed00 100644 --- a/VEX/priv/ir/irdefs.c +++ b/VEX/priv/ir/irdefs.c @@ -1143,6 +1143,77 @@ Bool isPlausibleType ( IRType ty ) } +/*---------------------------------------------------------------*/ +/*--- Sanity checking -- FLATNESS ---*/ +/*---------------------------------------------------------------*/ + +/* Check that the canonical flatness constraints hold on an + IRStmt. The only place where any expression is allowed to be + non-atomic is the RHS of IRStmt_Tmp. */ + +/* Relies on: + inline static Bool isAtom ( IRExpr* e ) { + return e->tag == Iex_Tmp || e->tag == Iex_Const; + } +*/ + +Bool isFlatIRStmt ( IRStmt* st ) +{ + Int i; + IRExpr* e; + IRDirty* di; + + switch (st->tag) { + case Ist_Put: + return isAtom(st->Ist.Put.data); + case Ist_PutI: + return isAtom(st->Ist.PutI.ix) && isAtom(st->Ist.PutI.data); + case Ist_Tmp: + /* This is the only interesting case. The RHS can be any + expression, *but* all its subexpressions *must* be + atoms. */ + e = st->Ist.Tmp.data; + switch (e->tag) { + case Iex_Binder: return True; + case Iex_Get: return True; + case Iex_GetI: return isAtom(e->Iex.GetI.ix); + case Iex_Tmp: return True; + case Iex_Binop: return isAtom(e->Iex.Binop.arg1) + && isAtom(e->Iex.Binop.arg2); + case Iex_Unop: return isAtom(e->Iex.Unop.arg); + case Iex_LDle: return isAtom(e->Iex.LDle.addr); + case Iex_Const: return True; + case Iex_CCall: for (i = 0; e->Iex.CCall.args[i]; i++) + if (!isAtom(e->Iex.CCall.args[i])) + return False; + return True; + case Iex_Mux0X: return isAtom(e->Iex.Mux0X.cond) + && isAtom(e->Iex.Mux0X.expr0) + && isAtom(e->Iex.Mux0X.exprX); + default: vpanic("isFlatIRStmt(e)"); + } + /*notreached*/ + vassert(0); + case Ist_STle: + return isAtom(st->Ist.STle.addr) && isAtom(st->Ist.STle.data); + case Ist_Dirty: + di = st->Ist.Dirty.details; + if (!isAtom(di->guard)) + return False; + for (i = 0; di->args[i]; i++) + if (!isAtom(di->args[i])) + return False; + if (di->mAddr && !isAtom(di->mAddr)) + return False; + return True; + case Ist_Exit: + return isAtom(st->Ist.Exit.cond); + default: + vpanic("isFlatIRStmt(st)"); + } +} + + /*---------------------------------------------------------------*/ /*--- Sanity checking ---*/ /*---------------------------------------------------------------*/ @@ -1357,7 +1428,7 @@ void tcExpr ( IRBB* bb, IRStmt* stmt, IRExpr* expr, IRType gWordTy ) case Iex_CCall: if (!saneIRCallee(expr->Iex.CCall.cee)) sanityCheckFail(bb,stmt,"Iex.CCall.cee: bad IRCallee"); - if (expr->Iex.CCall.cee->regparms > countArgs(expr->Iex.CCall.args)) + if (expr->Iex.CCall.cee->regparms > countArgs(expr->Iex.CCall.args)) sanityCheckFail(bb,stmt,"Iex.CCall.cee: #regparms > #args"); for (i = 0; expr->Iex.CCall.args[i]; i++) tcExpr(bb,stmt, expr->Iex.CCall.args[i], gWordTy); @@ -1429,7 +1500,7 @@ void tcStmt ( IRBB* bb, IRStmt* stmt, IRType gWordTy ) d = stmt->Ist.Dirty.details; if (d->cee == NULL) goto bad_dirty; if (!saneIRCallee(d->cee)) goto bad_dirty; - if (d->cee->regparms > countArgs(d->args)) goto bad_dirty; + if (d->cee->regparms > countArgs(d->args)) goto bad_dirty; if (d->mFx == Ifx_None) { if (d->mAddr != NULL || d->mSize != 0) goto bad_dirty; @@ -1516,7 +1587,7 @@ void sanityCheckIRBB ( IRBB* bb, IRType guest_word_size ) def_counts[stmt->Ist.Tmp.tmp]++; if (def_counts[stmt->Ist.Tmp.tmp] > 1) sanityCheckFail(bb, stmt, - "IRStmt.Tmp: destinatiion tmp is assigned more than once"); + "IRStmt.Tmp: destination tmp is assigned more than once"); } else if (stmt->tag == Ist_Dirty diff --git a/VEX/priv/main/vex_main.c b/VEX/priv/main/vex_main.c index f3b76d5169..e0b0983655 100644 --- a/VEX/priv/main/vex_main.c +++ b/VEX/priv/main/vex_main.c @@ -126,8 +126,8 @@ TranslateResult LibVEX_Translate ( /* OUT: how much of the output area is used. */ Int* host_bytes_used, /* IN: optionally, two instrumentation functions. */ - IRBB* (*instrument1) ( IRBB*, VexGuestLayout* ), - IRBB* (*instrument2) ( IRBB*, VexGuestLayout* ), + IRBB* (*instrument1) ( IRBB*, VexGuestLayout*, IRType hWordTy ), + IRBB* (*instrument2) ( IRBB*, VexGuestLayout*, IRType hWordTy ), /* IN: optionally, an access check function for guest code. */ Bool (*byte_accessible) ( Addr64 ), /* IN: debug: trace vex activity at various points */ @@ -160,7 +160,8 @@ TranslateResult LibVEX_Translate ( HInstrArray* rcode; Int i, j, k, out_used, guest_sizeB; UChar insn_bytes[32]; - IRType guest_word_size; + IRType guest_word_type; + IRType host_word_type; guest_layout = NULL; available_real_regs = NULL; @@ -177,7 +178,8 @@ TranslateResult LibVEX_Translate ( emit = NULL; specHelper = NULL; preciseMemExnsFn = NULL; - guest_word_size = Ity_INVALID; + guest_word_type = Ity_INVALID; + host_word_type = Ity_INVALID; vex_traceflags = traceflags; @@ -200,6 +202,7 @@ TranslateResult LibVEX_Translate ( iselBB = iselBB_X86; emit = (Int(*)(UChar*,Int,HInstr*)) emit_X86Instr; host_is_bigendian = False; + host_word_type = Ity_I32; break; default: vpanic("LibVEX_Translate: unsupported target insn set"); @@ -211,7 +214,7 @@ TranslateResult LibVEX_Translate ( bbToIR = bbToIR_X86Instr; specHelper = x86guest_spechelper; guest_sizeB = sizeof(VexGuestX86State); - guest_word_size = Ity_I32; + guest_word_type = Ity_I32; guest_layout = &x86guest_layout; break; default: @@ -246,12 +249,12 @@ TranslateResult LibVEX_Translate ( } /* Sanity check the initial IR. */ - sanityCheckIRBB(irbb, guest_word_size); + sanityCheckIRBB(irbb, guest_word_type); /* Clean it up, hopefully a lot. */ irbb = do_iropt_BB ( irbb, specHelper, preciseMemExnsFn, guest_bytes_addr ); - sanityCheckIRBB(irbb, guest_word_size); + sanityCheckIRBB(irbb, guest_word_type); if (vex_traceflags & VEX_TRACE_OPT1) { vex_printf("\n------------------------" @@ -263,9 +266,9 @@ TranslateResult LibVEX_Translate ( /* Get the thing instrumented. */ if (instrument1) - irbb = (*instrument1)(irbb, guest_layout); + irbb = (*instrument1)(irbb, guest_layout, host_word_type); if (instrument2) - irbb = (*instrument2)(irbb, guest_layout); + irbb = (*instrument2)(irbb, guest_layout, host_word_type); if (vex_traceflags & VEX_TRACE_INST) { vex_printf("\n------------------------" @@ -276,7 +279,7 @@ TranslateResult LibVEX_Translate ( } if (instrument1 || instrument2) - sanityCheckIRBB(irbb, guest_word_size); + sanityCheckIRBB(irbb, guest_word_type); /* Turn it into virtual-registerised code. */ do_deadcode_BB( irbb ); diff --git a/VEX/pub/libvex.h b/VEX/pub/libvex.h index e8cbc8f506..757ae9f3aa 100644 --- a/VEX/pub/libvex.h +++ b/VEX/pub/libvex.h @@ -102,14 +102,15 @@ extern void* LibVEX_Alloc ( Int nbytes ); typedef struct { - /* Total size of the guest state, in bytes. */ + /* Total size of the guest state, in bytes. Must be + 8-aligned. */ Int total_sizeB; /* Whereabouts is the stack pointer? */ Int offset_SP; Int sizeof_SP; /* 4 or 8 */ - /* Describe the indexed sections */ - Int n_descrs; /* must be 0 .. VEXG_N_DESCRS */ - IRArray descrs[VEXGLO_N_DESCRS]; + /* Whereabouts is the instruction pointer? */ + Int offset_IP; + Int sizeof_IP; /* 4 or 8 */ /* Describe parts of the guest state regarded as 'always defined'. */ Int n_alwaysDefd; @@ -147,8 +148,8 @@ TranslateResult LibVEX_Translate ( /* OUT: how much of the output area is used. */ Int* host_bytes_used, /* IN: optionally, two instrumentation functions. */ - IRBB* (*instrument1) ( IRBB*, VexGuestLayout* ), - IRBB* (*instrument2) ( IRBB*, VexGuestLayout* ), + IRBB* (*instrument1) ( IRBB*, VexGuestLayout*, IRType hWordTy ), + IRBB* (*instrument2) ( IRBB*, VexGuestLayout*, IRType hWordTy ), /* IN: optionally, an access check function for guest code. */ Bool (*byte_accessible) ( Addr64 ), /* IN: debug: trace vex activity at various points */ diff --git a/VEX/pub/libvex_ir.h b/VEX/pub/libvex_ir.h index 477bf47969..d8da1963dc 100644 --- a/VEX/pub/libvex_ir.h +++ b/VEX/pub/libvex_ir.h @@ -190,6 +190,7 @@ typedef Iop_32to1, /* :: Ity_I32 -> Ity_Bit, just select bit[0] */ Iop_1Uto8, /* :: Ity_Bit -> Ity_I8, unsigned widen */ Iop_1Uto32, /* :: Ity_Bit -> Ity_I32, unsigned widen */ + Iop_1Sto32, /* :: Ity_Bit -> Ity_I32, signed widen */ /* ------ Floating point. We try and be IEEE754 compliant. ------ */ @@ -700,6 +701,7 @@ extern IRType typeOfIRExpr ( IRTypeEnv*, IRExpr* ); /* Sanity check a BB of IR */ extern void sanityCheckIRBB ( IRBB* bb, IRType guest_word_size ); +extern Bool isFlatIRStmt ( IRStmt* ); /* Is this any value actually in the enumeration 'IRType' ? */ extern Bool isPlausibleType ( IRType ty );