From: Julian Seward Date: Wed, 28 Feb 2007 13:03:27 +0000 (+0000) Subject: Handle DW_CFA_def_cfa_expression; also DW_OP_mul. X-Git-Tag: svn/VALGRIND_3_3_0~339 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1907f8c209595caf82edd519a7b9b2415e948ba3;p=thirdparty%2Fvalgrind.git Handle DW_CFA_def_cfa_expression; also DW_OP_mul. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@6627 --- diff --git a/coregrind/m_debuginfo/debuginfo.c b/coregrind/m_debuginfo/debuginfo.c index 4262cb1596..a9cc654175 100644 --- a/coregrind/m_debuginfo/debuginfo.c +++ b/coregrind/m_debuginfo/debuginfo.c @@ -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); diff --git a/coregrind/m_debuginfo/priv_storage.h b/coregrind/m_debuginfo/priv_storage.h index 69a2e83f1c..058b6ba6d6 100644 --- a/coregrind/m_debuginfo/priv_storage.h +++ b/coregrind/m_debuginfo/priv_storage.h @@ -146,7 +146,8 @@ typedef enum { Cop_Add=0x321, Cop_Sub, - Cop_And + Cop_And, + Cop_Mul } CfiOp; diff --git a/coregrind/m_debuginfo/readdwarf.c b/coregrind/m_debuginfo/readdwarf.c index d5b68adaea..91a1f3a454 100644 --- a/coregrind/m_debuginfo/readdwarf.c +++ b/coregrind/m_debuginfo/readdwarf.c @@ -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: diff --git a/coregrind/m_debuginfo/storage.c b/coregrind/m_debuginfo/storage.c index e4ce739965..6c92bba032 100644 --- a/coregrind/m_debuginfo/storage.c +++ b/coregrind/m_debuginfo/storage.c @@ -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); } }