From fcbcff4fa4708f6d51a986748b14cbb126c20248 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Jul 13 2009 14:17:46 +0000 Subject: 3.4.1-5 --- diff --git a/valgrind-3.4.1-dwarf-cfa-remember-state1.patch b/valgrind-3.4.1-dwarf-cfa-remember-state1.patch new file mode 100644 index 0000000..101dc53 --- /dev/null +++ b/valgrind-3.4.1-dwarf-cfa-remember-state1.patch @@ -0,0 +1,310 @@ +--- valgrind/coregrind/m_debuginfo/readdwarf.c.jj 2009-07-13 14:09:14.478329957 +0200 ++++ valgrind/coregrind/m_debuginfo/readdwarf.c 2009-07-13 15:18:35.596080042 +0200 +@@ -1923,6 +1923,11 @@ static void ppRegRule ( XArray* exprs, R + } + + ++/* Size of the stack of register unwind rules. This is only ++ exceedingly rarely used, so a stack of size 1 should actually work ++ with almost all compiler-generated CFA. */ ++#define N_RR_STACK 4 ++ + typedef + struct { + /* Read-only fields (set by the CIE) */ +@@ -1939,8 +1944,12 @@ typedef + Int cfa_reg; + Int cfa_off; /* in bytes */ + Int cfa_expr_ix; /* index into cfa_exprs */ +- /* register unwind rules */ +- RegRule reg[N_CFI_REGS]; ++ /* A stack of register unwind rules. We need a stack of them, ++ rather than just one set of rules, in order to handle ++ DW_CFA_{remember,restore}_state. */ ++ RegRule reg[N_RR_STACK][N_CFI_REGS]; ++ Int reg_sp; /* 0 <= reg_sp < N_RR_STACK; points at the ++ currently-in-use rule set. */ + /* array of CfiExpr, shared by reg[] and cfa_expr_ix */ + XArray* exprs; + } +@@ -1948,7 +1957,7 @@ typedef + + static void ppUnwindContext ( UnwindContext* ctx ) + { +- Int i; ++ Int j, i; + VG_(printf)("0x%llx: ", (ULong)ctx->loc); + if (ctx->cfa_is_regoff) { + VG_(printf)("%d(r%d) ", ctx->cfa_off, ctx->cfa_reg); +@@ -1958,14 +1967,19 @@ static void ppUnwindContext ( UnwindCont + ML_(ppCfiExpr)( ctx->exprs, ctx->cfa_expr_ix ); + VG_(printf)("} "); + } +- for (i = 0; i < N_CFI_REGS; i++) +- ppRegRule(ctx->exprs, &ctx->reg[i]); ++ for (j = 0; j <= ctx->reg_sp; j++) { ++ VG_(printf)("%s[%d]={ ", j > 0 ? " " : "", j); ++ for (i = 0; i < N_CFI_REGS; i++) ++ ppRegRule(ctx->exprs, &ctx->reg[j][i]); ++ VG_(printf)("}"); ++ } + VG_(printf)("\n"); + } + + static void initUnwindContext ( /*OUT*/UnwindContext* ctx ) + { +- Int i; ++ Int j, i; ++ VG_(memset)(ctx, 0, sizeof(*ctx)); + ctx->code_a_f = 0; + ctx->data_a_f = 0; + ctx->initloc = 0; +@@ -1976,9 +1990,12 @@ static void initUnwindContext ( /*OUT*/U + ctx->cfa_off = 0; + ctx->cfa_expr_ix = 0; + ctx->exprs = NULL; +- for (i = 0; i < N_CFI_REGS; i++) { +- ctx->reg[i].tag = RR_Undef; +- ctx->reg[i].arg = 0; ++ ctx->reg_sp = 0; ++ for (j = 0; j < N_RR_STACK; j++) { ++ for (i = 0; i < N_CFI_REGS; i++) { ++ ctx->reg[j][i].tag = RR_Undef; ++ ctx->reg[j][i].arg = 0; ++ } + } + } + +@@ -2104,8 +2121,15 @@ static Bool summarise_context( /*OUT*/Di + why = 2; goto failed; /* otherwise give up */ \ + } + +- SUMMARISE_HOW(si->ra_how, si->ra_off, ctx->reg[ctx->ra_reg] ); +- SUMMARISE_HOW(si->fp_how, si->fp_off, ctx->reg[FP_REG] ); ++ /* Guard against obviously stupid settings of the reg-rule stack ++ pointer. */ ++ if (ctx->reg_sp < 0) { why = 8; goto failed; } ++ if (ctx->reg_sp >= N_RR_STACK) { why = 9; goto failed; } ++ ++ SUMMARISE_HOW(si->ra_how, si->ra_off, ++ ctx->reg[ctx->reg_sp][ctx->ra_reg] ); ++ SUMMARISE_HOW(si->fp_how, si->fp_off, ++ ctx->reg[ctx->reg_sp][FP_REG] ); + + # undef SUMMARISE_HOW + +@@ -2116,7 +2140,7 @@ static Bool summarise_context( /*OUT*/Di + + /* also, gcc says "Undef" for %{e,r}bp when it is unchanged. So + .. */ +- if (ctx->reg[FP_REG].tag == RR_Undef) ++ if (ctx->reg[ctx->reg_sp][FP_REG].tag == RR_Undef) + si->fp_how = CFIR_SAME; + + /* knock out some obviously stupid cases */ +@@ -2215,10 +2239,10 @@ static void ppUnwindContext_summary ( Un + } + + VG_(printf)("RA="); +- ppRegRule( ctx->exprs, &ctx->reg[ctx->ra_reg] ); ++ ppRegRule( ctx->exprs, &ctx->reg[ctx->reg_sp][ctx->ra_reg] ); + + VG_(printf)("FP="); +- ppRegRule( ctx->exprs, &ctx->reg[FP_REG] ); ++ ppRegRule( ctx->exprs, &ctx->reg[ctx->reg_sp][FP_REG] ); + VG_(printf)("\n"); + } + +@@ -2664,6 +2688,9 @@ static Int run_CF_instruction ( /*MOD*/U + Addr printing_bias = ((Addr)ctx->initloc) - ((Addr)di->text_bias); + i++; + ++ if (ctx->reg_sp < 0 || ctx->reg_sp >= N_RR_STACK) ++ return 0; /* bogus reg-rule stack pointer */ ++ + if (hi2 == DW_CFA_advance_loc) { + delta = (UInt)lo6; + ctx->loc += delta; +@@ -2680,12 +2707,13 @@ static Int run_CF_instruction ( /*MOD*/U + reg = (Int)lo6; + if (reg < 0 || reg >= N_CFI_REGS) + return 0; /* fail */ +- ctx->reg[reg].tag = RR_CFAOff; +- ctx->reg[reg].arg = off * ctx->data_a_f; ++ ctx->reg[ctx->reg_sp][reg].tag = RR_CFAOff; ++ ctx->reg[ctx->reg_sp][reg].arg = off * ctx->data_a_f; + if (di->ddump_frames) + VG_(printf)(" DW_CFA_offset: r%d at cfa%s%d\n", +- (Int)reg, ctx->reg[reg].arg < 0 ? "" : "+", +- (Int)ctx->reg[reg].arg ); ++ (Int)reg, ++ ctx->reg[ctx->reg_sp][reg].arg < 0 ? "" : "+", ++ (Int)ctx->reg[ctx->reg_sp][reg].arg ); + return i; + } + +@@ -2695,7 +2723,7 @@ static Int run_CF_instruction ( /*MOD*/U + return 0; /* fail */ + if (restore_ctx == NULL) + return 0; /* fail */ +- ctx->reg[reg] = restore_ctx->reg[reg]; ++ ctx->reg[ctx->reg_sp][reg] = restore_ctx->reg[ctx->reg_sp][reg]; + if (di->ddump_frames) + VG_(printf)(" DW_CFA_restore: r%d\n", (Int)reg); + return i; +@@ -2781,8 +2809,8 @@ static Int run_CF_instruction ( /*MOD*/U + return 0; /* fail */ + if (reg2 < 0 || reg2 >= N_CFI_REGS) + return 0; /* fail */ +- ctx->reg[reg].tag = RR_Reg; +- ctx->reg[reg].arg = reg2; ++ ctx->reg[ctx->reg_sp][reg].tag = RR_Reg; ++ ctx->reg[ctx->reg_sp][reg].arg = reg2; + if (di->ddump_frames) + VG_(printf)(" DW_CFA_register: r%d in r%d\n", + (Int)reg, (Int)reg2); +@@ -2795,8 +2823,8 @@ static Int run_CF_instruction ( /*MOD*/U + i += nleb; + if (reg < 0 || reg >= N_CFI_REGS) + return 0; /* fail */ +- ctx->reg[reg].tag = RR_CFAOff; +- ctx->reg[reg].arg = off * ctx->data_a_f; ++ ctx->reg[ctx->reg_sp][reg].tag = RR_CFAOff; ++ ctx->reg[ctx->reg_sp][reg].arg = off * ctx->data_a_f; + if (di->ddump_frames) + VG_(printf)(" rci:DW_CFA_offset_extended\n"); + break; +@@ -2808,12 +2836,13 @@ static Int run_CF_instruction ( /*MOD*/U + i += nleb; + if (reg < 0 || reg >= N_CFI_REGS) + return 0; /* fail */ +- ctx->reg[reg].tag = RR_CFAOff; +- ctx->reg[reg].arg = off * ctx->data_a_f; ++ ctx->reg[ctx->reg_sp][reg].tag = RR_CFAOff; ++ ctx->reg[ctx->reg_sp][reg].arg = off * ctx->data_a_f; + if (di->ddump_frames) + VG_(printf)(" DW_CFA_offset_extended_sf: r%d at cfa%s%d\n", +- reg, ctx->reg[reg].arg < 0 ? "" : "+", +- (Int)ctx->reg[reg].arg); ++ reg, ++ ctx->reg[ctx->reg_sp][reg].arg < 0 ? "" : "+", ++ (Int)ctx->reg[ctx->reg_sp][reg].arg); + break; + + case DW_CFA_GNU_negative_offset_extended: +@@ -2823,8 +2852,8 @@ static Int run_CF_instruction ( /*MOD*/U + i += nleb; + if (reg < 0 || reg >= N_CFI_REGS) + return 0; /* fail */ +- ctx->reg[reg].tag = RR_CFAOff; +- ctx->reg[reg].arg = (-off) * ctx->data_a_f; ++ ctx->reg[ctx->reg_sp][reg].tag = RR_CFAOff; ++ ctx->reg[ctx->reg_sp][reg].arg = (-off) * ctx->data_a_f; + if (di->ddump_frames) + VG_(printf)(" rci:DW_CFA_GNU_negative_offset_extended\n"); + break; +@@ -2836,7 +2865,7 @@ static Int run_CF_instruction ( /*MOD*/U + return 0; /* fail */ + if (restore_ctx == NULL) + return 0; /* fail */ +- ctx->reg[reg] = restore_ctx->reg[reg]; ++ ctx->reg[ctx->reg_sp][reg] = restore_ctx->reg[ctx->reg_sp][reg]; + if (di->ddump_frames) + VG_(printf)(" rci:DW_CFA_restore_extended\n"); + break; +@@ -2848,8 +2877,8 @@ static Int run_CF_instruction ( /*MOD*/U + i += nleb; + if (reg < 0 || reg >= N_CFI_REGS) + return 0; /* fail */ +- ctx->reg[reg].tag = RR_CFAValOff; +- ctx->reg[reg].arg = off * ctx->data_a_f; ++ ctx->reg[ctx->reg_sp][reg].tag = RR_CFAValOff; ++ ctx->reg[ctx->reg_sp][reg].arg = off * ctx->data_a_f; + if (di->ddump_frames) + VG_(printf)(" rci:DW_CFA_val_offset\n"); + break; +@@ -2861,8 +2890,8 @@ static Int run_CF_instruction ( /*MOD*/U + i += nleb; + if (reg < 0 || reg >= N_CFI_REGS) + return 0; /* fail */ +- ctx->reg[reg].tag = RR_CFAValOff; +- ctx->reg[reg].arg = off * ctx->data_a_f; ++ ctx->reg[ctx->reg_sp][reg].tag = RR_CFAValOff; ++ ctx->reg[ctx->reg_sp][reg].arg = off * ctx->data_a_f; + if (di->ddump_frames) + VG_(printf)(" rci:DW_CFA_val_offset_sf\n"); + break; +@@ -2907,8 +2936,8 @@ static Int run_CF_instruction ( /*MOD*/U + i += nleb; + if (reg < 0 || reg >= N_CFI_REGS) + return 0; /* fail */ +- ctx->reg[reg].tag = RR_Undef; +- ctx->reg[reg].arg = 0; ++ ctx->reg[ctx->reg_sp][reg].tag = RR_Undef; ++ ctx->reg[ctx->reg_sp][reg].arg = 0; + if (di->ddump_frames) + VG_(printf)(" rci:DW_CFA_undefined\n"); + break; +@@ -2952,8 +2981,8 @@ static Int run_CF_instruction ( /*MOD*/U + return 0; /* fail */ + /* Add an extra dereference */ + j = ML_(CfiExpr_Deref)( ctx->exprs, j ); +- ctx->reg[reg].tag = RR_ValExpr; +- ctx->reg[reg].arg = j; ++ ctx->reg[ctx->reg_sp][reg].tag = RR_ValExpr; ++ ctx->reg[ctx->reg_sp][reg].arg = j; + break; + + case DW_CFA_val_expression: +@@ -2981,8 +3010,8 @@ static Int run_CF_instruction ( /*MOD*/U + } + if (j == -1) + return 0; /* fail */ +- ctx->reg[reg].tag = RR_ValExpr; +- ctx->reg[reg].arg = j; ++ ctx->reg[ctx->reg_sp][reg].tag = RR_ValExpr; ++ ctx->reg[ctx->reg_sp][reg].arg = j; + break; + + case DW_CFA_def_cfa_expression: +@@ -3008,7 +3037,39 @@ static Int run_CF_instruction ( /*MOD*/U + /* Ignored. This appears to be sparc-specific; quite why it + turns up in SuSE-supplied x86 .so's beats me. */ + if (di->ddump_frames) +- VG_(printf)("DW_CFA_GNU_window_save\n"); ++ VG_(printf)(" DW_CFA_GNU_window_save\n"); ++ break; ++ ++ case DW_CFA_remember_state: ++ if (di->ddump_frames) ++ VG_(printf)(" DW_CFA_remember_state\n"); ++ /* we just checked this at entry, so: */ ++ vg_assert(ctx->reg_sp >= 0 && ctx->reg_sp < N_RR_STACK); ++ ctx->reg_sp++; ++ if (ctx->reg_sp == N_RR_STACK) { ++ /* stack overflow. We're hosed. */ ++ VG_(message)(Vg_DebugMsg, "DWARF2 CFI reader: N_RR_STACK is " ++ "too low; increase and recompile."); ++ i = 0; /* indicate failure */ ++ } else { ++ VG_(memcpy)(/*dst*/&ctx->reg[ctx->reg_sp], ++ /*src*/&ctx->reg[ctx->reg_sp - 1], ++ sizeof(ctx->reg[ctx->reg_sp]) ); ++ } ++ break; ++ ++ case DW_CFA_restore_state: ++ if (di->ddump_frames) ++ VG_(printf)(" DW_CFA_restore_state\n"); ++ /* we just checked this at entry, so: */ ++ vg_assert(ctx->reg_sp >= 0 && ctx->reg_sp < N_RR_STACK); ++ if (ctx->reg_sp == 0) { ++ /* stack overflow. Give up. */ ++ i = 0; /* indicate failure */ ++ } else { ++ /* simply fall back to previous entry */ ++ ctx->reg_sp--; ++ } + break; + + default: diff --git a/valgrind-3.4.1-dwarf-cfa-remember-state2.patch b/valgrind-3.4.1-dwarf-cfa-remember-state2.patch new file mode 100644 index 0000000..9559b28 --- /dev/null +++ b/valgrind-3.4.1-dwarf-cfa-remember-state2.patch @@ -0,0 +1,518 @@ +--- valgrind/coregrind/m_debuginfo/readdwarf.c.jj 2009-07-13 15:18:35.596080042 +0200 ++++ valgrind/coregrind/m_debuginfo/readdwarf.c 2009-07-13 15:54:43.576955651 +0200 +@@ -1939,17 +1939,20 @@ typedef + run_CF_instruction. */ + /* The LOC entry */ + Addr loc; +- /* The CFA entry. This can be either reg+/-offset or an expr. */ +- Bool cfa_is_regoff; /* True=>is reg+offset; False=>is expr */ +- Int cfa_reg; +- Int cfa_off; /* in bytes */ +- Int cfa_expr_ix; /* index into cfa_exprs */ +- /* A stack of register unwind rules. We need a stack of them, +- rather than just one set of rules, in order to handle ++ /* We need a stack of these in order to handle + DW_CFA_{remember,restore}_state. */ +- RegRule reg[N_RR_STACK][N_CFI_REGS]; +- Int reg_sp; /* 0 <= reg_sp < N_RR_STACK; points at the +- currently-in-use rule set. */ ++ struct UnwindContextState { ++ /* The CFA entry. This can be either reg+/-offset or an expr. */ ++ Bool cfa_is_regoff; /* True=>is reg+offset; False=>is expr */ ++ Int cfa_reg; ++ Int cfa_off; /* in bytes */ ++ Int cfa_expr_ix; /* index into cfa_exprs */ ++ /* Register unwind rules. */ ++ RegRule reg[N_CFI_REGS]; ++ } ++ state[N_RR_STACK]; ++ Int state_sp; /* 0 <= state_sp < N_RR_STACK; points at the ++ currently-in-use rule set. */ + /* array of CfiExpr, shared by reg[] and cfa_expr_ix */ + XArray* exprs; + } +@@ -1959,18 +1962,20 @@ static void ppUnwindContext ( UnwindCont + { + Int j, i; + VG_(printf)("0x%llx: ", (ULong)ctx->loc); +- if (ctx->cfa_is_regoff) { +- VG_(printf)("%d(r%d) ", ctx->cfa_off, ctx->cfa_reg); +- } else { +- vg_assert(ctx->exprs); +- VG_(printf)("{"); +- ML_(ppCfiExpr)( ctx->exprs, ctx->cfa_expr_ix ); +- VG_(printf)("} "); +- } +- for (j = 0; j <= ctx->reg_sp; j++) { ++ for (j = 0; j <= ctx->state_sp; j++) { ++ struct UnwindContextState* ctxs = &ctx->state[j]; + VG_(printf)("%s[%d]={ ", j > 0 ? " " : "", j); ++ if (ctxs->cfa_is_regoff) { ++ VG_(printf)("%d(r%d) ", ctxs->cfa_off, ctxs->cfa_reg); ++ } else { ++ vg_assert(ctx->exprs); ++ VG_(printf)("{"); ++ ML_(ppCfiExpr)( ctx->exprs, ctxs->cfa_expr_ix ); ++ VG_(printf)("} "); ++ } ++ VG_(printf)("{ "); + for (i = 0; i < N_CFI_REGS; i++) +- ppRegRule(ctx->exprs, &ctx->reg[j][i]); ++ ppRegRule(ctx->exprs, &ctxs->reg[i]); + VG_(printf)("}"); + } + VG_(printf)("\n"); +@@ -1980,21 +1985,22 @@ static void initUnwindContext ( /*OUT*/U + { + Int j, i; + VG_(memset)(ctx, 0, sizeof(*ctx)); +- ctx->code_a_f = 0; ++ /* ctx->code_a_f = 0; + ctx->data_a_f = 0; +- ctx->initloc = 0; ++ ctx->initloc = 0; */ + ctx->ra_reg = RA_REG_DEFAULT; +- ctx->loc = 0; +- ctx->cfa_is_regoff = True; +- ctx->cfa_reg = 0; +- ctx->cfa_off = 0; +- ctx->cfa_expr_ix = 0; ++ /* ctx->loc = 0; + ctx->exprs = NULL; +- ctx->reg_sp = 0; ++ ctx->state_sp = 0; */ + for (j = 0; j < N_RR_STACK; j++) { ++ ctx->state[j].cfa_is_regoff = True; ++ /* ctx->state[j].cfa_reg = 0; ++ ctx->state[j].cfa_off = 0; ++ ctx->state[j].cfa_expr_ix = 0; */ + for (i = 0; i < N_CFI_REGS; i++) { +- ctx->reg[j][i].tag = RR_Undef; +- ctx->reg[j][i].arg = 0; ++ if (RR_Undef != 0) ++ ctx->state[j].reg[i].tag = RR_Undef; ++ /* ctx->state[j].reg[i].arg = 0; */ + } + } + } +@@ -2048,10 +2054,17 @@ static Bool summarise_context( /*OUT*/Di + struct _DebugInfo* debuginfo ) + { + Int why = 0; ++ struct UnwindContextState* ctxs; + initCfiSI(si); + ++ /* Guard against obviously stupid settings of the reg-rule stack ++ pointer. */ ++ if (ctx->state_sp < 0) { why = 8; goto failed; } ++ if (ctx->state_sp >= N_RR_STACK) { why = 9; goto failed; } ++ ctxs = &ctx->state[ctx->state_sp]; ++ + /* How to generate the CFA */ +- if (!ctx->cfa_is_regoff) { ++ if (!ctxs->cfa_is_regoff) { + /* it was set by DW_CFA_def_cfa_expression; try to convert */ + XArray *src, *dst; + Int conv; +@@ -2064,7 +2077,7 @@ static Bool summarise_context( /*OUT*/Di + debuginfo->cfsi_exprs = dst; + } + conv = copy_convert_CfiExpr_tree +- ( dst, ctx, ctx->cfa_expr_ix ); ++ ( dst, ctx, ctxs->cfa_expr_ix ); + vg_assert(conv >= -1); + if (conv == -1) { why = 6; goto failed; } + si->cfa_how = CFIC_EXPR; +@@ -2072,13 +2085,13 @@ static Bool summarise_context( /*OUT*/Di + if (0 && debuginfo->ddump_frames) + ML_(ppCfiExpr)(dst, conv); + } else +- if (ctx->cfa_is_regoff && ctx->cfa_reg == SP_REG) { ++ if (ctxs->cfa_is_regoff && ctxs->cfa_reg == SP_REG) { + si->cfa_how = CFIC_SPREL; +- si->cfa_off = ctx->cfa_off; ++ si->cfa_off = ctxs->cfa_off; + } else +- if (ctx->cfa_is_regoff && ctx->cfa_reg == FP_REG) { ++ if (ctxs->cfa_is_regoff && ctxs->cfa_reg == FP_REG) { + si->cfa_how = CFIC_FPREL; +- si->cfa_off = ctx->cfa_off; ++ si->cfa_off = ctxs->cfa_off; + } else { + why = 1; + goto failed; +@@ -2121,15 +2134,10 @@ static Bool summarise_context( /*OUT*/Di + why = 2; goto failed; /* otherwise give up */ \ + } + +- /* Guard against obviously stupid settings of the reg-rule stack +- pointer. */ +- if (ctx->reg_sp < 0) { why = 8; goto failed; } +- if (ctx->reg_sp >= N_RR_STACK) { why = 9; goto failed; } +- + SUMMARISE_HOW(si->ra_how, si->ra_off, +- ctx->reg[ctx->reg_sp][ctx->ra_reg] ); ++ ctxs->reg[ctx->ra_reg] ); + SUMMARISE_HOW(si->fp_how, si->fp_off, +- ctx->reg[ctx->reg_sp][FP_REG] ); ++ ctxs->reg[FP_REG] ); + + # undef SUMMARISE_HOW + +@@ -2140,7 +2148,7 @@ static Bool summarise_context( /*OUT*/Di + + /* also, gcc says "Undef" for %{e,r}bp when it is unchanged. So + .. */ +- if (ctx->reg[ctx->reg_sp][FP_REG].tag == RR_Undef) ++ if (ctxs->reg[FP_REG].tag == RR_Undef) + si->fp_how = CFIR_SAME; + + /* knock out some obviously stupid cases */ +@@ -2227,22 +2235,24 @@ static Int copy_convert_CfiExpr_tree ( X + + static void ppUnwindContext_summary ( UnwindContext* ctx ) + { ++ struct UnwindContextState* ctxs = &ctx->state[ctx->state_sp]; ++ + VG_(printf)("0x%llx-1: ", (ULong)ctx->loc); + +- if (ctx->cfa_reg == SP_REG) { +- VG_(printf)("SP/CFA=%d+SP ", ctx->cfa_off); ++ if (ctxs->cfa_reg == SP_REG) { ++ VG_(printf)("SP/CFA=%d+SP ", ctxs->cfa_off); + } else +- if (ctx->cfa_reg == FP_REG) { +- VG_(printf)("SP/CFA=%d+FP ", ctx->cfa_off); ++ if (ctxs->cfa_reg == FP_REG) { ++ VG_(printf)("SP/CFA=%d+FP ", ctxs->cfa_off); + } else { + VG_(printf)("SP/CFA=unknown "); + } + + VG_(printf)("RA="); +- ppRegRule( ctx->exprs, &ctx->reg[ctx->reg_sp][ctx->ra_reg] ); ++ ppRegRule( ctx->exprs, &ctxs->reg[ctx->ra_reg] ); + + VG_(printf)("FP="); +- ppRegRule( ctx->exprs, &ctx->reg[ctx->reg_sp][FP_REG] ); ++ ppRegRule( ctx->exprs, &ctxs->reg[FP_REG] ); + VG_(printf)("\n"); + } + +@@ -2510,6 +2520,7 @@ static Int dwarfexpr_to_dag ( UnwindCont + + Int sp; /* # of top element: valid is -1 .. N_EXPR_STACK-1 */ + Int stack[N_EXPR_STACK]; /* indices into ctx->exprs */ ++ struct UnwindContextState* ctxs = &ctx->state[ctx->state_sp]; + + XArray* dst = ctx->exprs; + UChar* limit = expr + exprlen; +@@ -2521,17 +2532,17 @@ static Int dwarfexpr_to_dag ( UnwindCont + + /* Synthesise the CFA as a CfiExpr */ + if (push_cfa_at_start) { +- if (ctx->cfa_is_regoff) { ++ if (ctxs->cfa_is_regoff) { + /* cfa is reg +/- offset */ + ix = ML_(CfiExpr_Binop)( dst, + Cop_Add, +- ML_(CfiExpr_DwReg)( dst, ctx->cfa_reg ), +- ML_(CfiExpr_Const)( dst, (UWord)(Word)ctx->cfa_off ) ++ ML_(CfiExpr_DwReg)( dst, ctxs->cfa_reg ), ++ ML_(CfiExpr_Const)( dst, (UWord)(Word)ctxs->cfa_off ) + ); + PUSH(ix); + } else { + /* CFA is already an expr; use its root node */ +- PUSH(ctx->cfa_expr_ix); ++ PUSH(ctxs->cfa_expr_ix); + } + } + +@@ -2686,11 +2697,13 @@ static Int run_CF_instruction ( /*MOD*/U + UChar hi2 = (instr[i] >> 6) & 3; + UChar lo6 = instr[i] & 0x3F; + Addr printing_bias = ((Addr)ctx->initloc) - ((Addr)di->text_bias); ++ struct UnwindContextState* ctxs; + i++; + +- if (ctx->reg_sp < 0 || ctx->reg_sp >= N_RR_STACK) ++ if (ctx->state_sp < 0 || ctx->state_sp >= N_RR_STACK) + return 0; /* bogus reg-rule stack pointer */ + ++ ctxs = &ctx->state[ctx->state_sp]; + if (hi2 == DW_CFA_advance_loc) { + delta = (UInt)lo6; + ctx->loc += delta; +@@ -2707,13 +2720,13 @@ static Int run_CF_instruction ( /*MOD*/U + reg = (Int)lo6; + if (reg < 0 || reg >= N_CFI_REGS) + return 0; /* fail */ +- ctx->reg[ctx->reg_sp][reg].tag = RR_CFAOff; +- ctx->reg[ctx->reg_sp][reg].arg = off * ctx->data_a_f; ++ ctxs->reg[reg].tag = RR_CFAOff; ++ ctxs->reg[reg].arg = off * ctx->data_a_f; + if (di->ddump_frames) + VG_(printf)(" DW_CFA_offset: r%d at cfa%s%d\n", + (Int)reg, +- ctx->reg[ctx->reg_sp][reg].arg < 0 ? "" : "+", +- (Int)ctx->reg[ctx->reg_sp][reg].arg ); ++ ctxs->reg[reg].arg < 0 ? "" : "+", ++ (Int)ctxs->reg[reg].arg ); + return i; + } + +@@ -2723,7 +2736,7 @@ static Int run_CF_instruction ( /*MOD*/U + return 0; /* fail */ + if (restore_ctx == NULL) + return 0; /* fail */ +- ctx->reg[ctx->reg_sp][reg] = restore_ctx->reg[ctx->reg_sp][reg]; ++ ctxs->reg[reg] = restore_ctx->state[restore_ctx->state_sp].reg[reg]; + if (di->ddump_frames) + VG_(printf)(" DW_CFA_restore: r%d\n", (Int)reg); + return i; +@@ -2777,10 +2791,10 @@ static Int run_CF_instruction ( /*MOD*/U + i += nleb; + if (reg < 0 || reg >= N_CFI_REGS) + return 0; /* fail */ +- ctx->cfa_is_regoff = True; +- ctx->cfa_expr_ix = 0; +- ctx->cfa_reg = reg; +- ctx->cfa_off = off; ++ ctxs->cfa_is_regoff = True; ++ ctxs->cfa_expr_ix = 0; ++ ctxs->cfa_reg = reg; ++ ctxs->cfa_off = off; + if (di->ddump_frames) + VG_(printf)(" DW_CFA_def_cfa: r%d ofs %d\n", (Int)reg, (Int)off); + break; +@@ -2792,10 +2806,10 @@ static Int run_CF_instruction ( /*MOD*/U + i += nleb; + if (reg < 0 || reg >= N_CFI_REGS) + return 0; /* fail */ +- ctx->cfa_is_regoff = True; +- ctx->cfa_expr_ix = 0; +- ctx->cfa_reg = reg; +- ctx->cfa_off = off * ctx->data_a_f; ++ ctxs->cfa_is_regoff = True; ++ ctxs->cfa_expr_ix = 0; ++ ctxs->cfa_reg = reg; ++ ctxs->cfa_off = off * ctx->data_a_f; + if (di->ddump_frames) + VG_(printf)(" rci:DW_CFA_def_cfa_sf\n"); + break; +@@ -2809,8 +2823,8 @@ static Int run_CF_instruction ( /*MOD*/U + return 0; /* fail */ + if (reg2 < 0 || reg2 >= N_CFI_REGS) + return 0; /* fail */ +- ctx->reg[ctx->reg_sp][reg].tag = RR_Reg; +- ctx->reg[ctx->reg_sp][reg].arg = reg2; ++ ctxs->reg[reg].tag = RR_Reg; ++ ctxs->reg[reg].arg = reg2; + if (di->ddump_frames) + VG_(printf)(" DW_CFA_register: r%d in r%d\n", + (Int)reg, (Int)reg2); +@@ -2823,8 +2837,8 @@ static Int run_CF_instruction ( /*MOD*/U + i += nleb; + if (reg < 0 || reg >= N_CFI_REGS) + return 0; /* fail */ +- ctx->reg[ctx->reg_sp][reg].tag = RR_CFAOff; +- ctx->reg[ctx->reg_sp][reg].arg = off * ctx->data_a_f; ++ ctxs->reg[reg].tag = RR_CFAOff; ++ ctxs->reg[reg].arg = off * ctx->data_a_f; + if (di->ddump_frames) + VG_(printf)(" rci:DW_CFA_offset_extended\n"); + break; +@@ -2836,13 +2850,13 @@ static Int run_CF_instruction ( /*MOD*/U + i += nleb; + if (reg < 0 || reg >= N_CFI_REGS) + return 0; /* fail */ +- ctx->reg[ctx->reg_sp][reg].tag = RR_CFAOff; +- ctx->reg[ctx->reg_sp][reg].arg = off * ctx->data_a_f; ++ ctxs->reg[reg].tag = RR_CFAOff; ++ ctxs->reg[reg].arg = off * ctx->data_a_f; + if (di->ddump_frames) + VG_(printf)(" DW_CFA_offset_extended_sf: r%d at cfa%s%d\n", + reg, +- ctx->reg[ctx->reg_sp][reg].arg < 0 ? "" : "+", +- (Int)ctx->reg[ctx->reg_sp][reg].arg); ++ ctxs->reg[reg].arg < 0 ? "" : "+", ++ (Int)ctxs->reg[reg].arg); + break; + + case DW_CFA_GNU_negative_offset_extended: +@@ -2852,8 +2866,8 @@ static Int run_CF_instruction ( /*MOD*/U + i += nleb; + if (reg < 0 || reg >= N_CFI_REGS) + return 0; /* fail */ +- ctx->reg[ctx->reg_sp][reg].tag = RR_CFAOff; +- ctx->reg[ctx->reg_sp][reg].arg = (-off) * ctx->data_a_f; ++ ctxs->reg[reg].tag = RR_CFAOff; ++ ctxs->reg[reg].arg = (-off) * ctx->data_a_f; + if (di->ddump_frames) + VG_(printf)(" rci:DW_CFA_GNU_negative_offset_extended\n"); + break; +@@ -2865,7 +2879,7 @@ static Int run_CF_instruction ( /*MOD*/U + return 0; /* fail */ + if (restore_ctx == NULL) + return 0; /* fail */ +- ctx->reg[ctx->reg_sp][reg] = restore_ctx->reg[ctx->reg_sp][reg]; ++ ctxs->reg[reg] = restore_ctx->state[restore_ctx->state_sp].reg[reg]; + if (di->ddump_frames) + VG_(printf)(" rci:DW_CFA_restore_extended\n"); + break; +@@ -2877,8 +2891,8 @@ static Int run_CF_instruction ( /*MOD*/U + i += nleb; + if (reg < 0 || reg >= N_CFI_REGS) + return 0; /* fail */ +- ctx->reg[ctx->reg_sp][reg].tag = RR_CFAValOff; +- ctx->reg[ctx->reg_sp][reg].arg = off * ctx->data_a_f; ++ ctxs->reg[reg].tag = RR_CFAValOff; ++ ctxs->reg[reg].arg = off * ctx->data_a_f; + if (di->ddump_frames) + VG_(printf)(" rci:DW_CFA_val_offset\n"); + break; +@@ -2890,8 +2904,8 @@ static Int run_CF_instruction ( /*MOD*/U + i += nleb; + if (reg < 0 || reg >= N_CFI_REGS) + return 0; /* fail */ +- ctx->reg[ctx->reg_sp][reg].tag = RR_CFAValOff; +- ctx->reg[ctx->reg_sp][reg].arg = off * ctx->data_a_f; ++ ctxs->reg[reg].tag = RR_CFAValOff; ++ ctxs->reg[reg].arg = off * ctx->data_a_f; + if (di->ddump_frames) + VG_(printf)(" rci:DW_CFA_val_offset_sf\n"); + break; +@@ -2901,9 +2915,9 @@ static Int run_CF_instruction ( /*MOD*/U + i += nleb; + if (reg < 0 || reg >= N_CFI_REGS) + return 0; /* fail */ +- ctx->cfa_is_regoff = True; +- ctx->cfa_expr_ix = 0; +- ctx->cfa_reg = reg; ++ ctxs->cfa_is_regoff = True; ++ ctxs->cfa_expr_ix = 0; ++ ctxs->cfa_reg = reg; + /* ->cfa_off unchanged */ + if (di->ddump_frames) + VG_(printf)(" DW_CFA_def_cfa_reg: r%d\n", (Int)reg ); +@@ -2912,10 +2926,10 @@ static Int run_CF_instruction ( /*MOD*/U + case DW_CFA_def_cfa_offset: + off = read_leb128( &instr[i], &nleb, 0); + i += nleb; +- ctx->cfa_is_regoff = True; +- ctx->cfa_expr_ix = 0; ++ ctxs->cfa_is_regoff = True; ++ ctxs->cfa_expr_ix = 0; + /* ->reg is unchanged */ +- ctx->cfa_off = off; ++ ctxs->cfa_off = off; + if (di->ddump_frames) + VG_(printf)(" DW_CFA_def_cfa_offset: %d\n", (Int)off); + break; +@@ -2923,12 +2937,12 @@ static Int run_CF_instruction ( /*MOD*/U + case DW_CFA_def_cfa_offset_sf: + off = read_leb128( &instr[i], &nleb, 1); + i += nleb; +- ctx->cfa_is_regoff = True; +- ctx->cfa_expr_ix = 0; ++ ctxs->cfa_is_regoff = True; ++ ctxs->cfa_expr_ix = 0; + /* ->reg is unchanged */ +- ctx->cfa_off = off * ctx->data_a_f; ++ ctxs->cfa_off = off * ctx->data_a_f; + if (di->ddump_frames) +- VG_(printf)(" DW_CFA_def_cfa_offset_sf: %d\n", ctx->cfa_off); ++ VG_(printf)(" DW_CFA_def_cfa_offset_sf: %d\n", ctxs->cfa_off); + break; + + case DW_CFA_undefined: +@@ -2936,8 +2950,8 @@ static Int run_CF_instruction ( /*MOD*/U + i += nleb; + if (reg < 0 || reg >= N_CFI_REGS) + return 0; /* fail */ +- ctx->reg[ctx->reg_sp][reg].tag = RR_Undef; +- ctx->reg[ctx->reg_sp][reg].arg = 0; ++ ctxs->reg[reg].tag = RR_Undef; ++ ctxs->reg[reg].arg = 0; + if (di->ddump_frames) + VG_(printf)(" rci:DW_CFA_undefined\n"); + break; +@@ -2981,8 +2995,8 @@ static Int run_CF_instruction ( /*MOD*/U + return 0; /* fail */ + /* Add an extra dereference */ + j = ML_(CfiExpr_Deref)( ctx->exprs, j ); +- ctx->reg[ctx->reg_sp][reg].tag = RR_ValExpr; +- ctx->reg[ctx->reg_sp][reg].arg = j; ++ ctxs->reg[reg].tag = RR_ValExpr; ++ ctxs->reg[reg].arg = j; + break; + + case DW_CFA_val_expression: +@@ -3010,8 +3024,8 @@ static Int run_CF_instruction ( /*MOD*/U + } + if (j == -1) + return 0; /* fail */ +- ctx->reg[ctx->reg_sp][reg].tag = RR_ValExpr; +- ctx->reg[ctx->reg_sp][reg].arg = j; ++ ctxs->reg[reg].tag = RR_ValExpr; ++ ctxs->reg[reg].arg = j; + break; + + case DW_CFA_def_cfa_expression: +@@ -3027,10 +3041,10 @@ static Int run_CF_instruction ( /*MOD*/U + di->ddump_frames); + if (di->ddump_frames) + VG_(printf)(")\n"); +- ctx->cfa_is_regoff = False; +- ctx->cfa_reg = 0; +- ctx->cfa_off = 0; +- ctx->cfa_expr_ix = j; ++ ctxs->cfa_is_regoff = False; ++ ctxs->cfa_reg = 0; ++ ctxs->cfa_off = 0; ++ ctxs->cfa_expr_ix = j; + break; + + case DW_CFA_GNU_window_save: +@@ -3044,17 +3058,17 @@ static Int run_CF_instruction ( /*MOD*/U + if (di->ddump_frames) + VG_(printf)(" DW_CFA_remember_state\n"); + /* we just checked this at entry, so: */ +- vg_assert(ctx->reg_sp >= 0 && ctx->reg_sp < N_RR_STACK); +- ctx->reg_sp++; +- if (ctx->reg_sp == N_RR_STACK) { ++ vg_assert(ctx->state_sp >= 0 && ctx->state_sp < N_RR_STACK); ++ ctx->state_sp++; ++ if (ctx->state_sp == N_RR_STACK) { + /* stack overflow. We're hosed. */ + VG_(message)(Vg_DebugMsg, "DWARF2 CFI reader: N_RR_STACK is " + "too low; increase and recompile."); + i = 0; /* indicate failure */ + } else { +- VG_(memcpy)(/*dst*/&ctx->reg[ctx->reg_sp], +- /*src*/&ctx->reg[ctx->reg_sp - 1], +- sizeof(ctx->reg[ctx->reg_sp]) ); ++ VG_(memcpy)(/*dst*/&ctx->state[ctx->state_sp], ++ /*src*/&ctx->state[ctx->state_sp - 1], ++ sizeof(ctx->state[ctx->state_sp]) ); + } + break; + +@@ -3062,13 +3076,13 @@ static Int run_CF_instruction ( /*MOD*/U + if (di->ddump_frames) + VG_(printf)(" DW_CFA_restore_state\n"); + /* we just checked this at entry, so: */ +- vg_assert(ctx->reg_sp >= 0 && ctx->reg_sp < N_RR_STACK); +- if (ctx->reg_sp == 0) { ++ vg_assert(ctx->state_sp >= 0 && ctx->state_sp < N_RR_STACK); ++ if (ctx->state_sp == 0) { + /* stack overflow. Give up. */ + i = 0; /* indicate failure */ + } else { + /* simply fall back to previous entry */ +- ctx->reg_sp--; ++ ctx->state_sp--; + } + break; + diff --git a/valgrind.spec b/valgrind.spec index 5fe74dc..aad3dfe 100644 --- a/valgrind.spec +++ b/valgrind.spec @@ -1,7 +1,7 @@ Summary: Tool for finding memory management bugs in programs Name: valgrind Version: 3.4.1 -Release: 4 +Release: 5 Epoch: 1 Source0: http://www.valgrind.org/downloads/valgrind-%{version}.tar.bz2 Patch1: valgrind-3.4.1-cachegrind-improvements.patch @@ -9,6 +9,8 @@ Patch2: valgrind-3.4.1-openat.patch Patch3: valgrind-3.4.1-x86_64-ldso-strlen.patch Patch4: valgrind-3.4.1-glibc-2.10.1.patch Patch5: valgrind-3.4.1-dwarf3.patch +Patch6: valgrind-3.4.1-dwarf-cfa-remember-state1.patch +Patch7: valgrind-3.4.1-dwarf-cfa-remember-state2.patch License: GPLv2 URL: http://www.valgrind.org/ Group: Development/Debuggers @@ -67,6 +69,8 @@ or valgrind plugins. %patch3 -p1 %patch4 -p1 %patch5 -p1 +%patch6 -p1 +%patch7 -p1 %build %ifarch x86_64 ppc64 @@ -157,6 +161,9 @@ rm -rf $RPM_BUILD_ROOT %{_libdir}/pkgconfig/* %changelog +* Mon Jul 13 2009 Jakub Jelinek 3.4.1-5 +- add support for DW_CFA_{remember,restore}_state + * Mon Jul 13 2009 Jakub Jelinek 3.4.1-4 - handle version 3 .debug_frame, .eh_frame, .debug_info and .debug_line (#509197)