]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Further improvements to the IR sanity checker.
authorJulian Seward <jseward@acm.org>
Thu, 15 Jul 2004 09:38:27 +0000 (09:38 +0000)
committerJulian Seward <jseward@acm.org>
Thu, 15 Jul 2004 09:38:27 +0000 (09:38 +0000)
Use these to fix various bugs found in x86->IR.

git-svn-id: svn://svn.valgrind.org/vex/trunk@87

VEX/priv/guest-x86/x86toIR.c
VEX/priv/ir/ir_defs.c
VEX/pub/libvex_ir.h

index e139fc93db2b4c8121755e1555a34dfba169b40f..aa8412f4180d5ba6c8ba88db4cc060ad296cf302 100644 (file)
@@ -70,6 +70,7 @@ static void stmt ( IRStmt* stmt )
 /* Generate a new temporary of the given type. */
 static IRTemp newTemp ( IRType ty )
 {
+   vassert(isPlausibleType(ty));
    return newIRTemp( irbb->tyenv, ty );
 }
 
@@ -583,7 +584,7 @@ static IRExpr* flag_to_bit0 ( UInt ccmask, IRTemp eflags )
    if (shifts == 0)
       return mkexpr(eflags);
    else
-      return binop(Iop_Shr32, mkexpr(eflags), mkU32(shifts));
+      return binop(Iop_Shr32, mkexpr(eflags), mkU8(shifts));
 }
 
 
@@ -1315,7 +1316,7 @@ IRTemp disAMode ( Int* len, UChar sorb, UInt delta, UChar* buf )
                  binop(Iop_Add32, 
                         getIReg(4,base_r),
                         binop(Iop_Shl32, getIReg(4,index_r),
-                              mkU32(scale)))));
+                              mkU8(scale)))));
          }
 
          if (index_r != R_ESP && base_r == R_EBP) {
@@ -1327,7 +1328,7 @@ IRTemp disAMode ( Int* len, UChar sorb, UInt delta, UChar* buf )
                disAMode_copy2tmp(
                handleSegOverride(sorb, 
                  binop(Iop_Add32,
-                       binop(Iop_Shl32, getIReg(4,index_r), mkU32(scale)),
+                       binop(Iop_Shl32, getIReg(4,index_r), mkU8(scale)),
                         mkU32(d))));
          }
 
@@ -1383,7 +1384,7 @@ IRTemp disAMode ( Int* len, UChar sorb, UInt delta, UChar* buf )
                         binop(Iop_Add32, 
                               getIReg(4,base_r), 
                               binop(Iop_Shl32, 
-                                    getIReg(4,index_r), mkU32(scale))),
+                                    getIReg(4,index_r), mkU8(scale))),
                         mkU32(d))));
          }
          vassert(0);
@@ -1422,7 +1423,7 @@ IRTemp disAMode ( Int* len, UChar sorb, UInt delta, UChar* buf )
                         binop(Iop_Add32, 
                               getIReg(4,base_r), 
                               binop(Iop_Shl32, 
-                                    getIReg(4,index_r), mkU32(scale))),
+                                    getIReg(4,index_r), mkU8(scale))),
                         mkU32(d))));
          }
          vassert(0);
@@ -1963,25 +1964,24 @@ UInt dis_Grp1 ( UChar sorb,
 }
 
 
