]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Handle DW_CFA_def_cfa_expression; also DW_OP_mul.
authorJulian Seward <jseward@acm.org>
Wed, 28 Feb 2007 13:03:27 +0000 (13:03 +0000)
committerJulian Seward <jseward@acm.org>
Wed, 28 Feb 2007 13:03:27 +0000 (13:03 +0000)
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@6627

coregrind/m_debuginfo/debuginfo.c
coregrind/m_debuginfo/priv_storage.h
coregrind/m_debuginfo/readdwarf.c
coregrind/m_debuginfo/storage.c

index 4262cb15960b0569f80c3a6e11f013bcf499f39d..a9cc654175cab706b02df08f5b29baf60a1b5966 100644 (file)
@@ -1010,6 +1010,7 @@ UWord evalCfiExpr ( XArray* exprs, Int ix,
             case Cop_Add: return wL + wR;
             case Cop_Sub: return wL - wR;
             case Cop_And: return wL & wR;
+            case Cop_Mul: return wL * wR;
             default: goto unhandled;
          }
          /*NOTREACHED*/
@@ -1149,7 +1150,19 @@ Bool VG_(use_CF_info) ( /*MOD*/Addr* ipP,
          cfa = cfsi->cfa_off + fpHere;
          break;
       case CFIC_EXPR: 
-         vg_assert(0);
+         if (0) {
+            VG_(printf)("CFIC_EXPR: ");
+            ML_(ppCfiExpr)(si->cfsi_exprs, cfsi->cfa_off);
+            VG_(printf)("\n");
+         }
+         eec.ipHere = ipHere;
+         eec.spHere = spHere;
+         eec.fpHere = fpHere;
+         eec.min_accessible = min_accessible;
+         eec.max_accessible = max_accessible;
+         ok = True;
+         cfa = evalCfiExpr(si->cfsi_exprs, cfsi->cfa_off, &eec, &ok );
+         if (!ok) return False;
          break;
       default: 
          vg_assert(0);
index 69a2e83f1ce74dba1d3934cadbb7e0e626751ff5..058b6ba6d6d382da2133705b48cb7c2804e48cdd 100644 (file)
@@ -146,7 +146,8 @@ typedef
    enum {
       Cop_Add=0x321,
       Cop_Sub,
-      Cop_And
+      Cop_And,
+      Cop_Mul
    }
    CfiOp;
 
index d5b68adaea40e7b088b65f83c72b2477a05bf68f..91a1f3a4541aac3b94ddf25757c414fdd09c9aee 100644 (file)
@@ -1992,10 +1992,25 @@ static Bool summarise_context( /*OUT*/DiCfSI* si,
 
    /* How to generate the CFA */
    if (!ctx->cfa_is_regoff) {
-      /* it was set by DW_CFA_def_cfa_expression; we don't know what
-         it really is */
-      why = 6;
-      goto failed;
+      /* it was set by DW_CFA_def_cfa_expression; try to convert */
+      XArray *src, *dst;
+      Int    conv;
+      src = ctx->exprs;
+      dst = seginfo->cfsi_exprs;
+      if (src && (VG_(sizeXA)(src) > 0) && (!dst)) {
+         dst = VG_(newXA)( symtab_alloc, symtab_free,
+                           sizeof(CfiExpr) );
+         vg_assert(dst);
+         seginfo->cfsi_exprs = dst;
+      }
+      conv = copy_convert_CfiExpr_tree
+                    ( dst, ctx, ctx->cfa_expr_ix );
+      vg_assert(conv >= -1);
+      if (conv == -1) { why = 6; goto failed; }
+      si->cfa_how = CFIC_EXPR;
+      si->cfa_off = conv;
+      if (0 && seginfo->ddump_frames)
+         ML_(ppCfiExpr)(dst, conv);
    } else
    if (ctx->cfa_is_regoff && ctx->cfa_reg == SP_REG) {
       si->cfa_how = CFIC_SPREL;
@@ -2556,7 +2571,8 @@ enum dwarf_location_atom
 /* Convert the DWARF3 expression in expr[0 .. exprlen-1] into a dag
    (of CfiExprs) stored in ctx->exprs, and return the index in
    ctx->exprs of the root node.  Or fail in which case return -1. */
-
+/* IMPORTANT: when adding expression forms here, also remember to
+   add suitable evaluation code in evalCfiExpr in debuginfo.c. */
 static Int dwarfexpr_to_dag ( UnwindContext* ctx, 
                               UChar* expr, Int exprlen, 
                               Bool push_cfa_at_start,
@@ -2674,6 +2690,8 @@ static Int dwarfexpr_to_dag ( UnwindContext* ctx,
             op = Cop_Add; opname = "plus"; goto binop;
          case DW_OP_and:
             op = Cop_And; opname = "and"; goto binop;
+         case DW_OP_mul:
+            op = Cop_Mul; opname = "mul"; goto binop;
          binop:
             POP( ix );
             POP( ix2 );
@@ -2683,8 +2701,10 @@ static Int dwarfexpr_to_dag ( UnwindContext* ctx,
             break;
 
          default:
-            VG_(message)(Vg_DebugMsg, "DWARF2 CFI reader: unhandled DW_OP_ "
-                                      "opcode 0x%x", (Int)opcode); 
+            if (!VG_(clo_xml))
+               VG_(message)(Vg_DebugMsg, 
+                            "DWARF2 CFI reader: unhandled DW_OP_ "
+                            "opcode 0x%x", (Int)opcode); 
             return -1;
       }
 
@@ -3050,18 +3070,22 @@ static Int run_CF_instruction ( /*MOD*/UnwindContext* ctx,
          break;
 
       case DW_CFA_def_cfa_expression:
-         if (si->trace_cfi)
-            VG_(printf)("DWARF2 CFI reader: "
-                        "ignoring DW_CFA_def_cfa_expression\n");
          len = read_leb128( &instr[i], &nleb, 0 );
          i += nleb;
+         expr = &instr[i];
          i += len;
+         if (si->ddump_frames)
+            VG_(printf)("  DW_CFA_def_cfa_expression (");
+         /* Convert the expression into a dag rooted at ctx->exprs index j,
+            or fail. */
+         j = dwarfexpr_to_dag ( ctx, expr, len, True/*push CFA at start*/, 
+                                si->ddump_frames);
+         if (si->ddump_frames)
+            VG_(printf)(")\n");
          ctx->cfa_is_regoff = False;
          ctx->cfa_reg       = 0;
          ctx->cfa_off       = 0;
-         ctx->cfa_expr_ix   = -1; /* invalid - should handle properly */
-         if (si->ddump_frames)
-            VG_(printf)("  rci:DW_CFA_def_cfa_expression (ignored)\n");
+         ctx->cfa_expr_ix   = j;
          break;
 
       case DW_CFA_GNU_window_save:
index e4ce739965ffe1883b0438b46e718eae88185342..6c92bba03233ddb51cb78b868f5d37eb3a5be7d1 100644 (file)
@@ -438,6 +438,7 @@ static void ppCfiOp ( CfiOp 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;
       default:      vg_assert(0);
    }
 }