Blob Blame Raw
------------------------------------------------------------------------
r13008 | tom | 2012-09-21 10:57:46 +0200 (Fri, 21 Sep 2012) | 3 lines

When processing DW_OP_plus_uconst make sure we record an add, not
whatever binary operation we happened to see last.

------------------------------------------------------------------------
r13009 | tom | 2012-09-21 11:04:27 +0200 (Fri, 21 Sep 2012) | 2 lines

Rename CfiOp to CfiBinop in preparation for adding unary operators.

------------------------------------------------------------------------
r13010 | tom | 2012-09-21 11:12:30 +0200 (Fri, 21 Sep 2012) | 3 lines

Implement some extra DW_OPs - more constants and some unary operators.
Patch from Mark Wielaard on BZ#307038.

------------------------------------------------------------------------

Index: valgrind/coregrind/m_debuginfo/readdwarf.c
===================================================================
--- valgrind/coregrind/m_debuginfo/readdwarf.c	(revision 13007)
+++ valgrind/coregrind/m_debuginfo/readdwarf.c	(working copy)
@@ -2728,12 +2728,13 @@
          sp--;                                     \
       } while (0)
 
-   Int    ix, ix2, reg;
-   UChar  opcode;
-   Word   sw;
-   UWord  uw;
-   CfiOp  op;
-   HChar* opname;
+   Int      ix, ix2, reg;
+   UChar    opcode;
+   Word     sw;
+   UWord    uw;
+   CfiUnop  uop;
+   CfiBinop bop;
+   HChar*   opname;
 
    Int sp; /* # of top element: valid is -1 .. N_EXPR_STACK-1 */
    Int stack[N_EXPR_STACK];  /* indices into ctx->exprs */
@@ -2752,7 +2753,7 @@
       if (ctxs->cfa_is_regoff) {
          /* cfa is reg +/- offset */
          ix = ML_(CfiExpr_Binop)( dst,
-                 Cop_Add,
+                 Cbinop_Add,
                  ML_(CfiExpr_DwReg)( dst, ctxs->cfa_reg ),
                  ML_(CfiExpr_Const)( dst, (UWord)(Word)ctxs->cfa_off )
               );
@@ -2778,7 +2779,7 @@
            break;
       }
 