-/* Group 2 extended opcodes. */
+/* Group 2 extended opcodes.  shift_expr must be an 8-bit typed
+   expression. */
+
 static
 UInt dis_Grp2 ( UChar  sorb,
                 UInt delta, UChar modrm,
-                Int am_sz, Int d_sz, Int sz, IRExpr* shift_expr )
+                Int am_sz, Int d_sz, Int sz, IRExpr* shift_expr,
+                Char* shift_expr_txt )
 {
    /* delta on entry points at the modrm byte. */
-   UChar dis_buf[50];
-   Int len;
-   IROp op8;
-   IRType ty        = szToITy(sz);
-   IRTemp dst0      = newTemp(ty);
-   IRTemp dst1      = newTemp(ty);
-   IRTemp addr = INVALID_IRTEMP;
-   Bool isShift;
-
-   //   IRTemp  dst1 = newTemp(ty);
-   //   IRTemp  src  = newTemp(ty);
-   //   IRTemp  dst0 = newTemp(ty);
+   UChar  dis_buf[50];
+   Int    len;
+   IROp   op8;
+   Bool   isShift;
+   IRType ty    = szToITy(sz);
+   IRTemp dst0  = newTemp(ty);
+   IRTemp dst1  = newTemp(ty);
+   IRTemp addr  = INVALID_IRTEMP;
 
    vassert(sz == 1 || sz == 2 || sz == 4);
 
@@ -2011,7 +2011,7 @@ UInt dis_Grp2 ( UChar  sorb,
    if (isShift) {
 
       IRTemp subshift  = newTemp(ty);
-      IRTemp shift_amt = newTemp(ty);
+      IRTemp shift_amt = newTemp(Ity_I8);
       IRTemp guard     = newTemp(Ity_Bit);
 
       switch (gregOfRM(modrm)) { 
@@ -2022,8 +2022,8 @@ UInt dis_Grp2 ( UChar  sorb,
       }
 
       /* shift_amt = shift_expr & mask */
-      assign(shift_amt, binop(mkSizedOp(ty,Iop_And8)
-                              shift_expr, mkU(ty,8*sz-1)));
+      assign(shift_amt, binop(Iop_And8
+                              shift_expr, mkU8(8*sz-1)));
       /* dst1 = dst0 `shift` shift_amt */
       assign(dst1, binop(mkSizedOp(ty,op8), 
                          mkexpr(dst0), mkexpr(shift_amt)));
@@ -2031,11 +2031,13 @@ UInt dis_Grp2 ( UChar  sorb,
       assign(subshift, 
              binop(mkSizedOp(ty,op8), 
                    mkexpr(dst0), 
-                   binop(mkSizedOp(ty,Iop_Sub8),
-                         mkexpr(shift_amt), mkU(ty,1))));
+                   binop(Iop_And8,
+                         binop(Iop_Sub8,
+                               mkexpr(shift_amt), mkU8(1)),
+                         mkU8(8*sz-1))));
       /* guard = (shift_amt != 0) */
-      assign(guard, binop(mkSizedOp(ty,Iop_CmpNE8)
-                    mkexpr(shift_amt), mkU(ty,0)));
+      assign(guard, binop(Iop_CmpNE8
+                           mkexpr(shift_amt), mkU8(0)));
 
       /* Build the flags thunk. */
       setFlags_DSTus_DST1(op8, subshift, dst1, ty, guard);
@@ -2050,7 +2052,10 @@ UInt dis_Grp2 ( UChar  sorb,
       if (print_codegen) {
          vex_printf("%s%c ",
                     nameGrp2(gregOfRM(modrm)), nameISize(sz) );
-        ppIRExpr(shift_expr);
+         if (shift_expr_txt)
+            vex_printf("%s", shift_expr_txt);
+         else
+            ppIRExpr(shift_expr);
          vex_printf(", %s\n", nameIReg(sz,eregOfRM(modrm)));
       }
    } else {
@@ -2058,7 +2063,10 @@ UInt dis_Grp2 ( UChar  sorb,
       if (print_codegen) {
          vex_printf("%s%c ",
                     nameGrp2(gregOfRM(modrm)), nameISize(sz) );
-        ppIRExpr(shift_expr);
+         if (shift_expr_txt)
+            vex_printf("%s", shift_expr_txt);
+         else
+            ppIRExpr(shift_expr);
          vex_printf(", %s\n", dis_buf);
       }
    }
@@ -2585,7 +2593,7 @@ void dis_string_op_increment(Int sz, Int t_inc)
    if (sz == 4 || sz == 2) {
       assign( t_inc, 
               binop(Iop_Shl32, IRExpr_Get( OFFB_DFLAG, Ity_I32 ),
-                               mkU32(sz/2) ) );
+                               mkU8(sz/2) ) );
    } else {
       assign( t_inc, 
               IRExpr_Get( OFFB_DFLAG, Ity_I32 ) );
@@ -2659,7 +2667,7 @@ void dis_STOS ( Int sz, IRTemp t_inc )
    assign( td, getIReg(4, R_EDI) );
 
    //uInstr2(cb, STORE, sz, TempReg, ta,    TempReg, td);
-   storeLE( mkexpr(ta), mkexpr(td) );
+   storeLE( mkexpr(td), mkexpr(ta) );
 
    //uInstr2(cb, ADD,   4, TempReg, t_inc, TempReg, td);
    //uInstr2(cb, PUT,   4, TempReg, td,    ArchReg, R_EDI);
@@ -2670,8 +2678,8 @@ static
 void dis_CMPS ( Int sz, IRTemp t_inc )
 {
    IRType ty  = szToITy(sz);
-   IRTemp tdv = newTemp(sz);      /* (EDI) */
-   IRTemp tsv = newTemp(sz);      /* (ESI) */
+   IRTemp tdv = newTemp(ty);      /* (EDI) */
+   IRTemp tsv = newTemp(ty);      /* (ESI) */
    IRTemp td  = newTemp(Ity_I32); /*  EDI  */
    IRTemp ts  = newTemp(Ity_I32); /*  ESI  */
 
@@ -2786,8 +2794,8 @@ UInt dis_mul_E_G ( UChar       sorb,
    UChar  rm = getIByte(delta0);
    IRType ty = szToITy(size);
    //IRTemp ta = INVALID_IRTEMP;
-   IRTemp te = newTemp(size);
-   IRTemp tg = newTemp(size);
+   IRTemp te = newTemp(ty);
+   IRTemp tg = newTemp(ty);
 
    if (epartIsReg(rm)) {
       vassert(signed_multiply);
@@ -3172,14 +3180,14 @@ UInt dis_SHLRD_Gv_Ev ( UChar sorb,
    Int len;
    UChar dis_buf[50];
 
-   IRType ty = szToITy(sz);
-   IRTemp gsrc = newTemp(ty);
-   IRTemp esrc = newTemp(ty);
-   IRTemp addr = INVALID_IRTEMP;
-   IRTemp tmpSH = newTemp(Ity_I8);
-   IRTemp guard = newTemp(Ity_I32);
-   IRTemp tmpL = INVALID_IRTEMP;
-   IRTemp tmpRes = INVALID_IRTEMP;
+   IRType ty       = szToITy(sz);
+   IRTemp gsrc     = newTemp(ty);
+   IRTemp esrc     = newTemp(ty);
+   IRTemp addr     = INVALID_IRTEMP;
+   IRTemp tmpSH    = newTemp(Ity_I8);
+   IRTemp guard    = newTemp(Ity_Bit);
+   IRTemp tmpL     = INVALID_IRTEMP;
+   IRTemp tmpRes   = INVALID_IRTEMP;
    IRTemp tmpSubSh = INVALID_IRTEMP;
    IROp   mkpair;
    IROp   getres;
@@ -6013,7 +6021,7 @@ static UInt disInstr ( UInt delta, Bool* isEnd )
       putIReg(sz, R_EDX,
                   binop(mkSizedOp(ty,Iop_Sar8), 
                         getIReg(sz, R_EAX),
-                       mkU(ty,sz == 2 ? 15  : 31)) );
+                       mkU8(sz == 2 ? 15  : 31)) );
       DIP(sz == 2 ? "cwdq\n" : "cdqq\n");
       break;
 
@@ -7034,7 +7042,8 @@ static UInt disInstr ( UInt delta, Bool* isEnd )
       d_sz  = 1;
       d32   = getSDisp8(delta + am_sz);
       sz    = 1;
-      delta = dis_Grp2 ( sorb, delta, modrm, am_sz, d_sz, sz, mkU32(d32) );
+      delta = dis_Grp2 ( sorb, delta, modrm, am_sz, d_sz, sz, 
+                         mkU8(d32 & 0xFF), NULL );
       break;
 
    case 0xC1: /* Grp2 Ib,Ev */
@@ -7042,7 +7051,8 @@ static UInt disInstr ( UInt delta, Bool* isEnd )
       am_sz = lengthAMode(delta);
       d_sz  = 1;
       d32   = getSDisp8(delta + am_sz);
-      delta = dis_Grp2 ( sorb, delta, modrm, am_sz, d_sz, sz, mkU32(d32) );
+      delta = dis_Grp2 ( sorb, delta, modrm, am_sz, d_sz, sz, 
+                         mkU8(d32 & 0xFF), NULL );
       break;
 
 //--    case 0xD0: /* Grp2 1,Eb */
@@ -7059,7 +7069,8 @@ static UInt disInstr ( UInt delta, Bool* isEnd )
       am_sz = lengthAMode(delta);
       d_sz  = 0;
       d32   = 1;
-      delta = dis_Grp2 ( sorb, delta, modrm, am_sz, d_sz, sz, mkU32(d32) );
+      delta = dis_Grp2 ( sorb, delta, modrm, am_sz, d_sz, sz, 
+                         mkU8(d32), NULL );
       break;
 
 //--    case 0xD2: /* Grp2 CL,Eb */
@@ -7075,7 +7086,7 @@ static UInt disInstr ( UInt delta, Bool* isEnd )
       am_sz = lengthAMode(delta);
       d_sz  = 0;
       delta = dis_Grp2 ( sorb, delta, modrm, am_sz, d_sz, sz, 
-                         getIReg(sz,R_ECX) );
+                         getIReg(1,R_ECX), "%cl" );
       break;
 
    /* ------------------------ (Grp3 extensions) ---------- */
index c0ff306ae104dc1bd425e358ea0379f4d2c01afd..0a38f972c33f3b0e0c03858c97e7544e4b5f5078 100644 (file)
@@ -25,7 +25,8 @@ void ppIRType ( IRType ty )
     case Ity_I16:     vex_printf( "I16"); break;
     case Ity_I32:     vex_printf( "I32"); break;
     case Ity_I64:     vex_printf( "I64"); break;
-    default: vpanic("ppIRType");
+    default: vex_printf("ty = 0x%x\n", (Int)ty);
+             vpanic("ppIRType");
   }
 }
 
@@ -452,6 +453,22 @@ void typeOfPrimop ( IROp op, IRType* t_dst, IRType* t_arg1, IRType* t_arg2 )
       case Iop_CmpEQ64: case Iop_CmpNE64:
          COMPARISON(Ity_I64);
 
+      case Iop_MullU32: case Iop_MullS32:
+         BINARY(Ity_I64,Ity_I32,Ity_I32);
+
+      case Iop_DivModU64to32:
+         BINARY(Ity_I64,Ity_I64,Ity_I32);
+
+      case Iop_64HIto32: case Iop_64LOto32:
+         UNARY(Ity_I32, Ity_I64);
+      case Iop_32HLto64:
+         BINARY(Ity_I64,Ity_I32,Ity_I32);
+
+      case Iop_1Uto8:   UNARY(Ity_I8,Ity_Bit);
+      case Iop_32to1:   UNARY(Ity_Bit,Ity_I32);
+      case Iop_8Uto32:  UNARY(Ity_I32,Ity_I8);
+      case Iop_16Uto32: UNARY(Ity_I32,Ity_I16);
+
       default:
          ppIROp(op);
          vpanic("typeOfPrimop");
@@ -544,6 +561,18 @@ IRType typeOfIRExpr ( IRTypeEnv* tyenv, IRExpr* e )
    }
 }
 
