]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Liberalise IRTemp bookkeeping in the h_ instrumenter, so as to allow
authorJulian Seward <jseward@acm.org>
Thu, 9 Jul 2009 10:45:11 +0000 (10:45 +0000)
committerJulian Seward <jseward@acm.org>
Thu, 9 Jul 2009 10:45:11 +0000 (10:45 +0000)
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

exp-ptrcheck/h_main.c
exp-ptrcheck/sg_main.c
exp-ptrcheck/sg_main.h

index d5e532fb1c6fd1eaebce69e18f7fe98335dd4613..aaac5cc16749810468cb743a9a3a4cf9588eb395 100644 (file)
@@ -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;
 }
 
 
index 20b53823e6d6259c769abd2fa52752e7e8c1b902..85d8078ea114654417e3b7a811a18725707f7fe8 100644 (file)
@@ -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);
index 5d56f6b82e9db4dccc6c5b72b45d0ee7478bd52e..ad3c58efa2f67037781773e2718aa84960542032 100644 (file)
@@ -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 );