From dd82b94e39c534481881288355652a7cd0211303 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Oct 14 2009 15:03:39 +0000 Subject: 3.5.0-3 --- diff --git a/valgrind-3.5.0-dwarf3.patch b/valgrind-3.5.0-dwarf3.patch new file mode 100644 index 0000000..7f3b8ed --- /dev/null +++ b/valgrind-3.5.0-dwarf3.patch @@ -0,0 +1,547 @@ +--- valgrind/coregrind/m_debuginfo/priv_d3basics.h.jj 2009-10-09 12:52:05.000000000 +0200 ++++ valgrind/coregrind/m_debuginfo/priv_d3basics.h 2009-10-13 14:55:12.000000000 +0200 +@@ -522,6 +522,9 @@ typedef enum + DW_OP_form_tls_address = 0x9b, + DW_OP_call_frame_cfa = 0x9c, + DW_OP_bit_piece = 0x9d, ++ /* DWARF 4 extensions. */ ++ DW_OP_implicit_value = 0x9e, ++ DW_OP_stack_value = 0x9f, + /* GNU extensions. */ + DW_OP_GNU_push_tls_address = 0xe0, + /* HP extensions. */ +@@ -596,12 +599,13 @@ typedef + + /* This describes the result of evaluating a DWARF3 expression. + GXR_Failure: failed; .word is an asciiz string summarising why ++ GXR_Addr: evaluated to an address of the object, in .word + GXR_Value: evaluated to a value, in .word + GXR_RegNo: evaluated to a DWARF3 register number, in .word + */ + typedef + struct { +- enum { GXR_Failure, GXR_Value, GXR_RegNo } kind; ++ enum { GXR_Failure, GXR_Addr, GXR_Value, GXR_RegNo } kind; + UWord word; + } + GXResult; +@@ -644,6 +648,10 @@ GXResult ML_(evaluate_Dwarf3_Expr) ( UCh + covered by the guard is also ignored. */ + GXResult ML_(evaluate_trivial_GX)( GExpr* gx, const DebugInfo* di ); + ++/* Compute CFA for IP/SP/FP. */ ++Addr ML_(get_CFA) (Addr ip, Addr sp, Addr fp, ++ Addr min_accessible, Addr max_accessible); ++ + #endif /* ndef __PRIV_D3BASICS_H */ + + /*--------------------------------------------------------------------*/ +--- valgrind/coregrind/m_debuginfo/d3basics.c.jj 2009-10-09 12:52:05.000000000 +0200 ++++ valgrind/coregrind/m_debuginfo/d3basics.c 2009-10-13 14:54:40.000000000 +0200 +@@ -443,7 +443,7 @@ static Bool bias_address( Addr* a, const + + + /* Evaluate a standard DWARF3 expression. See detailed description in +- priv_d3basics.h. */ ++ priv_d3basics.h. Doesn't handle DW_OP_piece/DW_OP_bit_piece yet. */ + GXResult ML_(evaluate_Dwarf3_Expr) ( UChar* expr, UWord exprszB, + GExpr* fbGX, RegSummary* regs, + const DebugInfo* di, +@@ -482,8 +482,8 @@ GXResult ML_(evaluate_Dwarf3_Expr) ( UCh + Addr stack[N_EXPR_STACK]; /* stack of addresses, as per D3 spec */ + GXResult fbval, res; + Addr a1; +- Word sw1; +- UWord uw1; ++ Word sw1, sw2; ++ UWord uw1, uw2; + Bool ok; + + sp = -1; +@@ -568,12 +568,15 @@ GXResult ML_(evaluate_Dwarf3_Expr) ( UCh + switch (fbval.kind) { + case GXR_Failure: + return fbval; /* propagate failure */ +- case GXR_Value: ++ case GXR_Addr: + a1 = fbval.word; break; /* use as-is */ + case GXR_RegNo: + ok = get_Dwarf_Reg( &a1, fbval.word, regs ); + if (!ok) return fbval; /* propagate failure */ + break; ++ case GXR_Value: ++ FAIL("evaluate_Dwarf3_Expr: DW_OP_{implicit,stack}_value " ++ "in DW_AT_frame_base"); + default: + vg_assert(0); + } +@@ -599,11 +602,23 @@ GXResult ML_(evaluate_Dwarf3_Expr) ( UCh + a1 += sw1; + PUSH( a1 ); + break; ++ case DW_OP_bregx: ++ if (!regs) ++ FAIL("evaluate_Dwarf3_Expr: DW_OP_breg* but no reg info"); ++ a1 = 0; ++ uw1 = (UWord)read_leb128U( &expr ); ++ if (!get_Dwarf_Reg( &a1, uw1, regs )) ++ FAIL("evaluate_Dwarf3_Expr: unhandled DW_OP_bregx reg value"); ++ sw1 = (Word)read_leb128S( &expr ); ++ a1 += sw1; ++ PUSH( a1 ); ++ break; + /* As per comment on DW_OP_breg*, the following denote that + the value in question is in a register, not in memory. So + we simply return failure. (iow, the expression is + malformed). */ + case DW_OP_reg0 ... DW_OP_reg31: ++ case DW_OP_regx: + FAIL("evaluate_Dwarf3_Expr: DW_OP_reg* " + "whilst evaluating for a value"); + break; +@@ -637,6 +652,297 @@ GXResult ML_(evaluate_Dwarf3_Expr) ( UCh + "address not valid for client"); + } + break; ++ case DW_OP_deref_size: ++ POP(uw1); ++ uw2 = *expr++; ++ if (VG_(am_is_valid_for_client)( (Addr)uw1, uw2, ++ VKI_PROT_READ )) { ++ switch (uw2) { ++ case 1: uw1 = *(UChar*)uw1; break; ++ case 2: uw1 = *(UShort*)uw1; break; ++ case 4: uw1 = *(UInt*)uw1; break; ++ case 8: uw1 = *(ULong*)uw1; break; ++ default: ++ FAIL("warning: evaluate_Dwarf3_Expr: unhandled " ++ "DW_OP_deref_size size"); ++ } ++ PUSH(uw1); ++ } else { ++ FAIL("warning: evaluate_Dwarf3_Expr: DW_OP_deref_size: " ++ "address not valid for client"); ++ } ++ break; ++ case DW_OP_lit0 ... DW_OP_lit31: ++ PUSH(opcode - DW_OP_lit0); ++ break; ++ case DW_OP_const1u: ++ uw1 = *expr++; ++ PUSH(uw1); ++ break; ++ case DW_OP_const2u: ++ uw1 = *(UShort *)expr; ++ expr += 2; ++ PUSH(uw1); ++ break; ++ case DW_OP_const4u: ++ uw1 = *(UInt *)expr; ++ expr += 4; ++ PUSH(uw1); ++ break; ++ case DW_OP_const8u: ++ uw1 = *(ULong *)expr; ++ expr += 8; ++ PUSH(uw1); ++ break; ++ case DW_OP_constu: ++ uw1 = read_leb128U( &expr ); ++ PUSH(uw1); ++ break; ++ case DW_OP_const1s: ++ uw1 = *(Char *) expr; ++ expr++; ++ PUSH(uw1); ++ break; ++ case DW_OP_const2s: ++ uw1 = *(Short *)expr; ++ expr += 2; ++ PUSH(uw1); ++ break; ++ case DW_OP_const4s: ++ uw1 = *(Int *)expr; ++ expr += 4; ++ PUSH(uw1); ++ break; ++ case DW_OP_const8s: ++ uw1 = *(Long *)expr; ++ expr += 8; ++ PUSH(uw1); ++ break; ++ case DW_OP_consts: ++ uw1 = read_leb128S( &expr ); ++ PUSH(uw1); ++ break; ++ case DW_OP_dup: ++ POP(uw1); ++ PUSH(uw1); ++ PUSH(uw1); ++ break; ++ case DW_OP_drop: ++ POP(uw1); ++ break; ++ case DW_OP_over: ++ uw1 = 1; ++ goto do_pick; ++ case DW_OP_pick: ++ uw1 = *expr++; ++ do_pick: ++ if (sp < (Int) uw1) ++ FAIL("evaluate_Dwarf3_Expr: stack underflow"); ++ uw1 = stack[sp - uw1]; ++ PUSH(uw1); ++ break; ++ case DW_OP_swap: ++ if (sp < 1) ++ FAIL("evaluate_Dwarf3_Expr: stack underflow"); ++ uw1 = stack[sp]; ++ stack[sp] = stack[sp - 1]; ++ stack[sp - 1] = uw1; ++ break; ++ case DW_OP_rot: ++ if (sp < 2) ++ FAIL("evaluate_Dwarf3_Expr: stack underflow"); ++ uw1 = stack[sp]; ++ stack[sp] = stack[sp - 1]; ++ stack[sp - 1] = stack[sp - 2]; ++ stack[sp - 2] = uw1; ++ break; ++ case DW_OP_abs: ++ POP(sw1); ++ if (sw1 < 0) ++ sw1 = -sw1; ++ PUSH(sw1); ++ break; ++ case DW_OP_and: ++ POP(uw2); ++ POP(uw1); ++ uw1 &= uw2; ++ PUSH(uw1); ++ break; ++ case DW_OP_div: ++ POP(sw2); ++ if (sw2 == 0) ++ FAIL("evaluate_Dwarf3_Expr: division by zero"); ++ POP(sw1); ++ sw1 /= sw2; ++ PUSH(sw1); ++ break; ++ case DW_OP_minus: ++ POP(uw2); ++ POP(uw1); ++ uw1 -= uw2; ++ PUSH(uw1); ++ break; ++ case DW_OP_mod: ++ POP(sw2); ++ if (sw2 == 0) ++ FAIL("evaluate_Dwarf3_Expr: division by zero"); ++ POP(sw1); ++ sw1 %= sw2; ++ PUSH(sw1); ++ break; ++ case DW_OP_mul: ++ POP(uw2); ++ POP(uw1); ++ uw1 *= uw2; ++ PUSH(uw1); ++ break; ++ case DW_OP_neg: ++ POP(uw1); ++ uw1 = -uw1; ++ PUSH(uw1); ++ break; ++ case DW_OP_not: ++ POP(uw1); ++ uw1 = ~uw1; ++ PUSH(uw1); ++ break; ++ case DW_OP_or: ++ POP(uw2); ++ POP(uw1); ++ uw1 |= uw2; ++ PUSH(uw1); ++ break; ++ case DW_OP_plus: ++ POP(uw2); ++ POP(uw1); ++ uw1 += uw2; ++ PUSH(uw1); ++ break; ++ case DW_OP_shl: ++ POP(uw2); ++ POP(uw1); ++ uw1 <<= uw2; ++ PUSH(uw1); ++ break; ++ case DW_OP_shr: ++ POP(uw2); ++ POP(uw1); ++ uw1 >>= uw2; ++ PUSH(uw1); ++ break; ++ case DW_OP_shra: ++ POP(uw2); ++ POP(sw1); ++ sw1 >>= uw2; ++ PUSH(sw1); ++ break; ++ case DW_OP_xor: ++ POP(uw2); ++ POP(uw1); ++ uw1 ^= uw2; ++ PUSH(uw1); ++ break; ++ case DW_OP_le: ++ POP(sw2); ++ POP(sw1); ++ sw1 = sw1 <= sw2; ++ PUSH(sw1); ++ break; ++ case DW_OP_lt: ++ POP(sw2); ++ POP(sw1); ++ sw1 = sw1 < sw2; ++ PUSH(sw1); ++ break; ++ case DW_OP_ge: ++ POP(sw2); ++ POP(sw1); ++ sw1 = sw1 >= sw2; ++ PUSH(sw1); ++ break; ++ case DW_OP_gt: ++ POP(sw2); ++ POP(sw1); ++ sw1 = sw1 > sw2; ++ PUSH(sw1); ++ break; ++ case DW_OP_ne: ++ POP(sw2); ++ POP(sw1); ++ sw1 = sw1 != sw2; ++ PUSH(sw1); ++ break; ++ case DW_OP_eq: ++ POP(sw2); ++ POP(sw1); ++ sw1 = sw1 == sw2; ++ PUSH(sw1); ++ break; ++ case DW_OP_skip: ++ sw1 = *(Short *)expr; ++ expr += 2; ++ if (sw1 < 0 && expr < limit - exprszB - sw1) ++ FAIL("evaluate_Dwarf3_Expr: DW_OP_skip before start of expr"); ++ expr += sw1; ++ break; ++ case DW_OP_bra: ++ sw1 = *(Short *)expr; ++ expr += 2; ++ if (sw1 < 0 && expr < limit - exprszB - sw1) ++ FAIL("evaluate_Dwarf3_Expr: DW_OP_bra before start of expr"); ++ POP(uw1); ++ if (uw1) ++ expr += sw1; ++ break; ++ case DW_OP_nop: ++ break; ++ case DW_OP_call_frame_cfa: ++ if (!regs) ++ FAIL("evaluate_Dwarf3_Expr: DW_OP_call_frame_cfa but no reg info"); ++ uw1 = ML_(get_CFA)(regs->ip, regs->sp, regs->fp, 0, ~(UWord) 0); ++ if (!uw1) ++ FAIL("evaluate_Dwarf3_Expr: Could not resolve " ++ "DW_OP_call_frame_cfa"); ++ PUSH(uw1); ++ break; ++ case DW_OP_implicit_value: ++ sw1 = (Word)read_leb128S( &expr ); ++ uw1 = 0; ++ switch (sw1) { ++ case 1: ++ uw1 = *(UChar *) expr; ++ expr += 1; ++ break; ++ case 2: ++ uw1 = *(UShort *) expr; ++ expr += 2; ++ break; ++ case 4: ++ uw1 = *(UInt *) expr; ++ expr += 4; ++ break; ++ case 8: ++ uw1 = *(ULong *) expr; ++ expr += 8; ++ break; ++ default: ++ FAIL("evaluate_Dwarf3_Expr: Unhandled " ++ "DW_OP_implicit_value size"); ++ } ++ if (expr != limit) ++ FAIL("evaluate_Dwarf3_Expr: DW_OP_implicit_value " ++ "does not terminate expression"); ++ res.word = uw1; ++ res.kind = GXR_Value; ++ return res; ++ case DW_OP_stack_value: ++ POP (uw1); ++ res.word = uw1; ++ res.kind = GXR_Value; ++ if (expr != limit) ++ FAIL("evaluate_Dwarf3_Expr: DW_OP_stack_value " ++ "does not terminate expression"); ++ break; + default: + if (!VG_(clo_xml)) + VG_(message)(Vg_DebugMsg, +@@ -650,7 +956,7 @@ GXResult ML_(evaluate_Dwarf3_Expr) ( UCh + + vg_assert(sp >= 0 && sp < N_EXPR_STACK); + res.word = stack[sp]; +- res.kind = GXR_Value; ++ res.kind = GXR_Addr; + return res; + + # undef POP +@@ -884,7 +1190,7 @@ GXResult ML_(evaluate_trivial_GX)( GExpr + + /* Well, we have success. All subexpressions evaluated, and + they all agree. Hurrah. */ +- res.kind = GXR_Value; ++ res.kind = GXR_Addr; + res.word = (UWord)mul->ul; /* NB: narrowing from ULong */ + VG_(deleteXA)( results ); + return res; +@@ -896,6 +1202,8 @@ void ML_(pp_GXResult) ( GXResult res ) + switch (res.kind) { + case GXR_Failure: + VG_(printf)("GXR_Failure(%s)", (HChar*)res.word); break; ++ case GXR_Addr: ++ VG_(printf)("GXR_Addr(0x%lx)", res.word); break; + case GXR_Value: + VG_(printf)("GXR_Value(0x%lx)", res.word); break; + case GXR_RegNo: +--- valgrind/coregrind/m_debuginfo/debuginfo.c.jj 2009-10-09 12:52:05.000000000 +0200 ++++ valgrind/coregrind/m_debuginfo/debuginfo.c 2009-10-13 14:55:45.000000000 +0200 +@@ -2003,6 +2003,62 @@ static void cfsi_cache__invalidate ( voi + } + + ++Addr ML_(get_CFA) (Addr ip, Addr sp, Addr fp, ++ Addr min_accessible, Addr max_accessible ) ++{ ++ Bool ok; ++ DebugInfo* di; ++ DiCfSI* cfsi = NULL; ++ Addr cfa; ++ CfiExprEvalContext eec; ++ UWord hash = ip % N_CFSI_CACHE; ++ CFSICacheEnt* ce = &cfsi_cache[hash]; ++ ++ if (LIKELY(ce->ip == ip) && LIKELY(ce->di != NULL)) { ++ /* found an entry in the cache .. */ ++ } else { ++ /* not found in cache. Search and update. */ ++ ce->ip = ip; ++ find_DiCfSI( &ce->di, &ce->ix, ip ); ++ } ++ ++ if (UNLIKELY(ce->di == (DebugInfo*)1)) { ++ /* no DiCfSI for this address */ ++ return 0; ++ } else { ++ /* found a DiCfSI for this address */ ++ di = ce->di; ++ cfsi = &di->cfsi[ ce->ix ]; ++ } ++ ++ if (UNLIKELY(cfsi == NULL)) ++ return 0; /* no info. Nothing we can do. */ ++ ++ /* Compute the CFA. */ ++ cfa = 0; ++ switch (cfsi->cfa_how) { ++ case CFIC_SPREL: ++ cfa = cfsi->cfa_off + sp; ++ break; ++ case CFIC_FPREL: ++ cfa = cfsi->cfa_off + fp; ++ break; ++ case CFIC_EXPR: ++ eec.ipHere = ip; ++ eec.spHere = sp; ++ eec.fpHere = fp; ++ eec.min_accessible = min_accessible; ++ eec.max_accessible = max_accessible; ++ ok = True; ++ cfa = evalCfiExpr(di->cfsi_exprs, cfsi->cfa_off, &eec, &ok ); ++ if (!ok) return 0; ++ break; ++ default: ++ vg_assert(0); ++ } ++ return cfa; ++} ++ + /* The main function for DWARF2/3 CFI-based stack unwinding. + Given an IP/SP/FP triple, produce the IP/SP/FP values for the + previous frame, if possible. */ +@@ -2346,7 +2402,7 @@ static Bool data_address_is_in_var ( /*O + VG_(printf)("\n"); + } + +- if (res.kind == GXR_Value ++ if (res.kind == GXR_Addr + && res.word <= data_addr + && data_addr < res.word + var_szB) { + *offset = data_addr - res.word; +@@ -3057,7 +3113,7 @@ void analyse_deps ( /*MOD*/XArray* /* of + vg_assert(res_sp_6k.kind == res_fp_6k.kind); + vg_assert(res_sp_6k.kind == res_fp_7k.kind); + +- if (res_sp_6k.kind == GXR_Value) { ++ if (res_sp_6k.kind == GXR_Addr) { + StackBlock block; + GXResult res; + UWord sp_delta = res_sp_7k.word - res_sp_6k.word; +@@ -3074,7 +3130,7 @@ void analyse_deps ( /*MOD*/XArray* /* of + regs.sp = regs.fp = 0; + regs.ip = ip; + res = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, di ); +- tl_assert(res.kind == GXR_Value); ++ tl_assert(res.kind == GXR_Addr); + if (debug) + VG_(printf)(" %5ld .. %5ld (sp) %s\n", + res.word, res.word + ((UWord)mul.ul) - 1, var->name); +@@ -3093,7 +3149,7 @@ void analyse_deps ( /*MOD*/XArray* /* of + regs.sp = regs.fp = 0; + regs.ip = ip; + res = ML_(evaluate_GX)( var->gexpr, var->fbGX, ®s, di ); +- tl_assert(res.kind == GXR_Value); ++ tl_assert(res.kind == GXR_Addr); + if (debug) + VG_(printf)(" %5ld .. %5ld (FP) %s\n", + res.word, res.word + ((UWord)mul.ul) - 1, var->name); +@@ -3308,7 +3364,7 @@ void* /* really, XArray* of GlobalBlock + res = ML_(evaluate_trivial_GX)( var->gexpr, di ); + + /* Not a constant address => not interesting */ +- if (res.kind != GXR_Value) { ++ if (res.kind != GXR_Addr) { + if (0) VG_(printf)("FAIL\n"); + continue; + } +--- valgrind/coregrind/m_debuginfo/tytypes.c.jj 2009-10-09 12:52:05.000000000 +0200 ++++ valgrind/coregrind/m_debuginfo/tytypes.c 2009-10-13 13:52:57.000000000 +0200 +@@ -766,7 +766,7 @@ XArray* /*UChar*/ ML_(describe_type)( /* + ML_(pp_GXResult)(res); + VG_(printf)("\n"); + } +- if (res.kind != GXR_Value) ++ if (res.kind != GXR_Addr) + continue; + mul = ML_(sizeOfType)( tyents, field->Te.Field.typeR ); + if (mul.b != True) diff --git a/valgrind-3.5.0-ifunc.patch b/valgrind-3.5.0-ifunc.patch index 434bbde..19d6083 100644 --- a/valgrind-3.5.0-ifunc.patch +++ b/valgrind-3.5.0-ifunc.patch @@ -1,4 +1,4 @@ -commit 27dc1029d4bca6409d0ed990264592dc75761cd0 +commit 3bd6e2ed7544778a5bbb0acaf69b103d7907185e Author: Dodji Seketeli Date: Wed Oct 7 16:09:30 2009 +0200 @@ -58,7 +58,10 @@ Date: Wed Oct 7 16:09:30 2009 +0200 means once we have intercepted the strlen call by the runtime linker to get the pointer to strlen_target. So we now store the strlen -> vg_strlen redirection request in the iFuncToDirectFuncSet set so that - we can get it later. + we can get it later. For a given ifunc symbol that is loaded, activate + the ifunc --> standard func redirection only if there is a + standard func --> standard func redirection matching the ifunc + symbol. * coregrind/m_scheduler/scheduler.c (do_client_request): Add a new VG_USERREQ__CHANGE_IFUNC_REDIR_TARGET. * coregrind/pub_core_clreq.h (enum Vg_InternalClientRequest): Add @@ -294,7 +297,7 @@ index 262fcfc..3ae050a 100644 if (sym[i] == '_') diff --git a/coregrind/m_redir.c b/coregrind/m_redir.c -index 98a502f..0140fc0 100644 +index 98a502f..cf968bd 100644 --- a/coregrind/m_redir.c +++ b/coregrind/m_redir.c @@ -223,6 +223,7 @@ typedef @@ -305,7 +308,15 @@ index 98a502f..0140fc0 100644 const HChar** mandatory; /* non-NULL ==> abort V and print the strings if from_sopatt is loaded but from_fnpatt cannot be found */ -@@ -268,12 +269,20 @@ typedef +@@ -252,7 +253,6 @@ typedef + to record abovementioned preloaded specifications.) */ + static TopSpec* topSpecs = NULL; + +- + /*------------------------------------------------------------*/ + /*--- CURRENTLY ACTIVE REDIRECTIONS ---*/ + /*------------------------------------------------------------*/ +@@ -268,12 +268,20 @@ typedef TopSpec* parent_spec; /* the TopSpec which supplied the Spec */ TopSpec* parent_sym; /* the TopSpec which supplied the symbol */ Bool isWrap; /* wrap or replacement? */ @@ -327,7 +338,7 @@ index 98a502f..0140fc0 100644 /*------------------------------------------------------------*/ /*--- FWDses ---*/ -@@ -317,7 +326,7 @@ void generate_and_add_actives ( +@@ -317,7 +325,7 @@ void generate_and_add_actives ( void VG_(redir_notify_new_DebugInfo)( DebugInfo* newsi ) { @@ -336,7 +347,7 @@ index 98a502f..0140fc0 100644 Int i, nsyms; Spec* specList; Spec* spec; -@@ -350,10 +359,16 @@ void VG_(redir_notify_new_DebugInfo)( DebugInfo* newsi ) +@@ -350,10 +358,16 @@ void VG_(redir_notify_new_DebugInfo)( DebugInfo* newsi ) nsyms = VG_(DebugInfo_syms_howmany)( newsi ); for (i = 0; i < nsyms; i++) { @@ -357,7 +368,7 @@ index 98a502f..0140fc0 100644 /* ignore data symbols */ if (!isText) continue; -@@ -378,6 +393,7 @@ void VG_(redir_notify_new_DebugInfo)( DebugInfo* newsi ) +@@ -378,6 +392,7 @@ void VG_(redir_notify_new_DebugInfo)( DebugInfo* newsi ) vg_assert(spec->from_fnpatt); spec->to_addr = sym_addr; spec->isWrap = isWrap; @@ -365,7 +376,7 @@ index 98a502f..0140fc0 100644 /* check we're not adding manifestly stupid destinations */ vg_assert(is_plausible_guest_addr(sym_addr)); spec->next = specList; -@@ -388,12 +404,15 @@ void VG_(redir_notify_new_DebugInfo)( DebugInfo* newsi ) +@@ -388,12 +403,15 @@ void VG_(redir_notify_new_DebugInfo)( DebugInfo* newsi ) if (check_ppcTOCs) { for (i = 0; i < nsyms; i++) { @@ -384,7 +395,7 @@ index 98a502f..0140fc0 100644 if (!ok) /* not a redirect. Ignore. */ continue; -@@ -470,6 +489,38 @@ void VG_(redir_notify_new_DebugInfo)( DebugInfo* newsi ) +@@ -470,6 +488,42 @@ void VG_(redir_notify_new_DebugInfo)( DebugInfo* newsi ) #undef N_DEMANGLED @@ -404,26 +415,30 @@ index 98a502f..0140fc0 100644 + old = VG_(OSetGen_Lookup)(activeSet, &old_from); + vg_assert(old); + vg_assert(old->isIFunc); ++ /* We must have got here only if there was an ifunc symbol ++ that matches an active direct function --> direct function ++ redirection. Otherwise, it is not necessary to call this function. */ ++ vg_assert(iFuncToDirectFuncSet); + + e = VG_(OSetGen_Lookup)(iFuncToDirectFuncSet, &old_from); ++ /* Same comment as for vg_assert(iFuncToDirectFuncSet) above. */ ++ vg_assert(e); + + new = *old; -+ if (e) { -+ new.from_addr = new_from; -+ new.to_addr = e->direct_func; -+ if (VG_(clo_trace_redir)) -+ VG_(message) (Vg_DebugMsg, "changed redir (%lx)[indired]->(%lx) " -+ "to (%lx) -> (%lx))\n", -+ old_from, old->to_addr, -+ new_from, e->direct_func); -+ new.isIFunc = False; -+ maybe_add_active (new); -+ } ++ new.from_addr = new_from; ++ new.to_addr = e->direct_func; ++ if (VG_(clo_trace_redir)) ++ VG_(message) (Vg_DebugMsg, "changed redir (%lx)[indired]->(%lx) " ++ "to (%lx) -> (%lx))\n", ++ old_from, old->to_addr, ++ new_from, e->direct_func); ++ new.isIFunc = False; ++ maybe_add_active (new); +} /* Do one element of the basic cross product: add to the active set, all matches resulting from comparing all the given specs against -@@ -487,7 +538,7 @@ void generate_and_add_actives ( +@@ -487,7 +541,7 @@ void generate_and_add_actives ( ) { Spec* sp; @@ -432,7 +447,7 @@ index 98a502f..0140fc0 100644 Active act; Int nsyms, i; Addr sym_addr; -@@ -513,7 +564,7 @@ void generate_and_add_actives ( +@@ -513,7 +567,7 @@ void generate_and_add_actives ( nsyms = VG_(DebugInfo_syms_howmany)( di ); for (i = 0; i < nsyms; i++) { VG_(DebugInfo_syms_getidx)( di, i, &sym_addr, NULL, NULL, @@ -441,7 +456,7 @@ index 98a502f..0140fc0 100644 /* ignore data symbols */ if (!isText) -@@ -533,13 +584,47 @@ void generate_and_add_actives ( +@@ -533,13 +587,61 @@ void generate_and_add_actives ( if (!sp->mark) continue; /* soname doesn't match */ if (VG_(string_match)( sp->from_fnpatt, sym_name )) { @@ -450,8 +465,9 @@ index 98a502f..0140fc0 100644 + sp->done = True; + if (isIFunc && !sp->isIFunc) { + IFuncToDirectFuncEntry *e; -+ /* So we are facing a redirection spec -+ indirect function -> direct function. ++ /* So we are facing an indirect function ++ that matches a direct function -> direct function ++ redirection spec. + We need to store that mapping in iFuncToDirectFuncSet so + that later once the indirect function's relocations are + processed by the dynamic linker on the client, we @@ -478,6 +494,19 @@ index 98a502f..0140fc0 100644 + VG_(OSetGen_Insert)(iFuncToDirectFuncSet, e); + continue; + } ++ ++ /* Consider special ifunc --> direct function redirections only when ++ there already is an direct function --> direct function ++ redirection that matches an ifunc symbol. Otherwise, we would ++ grow the active set unnecessarily. */ ++ if (isIFunc && sp->isIFunc) { ++ IFuncToDirectFuncEntry *e = NULL; ++ if (iFuncToDirectFuncSet) ++ e = VG_(OSetGen_Lookup)(iFuncToDirectFuncSet, &sym_addr); ++ if (!e) ++ continue; ++ } ++ /* got a new binding. Add to collection. */ act.from_addr = sym_addr; act.to_addr = sp->to_addr; @@ -559,7 +588,7 @@ index c993c27..025789d 100644 // Queries //-------------------------------------------------------------------- diff --git a/coregrind/vg_preloaded.c b/coregrind/vg_preloaded.c -index 6f0f049..28e6c7d 100644 +index 6f0f049..41986d2 100644 --- a/coregrind/vg_preloaded.c +++ b/coregrind/vg_preloaded.c @@ -68,6 +68,33 @@ void VG_NOTIFY_ON_LOAD(freeres)( void ) @@ -573,8 +602,8 @@ index 6f0f049..28e6c7d 100644 + (running on the real CPU) to update the redirection "ifunc -> this function". + +*/ -+void * VG_WRAP_I_FUNCTION_ZZ(VG_Z_LIBC_SONAME, Za) (void); -+void * VG_WRAP_I_FUNCTION_ZZ(VG_Z_LIBC_SONAME, Za) (void) ++void * VG_WRAP_I_FUNCTION_ZZ(Za, Za) (void); ++void * VG_WRAP_I_FUNCTION_ZZ(Za, Za) (void) +{ + OrigFn fn; + Addr result = 0; @@ -611,7 +640,7 @@ index a02b790..85129ce 100644 /* A simple enumeration to describe the 'kind' of various kinds of segments that arise from the mapping of object files. */ diff --git a/include/pub_tool_redir.h b/include/pub_tool_redir.h -index 3d3b516..ff6af2e 100644 +index 3d3b516..ec3e00a 100644 --- a/include/pub_tool_redir.h +++ b/include/pub_tool_redir.h @@ -51,6 +51,16 @@ @@ -641,25 +670,29 @@ index 3d3b516..ff6af2e 100644 characters are transformed. * --> Za (asterisk) -@@ -143,6 +154,17 @@ +@@ -143,6 +154,21 @@ Z --> ZZ (Z) Everything else is left unchanged. + + Indirect function wrapping -+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ++ ~~~~~~~~~~~~~~~~~~~~~~~~~~ + + VG_WRAP_I_FUNCTION_ZZ is a macro (similar to VG_WRAP_FUNCTION_ZZ) that -+ wraps functions only. It does not have any effect on regular (STT_FUNC) functions. -+ Beware, the use of VG_WRAP_I_FUNCTION_ZZ in coregrin/vg_preloaded.c makes -+ the wrapping function match all the indirect functions of the C library. -+ So no other use of that macro should be necessary to match -+ indirect functions of the C library. ++ wraps indirect functions (a.k.a. ifunc) only. It does not have any effect on ++ regular (STT_FUNC) functions. In other words this macros registers an ++ ifunc --> regular function redirection. It does it in a special way though. ++ The ifunc --> regular function redirection is registered iff there is a ++ regular function --> regular function redirection that matches the ifunc symbol ++ pattern of this macro. ++ Beware, the use of VG_WRAP_I_FUNCTION_ZZ in coregrind/vg_preloaded.c makes ++ the wrapping function match all the indirect functions of all libraries. ++ So no other use of that macro should be necessary. + */ /* If you change these, the code in VG_(maybe_Z_demangle) needs to be -@@ -158,6 +180,7 @@ +@@ -158,6 +184,7 @@ #define VG_WRAP_FUNCTION_ZU(soname,fnname) VG_CONCAT4(_vgwZU_,soname,_,fnname) #define VG_WRAP_FUNCTION_ZZ(soname,fnname) VG_CONCAT4(_vgwZZ_,soname,_,fnname) @@ -668,7 +701,7 @@ index 3d3b516..ff6af2e 100644 /* --------- Some handy Z-encoded names. --------- */ diff --git a/memcheck/mc_replace_strmem.c b/memcheck/mc_replace_strmem.c -index c15717a..2bfe40b 100644 +index c15717a..abd838f 100644 --- a/memcheck/mc_replace_strmem.c +++ b/memcheck/mc_replace_strmem.c @@ -116,6 +116,7 @@ Bool is_overlap ( void* dst, const void* src, SizeT dstlen, SizeT srclen ) @@ -765,3 +798,14 @@ index c15717a..2bfe40b 100644 STPCPY(VG_Z_LD_LINUX_SO_2, stpcpy) STPCPY(VG_Z_LD_LINUX_X86_64_SO_2, stpcpy) #elif defined(VGO_darwin) +@@ -709,7 +725,9 @@ GLIBC232_STRCHRNUL(VG_Z_LIBC_SONAME, strchrnul) + } + + GLIBC232_RAWMEMCHR(VG_Z_LIBC_SONAME, rawmemchr) +- ++#if defined (VGO_linux) ++GLIBC232_RAWMEMCHR(VG_Z_LIBC_SONAME, __GI___rawmemchr) ++#endif + + /* glibc variant of strcpy that checks the dest is big enough. + Copied from glibc-2.5/debug/test-strcpy_chk.c. */ diff --git a/valgrind-3.5.0-pr40659.patch b/valgrind-3.5.0-pr40659.patch new file mode 100644 index 0000000..e5fc3bd --- /dev/null +++ b/valgrind-3.5.0-pr40659.patch @@ -0,0 +1,163 @@ +--- valgrind/coregrind/m_debuginfo/tytypes.c.jj 2009-10-14 15:00:07.000000000 +0200 ++++ valgrind/coregrind/m_debuginfo/tytypes.c 2009-10-14 16:28:39.000000000 +0200 +@@ -98,10 +98,15 @@ void ML_(pp_TyEnt)( TyEnt* te ) + te->Te.Atom.value, te->Te.Atom.name); + break; + case Te_Field: +- VG_(printf)("Te_Field(ty=0x%05lx,nLoc=%lu,loc=%p,\"%s\")", +- te->Te.Field.typeR, te->Te.Field.nLoc, +- te->Te.Field.loc, +- te->Te.Field.name ? te->Te.Field.name : (UChar*)""); ++ if (te->Te.Field.nLoc == -1) ++ VG_(printf)("Te_Field(ty=0x%05lx,pos.offset=%ld,\"%s\")", ++ te->Te.Field.typeR, te->Te.Field.pos.offset, ++ te->Te.Field.name ? te->Te.Field.name : (UChar*)""); ++ else ++ VG_(printf)("Te_Field(ty=0x%05lx,nLoc=%lu,pos.loc=%p,\"%s\")", ++ te->Te.Field.typeR, te->Te.Field.nLoc, ++ te->Te.Field.pos.loc, ++ te->Te.Field.name ? te->Te.Field.name : (UChar*)""); + break; + case Te_Bound: + VG_(printf)("Te_Bound["); +@@ -476,7 +481,9 @@ Word ML_(TyEnt__cmp_by_all_except_cuOff) + if (r != 0) return r; + r = UWord__cmp(te1->Te.Field.nLoc, te2->Te.Field.nLoc); + if (r != 0) return r; +- r = Bytevector__cmp(te1->Te.Field.loc, te2->Te.Field.loc, ++ if (te1->Te.Field.nLoc == -1) ++ return Long__cmp(te1->Te.Field.pos.offset, te2->Te.Field.pos.offset); ++ r = Bytevector__cmp(te1->Te.Field.pos.loc, te2->Te.Field.pos.loc, + te1->Te.Field.nLoc); + return r; + case Te_Bound: +@@ -568,7 +575,8 @@ void ML_(TyEnt__make_EMPTY) ( TyEnt* te + break; + case Te_Field: + if (te->Te.Field.name) ML_(dinfo_free)(te->Te.Field.name); +- if (te->Te.Field.loc) ML_(dinfo_free)(te->Te.Field.loc); ++ if (te->Te.Field.nLoc > 0 && te->Te.Field.pos.loc) ++ ML_(dinfo_free)(te->Te.Field.pos.loc); + break; + case Te_Bound: + break; +@@ -747,24 +755,30 @@ XArray* /*UChar*/ ML_(describe_type)( /* + field = ML_(TyEnts__index_by_cuOff)(tyents, NULL, fieldR); + vg_assert(field); + vg_assert(field->tag == Te_Field); +- vg_assert(field->Te.Field.loc); +- vg_assert(field->Te.Field.nLoc > 0); +- /* Re data_bias in this call, we should really send in +- a legitimate value. But the expression is expected +- to be a constant expression, evaluation of which +- will not need to use DW_OP_addr and hence we can +- avoid the trouble of plumbing the data bias through +- to this point (if, indeed, it has any meaning; from +- which DebugInfo would we take the data bias? */ +- res = ML_(evaluate_Dwarf3_Expr)( +- field->Te.Field.loc, field->Te.Field.nLoc, +- NULL/*fbGX*/, NULL/*RegSummary*/, +- 0/*data_bias*/, +- True/*push_initial_zero*/); +- if (0) { +- VG_(printf)("QQQ "); +- ML_(pp_GXResult)(res); +- VG_(printf)("\n"); ++ vg_assert(field->Te.Field.nLoc < 0 ++ || (field->Te.Field.nLoc > 0 ++ && field->Te.Field.pos.loc)); ++ if (field->Te.Field.nLoc == -1) { ++ res.kind = GXR_Addr; ++ res.word = field->Te.Field.pos.offset; ++ } else { ++ /* Re data_bias in this call, we should really send in ++ a legitimate value. But the expression is expected ++ to be a constant expression, evaluation of which ++ will not need to use DW_OP_addr and hence we can ++ avoid the trouble of plumbing the data bias through ++ to this point (if, indeed, it has any meaning; from ++ which DebugInfo would we take the data bias? */ ++ res = ML_(evaluate_Dwarf3_Expr)( ++ field->Te.Field.pos.loc, field->Te.Field.nLoc, ++ NULL/*fbGX*/, NULL/*RegSummary*/, ++ 0/*data_bias*/, ++ True/*push_initial_zero*/); ++ if (0) { ++ VG_(printf)("QQQ "); ++ ML_(pp_GXResult)(res); ++ VG_(printf)("\n"); ++ } + } + if (res.kind != GXR_Addr) + continue; +--- valgrind/coregrind/m_debuginfo/priv_tytypes.h.jj 2009-08-19 15:37:44.000000000 +0200 ++++ valgrind/coregrind/m_debuginfo/priv_tytypes.h 2009-10-14 15:49:52.000000000 +0200 +@@ -78,8 +78,13 @@ typedef + struct { + UChar* name; /* in mallocville */ + UWord typeR; /* should be Te_TyXXXX */ +- UChar* loc; /* location expr, in mallocville */ +- UWord nLoc; /* number of bytes in .loc */ ++ union { ++ UChar* loc; /* location expr, in mallocville */ ++ Word offset; /* or offset from the beginning of containing ++ entity */ ++ } pos; ++ Word nLoc; /* number of bytes in .pos.loc if >= 0, or -1 ++ if .pos.offset should be used instead */ + Bool isStruct; + } Field; + struct { +--- valgrind/coregrind/m_debuginfo/readdwarf3.c.jj 2009-08-19 15:37:44.000000000 +0200 ++++ valgrind/coregrind/m_debuginfo/readdwarf3.c 2009-10-14 16:25:51.000000000 +0200 +@@ -2356,9 +2356,16 @@ static void parse_type_DIE ( /*MOD*/XArr + if (attr == DW_AT_type && ctsSzB > 0) { + fieldE.Te.Field.typeR = (UWord)cts; + } +- if (attr == DW_AT_data_member_location && ctsMemSzB > 0) { ++ /* There are 2 different cases for DW_AT_data_member_location. ++ If it is a constant class attribute, it contains byte offset ++ from the beginning of the containing entity. ++ Otherwise it is a location expression. */ ++ if (attr == DW_AT_data_member_location && ctsSzB > 0) { ++ fieldE.Te.Field.nLoc = -1; ++ fieldE.Te.Field.pos.offset = cts; ++ } else if (attr == DW_AT_data_member_location && ctsMemSzB > 0) { + fieldE.Te.Field.nLoc = (UWord)ctsMemSzB; +- fieldE.Te.Field.loc ++ fieldE.Te.Field.pos.loc + = ML_(dinfo_memdup)( "di.readdwarf3.ptD.member.2", + (UChar*)(UWord)cts, + (SizeT)fieldE.Te.Field.nLoc ); +@@ -2385,13 +2392,14 @@ static void parse_type_DIE ( /*MOD*/XArr + vg_assert(fieldE.Te.Field.name); + if (fieldE.Te.Field.typeR == D3_INVALID_CUOFF) + goto bad_DIE; +- if (fieldE.Te.Field.loc) { ++ if (fieldE.Te.Field.nLoc) { + if (!parent_is_struct) { + /* If this is a union type, pretend we haven't seen the data + member location expression, as it is by definition + redundant (it must be zero). */ +- ML_(dinfo_free)(fieldE.Te.Field.loc); +- fieldE.Te.Field.loc = NULL; ++ if (fieldE.Te.Field.nLoc > 0) ++ ML_(dinfo_free)(fieldE.Te.Field.pos.loc); ++ fieldE.Te.Field.pos.loc = NULL; + fieldE.Te.Field.nLoc = 0; + } + /* Record this child in the parent */ +@@ -2616,10 +2624,10 @@ static void parse_type_DIE ( /*MOD*/XArr + /* For union members, Expr should be absent */ + if (0) VG_(printf)("YYYY Acquire Field\n"); + vg_assert(fieldE.tag == Te_Field); +- vg_assert( (fieldE.Te.Field.nLoc > 0 && fieldE.Te.Field.loc != NULL) +- || (fieldE.Te.Field.nLoc == 0 && fieldE.Te.Field.loc == NULL) ); ++ vg_assert(fieldE.Te.Field.nLoc <= 0 || fieldE.Te.Field.pos.loc != NULL); ++ vg_assert(fieldE.Te.Field.nLoc != 0 || fieldE.Te.Field.pos.loc == NULL); + if (fieldE.Te.Field.isStruct) { +- vg_assert(fieldE.Te.Field.nLoc > 0); ++ vg_assert(fieldE.Te.Field.nLoc != 0); + } else { + vg_assert(fieldE.Te.Field.nLoc == 0); + } diff --git a/valgrind.spec b/valgrind.spec index 578004c..74fdb65 100644 --- a/valgrind.spec +++ b/valgrind.spec @@ -1,7 +1,7 @@ Summary: Tool for finding memory management bugs in programs Name: valgrind Version: 3.5.0 -Release: 2 +Release: 3 Epoch: 1 Source0: http://www.valgrind.org/downloads/valgrind-%{version}.tar.bz2 Patch1: valgrind-3.5.0-cachegrind-improvements.patch @@ -10,6 +10,8 @@ Patch3: valgrind-3.5.0-glibc-2.10.1.patch Patch4: valgrind-3.5.0-ifunc.patch Patch5: valgrind-3.5.0-inotify-init1.patch Patch6: valgrind-3.5.0-mmap-mprotect.patch +Patch7: valgrind-3.5.0-dwarf3.patch +Patch8: valgrind-3.5.0-pr40659.patch License: GPLv2 URL: http://www.valgrind.org/ Group: Development/Debuggers @@ -69,6 +71,8 @@ or valgrind plugins. %patch4 -p1 %patch5 -p1 %patch6 -p1 +%patch7 -p1 +%patch8 -p1 %build %ifarch x86_64 ppc64 @@ -101,13 +105,6 @@ int main (int argc, char *const argv[]) EOF gcc $RPM_OPT_FLAGS -o close_fds close_fds.c -for i in `find . -type f \( -name *-amd64-linux -o -name *-x86-linux -o -name *-ppc*-linux \)`; do - case "`file $i`" in - *ELF*executable*statically\ linked*) - objcopy -R .debug_loc -R .debug_frame -R .debug_ranges $i - esac -done - # XXX pth_cancel2 hangs on x86_64 echo 'int main (void) { return 0; }' > none/tests/pth_cancel2.c @@ -161,6 +158,11 @@ rm -rf $RPM_BUILD_ROOT %{_libdir}/pkgconfig/* %changelog +* Wed Oct 14 2009 Jakub Jelinek 3.5.0-3 +- handle many more DW_OP_* ops that GCC now uses +- handle the more compact form of DW_AT_data_member_location +- don't strip .debug_loc etc. from valgrind binaries + * Mon Oct 12 2009 Jakub Jelinek 3.5.0-2 - add STT_GNU_IFUNC support (Dodji Seketeli, #518247) - wrap inotify_init1 syscall (Dodji Seketeli, #527198)