+/* Is this any value actually in the enumeration 'IRType' ? */
+Bool isPlausibleType ( IRType ty )
+{
+   switch (ty) {
+      case Ity_INVALID: case Ity_Bit:
+      case Ity_I8: case Ity_I16: case Ity_I32: case Ity_I64: 
+         return True;
+      default: 
+         return False;
+   }
+}
+
 
 /*---------------------------------------------------------------*/
 /*--- Sanity checking                                         ---*/
@@ -643,16 +672,36 @@ void tcExpr ( IRBB* bb, IRStmt* stmt, IRExpr* expr, IRType gWordTy )
       case Iex_Get:
       case Iex_Tmp:
          break;
-      case Iex_Binop:
+      case Iex_Binop: {
+         IRType ttarg1, ttarg2;
          tcExpr(bb,stmt, expr->Iex.Binop.arg1, gWordTy );
          tcExpr(bb,stmt, expr->Iex.Binop.arg2, gWordTy );
          typeOfPrimop(expr->Iex.Binop.op, &t_dst, &t_arg1, &t_arg2);
          if (t_arg1 == Ity_INVALID || t_arg2 == Ity_INVALID)
             sanityCheckFail(bb,stmt,"Iex.Binop: wrong arity op");
-         if (t_arg1 != typeOfIRExpr(tyenv, expr->Iex.Binop.arg1)
-             || t_arg2 != typeOfIRExpr(tyenv, expr->Iex.Binop.arg1))
-         sanityCheckFail(bb,stmt,"Iex.Binop: arg tys don't match op tys");
+         ttarg1 = typeOfIRExpr(tyenv, expr->Iex.Binop.arg1);
+         ttarg2 = typeOfIRExpr(tyenv, expr->Iex.Binop.arg2);
+         if (t_arg1 != ttarg1 || t_arg2 != ttarg2) {
+            vex_printf(" op name: ");
+            ppIROp(expr->Iex.Binop.op);
+            vex_printf("\n");
+            vex_printf(" op type is (");
+            ppIRType(t_arg1);
+            vex_printf(",");
+            ppIRType(t_arg2);
+            vex_printf(") -> ");
+            ppIRType (t_dst);
+            vex_printf("\narg tys are (");
+            ppIRType(ttarg1);
+            vex_printf(",");
+            ppIRType(ttarg2);
+            vex_printf(")\n");
+            sanityCheckFail(bb,stmt,
+               "Iex.Binop: arg tys don't match op tys\n"
+               "... additional details precede BB printout\n");
+        }
          break;
+      }
       case Iex_Unop:
          tcExpr(bb,stmt, expr->Iex.Unop.arg, gWordTy );
          typeOfPrimop(expr->Iex.Binop.op, &t_dst, &t_arg1, &t_arg2);
