]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Changes to support Memcheck:
authorJulian Seward <jseward@acm.org>
Wed, 3 Nov 2004 09:08:33 +0000 (09:08 +0000)
committerJulian Seward <jseward@acm.org>
Wed, 3 Nov 2004 09:08:33 +0000 (09:08 +0000)
* 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

VEX/priv/guest-x86/ghelpers.c
VEX/priv/ir/irdefs.c
VEX/priv/main/vex_main.c
VEX/pub/libvex.h
VEX/pub/libvex_ir.h

index d2b6fd5c66421309dbc6affd901d56d916baaa54..d9608a1577e4fff9b45618dc14b3aec89a3130c3 100644 (file)
@@ -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'. */
index a956975728b8a87c9eb29e04e1e00ced6c257e92..e76f77ed00ad599e79d86c2922d645e545ba1d19 100644 (file)
@@ -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 
index f3b76d5169b064ee66c9a03777e446ef1b5446f7..e0b0983655c94a290178470d684f8d645184b2ab 100644 (file)
@@ -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 );
index e8cbc8f5060f425314a4857c29b2d1a98308e1c2..757ae9f3aaa66ddc225a5bcb56151ba2d53dd7f6 100644 (file)
@@ -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 */
index 477bf47969c796f147fc20f570bf7f6c07ec0f8f..d8da1963dc6bf6059591c4ea39aa6584b8fc054b 100644 (file)
@@ -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 );