rpms/valgrind/F-12 valgrind-3.5.0-dwarf3.patch, NONE, 1.1 valgrind-3.5.0-pr40659.patch, NONE, 1.1 valgrind-3.5.0-ifunc.patch, 1.1, 1.2 valgrind.spec, 1.68, 1.69
Jakub Jelinek
jakub at fedoraproject.org
Wed Oct 14 15:03:39 UTC 2009
- Previous message (by thread): rpms/mutrace/F-12 import.log, NONE, 1.1 mutrace.spec, NONE, 1.1 .cvsignore, 1.1, 1.2 sources, 1.1, 1.2
- Next message (by thread): rpms/libguestfs/EL-5 libguestfs.spec,1.70,1.71
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Author: jakub
Update of /cvs/pkgs/rpms/valgrind/F-12
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv30638
Modified Files:
valgrind-3.5.0-ifunc.patch valgrind.spec
Added Files:
valgrind-3.5.0-dwarf3.patch valgrind-3.5.0-pr40659.patch
Log Message:
3.5.0-3
valgrind-3.5.0-dwarf3.patch:
d3basics.c | 320 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--
debuginfo.c | 66 ++++++++++-
priv_d3basics.h | 10 +
tytypes.c | 2
4 files changed, 385 insertions(+), 13 deletions(-)
--- NEW FILE valgrind-3.5.0-dwarf3.patch ---
--- 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)
valgrind-3.5.0-pr40659.patch:
priv_tytypes.h | 9 ++++++--
readdwarf3.c | 24 ++++++++++++++--------
tytypes.c | 62 ++++++++++++++++++++++++++++++++++-----------------------
3 files changed, 61 insertions(+), 34 deletions(-)
--- NEW FILE valgrind-3.5.0-pr40659.patch ---
--- 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);
}
valgrind-3.5.0-ifunc.patch:
coregrind/m_debuginfo/debuginfo.c | 14 ++-
coregrind/m_debuginfo/priv_storage.h | 1
coregrind/m_debuginfo/readelf.c | 22 ++++--
coregrind/m_demangle/demangle.c | 52 ++++++++++----
coregrind/m_redir.c | 128 +++++++++++++++++++++++++++++++----
coregrind/m_scheduler/scheduler.c | 6 +
coregrind/pub_core_clreq.h | 5 +
coregrind/pub_core_demangle.h | 3
coregrind/pub_core_redir.h | 3
coregrind/vg_preloaded.c | 27 +++++++
include/pub_tool_debuginfo.h | 3
include/pub_tool_redir.h | 29 +++++++
memcheck/mc_replace_strmem.c | 28 ++++++-
13 files changed, 276 insertions(+), 45 deletions(-)
Index: valgrind-3.5.0-ifunc.patch
===================================================================
RCS file: /cvs/pkgs/rpms/valgrind/F-12/valgrind-3.5.0-ifunc.patch,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -p -r1.1 -r1.2
--- valgrind-3.5.0-ifunc.patch 12 Oct 2009 15:18:45 -0000 1.1
+++ valgrind-3.5.0-ifunc.patch 14 Oct 2009 15:03:39 -0000 1.2
@@ -1,4 +1,4 @@
-commit 27dc1029d4bca6409d0ed990264592dc75761cd0
+commit 3bd6e2ed7544778a5bbb0acaf69b103d7907185e
Author: Dodji Seketeli <dodji at redhat.com>
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. */
Index: valgrind.spec
===================================================================
RCS file: /cvs/pkgs/rpms/valgrind/F-12/valgrind.spec,v
retrieving revision 1.68
retrieving revision 1.69
diff -u -p -r1.68 -r1.69
--- valgrind.spec 12 Oct 2009 15:18:45 -0000 1.68
+++ valgrind.spec 14 Oct 2009 15:03:39 -0000 1.69
@@ -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.patc
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 <jakub at redhat.com> 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 <jakub at redhat.com> 3.5.0-2
- add STT_GNU_IFUNC support (Dodji Seketeli, #518247)
- wrap inotify_init1 syscall (Dodji Seketeli, #527198)
- Previous message (by thread): rpms/mutrace/F-12 import.log, NONE, 1.1 mutrace.spec, NONE, 1.1 .cvsignore, 1.1, 1.2 sources, 1.1, 1.2
- Next message (by thread): rpms/libguestfs/EL-5 libguestfs.spec,1.70,1.71
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the fedora-extras-commits
mailing list