You can subscribe to this list here.
| 2002 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(1) |
Oct
(122) |
Nov
(152) |
Dec
(69) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2003 |
Jan
(6) |
Feb
(25) |
Mar
(73) |
Apr
(82) |
May
(24) |
Jun
(25) |
Jul
(10) |
Aug
(11) |
Sep
(10) |
Oct
(54) |
Nov
(203) |
Dec
(182) |
| 2004 |
Jan
(307) |
Feb
(305) |
Mar
(430) |
Apr
(312) |
May
(187) |
Jun
(342) |
Jul
(487) |
Aug
(637) |
Sep
(336) |
Oct
(373) |
Nov
(441) |
Dec
(210) |
| 2005 |
Jan
(385) |
Feb
(480) |
Mar
(636) |
Apr
(544) |
May
(679) |
Jun
(625) |
Jul
(810) |
Aug
(838) |
Sep
(634) |
Oct
(521) |
Nov
(965) |
Dec
(543) |
| 2006 |
Jan
(494) |
Feb
(431) |
Mar
(546) |
Apr
(411) |
May
(406) |
Jun
(322) |
Jul
(256) |
Aug
(401) |
Sep
(345) |
Oct
(542) |
Nov
(308) |
Dec
(481) |
| 2007 |
Jan
(427) |
Feb
(326) |
Mar
(367) |
Apr
(255) |
May
(244) |
Jun
(204) |
Jul
(223) |
Aug
(231) |
Sep
(354) |
Oct
(374) |
Nov
(497) |
Dec
(362) |
| 2008 |
Jan
(322) |
Feb
(482) |
Mar
(658) |
Apr
(422) |
May
(476) |
Jun
(396) |
Jul
(455) |
Aug
(267) |
Sep
(280) |
Oct
(253) |
Nov
(232) |
Dec
(304) |
| 2009 |
Jan
(486) |
Feb
(470) |
Mar
(458) |
Apr
(423) |
May
(696) |
Jun
(461) |
Jul
(551) |
Aug
(575) |
Sep
(134) |
Oct
(110) |
Nov
(157) |
Dec
(102) |
| 2010 |
Jan
(226) |
Feb
(86) |
Mar
(147) |
Apr
(117) |
May
(107) |
Jun
(203) |
Jul
(193) |
Aug
(238) |
Sep
(300) |
Oct
(246) |
Nov
(23) |
Dec
(75) |
| 2011 |
Jan
(133) |
Feb
(195) |
Mar
(315) |
Apr
(200) |
May
(267) |
Jun
(293) |
Jul
(353) |
Aug
(237) |
Sep
(278) |
Oct
(611) |
Nov
(274) |
Dec
(260) |
| 2012 |
Jan
(303) |
Feb
(391) |
Mar
(417) |
Apr
(441) |
May
(488) |
Jun
(655) |
Jul
(590) |
Aug
(610) |
Sep
(526) |
Oct
(478) |
Nov
(359) |
Dec
(372) |
| 2013 |
Jan
(467) |
Feb
(226) |
Mar
(391) |
Apr
(281) |
May
(299) |
Jun
(252) |
Jul
(311) |
Aug
(352) |
Sep
(481) |
Oct
(571) |
Nov
(222) |
Dec
(231) |
| 2014 |
Jan
(185) |
Feb
(329) |
Mar
(245) |
Apr
(238) |
May
(281) |
Jun
(399) |
Jul
(382) |
Aug
(500) |
Sep
(579) |
Oct
(435) |
Nov
(487) |
Dec
(256) |
| 2015 |
Jan
(338) |
Feb
(357) |
Mar
(330) |
Apr
(294) |
May
(191) |
Jun
(108) |
Jul
(142) |
Aug
(261) |
Sep
(190) |
Oct
(54) |
Nov
(83) |
Dec
(22) |
| 2016 |
Jan
(49) |
Feb
(89) |
Mar
(33) |
Apr
(50) |
May
(27) |
Jun
(34) |
Jul
(53) |
Aug
(53) |
Sep
(98) |
Oct
(206) |
Nov
(93) |
Dec
(53) |
| 2017 |
Jan
(65) |
Feb
(82) |
Mar
(102) |
Apr
(86) |
May
(187) |
Jun
(67) |
Jul
(23) |
Aug
(93) |
Sep
(65) |
Oct
(45) |
Nov
(35) |
Dec
(17) |
| 2018 |
Jan
(26) |
Feb
(35) |
Mar
(38) |
Apr
(32) |
May
(8) |
Jun
(43) |
Jul
(27) |
Aug
(30) |
Sep
(43) |
Oct
(42) |
Nov
(38) |
Dec
(67) |
| 2019 |
Jan
(32) |
Feb
(37) |
Mar
(53) |
Apr
(64) |
May
(49) |
Jun
(18) |
Jul
(14) |
Aug
(53) |
Sep
(25) |
Oct
(30) |
Nov
(49) |
Dec
(31) |
| 2020 |
Jan
(87) |
Feb
(45) |
Mar
(37) |
Apr
(51) |
May
(99) |
Jun
(36) |
Jul
(11) |
Aug
(14) |
Sep
(20) |
Oct
(24) |
Nov
(40) |
Dec
(23) |
| 2021 |
Jan
(14) |
Feb
(53) |
Mar
(85) |
Apr
(15) |
May
(19) |
Jun
(3) |
Jul
(14) |
Aug
(1) |
Sep
(57) |
Oct
(73) |
Nov
(56) |
Dec
(22) |
| 2022 |
Jan
(3) |
Feb
(22) |
Mar
(6) |
Apr
(55) |
May
(46) |
Jun
(39) |
Jul
(15) |
Aug
(9) |
Sep
(11) |
Oct
(34) |
Nov
(20) |
Dec
(36) |
| 2023 |
Jan
(79) |
Feb
(41) |
Mar
(99) |
Apr
(169) |
May
(48) |
Jun
(16) |
Jul
(16) |
Aug
(57) |
Sep
(19) |
Oct
|
Nov
|
Dec
|
| S | M | T | W | T | F | S |
|---|---|---|---|---|---|---|
|
1
(1) |
2
(4) |
3
(3) |
4
(6) |
5
(14) |
6
(10) |
7
(4) |
|
8
(2) |
9
(4) |
10
(7) |
11
(8) |
12
(5) |
13
(11) |
14
(4) |
|
15
(4) |
16
(9) |
17
(6) |
18
|
19
|
20
|
21
|
|
22
(3) |
23
(1) |
24
(7) |
25
(12) |
26
(8) |
27
(13) |
28
(4) |
|
29
(3) |
30
(4) |
|
|
|
|
|
|
From: <sv...@va...> - 2009-11-12 13:28:46
|
Author: tom
Date: 2009-11-12 13:28:34 +0000 (Thu, 12 Nov 2009)
New Revision: 10939
Log:
Various improvements to DWARF handling to cope with changes in recent
versions of gcc as shipped with Fedora 12. Specific changes include:
- Vastly increase the number of opcodes we understand how to
evaluate when processing a location expression.
- Process frame unwind data from the debug_frame ELF section as
well as the eh_frame section.
- Handle version 3 CIEs in frame unwind data.
- Handle the compact form of DW_AT_data_member_location which just
gives a constant offset from the start of it's base type instead
of a full location expression.
Based on patches from Jakub Jelinek on bugs #210479 and #210566.
Modified:
trunk/coregrind/m_debuginfo/d3basics.c
trunk/coregrind/m_debuginfo/debuginfo.c
trunk/coregrind/m_debuginfo/priv_d3basics.h
trunk/coregrind/m_debuginfo/priv_readdwarf.h
trunk/coregrind/m_debuginfo/priv_storage.h
trunk/coregrind/m_debuginfo/priv_tytypes.h
trunk/coregrind/m_debuginfo/readdwarf.c
trunk/coregrind/m_debuginfo/readdwarf3.c
trunk/coregrind/m_debuginfo/readelf.c
trunk/coregrind/m_debuginfo/storage.c
trunk/coregrind/m_debuginfo/tytypes.c
Modified: trunk/coregrind/m_debuginfo/d3basics.c
===================================================================
--- trunk/coregrind/m_debuginfo/d3basics.c 2009-11-12 13:19:41 UTC (rev 10938)
+++ trunk/coregrind/m_debuginfo/d3basics.c 2009-11-12 13:28:34 UTC (rev 10939)
@@ -387,12 +387,8 @@
if (regno == 7/*RSP*/) { *a = regs->sp; return True; }
# elif defined(VGP_ppc32_linux)
if (regno == 1/*SP*/) { *a = regs->sp; return True; }
- if (regno == 31) return False;
- vg_assert(0);
# elif defined(VGP_ppc64_linux)
if (regno == 1/*SP*/) { *a = regs->sp; return True; }
- if (regno == 31) return False;
- vg_assert(0);
# elif defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
vg_assert(0); /* this function should never be called */
# else
@@ -443,7 +439,7 @@
/* 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 +478,8 @@
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 +564,15 @@
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 +598,23 @@
a1 += sw1;
PUSH( a1 );
break;
+ case DW_OP_bregx:
+ if (!regs)
+ FAIL("evaluate_Dwarf3_Expr: DW_OP_bregx 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 +648,238 @@
"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_div:
+ POP(sw2);
+ if (sw2 == 0)
+ FAIL("evaluate_Dwarf3_Expr: division by zero");
+ POP(sw1);
+ sw1 /= sw2;
+ PUSH(sw1);
+ break;
+ case DW_OP_mod:
+ POP(sw2);
+ if (sw2 == 0)
+ FAIL("evaluate_Dwarf3_Expr: division by zero");
+ POP(sw1);
+ sw1 %= sw2;
+ PUSH(sw1);
+ break;
+#define BINARY(name, op, s) \
+ case DW_OP_##name: \
+ POP(s##w2); \
+ POP(s##w1); \
+ s##w1 = s##w1 op s##w2; \
+ PUSH(s##w1); \
+ break
+#define UNARY(name, op, s) \
+ case DW_OP_##name: \
+ POP(s##w1); \
+ s##w1 = op s##w1; \
+ PUSH(s##w1); \
+ break
+ BINARY (and, &, u);
+ BINARY (minus, -, u);
+ BINARY (mul, *, u);
+ UNARY (neg, -, u);
+ UNARY (not, ~, u);
+ BINARY (or, |, u);
+ BINARY (plus, +, u);
+ BINARY (shl, <<, u);
+ BINARY (shr, >>, u);
+ BINARY (shra, >>, s);
+ BINARY (xor, ^, u);
+ BINARY (le, <=, s);
+ BINARY (lt, <, s);
+ BINARY (ge, >=, s);
+ BINARY (gt, >, s);
+ BINARY (ne, !=, u);
+ BINARY (eq, ==, u);
+#undef UNARY
+#undef BINARY
+ case DW_OP_skip:
+ sw1 = *(Short *)expr;
+ expr += 2;
+ if (expr + sw1 < limit - exprszB)
+ FAIL("evaluate_Dwarf3_Expr: DW_OP_skip before start of expr");
+ if (expr + sw1 >= limit)
+ FAIL("evaluate_Dwarf3_Expr: DW_OP_skip after end of expr");
+ expr += sw1;
+ break;
+ case DW_OP_bra:
+ sw1 = *(Short *)expr;
+ expr += 2;
+ if (expr + sw1 < limit - exprszB)
+ FAIL("evaluate_Dwarf3_Expr: DW_OP_bra before start of expr");
+ if (expr + sw1 >= limit)
+ FAIL("evaluate_Dwarf3_Expr: DW_OP_bra after end 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");
+#if defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux)
+ /* Valgrind on ppc32/ppc64 currently doesn't use unwind info. */
+ uw1 = *(Addr *)(regs->sp);
+#else
+ uw1 = ML_(get_CFA)(regs->ip, regs->sp, regs->fp, 0, ~(UWord) 0);
+#endif
+ 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 +893,7 @@
vg_assert(sp >= 0 && sp < N_EXPR_STACK);
res.word = stack[sp];
- res.kind = GXR_Value;
+ res.kind = GXR_Addr;
return res;
# undef POP
@@ -829,12 +1072,15 @@
if (!badness)
badness = "trivial GExpr denotes register (2)";
}
- else {
+ else if (0) {
VG_(printf)(" ML_(evaluate_trivial_GX): unhandled:\n ");
ML_(pp_GX)( gx );
VG_(printf)("\n");
tl_assert(0);
}
+ else
+ if (!badness)
+ badness = "non-trivial GExpr";
VG_(addToXA)( results, &thisResult );
@@ -884,7 +1130,7 @@
/* 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 +1142,8 @@
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:
Modified: trunk/coregrind/m_debuginfo/debuginfo.c
===================================================================
--- trunk/coregrind/m_debuginfo/debuginfo.c 2009-11-12 13:19:41 UTC (rev 10938)
+++ trunk/coregrind/m_debuginfo/debuginfo.c 2009-11-12 13:28:34 UTC (rev 10939)
@@ -2003,75 +2003,51 @@
}
-/* 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. */
-/* Returns True if OK. If not OK, *{ip,sp,fp}P are not changed. */
-/* NOTE: this function may rearrange the order of entries in the
- DebugInfo list. */
-Bool VG_(use_CF_info) ( /*MOD*/Addr* ipP,
- /*MOD*/Addr* spP,
- /*MOD*/Addr* fpP,
- Addr min_accessible,
- Addr max_accessible )
+static CFSICacheEnt* cfsi_cache__find ( Addr ip )
{
- Bool ok;
- DebugInfo* di;
- DiCfSI* cfsi = NULL;
- Addr cfa, ipHere, spHere, fpHere, ipPrev, spPrev, fpPrev;
+ UWord hash = ip % N_CFSI_CACHE;
+ CFSICacheEnt* ce = &cfsi_cache[hash];
+ static UWord n_q = 0, n_m = 0;
- CfiExprEvalContext eec;
-
- static UWord n_q = 0, n_m = 0;
n_q++;
if (0 && 0 == (n_q & 0x1FFFFF))
VG_(printf)("QQQ %lu %lu\n", n_q, n_m);
- { UWord hash = (*ipP) % N_CFSI_CACHE;
- CFSICacheEnt* ce = &cfsi_cache[hash];
-
- if (LIKELY(ce->ip == *ipP) && LIKELY(ce->di != NULL)) {
- /* found an entry in the cache .. */
- } else {
- /* not found in cache. Search and update. */
- n_m++;
- ce->ip = *ipP;
- find_DiCfSI( &ce->di, &ce->ix, *ipP );
- }
-
- if (UNLIKELY(ce->di == (DebugInfo*)1)) {
- /* no DiCfSI for this address */
- cfsi = NULL;
- di = NULL;
- } else {
- /* found a DiCfSI for this address */
- di = ce->di;
- cfsi = &di->cfsi[ ce->ix ];
- }
+ if (LIKELY(ce->ip == ip) && LIKELY(ce->di != NULL)) {
+ /* found an entry in the cache .. */
+ } else {
+ /* not found in cache. Search and update. */
+ n_m++;
+ ce->ip = ip;
+ find_DiCfSI( &ce->di, &ce->ix, ip );
}
- if (UNLIKELY(cfsi == NULL))
- return False; /* no info. Nothing we can do. */
-
- if (0) {
- VG_(printf)("found cfisi: ");
- ML_(ppDiCfSI)(di->cfsi_exprs, cfsi);
+ if (UNLIKELY(ce->di == (DebugInfo*)1)) {
+ /* no DiCfSI for this address */
+ return NULL;
+ } else {
+ /* found a DiCfSI for this address */
+ return ce;
}
+}
- ipPrev = spPrev = fpPrev = 0;
- ipHere = *ipP;
- spHere = *spP;
- fpHere = *fpP;
+static Addr compute_cfa ( Addr ip, Addr sp, Addr fp,
+ Addr min_accessible, Addr max_accessible,
+ DebugInfo* di, DiCfSI* cfsi )
+{
+ CfiExprEvalContext eec;
+ Addr cfa;
+ Bool ok;
- /* First compute the CFA. */
+ /* Compute the CFA. */
cfa = 0;
switch (cfsi->cfa_how) {
case CFIC_SPREL:
- cfa = cfsi->cfa_off + spHere;
+ cfa = sp + cfsi->cfa_off;
break;
case CFIC_FPREL:
- cfa = cfsi->cfa_off + fpHere;
+ cfa = fp + cfsi->cfa_off;
break;
case CFIC_EXPR:
if (0) {
@@ -2079,19 +2055,86 @@
ML_(ppCfiExpr)(di->cfsi_exprs, cfsi->cfa_off);
VG_(printf)("\n");
}
- eec.ipHere = ipHere;
- eec.spHere = spHere;
- eec.fpHere = fpHere;
+ 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 False;
+ if (!ok) return 0;
break;
default:
vg_assert(0);
}
+ return cfa;
+}
+
+/* Get the call frame address (CFA) given an IP/SP/FP triple. */
+Addr ML_(get_CFA) ( Addr ip, Addr sp, Addr fp,
+ Addr min_accessible, Addr max_accessible )
+{
+ CFSICacheEnt* ce;
+ DebugInfo* di;
+ DiCfSI* cfsi;
+
+ ce = cfsi_cache__find(ip);
+
+ if (UNLIKELY(ce == NULL))
+ return 0; /* no info. Nothing we can do. */
+
+ di = ce->di;
+ cfsi = &di->cfsi[ ce->ix ];
+
+ return compute_cfa(ip, sp, fp, min_accessible, max_accessible, di, cfsi);
+}
+
+
+/* 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. */
+/* Returns True if OK. If not OK, *{ip,sp,fp}P are not changed. */
+/* NOTE: this function may rearrange the order of entries in the
+ DebugInfo list. */
+Bool VG_(use_CF_info) ( /*MOD*/Addr* ipP,
+ /*MOD*/Addr* spP,
+ /*MOD*/Addr* fpP,
+ Addr min_accessible,
+ Addr max_accessible )
+{
+ Bool ok;
+ DebugInfo* di;
+ DiCfSI* cfsi = NULL;
+ Addr cfa, ipHere, spHere, fpHere, ipPrev, spPrev, fpPrev;
+ CFSICacheEnt* ce;
+ CfiExprEvalContext eec;
+
+ ce = cfsi_cache__find(*ipP);
+
+ if (UNLIKELY(ce == NULL))
+ return False; /* no info. Nothing we can do. */
+
+ di = ce->di;
+ cfsi = &di->cfsi[ ce->ix ];
+
+ if (0) {
+ VG_(printf)("found cfisi: ");
+ ML_(ppDiCfSI)(di->cfsi_exprs, cfsi);
+ }
+
+ ipPrev = spPrev = fpPrev = 0;
+
+ ipHere = *ipP;
+ spHere = *spP;
+ fpHere = *fpP;
+
+ /* First compute the CFA. */
+ cfa = compute_cfa(ipHere, spHere, fpHere,
+ min_accessible, max_accessible, di, cfsi);
+ if (UNLIKELY(cfa == 0))
+ return False;
+
/* Now we know the CFA, use it to roll back the registers we're
interested in. */
@@ -2346,7 +2389,7 @@
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 +3100,7 @@
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 +3117,7 @@
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 +3136,7 @@
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 +3351,7 @@
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;
}
Modified: trunk/coregrind/m_debuginfo/priv_d3basics.h
===================================================================
--- trunk/coregrind/m_debuginfo/priv_d3basics.h 2009-11-12 13:19:41 UTC (rev 10938)
+++ trunk/coregrind/m_debuginfo/priv_d3basics.h 2009-11-12 13:28:34 UTC (rev 10939)
@@ -522,6 +522,9 @@
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 @@
/* 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 @@
covered by the guard is also ignored. */
GXResult ML_(evaluate_trivial_GX)( GExpr* gx, const DebugInfo* di );
+/* Compute call frame address (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 */
/*--------------------------------------------------------------------*/
Modified: trunk/coregrind/m_debuginfo/priv_readdwarf.h
===================================================================
--- trunk/coregrind/m_debuginfo/priv_readdwarf.h 2009-11-12 13:19:41 UTC (rev 10938)
+++ trunk/coregrind/m_debuginfo/priv_readdwarf.h 2009-11-12 13:28:34 UTC (rev 10939)
@@ -62,7 +62,7 @@
-------------------- */
extern
void ML_(read_callframe_info_dwarf3)
- ( /*OUT*/struct _DebugInfo* di, UChar* ehframe );
+ ( /*OUT*/struct _DebugInfo* di, UChar* frame, SizeT frame_sz, Bool for_eh );
#endif /* ndef __PRIV_READDWARF_H */
Modified: trunk/coregrind/m_debuginfo/priv_storage.h
===================================================================
--- trunk/coregrind/m_debuginfo/priv_storage.h 2009-11-12 13:19:41 UTC (rev 10938)
+++ trunk/coregrind/m_debuginfo/priv_storage.h 2009-11-12 13:28:34 UTC (rev 10939)
@@ -649,6 +649,11 @@
this after finishing adding entries to these tables. */
extern void ML_(canonicaliseTables) ( struct _DebugInfo* di );
+/* Canonicalise the call-frame-info table held by 'di', in preparation
+ for use. This is called by ML_(canonicaliseTables) but can also be
+ called on it's own to sort just this table. */
+extern void ML_(canonicaliseCFI) ( struct _DebugInfo* di );
+
/* ------ Searching ------ */
/* Find a symbol-table index containing the specified pointer, or -1
Modified: trunk/coregrind/m_debuginfo/priv_tytypes.h
===================================================================
--- trunk/coregrind/m_debuginfo/priv_tytypes.h 2009-11-12 13:19:41 UTC (rev 10938)
+++ trunk/coregrind/m_debuginfo/priv_tytypes.h 2009-11-12 13:28:34 UTC (rev 10939)
@@ -78,8 +78,13 @@
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 {
Modified: trunk/coregrind/m_debuginfo/readdwarf.c
===================================================================
--- trunk/coregrind/m_debuginfo/readdwarf.c 2009-11-12 13:19:41 UTC (rev 10938)
+++ trunk/coregrind/m_debuginfo/readdwarf.c 2009-11-12 13:28:34 UTC (rev 10939)
@@ -37,6 +37,7 @@
#include "pub_core_libcprint.h"
#include "pub_core_options.h"
#include "pub_core_xarray.h"
+#include "pub_core_tooliface.h" /* VG_(needs) */
#include "priv_misc.h" /* dinfo_zalloc/free/strdup */
#include "priv_d3basics.h"
#include "priv_tytypes.h"
@@ -1777,11 +1778,11 @@
#elif defined(VGP_ppc32_linux)
# define FP_REG 1
# define SP_REG 1
-# define RA_REG_DEFAULT 8 // CAB: What's a good default ?
+# define RA_REG_DEFAULT 65
#elif defined(VGP_ppc64_linux)
# define FP_REG 1
# define SP_REG 1
-# define RA_REG_DEFAULT 8 // CAB: What's a good default ?
+# define RA_REG_DEFAULT 65
#elif defined(VGP_x86_darwin)
# define FP_REG 5
# define SP_REG 4
@@ -1795,7 +1796,11 @@
#endif
/* the number of regs we are prepared to unwind */
-#define N_CFI_REGS 20
+#if defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux)
+# define N_CFI_REGS 72
+#else
+# define N_CFI_REGS 20
+#endif
/* Instructions for the automaton */
enum dwarf_cfa_primary_ops
@@ -3446,23 +3451,33 @@
void ML_(read_callframe_info_dwarf3)
- ( /*OUT*/struct _DebugInfo* di, UChar* ehframe_image )
+ ( /*OUT*/struct _DebugInfo* di, UChar* frame_image, SizeT frame_size,
+ Bool for_eh )
{
Int nbytes;
HChar* how = NULL;
Int n_CIEs = 0;
- UChar* data = ehframe_image;
+ UChar* data = frame_image;
+ UWord ehframe_cfsis = 0;
+ Addr frame_avma = for_eh ? di->ehframe_avma : 0;
# if defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux)
- /* These targets don't use CFI-based stack unwinding. */
+ /* These targets don't use CFI-based stack unwinding. */
return;
# endif
+ /* If we are reading .debug_frame after .eh_frame has been read, only
+ add FDEs which weren't covered in .eh_frame. To be able to quickly
+ search the FDEs, the records must be sorted. */
+ if ( ! for_eh && di->ehframe_size && di->cfsi_used ) {
+ ML_(canonicaliseCFI) ( di );
+ ehframe_cfsis = di->cfsi_used;
+ }
+
if (di->trace_cfi) {
VG_(printf)("\n-----------------------------------------------\n");
VG_(printf)("CFI info: szB %ld, _avma %#lx, _image %p\n",
- di->ehframe_size, di->ehframe_avma,
- ehframe_image );
+ frame_size, frame_avma, frame_image );
VG_(printf)("CFI info: name %s\n",
di->filename );
}
@@ -3495,11 +3510,11 @@
Bool dw64;
/* Are we done? */
- if (data == ehframe_image + di->ehframe_size)
+ if (data == frame_image + frame_size)
return;
/* Overshot the end? Means something is wrong */
- if (data > ehframe_image + di->ehframe_size) {
+ if (data > frame_image + frame_size) {
how = "overran the end of .eh_frame";
goto bad;
}
@@ -3509,9 +3524,9 @@
ciefde_start = data;
if (di->trace_cfi)
- VG_(printf)("\ncie/fde.start = %p (ehframe_image + 0x%lx)\n",
+ VG_(printf)("\ncie/fde.start = %p (frame_image + 0x%lx)\n",
ciefde_start,
- ciefde_start - ehframe_image + 0UL);
+ ciefde_start - frame_image + 0UL);
ciefde_len = (ULong) read_UInt(data); data += sizeof(UInt);
if (di->trace_cfi)
@@ -3524,7 +3539,7 @@
if (ciefde_len == 0) {
if (di->ddump_frames)
VG_(printf)("%08lx ZERO terminator\n\n",
- ((Addr)ciefde_start) - ((Addr)ehframe_image));
+ ((Addr)ciefde_start) - ((Addr)frame_image));
return;
}
@@ -3550,8 +3565,10 @@
if (di->trace_cfi)
VG_(printf)("cie.pointer = %lld\n", cie_pointer);
- /* If cie_pointer is zero, we've got a CIE; else it's an FDE. */
- if (cie_pointer == 0) {
+ /* If cie_pointer is zero for .eh_frame or all ones for .debug_frame,
+ we've got a CIE; else it's an FDE. */
+ if (cie_pointer == (for_eh ? 0ULL
+ : dw64 ? 0xFFFFFFFFFFFFFFFFULL : 0xFFFFFFFFULL)) {
Int this_CIE;
UChar cie_version;
@@ -3575,11 +3592,11 @@
/* Record its offset. This is how we will find it again
later when looking at an FDE. */
- the_CIEs[this_CIE].offset = (ULong)(ciefde_start - ehframe_image);
+ the_CIEs[this_CIE].offset = (ULong)(ciefde_start - frame_image);
if (di->ddump_frames)
VG_(printf)("%08lx %08lx %08lx CIE\n",
- ((Addr)ciefde_start) - ((Addr)ehframe_image),
+ ((Addr)ciefde_start) - ((Addr)frame_image),
(Addr)ciefde_len,
(Addr)(UWord)cie_pointer );
@@ -3623,8 +3640,13 @@
VG_(printf)(" Data alignment factor: %d\n",
(Int)the_CIEs[this_CIE].data_a_f);
- the_CIEs[this_CIE].ra_reg = (Int)read_UChar(data);
- data += sizeof(UChar);
+ if (cie_version == 1) {
+ the_CIEs[this_CIE].ra_reg = (Int)read_UChar(data);
+ data += sizeof(UChar);
+ } else {
+ the_CIEs[this_CIE].ra_reg = read_leb128( data, &nbytes, 0);
+ data += nbytes;
+ }
if (di->trace_cfi)
VG_(printf)("cie.ra_reg = %d\n",
the_CIEs[this_CIE].ra_reg);
@@ -3702,7 +3724,7 @@
}
if (the_CIEs[this_CIE].ilen < 0
- || the_CIEs[this_CIE].ilen > di->ehframe_size) {
+ || the_CIEs[this_CIE].ilen > frame_size) {
how = "implausible # cie initial insns";
goto bad;
}
@@ -3717,8 +3739,8 @@
if (di->trace_cfi || di->ddump_frames) {
AddressDecodingInfo adi;
adi.encoding = the_CIEs[this_CIE].address_encoding;
- adi.ehframe_image = ehframe_image;
- adi.ehframe_avma = di->ehframe_avma;
+ adi.ehframe_image = frame_image;
+ adi.ehframe_avma = frame_avma;
adi.text_bias = di->text_debug_bias;
show_CF_instructions( the_CIEs[this_CIE].instrs,
the_CIEs[this_CIE].ilen, &adi,
@@ -3747,9 +3769,12 @@
cie_pointer bytes back from here. */
/* re sizeof(UInt) / sizeof(ULong), matches XXX above. */
- look_for = (data - (dw64 ? sizeof(ULong) : sizeof(UInt))
- - ehframe_image)
- - cie_pointer;
+ if (for_eh)
+ look_for = (data - (dw64 ? sizeof(ULong) : sizeof(UInt))
+ - frame_image)
+ - cie_pointer;
+ else
+ look_for = cie_pointer;
for (cie = 0; cie < n_CIEs; cie++) {
if (0) VG_(printf)("look for %lld %lld\n",
@@ -3764,8 +3789,8 @@
}
adi.encoding = the_CIEs[cie].address_encoding;
- adi.ehframe_image = ehframe_image;
- adi.ehframe_avma = di->ehframe_avma;
+ adi.ehframe_image = frame_image;
+ adi.ehframe_avma = frame_avma;
adi.text_bias = di->text_debug_bias;
fde_initloc = read_encoded_Addr(&nbytes, &adi, data);
data += nbytes;
@@ -3773,8 +3798,8 @@
VG_(printf)("fde.initloc = %#lx\n", fde_initloc);
adi.encoding = the_CIEs[cie].address_encoding & 0xf;
- adi.ehframe_image = ehframe_image;
- adi.ehframe_avma = di->ehframe_avma;
+ adi.ehframe_image = frame_image;
+ adi.ehframe_avma = frame_avma;
adi.text_bias = di->text_debug_bias;
/* WAS (incorrectly):
@@ -3800,7 +3825,7 @@
if (di->ddump_frames)
VG_(printf)("%08lx %08lx %08lx FDE cie=%08lx pc=%08lx..%08lx\n",
- ((Addr)ciefde_start) - ((Addr)ehframe_image),
+ ((Addr)ciefde_start) - ((Addr)frame_image),
(Addr)ciefde_len,
(Addr)(UWord)cie_pointer,
(Addr)look_for,
@@ -3827,16 +3852,43 @@
VG_(printf)("fde.ilen = %d\n", (Int)fde_ilen);
}
- if (fde_ilen < 0 || fde_ilen > di->ehframe_size) {
+ if (fde_ilen < 0 || fde_ilen > frame_size) {
how = "implausible # fde insns";
goto bad;
}
data += fde_ilen;
+ if (ehframe_cfsis) {
+ Addr a_mid_lo, a_mid_hi;
+ Word mid, size,
+ lo = 0,
+ hi = ehframe_cfsis-1;
+ while (True) {
+ /* current unsearched space is from lo to hi, inclusive. */
+ if (lo > hi) break; /* not found */
+ mid = (lo + hi) / 2;
+ a_mid_lo = di->cfsi[mid].base;
+ size = di->cfsi[mid].len;
+ a_mid_hi = a_mid_lo + size - 1;
+ vg_assert(a_mid_hi >= a_mid_lo);
+ if (fde_initloc + fde_arange <= a_mid_lo) {
+ hi = mid-1; continue;
+ }
+ if (fde_initloc > a_mid_hi) { lo = mid+1; continue; }
+ break;
+ }
+
+ /* The range this .debug_frame FDE covers has been already
+ covered in .eh_frame section. Don't add it from .debug_frame
+ section again. */
+ if (lo <= hi)
+ continue;
+ }
+
adi.encoding = the_CIEs[cie].address_encoding;
- adi.ehframe_image = ehframe_image;
- adi.ehframe_avma = di->ehframe_avma;
+ adi.ehframe_image = frame_image;
+ adi.ehframe_avma = frame_avma;
adi.text_bias = di->text_debug_bias;
if (di->trace_cfi)
Modified: trunk/coregrind/m_debuginfo/readdwarf3.c
===================================================================
--- trunk/coregrind/m_debuginfo/readdwarf3.c 2009-11-12 13:19:41 UTC (rev 10938)
+++ trunk/coregrind/m_debuginfo/readdwarf3.c 2009-11-12 13:28:34 UTC (rev 10939)
@@ -2356,9 +2356,16 @@
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 @@
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 @@
/* 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);
}
Modified: trunk/coregrind/m_debuginfo/readelf.c
===================================================================
--- trunk/coregrind/m_debuginfo/readelf.c 2009-11-12 13:19:41 UTC (rev 10938)
+++ trunk/coregrind/m_debuginfo/readelf.c 2009-11-12 13:28:34 UTC (rev 10939)
@@ -1691,6 +1691,7 @@
UChar* debug_str_img = NULL; /* .debug_str (dwarf2) */
UChar* debug_ranges_img = NULL; /* .debug_ranges (dwarf2) */
UChar* debug_loc_img = NULL; /* .debug_loc (dwarf2) */
+ UChar* debug_frame_img = NULL; /* .debug_frame (dwarf2) */
UChar* dwarf1d_img = NULL; /* .debug (dwarf1) */
UChar* dwarf1l_img = NULL; /* .line (dwarf1) */
UChar* ehframe_img = NULL; /* .eh_frame (dwarf2) */
@@ -1710,6 +1711,7 @@
SizeT debug_str_sz = 0;
SizeT debug_ranges_sz = 0;
SizeT debug_loc_sz = 0;
+ SizeT debug_frame_sz = 0;
SizeT dwarf1d_sz = 0;
SizeT dwarf1l_sz = 0;
SizeT ehframe_sz = 0;
@@ -1767,6 +1769,7 @@
FIND(".debug_str", debug_str_sz, debug_str_img)
FIND(".debug_ranges", debug_ranges_sz, debug_ranges_img)
FIND(".debug_loc", debug_loc_sz, debug_loc_img)
+ FIND(".debug_frame", debug_frame_sz, debug_frame_img)
FIND(".debug", dwarf1d_sz, dwarf1d_img)
FIND(".line", dwarf1l_sz, dwarf1l_img)
@@ -1959,6 +1962,8 @@
FIND(need_dwarf2, ".debug_ranges", debug_ranges_sz,
debug_ranges_img)
FIND(need_dwarf2, ".debug_loc", debug_loc_sz, debug_loc_img)
+ FIND(need_dwarf2, ".debug_frame", debug_frame_sz,
+ debug_frame_img)
FIND(need_dwarf1, ".debug", dwarf1d_sz, dwarf1d_img)
FIND(need_dwarf1, ".line", dwarf1l_sz, dwarf1l_img)
@@ -1996,11 +2001,15 @@
False, opd_img);
}
- /* Read .eh_frame (call-frame-info) if any */
+ /* Read .eh_frame and .debug_frame (call-frame-info) if any */
if (ehframe_img) {
vg_assert(ehframe_sz == di->ehframe_size);
- ML_(read_callframe_info_dwarf3)( di, ehframe_img );
+ ML_(read_callframe_info_dwarf3)( di, ehframe_img, ehframe_sz, True );
}
+ if (debug_frame_sz) {
+ ML_(read_callframe_info_dwarf3)( di, debug_frame_img,
+ debug_frame_sz, False );
+ }
/* Read the stabs and/or dwarf2 debug information, if any. It
appears reading stabs stuff on amd64-linux doesn't work, so
Modified: trunk/coregrind/m_debuginfo/storage.c
===================================================================
--- trunk/coregrind/m_debuginfo/storage.c 2009-11-12 13:19:41 UTC (rev 10938)
+++ trunk/coregrind/m_debuginfo/storage.c 2009-11-12 13:28:34 UTC (rev 10939)
@@ -1435,7 +1435,7 @@
return 0;
}
-static void canonicaliseCFI ( struct _DebugInfo* di )
+void ML_(canonicaliseCFI) ( struct _DebugInfo* di )
{
Word i, j;
const Addr minAvma = 0;
@@ -1528,7 +1528,7 @@
{
canonicaliseSymtab ( di );
canonicaliseLoctab ( di );
- canonicaliseCFI ( di );
+ ML_(canonicaliseCFI) ( di );
canonicaliseVarInfo ( di );
}
Modified: trunk/coregrind/m_debuginfo/tytypes.c
===================================================================
--- trunk/coregrind/m_debuginfo/tytypes.c 2009-11-12 13:19:41 UTC (rev 10938)
+++ trunk/coregrind/m_debuginfo/tytypes.c 2009-11-12 13:28:34 UTC (rev 10939)
@@ -98,10 +98,15 @@
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,8 +481,11 @@
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,
- te1->Te.Field.nLoc);
+ if (te1->Te.Field.nLoc == -1)
+ r = Long__cmp(te1->Te.Field.pos.offset, te2->Te.Field.pos.offset);
+ else
+ r = Bytevector__cmp(te1->Te.Field.pos.loc, te2->Te.Field.pos.loc,
+ te1->Te.Field.nLoc);
return r;
case Te_Bound:
r = Bool__cmp(te1->Te.Bound.knownL, te2->Te.Bound.knownL);
@@ -568,7 +576,8 @@
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,26 +756,32 @@
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_Value)
+ if (res.kind != GXR_Addr)
continue;
mul = ML_(sizeOfType)( tyents, field->Te.Field.typeR );
if (mul.b != True)
|
|
From: <sv...@va...> - 2009-11-12 13:19:57
|
Author: tom
Date: 2009-11-12 13:19:41 +0000 (Thu, 12 Nov 2009)
New Revision: 10938
Log:
Fix stack unwinding on PPC to store the correct frame pointer for
frames other than the first one found.
This is taken from Jakub Jelinek's second patch on bug #210479.
Modified:
trunk/coregrind/m_stacktrace.c
Modified: trunk/coregrind/m_stacktrace.c
===================================================================
--- trunk/coregrind/m_stacktrace.c 2009-11-11 19:22:05 UTC (rev 10937)
+++ trunk/coregrind/m_stacktrace.c 2009-11-12 13:19:41 UTC (rev 10938)
@@ -430,9 +430,9 @@
# endif
if (0 == ip || 1 == ip) break;
- fp = (((UWord*)fp)[0]);
if (sps) sps[i] = fp; /* NB. not sp */
if (fps) fps[i] = fp;
+ fp = (((UWord*)fp)[0]);
ips[i++] = ip - 1; /* -1: refer to calling insn, not the RA */
if (debug)
VG_(printf)(" ipsF[%d]=%#08lx\n", i-1, ips[i-1]);
|
|
From: Tom H. <th...@cy...> - 2009-11-12 03:50:34
|
Nightly build on vauxhall ( x86_64, Fedora 11 ) Started at 2009-11-12 03:20:06 GMT Ended at 2009-11-12 03:50:09 GMT Results differ from 24 hours ago Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... failed Regression test results follow == 541 tests, 8 stderr failures, 1 stdout failure, 0 post failures == memcheck/tests/linux/stack_switch (stderr) memcheck/tests/long_namespace_xml (stderr) helgrind/tests/pth_spinlock (stderr) helgrind/tests/tc06_two_races_xml (stderr) helgrind/tests/tc20_verifywrap (stderr) helgrind/tests/tc23_bogus_condwait (stderr) drd/tests/pth_detached_sem (stdout) drd/tests/qt4_semaphore (stderr) exp-ptrcheck/tests/bad_percentify (stderr) ================================================= == Results from 24 hours ago == ================================================= Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... failed Regression test results follow == 541 tests, 7 stderr failures, 0 stdout failures, 0 post failures == memcheck/tests/linux/stack_switch (stderr) memcheck/tests/long_namespace_xml (stderr) helgrind/tests/tc06_two_races_xml (stderr) helgrind/tests/tc20_verifywrap (stderr) helgrind/tests/tc23_bogus_condwait (stderr) drd/tests/qt4_semaphore (stderr) exp-ptrcheck/tests/bad_percentify (stderr) ================================================= == Difference between 24 hours ago and now == ================================================= *** old.short Thu Nov 12 03:35:11 2009 --- new.short Thu Nov 12 03:50:09 2009 *************** *** 8,12 **** ! == 541 tests, 7 stderr failures, 0 stdout failures, 0 post failures == memcheck/tests/linux/stack_switch (stderr) memcheck/tests/long_namespace_xml (stderr) helgrind/tests/tc06_two_races_xml (stderr) --- 8,13 ---- ! == 541 tests, 8 stderr failures, 1 stdout failure, 0 post failures == memcheck/tests/linux/stack_switch (stderr) memcheck/tests/long_namespace_xml (stderr) + helgrind/tests/pth_spinlock (stderr) helgrind/tests/tc06_two_races_xml (stderr) *************** *** 14,15 **** --- 15,17 ---- helgrind/tests/tc23_bogus_condwait (stderr) + drd/tests/pth_detached_sem (stdout) drd/tests/qt4_semaphore (stderr) |
|
From: Tom H. <th...@cy...> - 2009-11-12 03:49:03
|
Nightly build on lloyd ( x86_64, Fedora 7 ) Started at 2009-11-12 03:05:06 GMT Ended at 2009-11-12 03:48:47 GMT Results unchanged from 24 hours ago Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... failed Regression test results follow == 531 tests, 1 stderr failure, 0 stdout failures, 0 post failures == helgrind/tests/tc06_two_races_xml (stderr) |
|
From: Tom H. <th...@cy...> - 2009-11-12 03:36:15
|
Nightly build on mg ( x86_64, Fedora 9 ) Started at 2009-11-12 03:10:06 GMT Ended at 2009-11-12 03:35:56 GMT Results unchanged from 24 hours ago Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... failed Regression test results follow == 538 tests, 1 stderr failure, 0 stdout failures, 0 post failures == helgrind/tests/tc06_two_races_xml (stderr) |