-      op = 0; opname = NULL; /* excessively conservative */
+      uop = 0; bop = 0; opname = NULL; /* excessively conservative */
 
       opcode = *expr++;
       switch (opcode) {
@@ -2798,7 +2799,7 @@
             vg_assert(reg >= 0 && reg <= 31);
             sw = read_leb128S( &expr );
             ix = ML_(CfiExpr_Binop)( dst,
-                    Cop_Add,
+                    Cbinop_Add,
                     ML_(CfiExpr_DwReg)( dst, reg ),
                     ML_(CfiExpr_Const)( dst, (UWord)sw )
                  );
@@ -2822,7 +2823,7 @@
             PUSH( ML_(CfiExpr_Const)( dst, uw ) );
             POP( ix );
             POP( ix2 );
-            PUSH( ML_(CfiExpr_Binop)( dst, op, ix2, ix ) );
+            PUSH( ML_(CfiExpr_Binop)( dst, Cbinop_Add, ix2, ix ) );
             if (ddump_frames)
                VG_(printf)("DW_OP_plus_uconst: %lu", uw);
             break;
@@ -2836,6 +2837,15 @@
                VG_(printf)("DW_OP_const4s: %ld", sw);
             break;
 
+         case DW_OP_const2s:
+            /* push: 16-bit signed immediate */
+            sw = read_le_s_encoded_literal( expr, 2 );
+            expr += 2;
+            PUSH( ML_(CfiExpr_Const)( dst, (UWord)sw ) );
+            if (ddump_frames)
+               VG_(printf)("DW_OP_const2s: %ld", sw);
+            break;
+
          case DW_OP_const1s:
             /* push: 8-bit signed immediate */
             sw = read_le_s_encoded_literal( expr, 1 );
@@ -2845,34 +2855,74 @@
                VG_(printf)("DW_OP_const1s: %ld", sw);
             break;
 
+         case DW_OP_const1u:
+            /* push: 8-bit unsigned immediate */
+            uw = read_le_u_encoded_literal( expr, 1 );
+            expr += 1;
+            PUSH( ML_(CfiExpr_Const)( dst, uw ) );
+            if (ddump_frames)
+               VG_(printf)("DW_OP_const1: %lu", uw);
+            break;
+
+         case DW_OP_const2u:
+            /* push: 16-bit unsigned immediate */
+            uw = read_le_u_encoded_literal( expr, 2 );
+            expr += 2;
+            PUSH( ML_(CfiExpr_Const)( dst, uw ) );
+            if (ddump_frames)
+               VG_(printf)("DW_OP_const2: %lu", uw);
+            break;
+
+         case DW_OP_const4u:
+            /* push: 32-bit unsigned immediate */
+            uw = read_le_u_encoded_literal( expr, 4 );
+            expr += 4;
+            PUSH( ML_(CfiExpr_Const)( dst, uw ) );
+            if (ddump_frames)
+               VG_(printf)("DW_OP_const4: %lu", uw);
+            break;
+
+         case DW_OP_abs:
+            uop = Cunop_Abs; opname = "abs"; goto unop;
+         case DW_OP_neg:
+            uop = Cunop_Neg; opname = "neg"; goto unop;
+         case DW_OP_not:
+            uop = Cunop_Not; opname = "not"; goto unop;
+         unop:
+            POP( ix );
+            PUSH( ML_(CfiExpr_Unop)( dst, uop, ix ) );
+            if (ddump_frames)
+               VG_(printf)("DW_OP_%s", opname);
+            break;
+
          case DW_OP_minus:
-            op = Cop_Sub; opname = "minus"; goto binop;
+            bop = Cbinop_Sub; opname = "minus"; goto binop;
          case DW_OP_plus:
-            op = Cop_Add; opname = "plus"; goto binop;
+            bop = Cbinop_Add; opname = "plus"; goto binop;
          case DW_OP_and:
-            op = Cop_And; opname = "and"; goto binop;
+            bop = Cbinop_And; opname = "and"; goto binop;
          case DW_OP_mul:
-            op = Cop_Mul; opname = "mul"; goto binop;
+            bop = Cbinop_Mul; opname = "mul"; goto binop;
          case DW_OP_shl:
-            op = Cop_Shl; opname = "shl"; goto binop;
+            bop = Cbinop_Shl; opname = "shl"; goto binop;
          case DW_OP_shr:
-            op = Cop_Shr; opname = "shr"; goto binop;
+            bop = Cbinop_Shr; opname = "shr"; goto binop;
          case DW_OP_eq:
-            op = Cop_Eq; opname = "eq"; goto binop;
+            bop = Cbinop_Eq; opname = "eq"; goto binop;
          case DW_OP_ge:
-            op = Cop_Ge; opname = "ge"; goto binop;
+            bop = Cbinop_Ge; opname = "ge"; goto binop;
          case DW_OP_gt:
-            op = Cop_Gt; opname = "gt"; goto binop;
+            bop = Cbinop_Gt; opname = "gt"; goto binop;
          case DW_OP_le:
-            op = Cop_Le; opname = "le"; goto binop;
+            bop = Cbinop_Le; opname = "le"; goto binop;
          case DW_OP_lt:
-            op = Cop_Lt; opname = "lt"; goto binop;
+            bop = Cbinop_Lt; opname = "lt"; goto binop;
          case DW_OP_ne:
-            op = Cop_Ne; opname = "ne"; goto binop;
+            bop = Cbinop_Ne; opname = "ne"; goto binop;
          binop:
             POP( ix );
             POP( ix2 );
-            PUSH( ML_(CfiExpr_Binop)( dst, op, ix2, ix ) );
+            PUSH( ML_(CfiExpr_Binop)( dst, bop, ix2, ix ) );
             if (ddump_frames)
                VG_(printf)("DW_OP_%s", opname);
             break;
Index: coregrind/m_debuginfo/debuginfo.c
===================================================================
--- valgrind/coregrind/m_debuginfo/debuginfo.c	(revision 13007)
+++ valgrind/coregrind/m_debuginfo/debuginfo.c	(working copy)
@@ -2051,30 +2051,40 @@
 UWord evalCfiExpr ( XArray* exprs, Int ix, 
                     CfiExprEvalContext* eec, Bool* ok )
 {
-   UWord wL, wR;
+   UWord w, wL, wR;
    Addr  a;
    CfiExpr* e;
    vg_assert(sizeof(Addr) == sizeof(UWord));
    e = VG_(indexXA)( exprs, ix );
    switch (e->tag) {
+      case Cex_Unop:
+         w = evalCfiExpr( exprs, e->Cex.Unop.ix, eec, ok );
+         if (!(*ok)) return 0;
+         switch (e->Cex.Unop.op) {
+            case Cunop_Abs: return (Word) w < 0 ? - w : w;
+            case Cunop_Neg: return - (Word) w;
+            case Cunop_Not: return ~ w;
+            default: goto unhandled;
+         }
+         /*NOTREACHED*/
       case Cex_Binop:
          wL = evalCfiExpr( exprs, e->Cex.Binop.ixL, eec, ok );
          if (!(*ok)) return 0;
          wR = evalCfiExpr( exprs, e->Cex.Binop.ixR, eec, ok );
          if (!(*ok)) return 0;
          switch (e->Cex.Binop.op) {
-            case Cop_Add: return wL + wR;
-            case Cop_Sub: return wL - wR;
-            case Cop_And: return wL & wR;
-            case Cop_Mul: return wL * wR;
-            case Cop_Shl: return wL << wR;
-            case Cop_Shr: return wL >> wR;
-            case Cop_Eq: return wL == wR ? 1 : 0;
-            case Cop_Ge: return (Word) wL >= (Word) wR ? 1 : 0;
-            case Cop_Gt: return (Word) wL > (Word) wR ? 1 : 0;
-            case Cop_Le: return (Word) wL <= (Word) wR ? 1 : 0;
-            case Cop_Lt: return (Word) wL < (Word) wR ? 1 : 0;
-            case Cop_Ne: return wL != wR ? 1 : 0;
+            case Cbinop_Add: return wL + wR;
+            case Cbinop_Sub: return wL - wR;
+            case Cbinop_And: return wL & wR;
+            case Cbinop_Mul: return wL * wR;
+            case Cbinop_Shl: return wL << wR;
+            case Cbinop_Shr: return wL >> wR;
+            case Cbinop_Eq: return wL == wR ? 1 : 0;
+            case Cbinop_Ge: return (Word) wL >= (Word) wR ? 1 : 0;
+            case Cbinop_Gt: return (Word) wL > (Word) wR ? 1 : 0;
+            case Cbinop_Le: return (Word) wL <= (Word) wR ? 1 : 0;
+            case Cbinop_Lt: return (Word) wL < (Word) wR ? 1 : 0;
+            case Cbinop_Ne: return wL != wR ? 1 : 0;
             default: goto unhandled;
          }
          /*NOTREACHED*/
Index: valgrind/coregrind/m_debuginfo/storage.c
===================================================================
--- valgrind/coregrind/m_debuginfo/storage.c	(revision 13007)
+++ valgrind/coregrind/m_debuginfo/storage.c	(working copy)
@@ -585,10 +585,19 @@
    e.Cex.Const.con = con;
    return (Int)VG_(addToXA)( dst, &e );
 }
-Int ML_(CfiExpr_Binop)( XArray* dst, CfiOp op, Int ixL, Int ixR )
+Int ML_(CfiExpr_Unop)( XArray* dst, CfiUnop op, Int ix )
 {
    CfiExpr e;
    VG_(memset)( &e, 0, sizeof(e) );
+   e.tag = Cex_Unop;
+   e.Cex.Unop.op  = op;
+   e.Cex.Unop.ix = ix;
+   return (Int)VG_(addToXA)( dst, &e );
+}
+Int ML_(CfiExpr_Binop)( XArray* dst, CfiBinop op, Int ixL, Int ixR )
+{
+   CfiExpr e;
+   VG_(memset)( &e, 0, sizeof(e) );
    e.tag = Cex_Binop;
    e.Cex.Binop.op  = op;
    e.Cex.Binop.ixL = ixL;
@@ -612,25 +621,35 @@
    return (Int)VG_(addToXA)( dst, &e );
 }
 
-static void ppCfiOp ( CfiOp op ) 
+static void ppCfiUnop ( CfiUnop op ) 
 {
    switch (op) {
-      case Cop_Add: VG_(printf)("+"); break;
-      case Cop_Sub: VG_(printf)("-"); break;
-      case Cop_And: VG_(printf)("&"); break;
-      case Cop_Mul: VG_(printf)("*"); break;
-      case Cop_Shl: VG_(printf)("<<"); break;
-      case Cop_Shr: VG_(printf)(">>"); break;
-      case Cop_Eq: VG_(printf)("=="); break;
-      case Cop_Ge: VG_(printf)(">="); break;
-      case Cop_Gt: VG_(printf)(">"); break;
-      case Cop_Le: VG_(printf)("<="); break;
-      case Cop_Lt: VG_(printf)("<"); break;
-      case Cop_Ne: VG_(printf)("!="); break;
-      default:      vg_assert(0);
+      case Cunop_Abs: VG_(printf)("abs"); break;
+      case Cunop_Neg: VG_(printf)("-"); break;
+      case Cunop_Not: VG_(printf)("~"); break;
+      default:        vg_assert(0);
    }
 }
 
+static void ppCfiBinop ( CfiBinop op ) 
+{
+   switch (op) {
+      case Cbinop_Add: VG_(printf)("+"); break;
+      case Cbinop_Sub: VG_(printf)("-"); break;
+      case Cbinop_And: VG_(printf)("&"); break;
+      case Cbinop_Mul: VG_(printf)("*"); break;
+      case Cbinop_Shl: VG_(printf)("<<"); break;
+      case Cbinop_Shr: VG_(printf)(">>"); break;
+      case Cbinop_Eq:  VG_(printf)("=="); break;
+      case Cbinop_Ge:  VG_(printf)(">="); break;
+      case Cbinop_Gt:  VG_(printf)(">"); break;
+      case Cbinop_Le:  VG_(printf)("<="); break;
+      case Cbinop_Lt:  VG_(printf)("<"); break;
+      case Cbinop_Ne:  VG_(printf)("!="); break;
+      default:         vg_assert(0);
+   }
+}
+
 static void ppCfiReg ( CfiReg reg )
 {
    switch (reg) {
@@ -664,11 +683,17 @@
       case Cex_Const: 
          VG_(printf)("0x%lx", e->Cex.Const.con); 
          break;
+      case Cex_Unop: 
+         ppCfiUnop(e->Cex.Unop.op);
+         VG_(printf)("(");
+         ML_(ppCfiExpr)(src, e->Cex.Unop.ix);
+         VG_(printf)(")");
+         break;
       case Cex_Binop: 
          VG_(printf)("(");
          ML_(ppCfiExpr)(src, e->Cex.Binop.ixL);
          VG_(printf)(")");
-         ppCfiOp(e->Cex.Binop.op);
+         ppCfiBinop(e->Cex.Binop.op);
          VG_(printf)("(");
          ML_(ppCfiExpr)(src, e->Cex.Binop.ixR);
          VG_(printf)(")");
Index: valgrind/coregrind/m_debuginfo/priv_storage.h
===================================================================
--- valgrind/coregrind/m_debuginfo/priv_storage.h	(revision 13007)
+++ valgrind/coregrind/m_debuginfo/priv_storage.h	(working copy)
@@ -279,23 +279,31 @@
 
 typedef
    enum {
-      Cop_Add=0x321,
-      Cop_Sub,
-      Cop_And,
-      Cop_Mul,
-      Cop_Shl,
-      Cop_Shr,
-      Cop_Eq,
-      Cop_Ge,
-      Cop_Gt,
-      Cop_Le,
-      Cop_Lt,
-      Cop_Ne
+      Cunop_Abs=0x231,
+      Cunop_Neg,
+      Cunop_Not
    }
-   CfiOp;
+   CfiUnop;
 
 typedef
    enum {
+      Cbinop_Add=0x321,
+      Cbinop_Sub,
+      Cbinop_And,
+      Cbinop_Mul,
+      Cbinop_Shl,
+      Cbinop_Shr,
+      Cbinop_Eq,
+      Cbinop_Ge,
+      Cbinop_Gt,
+      Cbinop_Le,
+      Cbinop_Lt,
+      Cbinop_Ne
+   }
+   CfiBinop;
+
+typedef
+   enum {
       Creg_IA_SP=0x213,
       Creg_IA_BP,
       Creg_IA_IP,
@@ -313,6 +321,7 @@
       Cex_Undef=0x123,
       Cex_Deref,
       Cex_Const,
+      Cex_Unop,
       Cex_Binop,
       Cex_CfiReg,
       Cex_DwReg
@@ -332,7 +341,11 @@
             UWord con;
          } Const;
          struct {
-            CfiOp op;
+            CfiUnop op;
+            Int ix;
+         } Unop;
+         struct {
+            CfiBinop op;
             Int ixL;
             Int ixR;
          } Binop;
@@ -350,7 +363,8 @@
 extern Int ML_(CfiExpr_Undef) ( XArray* dst );
 extern Int ML_(CfiExpr_Deref) ( XArray* dst, Int ixAddr );
 extern Int ML_(CfiExpr_Const) ( XArray* dst, UWord con );
-extern Int ML_(CfiExpr_Binop) ( XArray* dst, CfiOp op, Int ixL, Int ixR );
+extern Int ML_(CfiExpr_Unop)  ( XArray* dst, CfiUnop op, Int ix );
+extern Int ML_(CfiExpr_Binop) ( XArray* dst, CfiBinop op, Int ixL, Int ixR );
 extern Int ML_(CfiExpr_CfiReg)( XArray* dst, CfiReg reg );
 extern Int ML_(CfiExpr_DwReg) ( XArray* dst, Int reg );