From: Julian Seward Date: Thu, 9 Jul 2009 10:45:11 +0000 (+0000) Subject: Liberalise IRTemp bookkeeping in the h_ instrumenter, so as to allow X-Git-Tag: svn/VALGRIND_3_5_0~430 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=338cd1a59a139b8fc04e97dac0393157f70c9880;p=thirdparty%2Fvalgrind.git Liberalise IRTemp bookkeeping in the h_ instrumenter, so as to allow addition of non-shadow IRTemps without causing it to collapse into assertion failures. This changes is a simplified version of what was committed in svn://svn.valgrind.org/valgrind/branches/DCAS/memcheck/mc_translate.c r10109. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@10417 --- diff --git a/exp-ptrcheck/h_main.c b/exp-ptrcheck/h_main.c index d5e532fb1c..aaac5cc167 100644 --- a/exp-ptrcheck/h_main.c +++ b/exp-ptrcheck/h_main.c @@ -3447,24 +3447,61 @@ static VG_REGPARM(2) Seg* do_mulW(Seg* seg1, Seg* seg2) abstractify the sg_ instrumentation. See comments in sg_main.c's instrumentation section for further details. */ + +/* Carries info about a particular tmp. The tmp's number is not + recorded, as this is implied by (equal to) its index in the tmpMap + in PCEnv. The tmp's type is also not recorded, as this is present + in PCEnv.sb->tyenv. + + When .kind is NonShad, .shadow may give the identity of the temp + currently holding the associated shadow value, or it may be + IRTemp_INVALID if code to compute the shadow has not yet been + emitted. + + When .kind is Shad tmp holds a shadow value, and so .shadow must be + IRTemp_INVALID, since it is illogical for a shadow tmp itself to be + shadowed. +*/ +typedef + enum { NonShad=1, Shad=2 } + TempKind; + +typedef + struct { + TempKind kind; + IRTemp shadow; + } + TempMapEnt; + + + /* Carries around state during Ptrcheck instrumentation. */ typedef struct { /* MODIFIED: the superblock being constructed. IRStmts are added. */ - IRSB* bb; + IRSB* sb; Bool trace; - /* MODIFIED: a table [0 .. #temps_in_original_bb-1] which maps - original temps to their current their current shadow temp. - Initially all entries are IRTemp_INVALID. Entries are added - lazily since many original temps are not used due to - optimisation prior to instrumentation. Note that only - integer temps of the guest word size are shadowed, since it - is impossible (or meaningless) to hold a pointer in any other - type of temp. */ - IRTemp* tmpMap; - Int n_originalTmps; /* for range checking */ + /* MODIFIED: a table [0 .. #temps_in_sb-1] which gives the + current kind and possibly shadow temps for each temp in the + IRSB being constructed. Note that it does not contain the + type of each tmp. If you want to know the type, look at the + relevant entry in sb->tyenv. It follows that at all times + during the instrumentation process, the valid indices for + tmpMap and sb->tyenv are identical, being 0 .. N-1 where N is + total number of NonShad and Shad temps allocated so far. + + The reason for this strange split (types in one place, all + other info in another) is that we need the types to be + attached to sb so as to make it possible to do + "typeOfIRExpr(mce->bb->tyenv, ...)" at various places in the + instrumentation process. + + Note that only integer temps of the guest word size are + shadowed, since it is impossible (or meaningless) to hold a + pointer in any other type of temp. */ + XArray* /* of TempMapEnt */ qmpMap; /* READONLY: the host word type. Needed for constructing arguments of type 'HWord' to be passed to helper functions. @@ -3504,18 +3541,41 @@ typedef sanity checker should catch all such anomalies, however. */ +/* Create a new IRTemp of type 'ty' and kind 'kind', and add it to + both the table in pce->sb and to our auxiliary mapping. Note that + newTemp may cause pce->tmpMap to resize, hence previous results + from VG_(indexXA)(pce->tmpMap) are invalidated. */ +static IRTemp newTemp ( PCEnv* pce, IRType ty, TempKind kind ) +{ + Word newIx; + TempMapEnt ent; + IRTemp tmp = newIRTemp(pce->sb->tyenv, ty); + ent.kind = kind; + ent.shadow = IRTemp_INVALID; + newIx = VG_(addToXA)( pce->qmpMap, &ent ); + tl_assert(newIx == (Word)tmp); + return tmp; +} + /* Find the tmp currently shadowing the given original tmp. If none so far exists, allocate one. */ static IRTemp findShadowTmp ( PCEnv* pce, IRTemp orig ) { - tl_assert(orig < pce->n_originalTmps); - tl_assert(pce->bb->tyenv->types[orig] == pce->gWordTy); - if (pce->tmpMap[orig] == IRTemp_INVALID) { - tl_assert(0); - pce->tmpMap[orig] - = newIRTemp(pce->bb->tyenv, pce->gWordTy); + TempMapEnt* ent; + /* VG_(indexXA) range-checks 'orig', hence no need to check + here. */ + ent = (TempMapEnt*)VG_(indexXA)( pce->qmpMap, (Word)orig ); + tl_assert(ent->kind == NonShad); + if (ent->shadow == IRTemp_INVALID) { + IRTemp shadow = newTemp( pce, pce->gWordTy, Shad ); + /* newTemp may cause pce->tmpMap to resize, hence previous results + from VG_(indexXA) are invalid. */ + ent = (TempMapEnt*)VG_(indexXA)( pce->qmpMap, (Word)orig ); + tl_assert(ent->kind == NonShad); + tl_assert(ent->shadow == IRTemp_INVALID); + ent->shadow = shadow; } - return pce->tmpMap[orig]; + return ent->shadow; } /* Allocate a new shadow for the given original tmp. This means any @@ -3523,15 +3583,29 @@ static IRTemp findShadowTmp ( PCEnv* pce, IRTemp orig ) necessary to give a new value to a shadow once it has been tested for undefinedness, but unfortunately IR's SSA property disallows this. Instead we must abandon the old shadow, allocate a new one - and use that instead. */ -__attribute__((noinline)) + and use that instead. + + This is the same as findShadowTmp, except we don't bother to see + if a shadow temp already existed -- we simply allocate a new one + regardless. */ static IRTemp newShadowTmp ( PCEnv* pce, IRTemp orig ) { - tl_assert(orig < pce->n_originalTmps); - tl_assert(pce->bb->tyenv->types[orig] == pce->gWordTy); - pce->tmpMap[orig] - = newIRTemp(pce->bb->tyenv, pce->gWordTy); - return pce->tmpMap[orig]; + TempMapEnt* ent; + /* VG_(indexXA) range-checks 'orig', hence no need to check + here. */ + ent = (TempMapEnt*)VG_(indexXA)( pce->qmpMap, (Word)orig ); + tl_assert(ent->kind == NonShad); + if (1) { + IRTemp shadow = newTemp( pce, pce->gWordTy, Shad ); + /* newTemp may cause pce->tmpMap to resize, hence previous results + from VG_(indexXA) are invalid. */ + ent = (TempMapEnt*)VG_(indexXA)( pce->qmpMap, (Word)orig ); + tl_assert(ent->kind == NonShad); + ent->shadow = shadow; + return shadow; + } + /* NOTREACHED */ + tl_assert(0); } @@ -3593,7 +3667,7 @@ static inline void stmt ( HChar cat, PCEnv* pce, IRStmt* st ) { ppIRStmt(st); VG_(printf)("\n"); } - addStmtToIRSB(pce->bb, st); + addStmtToIRSB(pce->sb, st); } /* assign value to tmp */ @@ -3622,9 +3696,9 @@ void assign ( HChar cat, PCEnv* pce, IRTemp tmp, IRExpr* expr ) { that the two types agree. */ static IRAtom* assignNew ( HChar cat, PCEnv* pce, IRType ty, IRExpr* e ) { IRTemp t; - IRType tyE = typeOfIRExpr(pce->bb->tyenv, e); + IRType tyE = typeOfIRExpr(pce->sb->tyenv, e); tl_assert(tyE == ty); /* so 'ty' is redundant (!) */ - t = newIRTemp(pce->bb->tyenv, ty); + t = newTemp(pce, ty, Shad); assign(cat, pce, t, e); return mkexpr(t); } @@ -3704,8 +3778,8 @@ static IRTemp gen_dirty_W_W ( PCEnv* pce, void* h_fn, HChar* h_nm, IRTemp res; IRDirty* di; tl_assert(isIRAtom(a1)); - tl_assert(typeOfIRExpr(pce->bb->tyenv, a1) == pce->gWordTy); - res = newIRTemp(pce->bb->tyenv, pce->gWordTy); + tl_assert(typeOfIRExpr(pce->sb->tyenv, a1) == pce->gWordTy); + res = newTemp(pce, pce->gWordTy, Shad); di = unsafeIRDirty_1_N( res, 1/*regparms*/, h_nm, VG_(fnptr_to_fnentry)( h_fn ), mkIRExprVec_1( a1 ) ); @@ -3722,9 +3796,9 @@ static IRTemp gen_dirty_W_WW ( PCEnv* pce, void* h_fn, HChar* h_nm, IRDirty* di; tl_assert(isIRAtom(a1)); tl_assert(isIRAtom(a2)); - tl_assert(typeOfIRExpr(pce->bb->tyenv, a1) == pce->gWordTy); - tl_assert(typeOfIRExpr(pce->bb->tyenv, a2) == pce->gWordTy); - res = newIRTemp(pce->bb->tyenv, pce->gWordTy); + tl_assert(typeOfIRExpr(pce->sb->tyenv, a1) == pce->gWordTy); + tl_assert(typeOfIRExpr(pce->sb->tyenv, a2) == pce->gWordTy); + res = newTemp(pce, pce->gWordTy, Shad); di = unsafeIRDirty_1_N( res, 2/*regparms*/, h_nm, VG_(fnptr_to_fnentry)( h_fn ), mkIRExprVec_2( a1, a2 ) ); @@ -3742,10 +3816,10 @@ static IRTemp gen_dirty_W_WWW ( PCEnv* pce, void* h_fn, HChar* h_nm, tl_assert(isIRAtom(a1)); tl_assert(isIRAtom(a2)); tl_assert(isIRAtom(a3)); - tl_assert(typeOfIRExpr(pce->bb->tyenv, a1) == pce->gWordTy); - tl_assert(typeOfIRExpr(pce->bb->tyenv, a2) == pce->gWordTy); - tl_assert(typeOfIRExpr(pce->bb->tyenv, a3) == pce->gWordTy); - res = newIRTemp(pce->bb->tyenv, pce->gWordTy); + tl_assert(typeOfIRExpr(pce->sb->tyenv, a1) == pce->gWordTy); + tl_assert(typeOfIRExpr(pce->sb->tyenv, a2) == pce->gWordTy); + tl_assert(typeOfIRExpr(pce->sb->tyenv, a3) == pce->gWordTy); + res = newTemp(pce, pce->gWordTy, Shad); di = unsafeIRDirty_1_N( res, 3/*regparms*/, h_nm, VG_(fnptr_to_fnentry)( h_fn ), mkIRExprVec_3( a1, a2, a3 ) ); @@ -3765,11 +3839,11 @@ static IRTemp gen_dirty_W_WWWW ( PCEnv* pce, void* h_fn, HChar* h_nm, tl_assert(isIRAtom(a2)); tl_assert(isIRAtom(a3)); tl_assert(isIRAtom(a4)); - tl_assert(typeOfIRExpr(pce->bb->tyenv, a1) == pce->gWordTy); - tl_assert(typeOfIRExpr(pce->bb->tyenv, a2) == pce->gWordTy); - tl_assert(typeOfIRExpr(pce->bb->tyenv, a3) == pce->gWordTy); - tl_assert(typeOfIRExpr(pce->bb->tyenv, a4) == pce->gWordTy); - res = newIRTemp(pce->bb->tyenv, pce->gWordTy); + tl_assert(typeOfIRExpr(pce->sb->tyenv, a1) == pce->gWordTy); + tl_assert(typeOfIRExpr(pce->sb->tyenv, a2) == pce->gWordTy); + tl_assert(typeOfIRExpr(pce->sb->tyenv, a3) == pce->gWordTy); + tl_assert(typeOfIRExpr(pce->sb->tyenv, a4) == pce->gWordTy); + res = newTemp(pce, pce->gWordTy, Shad); di = unsafeIRDirty_1_N( res, 3/*regparms*/, h_nm, VG_(fnptr_to_fnentry)( h_fn ), mkIRExprVec_4( a1, a2, a3, a4 ) ); @@ -3785,8 +3859,8 @@ static void gen_dirty_v_WW ( PCEnv* pce, void* h_fn, HChar* h_nm, IRDirty* di; tl_assert(isIRAtom(a1)); tl_assert(isIRAtom(a2)); - tl_assert(typeOfIRExpr(pce->bb->tyenv, a1) == pce->gWordTy); - tl_assert(typeOfIRExpr(pce->bb->tyenv, a2) == pce->gWordTy); + tl_assert(typeOfIRExpr(pce->sb->tyenv, a1) == pce->gWordTy); + tl_assert(typeOfIRExpr(pce->sb->tyenv, a2) == pce->gWordTy); di = unsafeIRDirty_0_N( 2/*regparms*/, h_nm, VG_(fnptr_to_fnentry)( h_fn ), mkIRExprVec_2( a1, a2 ) ); @@ -3802,9 +3876,9 @@ static void gen_dirty_v_WWW ( PCEnv* pce, void* h_fn, HChar* h_nm, tl_assert(isIRAtom(a1)); tl_assert(isIRAtom(a2)); tl_assert(isIRAtom(a3)); - tl_assert(typeOfIRExpr(pce->bb->tyenv, a1) == pce->gWordTy); - tl_assert(typeOfIRExpr(pce->bb->tyenv, a2) == pce->gWordTy); - tl_assert(typeOfIRExpr(pce->bb->tyenv, a3) == pce->gWordTy); + tl_assert(typeOfIRExpr(pce->sb->tyenv, a1) == pce->gWordTy); + tl_assert(typeOfIRExpr(pce->sb->tyenv, a2) == pce->gWordTy); + tl_assert(typeOfIRExpr(pce->sb->tyenv, a3) == pce->gWordTy); di = unsafeIRDirty_0_N( 3/*regparms*/, h_nm, VG_(fnptr_to_fnentry)( h_fn ), mkIRExprVec_3( a1, a2, a3 ) ); @@ -3822,10 +3896,10 @@ static void gen_dirty_v_WWWW ( PCEnv* pce, void* h_fn, HChar* h_nm, tl_assert(isIRAtom(a2)); tl_assert(isIRAtom(a3)); tl_assert(isIRAtom(a4)); - tl_assert(typeOfIRExpr(pce->bb->tyenv, a1) == pce->gWordTy); - tl_assert(typeOfIRExpr(pce->bb->tyenv, a2) == pce->gWordTy); - tl_assert(typeOfIRExpr(pce->bb->tyenv, a3) == pce->gWordTy); - tl_assert(typeOfIRExpr(pce->bb->tyenv, a4) == pce->gWordTy); + tl_assert(typeOfIRExpr(pce->sb->tyenv, a1) == pce->gWordTy); + tl_assert(typeOfIRExpr(pce->sb->tyenv, a2) == pce->gWordTy); + tl_assert(typeOfIRExpr(pce->sb->tyenv, a3) == pce->gWordTy); + tl_assert(typeOfIRExpr(pce->sb->tyenv, a4) == pce->gWordTy); di = unsafeIRDirty_0_N( 3/*regparms*/, h_nm, VG_(fnptr_to_fnentry)( h_fn ), mkIRExprVec_4( a1, a2, a3, a4 ) ); @@ -3845,12 +3919,12 @@ static void gen_dirty_v_6W ( PCEnv* pce, void* h_fn, HChar* h_nm, tl_assert(isIRAtom(a4)); tl_assert(isIRAtom(a5)); tl_assert(isIRAtom(a6)); - tl_assert(typeOfIRExpr(pce->bb->tyenv, a1) == pce->gWordTy); - tl_assert(typeOfIRExpr(pce->bb->tyenv, a2) == pce->gWordTy); - tl_assert(typeOfIRExpr(pce->bb->tyenv, a3) == pce->gWordTy); - tl_assert(typeOfIRExpr(pce->bb->tyenv, a4) == pce->gWordTy); - tl_assert(typeOfIRExpr(pce->bb->tyenv, a5) == pce->gWordTy); - tl_assert(typeOfIRExpr(pce->bb->tyenv, a6) == pce->gWordTy); + tl_assert(typeOfIRExpr(pce->sb->tyenv, a1) == pce->gWordTy); + tl_assert(typeOfIRExpr(pce->sb->tyenv, a2) == pce->gWordTy); + tl_assert(typeOfIRExpr(pce->sb->tyenv, a3) == pce->gWordTy); + tl_assert(typeOfIRExpr(pce->sb->tyenv, a4) == pce->gWordTy); + tl_assert(typeOfIRExpr(pce->sb->tyenv, a5) == pce->gWordTy); + tl_assert(typeOfIRExpr(pce->sb->tyenv, a6) == pce->gWordTy); di = unsafeIRDirty_0_N( 3/*regparms*/, h_nm, VG_(fnptr_to_fnentry)( h_fn ), mkIRExprVec_6( a1, a2, a3, a4, a5, a6 ) ); @@ -3859,7 +3933,7 @@ static void gen_dirty_v_6W ( PCEnv* pce, void* h_fn, HChar* h_nm, static IRAtom* uwiden_to_host_word ( PCEnv* pce, IRAtom* a ) { - IRType a_ty = typeOfIRExpr(pce->bb->tyenv, a); + IRType a_ty = typeOfIRExpr(pce->sb->tyenv, a); tl_assert(isIRAtom(a)); if (pce->hWordTy == Ity_I32) { switch (a_ty) { @@ -3909,7 +3983,7 @@ static IRAtom* schemeEw_Atom ( PCEnv* pce, IRExpr* e ) return mkexpr(t); } if (e->tag == Iex_RdTmp - && typeOfIRExpr(pce->bb->tyenv, e) == Ity_I32) { + && typeOfIRExpr(pce->sb->tyenv, e) == Ity_I32) { return mkexpr( findShadowTmp(pce, e->Iex.RdTmp.tmp) ); } /* there are no other word-sized atom cases */ @@ -3922,7 +3996,7 @@ static IRAtom* schemeEw_Atom ( PCEnv* pce, IRExpr* e ) return mkexpr(t); } if (e->tag == Iex_RdTmp - && typeOfIRExpr(pce->bb->tyenv, e) == Ity_I64) { + && typeOfIRExpr(pce->sb->tyenv, e) == Ity_I64) { return mkexpr( findShadowTmp(pce, e->Iex.RdTmp.tmp) ); } /* there are no other word-sized atom cases */ @@ -4233,7 +4307,7 @@ static void schemeS ( PCEnv* pce, IRStmt* st ) di = st->Ist.Dirty.details; /* deal with the return tmp, if any */ if (di->tmp != IRTemp_INVALID - && typeOfIRTemp(pce->bb->tyenv, di->tmp) == pce->gWordTy) { + && typeOfIRTemp(pce->sb->tyenv, di->tmp) == pce->gWordTy) { /* di->tmp is shadowed. Set it to NONPTR. */ IRTemp dstv = newShadowTmp( pce, di->tmp ); if (pce->gWordTy == Ity_I32) { @@ -4331,7 +4405,7 @@ static void schemeS ( PCEnv* pce, IRStmt* st ) IntRegInfo iii; IRType ty; stmt( 'C', pce, st ); - ty = typeOfIRExpr(pce->bb->tyenv, st->Ist.Put.data); + ty = typeOfIRExpr(pce->sb->tyenv, st->Ist.Put.data); get_IntRegInfo( &iii, st->Ist.Put.offset, sizeofIRType(ty) ); if (iii.n_offsets == -1) { @@ -4376,11 +4450,11 @@ static void schemeS ( PCEnv* pce, IRStmt* st ) */ IRExpr* data = st->Ist.Store.data; IRExpr* addr = st->Ist.Store.addr; - IRType d_ty = typeOfIRExpr(pce->bb->tyenv, data); + IRType d_ty = typeOfIRExpr(pce->sb->tyenv, data); IRExpr* addrv = schemeEw_Atom( pce, addr ); IRTemp resSC = st->Ist.Store.resSC; if (resSC != IRTemp_INVALID) { - tl_assert(typeOfIRTemp(pce->bb->tyenv, resSC) == Ity_I1); + tl_assert(typeOfIRTemp(pce->sb->tyenv, resSC) == Ity_I1); /* viz, not something we want to shadow */ /* also, throw out all store-conditional cases that we can't handle */ @@ -4600,7 +4674,7 @@ static void schemeS ( PCEnv* pce, IRStmt* st ) appear, we in fact only get an atom (Iex_RdTmp or Iex_Const). */ IRExpr* e = st->Ist.WrTmp.data; - IRType e_ty = typeOfIRExpr( pce->bb->tyenv, e ); + IRType e_ty = typeOfIRExpr( pce->sb->tyenv, e ); Bool isWord = e_ty == pce->gWordTy; IRTemp dst = st->Ist.WrTmp.tmp; IRTemp dstv = isWord ? newShadowTmp( pce, dst ) @@ -4822,6 +4896,13 @@ static void schemeS ( PCEnv* pce, IRStmt* st ) } +static IRTemp for_sg__newIRTemp_cb ( IRType ty, void* opaque ) +{ + PCEnv* pce = (PCEnv*)opaque; + return newTemp( pce, ty, NonShad ); +} + + IRSB* h_instrument ( VgCallbackClosure* closure, IRSB* sbIn, VexGuestLayout* layout, @@ -4848,21 +4929,33 @@ IRSB* h_instrument ( VgCallbackClosure* closure, tl_assert(sizeof(UInt) == 4); tl_assert(sizeof(Int) == 4); - /* Set up the running environment. Only .bb is modified as we go - along. */ - pce.bb = deepCopyIRSBExceptStmts(sbIn); + /* Set up the running environment. Both .sb and .tmpMap are + modified as we go along. Note that tmps are added to both + .sb->tyenv and .tmpMap together, so the valid index-set for + those two arrays should always be identical. */ + VG_(memset)(&pce, 0, sizeof(pce)); + pce.sb = deepCopyIRSBExceptStmts(sbIn); pce.trace = verboze; - pce.n_originalTmps = sbIn->tyenv->types_used; pce.hWordTy = hWordTy; pce.gWordTy = gWordTy; pce.guest_state_sizeB = layout->total_sizeB; - pce.tmpMap = LibVEX_Alloc(pce.n_originalTmps * sizeof(IRTemp)); - for (i = 0; i < pce.n_originalTmps; i++) - pce.tmpMap[i] = IRTemp_INVALID; - /* Also set up for the sg_ instrumenter. See comments - at the top of this instrumentation section for details. */ - sgenv = sg_instrument_init(); + pce.qmpMap = VG_(newXA)( VG_(malloc), "pc.h_instrument.1", VG_(free), + sizeof(TempMapEnt)); + for (i = 0; i < sbIn->tyenv->types_used; i++) { + TempMapEnt ent; + ent.kind = NonShad; + ent.shadow = IRTemp_INVALID; + VG_(addToXA)( pce.qmpMap, &ent ); + } + tl_assert( VG_(sizeXA)( pce.qmpMap ) == sbIn->tyenv->types_used ); + + /* Also set up for the sg_ instrumenter. See comments at the top + of this instrumentation section for details. The two parameters + constitute a closure, which sg_ can use to correctly generate + new IRTemps as needed. */ + sgenv = sg_instrument_init( for_sg__newIRTemp_cb, + (void*)&pce ); /* Stay sane. These two should agree! */ tl_assert(layout->total_sizeB == MC_SIZEOF_GUEST_STATE); @@ -4925,20 +5018,25 @@ IRSB* h_instrument ( VgCallbackClosure* closure, for (/*use current i*/; i < sbIn->stmts_used; i++) { /* generate sg_ instrumentation for this stmt */ - sg_instrument_IRStmt( sgenv, pce.bb, sbIn->stmts[i], + sg_instrument_IRStmt( sgenv, pce.sb, sbIn->stmts[i], layout, gWordTy, hWordTy ); /* generate h_ instrumentation for this stmt */ schemeS( &pce, sbIn->stmts[i] ); } /* generate sg_ instrumentation for the final jump */ - sg_instrument_final_jump( sgenv, pce.bb, sbIn->next, sbIn->jumpkind, + sg_instrument_final_jump( sgenv, pce.sb, sbIn->next, sbIn->jumpkind, layout, gWordTy, hWordTy ); /* and finalise .. */ sg_instrument_fini( sgenv ); - return pce.bb; + /* If this fails, there's been some serious snafu with tmp management, + that should be investigated. */ + tl_assert( VG_(sizeXA)( pce.qmpMap ) == pce.sb->tyenv->types_used ); + VG_(deleteXA)( pce.qmpMap ); + + return pce.sb; } diff --git a/exp-ptrcheck/sg_main.c b/exp-ptrcheck/sg_main.c index 20b53823e6..85d8078ea1 100644 --- a/exp-ptrcheck/sg_main.c +++ b/exp-ptrcheck/sg_main.c @@ -2012,12 +2012,16 @@ struct _SGEnv { we basically can't really handle properly; and so we ignore all but the first ref. */ Bool firstRef; + /* READONLY */ + IRTemp (*newIRTemp_cb)(IRType,void*); + void* newIRTemp_opaque; }; /* --- Helper fns for instrumentation --- */ -static IRTemp gen_Get_SP ( IRSB* bbOut, +static IRTemp gen_Get_SP ( struct _SGEnv* sge, + IRSB* bbOut, VexGuestLayout* layout, Int hWordTy_szB ) { @@ -2029,12 +2033,13 @@ static IRTemp gen_Get_SP ( IRSB* bbOut, tl_assert(hWordTy_szB == layout->sizeof_SP); sp_type = layout->sizeof_SP == 8 ? Ity_I64 : Ity_I32; sp_expr = IRExpr_Get( layout->offset_SP, sp_type ); - sp_temp = newIRTemp( bbOut->tyenv, sp_type ); + sp_temp = sge->newIRTemp_cb( sp_type, sge->newIRTemp_opaque ); addStmtToIRSB( bbOut, IRStmt_WrTmp( sp_temp, sp_expr ) ); return sp_temp; } -static IRTemp gen_Get_FP ( IRSB* bbOut, +static IRTemp gen_Get_FP ( struct _SGEnv* sge, + IRSB* bbOut, VexGuestLayout* layout, Int hWordTy_szB ) { @@ -2046,12 +2051,13 @@ static IRTemp gen_Get_FP ( IRSB* bbOut, tl_assert(hWordTy_szB == layout->sizeof_SP); fp_type = layout->sizeof_FP == 8 ? Ity_I64 : Ity_I32; fp_expr = IRExpr_Get( layout->offset_FP, fp_type ); - fp_temp = newIRTemp( bbOut->tyenv, fp_type ); + fp_temp = sge->newIRTemp_cb( fp_type, sge->newIRTemp_opaque ); addStmtToIRSB( bbOut, IRStmt_WrTmp( fp_temp, fp_expr ) ); return fp_temp; } -static void instrument_mem_access ( IRSB* bbOut, +static void instrument_mem_access ( struct _SGEnv* sge, + IRSB* bbOut, IRExpr* addr, Int szB, Bool isStore, @@ -2088,8 +2094,8 @@ static void instrument_mem_access ( IRSB* bbOut, /* Generate a call to "helperc__mem_access", passing: addr current_SP current_FP szB curr_IP frameBlocks */ - { IRTemp t_SP = gen_Get_SP( bbOut, layout, hWordTy_szB ); - IRTemp t_FP = gen_Get_FP( bbOut, layout, hWordTy_szB ); + { IRTemp t_SP = gen_Get_SP( sge, bbOut, layout, hWordTy_szB ); + IRTemp t_FP = gen_Get_FP( sge, bbOut, layout, hWordTy_szB ); IRExpr** args = mkIRExprVec_6( addr, IRExpr_RdTmp(t_SP), @@ -2100,7 +2106,7 @@ static void instrument_mem_access ( IRSB* bbOut, IRDirty* di = unsafeIRDirty_0_N( 3/*regparms*/, "helperc__mem_access", - VG_(fnptr_to_fnentry)( &helperc__mem_access ), + VG_(fnptr_to_fnentry)( &helperc__mem_access ), args ); addStmtToIRSB( bbOut, IRStmt_Dirty(di) ); @@ -2110,14 +2116,17 @@ static void instrument_mem_access ( IRSB* bbOut, /* --- Instrumentation main (4 fns) --- */ -struct _SGEnv * sg_instrument_init ( void ) +struct _SGEnv * sg_instrument_init ( IRTemp (*newIRTemp_cb)(IRType,void*), + void* newIRTemp_opaque ) { struct _SGEnv * env = sg_malloc("di.sg_main.sii.1", sizeof(struct _SGEnv)); tl_assert(env); - env->curr_IP = 0; - env->curr_IP_known = False; - env->firstRef = True; + env->curr_IP = 0; + env->curr_IP_known = False; + env->firstRef = True; + env->newIRTemp_cb = newIRTemp_cb; + env->newIRTemp_opaque = newIRTemp_opaque; return env; } @@ -2164,7 +2173,7 @@ void sg_instrument_IRStmt ( /*MOD*/struct _SGEnv * env, tl_assert(env->curr_IP_known); if (env->firstRef) { instrument_mem_access( - sbOut, + env, sbOut, st->Ist.Store.addr, sizeofIRType(typeOfIRExpr(sbOut->tyenv, st->Ist.Store.data)), True/*isStore*/, @@ -2181,7 +2190,7 @@ void sg_instrument_IRStmt ( /*MOD*/struct _SGEnv * env, tl_assert(env->curr_IP_known); if (env->firstRef) { instrument_mem_access( - sbOut, + env, sbOut, data->Iex.Load.addr, sizeofIRType(data->Iex.Load.ty), False/*!isStore*/, @@ -2207,13 +2216,13 @@ void sg_instrument_IRStmt ( /*MOD*/struct _SGEnv * env, dataSize = d->mSize; if (d->mFx == Ifx_Read || d->mFx == Ifx_Modify) { instrument_mem_access( - sbOut, d->mAddr, dataSize, False/*!isStore*/, + env, sbOut, d->mAddr, dataSize, False/*!isStore*/, sizeofIRType(hWordTy), env->curr_IP, layout ); } if (d->mFx == Ifx_Write || d->mFx == Ifx_Modify) { instrument_mem_access( - sbOut, d->mAddr, dataSize, True/*isStore*/, + env, sbOut, d->mAddr, dataSize, True/*isStore*/, sizeofIRType(hWordTy), env->curr_IP, layout ); } @@ -2241,11 +2250,11 @@ void sg_instrument_IRStmt ( /*MOD*/struct _SGEnv * env, if (cas->dataHi != NULL) dataSize *= 2; /* since it's a doubleword-CAS */ instrument_mem_access( - sbOut, cas->addr, dataSize, False/*!isStore*/, + env, sbOut, cas->addr, dataSize, False/*!isStore*/, sizeofIRType(hWordTy), env->curr_IP, layout ); instrument_mem_access( - sbOut, cas->addr, dataSize, True/*isStore*/, + env, sbOut, cas->addr, dataSize, True/*isStore*/, sizeofIRType(hWordTy), env->curr_IP, layout ); env->firstRef = False; @@ -2280,9 +2289,9 @@ void sg_instrument_final_jump ( /*MOD*/struct _SGEnv * env, IRExpr** args; IRDirty* di; sp_post_call_insn - = gen_Get_SP( sbOut, layout, sizeofIRType(hWordTy) ); + = gen_Get_SP( env, sbOut, layout, sizeofIRType(hWordTy) ); fp_post_call_insn - = gen_Get_FP( sbOut, layout, sizeofIRType(hWordTy) ); + = gen_Get_FP( env, sbOut, layout, sizeofIRType(hWordTy) ); tl_assert(env->curr_IP_known); frameBlocks = get_StackBlocks_for_IP( env->curr_IP ); tl_assert(frameBlocks); diff --git a/exp-ptrcheck/sg_main.h b/exp-ptrcheck/sg_main.h index 5d56f6b82e..ad3c58efa2 100644 --- a/exp-ptrcheck/sg_main.h +++ b/exp-ptrcheck/sg_main.h @@ -54,7 +54,8 @@ void sg_die_mem_munmap ( Addr a, SizeT len ); struct _SGEnv; /* abstract export */ -struct _SGEnv * sg_instrument_init ( void ); +struct _SGEnv* sg_instrument_init ( IRTemp (*newIRTemp_cb)(IRType,void*), + void* newIRTemp_opaque ); void sg_instrument_fini ( struct _SGEnv * env );