@@ -702,7 +751,7 @@ void tcStmt ( IRBB* bb, IRStmt* stmt, IRType gWordTy )
          tcExpr( bb, stmt, stmt->Ist.Tmp.expr, gWordTy );
          if (lookupIRTypeEnv(tyenv, stmt->Ist.Tmp.tmp)
              != typeOfIRExpr(tyenv, stmt->Ist.Tmp.expr))
-            sanityCheckFail(bb,stmt,"IRStmt.Put.TMp: tmp and expr do not match");
+            sanityCheckFail(bb,stmt,"IRStmt.Put.Tmp: tmp and expr do not match");
          break;
       case Ist_STle:
          tcExpr( bb, stmt, stmt->Ist.STle.addr, gWordTy );
@@ -724,7 +773,6 @@ void tcStmt ( IRBB* bb, IRStmt* stmt, IRType gWordTy )
    }
 }
 
-
 void sanityCheckIRBB ( IRBB* bb, IRType guest_word_size )
 {
    Int     i;
@@ -735,11 +783,22 @@ void sanityCheckIRBB ( IRBB* bb, IRType guest_word_size )
    vassert(guest_word_size == Ity_I32
           || guest_word_size == Ity_I64);
 
-   for (i = 0; i < n_temps; i++)
-      def_counts[i] = 0;
+   /* Ensure each temp has a plausible type. */
+   for (i = 0; i < n_temps; i++) {
+      IRType ty = lookupIRTypeEnv(bb->tyenv,(IRTemp)i);
+      if (!isPlausibleType(ty)) {
+         vex_printf("Temp t%d declared with implausible type 0x%x\n",
+                    i, (UInt)ty);
+         sanityCheckFail(bb,NULL,"Temp declared with implausible type");
+      }
+   }
 
    /* Count the defs of each temp.  Only one def is allowed.
       Also, check that each used temp has already been defd. */
+
+   for (i = 0; i < n_temps; i++)
+      def_counts[i] = 0;
+
    for (stmt = bb->stmts; stmt; stmt=stmt->link) {
       useBeforeDef_Stmt(bb,stmt,def_counts);
       if (stmt->tag == Ist_Tmp) {
index c5a24783fce8e6c99c15b52738d02c24cd508b8f..85b61e7ee3bb74b21bc03eb4ac4265124485dbb7 100644 (file)
@@ -315,6 +315,9 @@ extern IRType typeOfIRExpr  ( IRTypeEnv*, IRExpr* );
 /* Sanity check a BB of IR */
 extern void sanityCheckIRBB ( IRBB* bb, IRType guest_word_size );
 
+/* Is this any value actually in the enumeration 'IRType' ? */
+extern Bool isPlausibleType ( IRType ty );
+
 #endif /* ndef __LIBVEX_IR_H */