Essentially non-functional tidyings and improvements to debuginfo
reading. Two sets of changes:
* New flags for debugging the readers.
--debug-dump=syms
--debug-dump=line
--debug-dump=frames
These (currently accepted but nonfunctional) are intended to
create output in the style of (that is, identical to)
/usr/bin/readelf --syms
/usr/bin/readelf --debug-dump=line
/usr/bin/readelf --debug-dump=frames
respectively. The plan is that flaws in these readers can then
be easily found by diff-ing the output against that from readelf.
Also, a new flag --trace-symtab-patt=<object filename pattern>
which is used to limit all debuginfo-related debug info to the
set of shared object names matching the given pattern. This
facilitates extracting the debuginfo details of one specific
shared object, which is usually what is required, rather than
having to wade through megabytes of junk from every object in
the process.
* Propagate the avma/svma/image address-naming scheme
(as described at the top of debuginfo.c) through large parts of
readelf.c and readdwarf.c.
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@6588 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/coregrind/m_debuginfo/debuginfo.c b/coregrind/m_debuginfo/debuginfo.c
index f651720..1477efc 100644
--- a/coregrind/m_debuginfo/debuginfo.c
+++ b/coregrind/m_debuginfo/debuginfo.c
@@ -85,7 +85,8 @@
This terminology is not used consistently, but a start has been
made. readelf.c and the call-frame info reader in readdwarf.c now
use it. Specifically, various variables and structure fields have
- been annotated with _avma / _svma / _image / _bias.
+ been annotated with _avma / _svma / _image / _bias. In places _img
+ is used instead of _image for the sake of brevity.
*/
@@ -112,8 +113,12 @@
const UChar* filename,
const UChar* memname)
{
- SegInfo* si = VG_(arena_calloc)(VG_AR_SYMTAB, 1, sizeof(SegInfo));
+ Bool traceme;
+ SegInfo* si;
+ vg_assert(filename);
+
+ si = VG_(arena_calloc)(VG_AR_SYMTAB, 1, sizeof(SegInfo));
si->text_start_avma = start;
si->text_size = size;
si->foffset = foffset;
@@ -122,7 +127,23 @@
? VG_(arena_strdup)(VG_AR_SYMTAB, memname)
: NULL;
- // Everything else -- pointers, sizes, arrays -- is zeroed by calloc.
+ /* Everything else -- pointers, sizes, arrays -- is zeroed by calloc.
+ Now set up the debugging-output flags. */
+ traceme
+ = VG_(string_match)( VG_(clo_trace_symtab_patt), filename )
+ || (memname && VG_(string_match)( VG_(clo_trace_symtab_patt),
+ memname ));
+ if (traceme) {
+ si->trace_symtab = VG_(clo_trace_symtab);
+ si->trace_cfi = VG_(clo_trace_cfi);
+#if 0
+ si->ddump_syms = VG_(clo_ddump_syms);
+ si->ddump_line = VG_(clo_ddump_line);
+ si->ddump_frames = VG_(clo_ddump_frames);
+#endif
+ }
+
+
return si;
}
diff --git a/coregrind/m_debuginfo/priv_storage.h b/coregrind/m_debuginfo/priv_storage.h
index c0618dc..dcd4887 100644
--- a/coregrind/m_debuginfo/priv_storage.h
+++ b/coregrind/m_debuginfo/priv_storage.h
@@ -194,6 +194,16 @@
UInt data_size;
Addr bss_start_avma;
UInt bss_size;
+
+ /* Used for debugging only - indicate what stuff to dump whilst
+ reading stuff into the seginfo. Are computed as early in the
+ lifetime of the SegInfo as possible. Use these when deciding
+ what to spew out; do not use the global VG_(clo_blah) flags. */
+ Bool trace_symtab; /* symbols, our style */
+ Bool trace_cfi; /* dwarf frame unwind, our style */
+ Bool ddump_syms; /* mimic /usr/bin/readelf --syms */
+ Bool ddump_line; /* mimic /usr/bin/readelf --debug-dump=line */
+ Bool ddump_frames; /* mimic /usr/bin/readelf --debug-dump=frames */
};
/* --------------------- functions --------------------- */
@@ -250,7 +260,7 @@
#define TRACE_SYMTAB(format, args...) \
- if (VG_(clo_trace_symtab)) { VG_(printf)(format, ## args); }
+ if (si->trace_symtab) { VG_(printf)(format, ## args); }
#endif /* ndef __PRIV_STORAGE_H */
diff --git a/coregrind/m_debuginfo/readdwarf.c b/coregrind/m_debuginfo/readdwarf.c
index 9288df0..58ec665 100644
--- a/coregrind/m_debuginfo/readdwarf.c
+++ b/coregrind/m_debuginfo/readdwarf.c
@@ -253,12 +253,12 @@
Read 32-bit value from p. If it is 0xFFFFFFFF, instead read a
64-bit bit value from p+4. This is used in 64-bit dwarf to encode
some table lengths. */
-static ULong read_initial_length_field ( UChar* p, /*OUT*/Bool* is64 )
+static ULong read_initial_length_field ( UChar* p_img, /*OUT*/Bool* is64 )
{
- UInt w32 = *((UInt*)p);
+ UInt w32 = *((UInt*)p_img);
if (w32 == 0xFFFFFFFF) {
*is64 = True;
- return *((ULong*)(p+4));
+ return *((ULong*)(p_img+4));
} else {
*is64 = False;
return (ULong)w32;
@@ -390,7 +390,7 @@
static
void read_dwarf2_lineblock ( struct _SegInfo* si, OffT debug_offset,
UnitInfo* ui,
- UChar* theBlock,
+ UChar* theBlock, /* IMAGE */
Int noLargerThan )
{
DebugLineInfo info;
@@ -786,9 +786,9 @@
*/
static
void read_unitinfo_dwarf2( /*OUT*/UnitInfo* ui,
- UChar* unitblock,
- UChar* debugabbrev,
- UChar* debugstr )
+ UChar* unitblock_img,
+ UChar* debugabbrev_img,
+ UChar* debugstr_img )
{
UInt acode, abcode;
ULong atoffs, blklen;
@@ -796,9 +796,9 @@
UShort ver;
UChar addr_size;
- UChar* p = unitblock;
- UChar* end;
- UChar* abbrev;
+ UChar* p = unitblock_img;
+ UChar* end_img;
+ UChar* abbrev_img;
VG_(memset)( ui, 0, sizeof( UnitInfo ) );
ui->stmt_list = -1LL;
@@ -821,12 +821,14 @@
addr_size = *p;
p += 1;
- end = unitblock + blklen + (ui->dw64 ? 12 : 4); /* End of this block */
- level = 0; /* Level in the abbrev tree */
- abbrev = debugabbrev + atoffs; /* Abbreviation data for this block */
+ end_img = unitblock_img
+ + blklen + (ui->dw64 ? 12 : 4); /* End of this block */
+ level = 0; /* Level in the abbrev tree */
+ abbrev_img = debugabbrev_img
+ + atoffs; /* Abbreviation data for this block */
/* Read the compilation unit entries */
- while ( p < end ) {
+ while ( p < end_img ) {
Bool has_child;
UInt tag;
@@ -839,18 +841,18 @@
}
/* Read abbreviation header */
- abcode = read_leb128U( &abbrev ); /* abbreviation code */
+ abcode = read_leb128U( &abbrev_img ); /* abbreviation code */
if ( acode != abcode ) {
/* We are in in children list, and must rewind to a
* previously declared abbrev code. This code works but is
* not triggered since we shortcut the parsing once we have
* read the compile_unit block. This should only occur when
* level > 0 */
- abbrev = lookup_abbrev( debugabbrev + atoffs, acode );
+ abbrev_img = lookup_abbrev( debugabbrev_img + atoffs, acode );
}
- tag = read_leb128U( &abbrev );
- has_child = *(abbrev++) == 1; /* DW_CHILDREN_yes */
+ tag = read_leb128U( &abbrev_img );
+ has_child = *(abbrev_img++) == 1; /* DW_CHILDREN_yes */
if ( has_child )
level++;
@@ -861,8 +863,8 @@
UInt name, form;
ULong cval = -1LL; /* Constant value read */
Char *sval = NULL; /* String value read */
- name = read_leb128U( &abbrev );
- form = read_leb128U( &abbrev );
+ name = read_leb128U( &abbrev_img );
+ form = read_leb128U( &abbrev_img );
if ( name == 0 )
break;
@@ -885,10 +887,10 @@
/* 2006-01-01: only generate a value if
debugstr is non-NULL (which means that a
debug_str section was found) */
- if (debugstr && !ui->dw64)
- sval = debugstr + *((UInt*)p);
- if (debugstr && ui->dw64)
- sval = debugstr + *((ULong*)p);
+ if (debugstr_img && !ui->dw64)
+ sval = debugstr_img + *((UInt*)p);
+ if (debugstr_img && ui->dw64)
+ sval = debugstr_img + *((ULong*)p);
p += ui->dw64 ? 8 : 4;
break;
case 0x08: /* FORM_string */ sval = (Char*)p;
@@ -951,15 +953,15 @@
*/
void ML_(read_debuginfo_dwarf2)
( struct _SegInfo* si, OffT debug_offset,
- UChar* debuginfo, Int debug_info_sz, /* .debug_info */
- UChar* debugabbrev, /* .debug_abbrev */
- UChar* debugline, Int debug_line_sz, /* .debug_line */
- UChar* debugstr ) /* .debug_str */
+ UChar* debuginfo_img, Int debug_info_sz, /* .debug_info */
+ UChar* debugabbrev_img, /* .debug_abbrev */
+ UChar* debugline_img, Int debug_line_sz, /* .debug_line */
+ UChar* debugstr_img ) /* .debug_str */
{
UnitInfo ui;
UShort ver;
- UChar* block;
- UChar* end = debuginfo + debug_info_sz;
+ UChar* block_img;
+ UChar* end_img = debuginfo_img + debug_info_sz;
ULong blklen;
Bool blklen_is_64;
Int blklen_len = 0;
@@ -971,20 +973,21 @@
}
/* Iterate on all the blocks we find in .debug_info */
- for ( block = debuginfo; block < end - 4; block += blklen + blklen_len ) {
+ for ( block_img = debuginfo_img; block_img < end_img - 4;
+ block_img += blklen + blklen_len ) {
/* Read the compilation unit header in .debug_info section - See
p 70 */
/* This block length */
- blklen = read_initial_length_field( block, &blklen_is_64 );
+ blklen = read_initial_length_field( block_img, &blklen_is_64 );
blklen_len = blklen_is_64 ? 12 : 4;
- if ( block + blklen + blklen_len > end ) {
+ if ( block_img + blklen + blklen_len > end_img ) {
ML_(symerr)( "Last block truncated in .debug_info; ignoring" );
return;
}
/* version should be 2 */
- ver = *((UShort*)( block + blklen_len ));
+ ver = *((UShort*)( block_img + blklen_len ));
if ( ver != 2 ) {
ML_(symerr)( "Ignoring non-dwarf2 block in .debug_info" );
continue;
@@ -992,8 +995,9 @@
/* Fill ui with offset in .debug_line and compdir */
if (0)
- VG_(printf)( "Reading UnitInfo at 0x%x.....\n", block - debuginfo );
- read_unitinfo_dwarf2( &ui, block, debugabbrev, debugstr );
+ VG_(printf)( "Reading UnitInfo at 0x%x.....\n",
+ block_img - debuginfo_img );
+ read_unitinfo_dwarf2( &ui, block_img, debugabbrev_img, debugstr_img );
if (0)
VG_(printf)( " => LINES=0x%llx NAME=%s DIR=%s\n",
ui.stmt_list, ui.name, ui.compdir );
@@ -1006,8 +1010,9 @@
VG_(printf)("debug_line_sz %d, ui.stmt_list %lld %s\n",
debug_line_sz, ui.stmt_list, ui.name );
/* Read the .debug_line block for this compile unit */
- read_dwarf2_lineblock( si, debug_offset, &ui, debugline + ui.stmt_list,
- debug_line_sz - ui.stmt_list );
+ read_dwarf2_lineblock(
+ si, debug_offset, &ui, debugline_img + ui.stmt_list,
+ debug_line_sz - ui.stmt_list );
}
}
@@ -1759,7 +1764,8 @@
*/
static Bool summarise_context( /*OUT*/DiCfSI* si,
Addr loc_start,
- UnwindContext* ctx )
+ UnwindContext* ctx,
+ struct _SegInfo* seginfo )
{
Int why = 0;
initCfiSI(si);
@@ -1824,7 +1830,7 @@
return True;
failed:
- if (VG_(clo_verbosity) > 2 || VG_(clo_trace_cfi)) {
+ if (VG_(clo_verbosity) > 2 || seginfo->trace_cfi) {
VG_(message)(Vg_DebugMsg,
"summarise_context(loc_start = %p)"
": cannot summarise(why=%d): ", loc_start, why);
@@ -2042,7 +2048,8 @@
static Int run_CF_instruction ( /*MOD*/UnwindContext* ctx,
UChar* instr,
UnwindContext* restore_ctx,
- AddressDecodingInfo* adi )
+ AddressDecodingInfo* adi,
+ struct _SegInfo* si )
{
Int off, reg, reg2, nleb, len;
UInt delta;
@@ -2244,7 +2251,7 @@
case DW_CFA_expression:
/* Too difficult to really handle; just skip over it and say
that we don't know what do to with the register. */
- if (VG_(clo_trace_cfi))
+ if (si->trace_cfi)
VG_(printf)("DWARF2 CFI reader: "
"ignoring DW_CFA_expression\n");
reg = read_leb128( &instr[i], &nleb, 0 );
@@ -2260,7 +2267,7 @@
case DW_CFA_val_expression:
/* Too difficult to really handle; just skip over it and say
that we don't know what do to with the register. */
- if (VG_(clo_trace_cfi))
+ if (si->trace_cfi)
VG_(printf)("DWARF2 CFI reader: "
"ignoring DW_CFA_val_expression\n");
reg = read_leb128( &instr[i], &nleb, 0 );
@@ -2274,7 +2281,7 @@
break;
case DW_CFA_def_cfa_expression:
- if (VG_(clo_trace_cfi))
+ if (si->trace_cfi)
VG_(printf)("DWARF2 CFI reader: "
"ignoring DW_CFA_def_cfa_expression\n");
len = read_leb128( &instr[i], &nleb, 0 );
@@ -2558,7 +2565,7 @@
/* Oh, well, let's kludge it into the text segment, then. */
/* First, though, complain: */
- if (VG_(clo_trace_cfi) || complaints > 0) {
+ if (si->trace_cfi || complaints > 0) {
complaints--;
if (VG_(clo_verbosity) > 1) {
VG_(message)(
@@ -2570,7 +2577,7 @@
si->text_bias + cfsi->base + cfsi->len - 1
);
}
- if (VG_(clo_trace_cfi))
+ if (si->trace_cfi)
ML_(ppDiCfSI)(cfsi);
}
@@ -2605,16 +2612,16 @@
loc_prev = ctx->loc;
if (i >= ilen) break;
if (0) (void)show_CF_instruction( &instrs[i], adi );
- j = run_CF_instruction( ctx, &instrs[i], restore_ctx, adi );
+ j = run_CF_instruction( ctx, &instrs[i], restore_ctx, adi, si );
if (j == 0)
return False; /* execution failed */
i += j;
if (0) ppUnwindContext(ctx);
if (loc_prev != ctx->loc && si) {
- summ_ok = summarise_context ( &cfsi, loc_prev, ctx );
+ summ_ok = summarise_context ( &cfsi, loc_prev, ctx, si );
if (summ_ok) {
kludge_then_addDiCfSI(si, &cfsi);
- if (VG_(clo_trace_cfi))
+ if (si->trace_cfi)
ML_(ppDiCfSI)(&cfsi);
}
}
@@ -2623,10 +2630,10 @@
loc_prev = ctx->loc;
ctx->loc = fde_arange;
if (si) {
- summ_ok = summarise_context ( &cfsi, loc_prev, ctx );
+ summ_ok = summarise_context ( &cfsi, loc_prev, ctx, si );
if (summ_ok) {
kludge_then_addDiCfSI(si, &cfsi);
- if (VG_(clo_trace_cfi))
+ if (si->trace_cfi)
ML_(ppDiCfSI)(&cfsi);
}
}
@@ -2686,7 +2693,7 @@
return;
# endif
- if (VG_(clo_trace_cfi)) {
+ if (si->trace_cfi) {
VG_(printf)("\n-----------------------------------------------\n");
VG_(printf)("CFI info: szB %d, _avma %p, _image %p\n",
ehframe_sz, (void*)ehframe_avma, (void*)ehframe_image );
@@ -2734,12 +2741,12 @@
Figure out which it is. */
ciefde_start = data;
- if (VG_(clo_trace_cfi))
+ if (si->trace_cfi)
VG_(printf)("\ncie/fde.start = %p (ehframe_image + 0x%x)\n",
ciefde_start, ciefde_start - ehframe_image);
ciefde_len = read_UInt(data); data += sizeof(UInt);
- if (VG_(clo_trace_cfi))
+ if (si->trace_cfi)
VG_(printf)("cie/fde.length = %d\n", ciefde_len);
/* Apparently, if the .length field is zero, we are at the end
@@ -2754,7 +2761,7 @@
cie_pointer = read_UInt(data);
data += sizeof(UInt); /* XXX see XXX below */
- if (VG_(clo_trace_cfi))
+ if (si->trace_cfi)
VG_(printf)("cie.pointer = %d\n", cie_pointer);
/* If cie_pointer is zero, we've got a CIE; else it's an FDE. */
@@ -2765,7 +2772,7 @@
UChar* cie_augmentation;
/* --------- CIE --------- */
- if (VG_(clo_trace_cfi))
+ if (si->trace_cfi)
VG_(printf)("------ new CIE (#%d of 0 .. %d) ------\n",
n_CIEs, N_CIEs - 1);
@@ -2785,7 +2792,7 @@
the_CIEs[this_CIE].offset = ciefde_start - ehframe_image;
cie_version = read_UChar(data); data += sizeof(UChar);
- if (VG_(clo_trace_cfi))
+ if (si->trace_cfi)
VG_(printf)("cie.version = %d\n", (Int)cie_version);
if (cie_version != 1) {
how = "unexpected CIE version (not 1)";
@@ -2794,7 +2801,7 @@
cie_augmentation = data;
data += 1 + VG_(strlen)(cie_augmentation);
- if (VG_(clo_trace_cfi))
+ if (si->trace_cfi)
VG_(printf)("cie.augment = \"%s\"\n", cie_augmentation);
if (cie_augmentation[0] == 'e' && cie_augmentation[1] == 'h') {
@@ -2804,19 +2811,19 @@
the_CIEs[this_CIE].code_a_f = read_leb128( data, &nbytes, 0);
data += nbytes;
- if (VG_(clo_trace_cfi))
+ if (si->trace_cfi)
VG_(printf)("cie.code_af = %d\n",
the_CIEs[this_CIE].code_a_f);
the_CIEs[this_CIE].data_a_f = read_leb128( data, &nbytes, 1);
data += nbytes;
- if (VG_(clo_trace_cfi))
+ if (si->trace_cfi)
VG_(printf)("cie.data_af = %d\n",
the_CIEs[this_CIE].data_a_f);
the_CIEs[this_CIE].ra_reg = (Int)read_UChar(data);
data += sizeof(UChar);
- if (VG_(clo_trace_cfi))
+ if (si->trace_cfi)
VG_(printf)("cie.ra_reg = %d\n",
the_CIEs[this_CIE].ra_reg);
if (the_CIEs[this_CIE].ra_reg < 0
@@ -2869,14 +2876,14 @@
done_augmentation:
- if (VG_(clo_trace_cfi))
+ if (si->trace_cfi)
VG_(printf)("cie.encoding = 0x%x\n",
the_CIEs[this_CIE].address_encoding);
the_CIEs[this_CIE].instrs = data;
the_CIEs[this_CIE].ilen
= ciefde_start + ciefde_len + sizeof(UInt) - data;
- if (VG_(clo_trace_cfi)) {
+ if (si->trace_cfi) {
VG_(printf)("cie.instrs = %p\n", the_CIEs[this_CIE].instrs);
VG_(printf)("cie.ilen = %d\n", the_CIEs[this_CIE].ilen);
}
@@ -2889,7 +2896,7 @@
data += the_CIEs[this_CIE].ilen;
- if (VG_(clo_trace_cfi)) {
+ if (si->trace_cfi) {
AddressDecodingInfo adi;
adi.encoding = the_CIEs[this_CIE].address_encoding;
adi.ehframe_image = ehframe_image;
@@ -2936,7 +2943,7 @@
adi.ehframe_avma = ehframe_avma;
fde_initloc = read_encoded_Addr(&nbytes, &adi, data);
data += nbytes;
- if (VG_(clo_trace_cfi))
+ if (si->trace_cfi)
VG_(printf)("fde.initloc = %p\n", (void*)fde_initloc);
adi.encoding = the_CIEs[cie].address_encoding & 0xf;
@@ -2944,7 +2951,7 @@
adi.ehframe_avma = ehframe_avma;
fde_arange = read_encoded_Addr(&nbytes, &adi, data);
data += nbytes;
- if (VG_(clo_trace_cfi))
+ if (si->trace_cfi)
VG_(printf)("fde.arangec = %p\n", (void*)fde_arange);
if (the_CIEs[cie].saw_z_augmentation) {
@@ -2954,7 +2961,7 @@
fde_instrs = data;
fde_ilen = ciefde_start + ciefde_len + sizeof(UInt) - data;
- if (VG_(clo_trace_cfi)) {
+ if (si->trace_cfi) {
VG_(printf)("fde.instrs = %p\n", fde_instrs);
VG_(printf)("fde.ilen = %d\n", (Int)fde_ilen);
}
@@ -2970,7 +2977,7 @@
adi.ehframe_image = ehframe_image;
adi.ehframe_avma = ehframe_avma;
- if (VG_(clo_trace_cfi))
+ if (si->trace_cfi)
show_CF_instructions(fde_instrs, fde_ilen, &adi);
initUnwindContext(&ctx);
diff --git a/coregrind/m_debuginfo/readelf.c b/coregrind/m_debuginfo/readelf.c
index 701936d..b540620 100644
--- a/coregrind/m_debuginfo/readelf.c
+++ b/coregrind/m_debuginfo/readelf.c
@@ -419,7 +419,7 @@
sym_name = (Char*)(o_strtab + sym->st_name);
sym_addr = o_symtab_offset + sym->st_value;
- if (VG_(clo_trace_symtab))
+ if (si->trace_symtab)
show_raw_elf_symbol(i, sym, sym_name, sym_addr, False);
if (get_elf_symbol_info(si, sym, sym_name, sym_addr,
@@ -438,7 +438,7 @@
vg_assert(risym.tocptr == 0); /* has no role except on ppc64-linux */
ML_(addSym) ( si, &risym );
- if (VG_(clo_trace_symtab)) {
+ if (si->trace_symtab) {
VG_(printf)(" record [%4d]: "
" val %010p, sz %4d %s\n",
i, (void*)risym.addr, (Int)risym.size,
@@ -527,7 +527,7 @@
sym_name = (Char*)(o_strtab + sym->st_name);
sym_addr = o_symtab_offset + sym->st_value;
- if (VG_(clo_trace_symtab))
+ if (si->trace_symtab)
show_raw_elf_symbol(i, sym, sym_name, sym_addr, True);
if (get_elf_symbol_info(si, sym, sym_name, sym_addr,
@@ -580,7 +580,7 @@
/* Only one or the other is possible (I think) */
vg_assert(!(modify_size && modify_tocptr));
- if (modify_size && VG_(clo_trace_symtab)) {
+ if (modify_size && si->trace_symtab) {
VG_(printf)(" modify (old sz %4d) "
" val %010p, toc %010p, sz %4d %s\n",
old_size,
@@ -590,7 +590,7 @@
(HChar*)prev->key.name
);
}
- if (modify_tocptr && VG_(clo_trace_symtab)) {
+ if (modify_tocptr && si->trace_symtab) {
VG_(printf)(" modify (upd tocptr) "
" val %010p, toc %010p, sz %4d %s\n",
(void*) prev->key.addr,
@@ -610,7 +610,7 @@
elem->size = sym_size;
elem->from_opd = from_opd;
VG_(OSet_Insert)(oset, elem);
- if (VG_(clo_trace_symtab)) {
+ if (si->trace_symtab) {
VG_(printf)(" to-oset [%4d]: "
" val %010p, toc %010p, sz %4d %s\n",
i, (void*) elem->key.addr,
@@ -638,7 +638,7 @@
vg_assert(risym.name != NULL);
ML_(addSym) ( si, &risym );
- if (VG_(clo_trace_symtab)) {
+ if (si->trace_symtab) {
VG_(printf)(" record [%4d]: "
" val %010p, toc %010p, sz %4d %s\n",
i, (void*) risym.addr,
@@ -1013,35 +1013,35 @@
/* Find interesting sections, read the symbol table(s), read any debug
information */
{
- /* Pointers to start of sections (in the oimage, not in the
- running image) -- image addresses */
- UChar* o_strtab = NULL; /* .strtab */
- ElfXX_Sym* o_symtab = NULL; /* .symtab */
- UChar* o_dynstr = NULL; /* .dynstr */
- ElfXX_Sym* o_dynsym = NULL; /* .dynsym */
- Char* debuglink = NULL; /* .gnu_debuglink */
- UChar* stab = NULL; /* .stab (stabs) */
- UChar* stabstr = NULL; /* .stabstr (stabs) */
- UChar* debug_line = NULL; /* .debug_line (dwarf2) */
- UChar* debug_info = NULL; /* .debug_info (dwarf2) */
- UChar* debug_abbv = NULL; /* .debug_abbrev (dwarf2) */
- UChar* debug_str = NULL; /* .debug_str (dwarf2) */
- UChar* dwarf1d = NULL; /* .debug (dwarf1) */
- UChar* dwarf1l = NULL; /* .line (dwarf1) */
- UChar* ehframe = NULL; /* .eh_frame (dwarf2) */
- UChar* opd_filea = NULL; /* .opd (dwarf2, ppc64-linux) */
- UChar* dummy_filea = NULL;
+ /* IMAGE addresses: pointers to start of sections (in the
+ oimage, not in the running image) -- image addresses */
+ UChar* strtab_img = NULL; /* .strtab */
+ ElfXX_Sym* symtab_img = NULL; /* .symtab */
+ UChar* dynstr_img = NULL; /* .dynstr */
+ ElfXX_Sym* dynsym_img = NULL; /* .dynsym */
+ Char* debuglink_img = NULL; /* .gnu_debuglink */
+ UChar* stab_img = NULL; /* .stab (stabs) */
+ UChar* stabstr_img = NULL; /* .stabstr (stabs) */
+ UChar* debug_line_img = NULL; /* .debug_line (dwarf2) */
+ UChar* debug_info_img = NULL; /* .debug_info (dwarf2) */
+ UChar* debug_abbv_img = NULL; /* .debug_abbrev (dwarf2) */
+ UChar* debug_str_img = NULL; /* .debug_str (dwarf2) */
+ UChar* dwarf1d_img = NULL; /* .debug (dwarf1) */
+ UChar* dwarf1l_img = NULL; /* .line (dwarf1) */
+ UChar* ehframe_img = NULL; /* .eh_frame (dwarf2) */
+ UChar* opd_filea_img = NULL; /* .opd (dwarf2, ppc64-linux) */
+ UChar* dummy_filea_img = NULL;
- OffT o_symtab_offset = offset_oimage;
- OffT o_dynsym_offset = offset_oimage;
+ OffT symtab_offset = offset_oimage;
+ OffT dynsym_offset = offset_oimage;
OffT debug_offset = offset_oimage;
OffT opd_offset = offset_oimage;
/* Section sizes, in bytes */
- UInt o_strtab_sz = 0;
- UInt o_symtab_sz = 0;
- UInt o_dynstr_sz = 0;
- UInt o_dynsym_sz = 0;
+ UInt strtab_sz = 0;
+ UInt symtab_sz = 0;
+ UInt dynstr_sz = 0;
+ UInt dynsym_sz = 0;
UInt debuglink_sz = 0;
UInt stab_sz = 0;
UInt stabstr_sz = 0;
@@ -1093,45 +1093,46 @@
/* Nb: must find where .got and .plt sections will be in the
* executable image, not in the object image transiently loaded. */
- /* NAME SIZE ADDR_IN_OIMAGE ADDR_WHEN_MAPPED */
- FIND(".dynsym", o_dynsym_sz, o_dynsym, dummy_avma)
- FIND(".dynstr", o_dynstr_sz, o_dynstr, dummy_avma)
- FIND(".symtab", o_symtab_sz, o_symtab, dummy_avma)
- FIND(".strtab", o_strtab_sz, o_strtab, dummy_avma)
+ /* NAME SIZE IMAGE addr AVMA */
+ FIND(".dynsym", dynsym_sz, dynsym_img, dummy_avma)
+ FIND(".dynstr", dynstr_sz, dynstr_img, dummy_avma)
+ FIND(".symtab", symtab_sz, symtab_img, dummy_avma)
+ FIND(".strtab", strtab_sz, strtab_img, dummy_avma)
- FIND(".gnu_debuglink", debuglink_sz, debuglink, dummy_avma)
+ FIND(".gnu_debuglink", debuglink_sz, debuglink_img, dummy_avma)
- FIND(".stab", stab_sz, stab, dummy_avma)
- FIND(".stabstr", stabstr_sz, stabstr, dummy_avma)
+ FIND(".stab", stab_sz, stab_img, dummy_avma)
+ FIND(".stabstr", stabstr_sz, stabstr_img, dummy_avma)
- FIND(".debug_line", debug_line_sz, debug_line, dummy_avma)
- FIND(".debug_info", debug_info_sz, debug_info, dummy_avma)
- FIND(".debug_abbrev", debug_abbv_sz, debug_abbv, dummy_avma)
- FIND(".debug_str", debug_str_sz, debug_str, dummy_avma)
+ FIND(".debug_line", debug_line_sz, debug_line_img, dummy_avma)
+ FIND(".debug_info", debug_info_sz, debug_info_img, dummy_avma)
+ FIND(".debug_abbrev", debug_abbv_sz, debug_abbv_img, dummy_avma)
+ FIND(".debug_str", debug_str_sz, debug_str_img, dummy_avma)
- FIND(".debug", dwarf1d_sz, dwarf1d, dummy_avma)
- FIND(".line", dwarf1l_sz, dwarf1l, dummy_avma)
- FIND(".eh_frame", ehframe_sz, ehframe, ehframe_avma)
+ FIND(".debug", dwarf1d_sz, dwarf1d_img, dummy_avma)
+ FIND(".line", dwarf1l_sz, dwarf1l_img, dummy_avma)
+ FIND(".eh_frame", ehframe_sz, ehframe_img, ehframe_avma)
- FIND(".got", si->got_size, dummy_filea, si->got_start_avma)
- FIND(".plt", si->plt_size, dummy_filea, si->plt_start_avma)
- FIND(".opd", si->opd_size, opd_filea, si->opd_start_avma)
+ FIND(".got", si->got_size, dummy_filea_img, si->got_start_avma)
+ FIND(".plt", si->plt_size, dummy_filea_img, si->plt_start_avma)
+ FIND(".opd", si->opd_size, opd_filea_img, si->opd_start_avma)
# undef FIND
}
/* Did we find a debuglink section? */
- if (debuglink != NULL) {
- UInt crc_offset = VG_ROUNDUP(VG_(strlen)(debuglink)+1, 4);
+ if (debuglink_img != NULL) {
+ UInt crc_offset = VG_ROUNDUP(VG_(strlen)(debuglink_img)+1, 4);
UInt crc;
vg_assert(crc_offset + sizeof(UInt) <= debuglink_sz);
/* Extract the CRC from the debuglink section */
- crc = *(UInt *)(debuglink + crc_offset);
+ crc = *(UInt *)(debuglink_img + crc_offset);
/* See if we can find a matching debug file */
- if ((dimage = find_debug_file(si->filename, debuglink, crc, &n_dimage)) != 0) {
+ dimage = find_debug_file(si->filename, debuglink_img, crc, &n_dimage);
+ if (dimage != 0) {
ehdr = (ElfXX_Ehdr*)dimage;
if (n_dimage >= sizeof(ElfXX_Ehdr)
@@ -1139,7 +1140,7 @@
&& ehdr->e_phoff + ehdr->e_phnum*sizeof(ElfXX_Phdr) <= n_dimage
&& ehdr->e_shoff + ehdr->e_shnum*sizeof(ElfXX_Shdr) <= n_dimage)
{
- Bool need_symtab = (NULL == o_symtab);
+ Bool need_symtab = (NULL == symtab_img);
for (i = 0; i < ehdr->e_phnum; i++) {
ElfXX_Phdr *o_phdr = &((ElfXX_Phdr *)(dimage + ehdr->e_phoff))[i];
@@ -1151,7 +1152,7 @@
debug_offset = offset_dimage;
if (need_symtab)
- o_symtab_offset = offset_dimage;
+ symtab_offset = offset_dimage;
shdr = (ElfXX_Shdr*)(dimage + ehdr->e_shoff);
sh_strtab = (UChar*)(dimage + shdr[ehdr->e_shstrndx].sh_offset);
@@ -1181,17 +1182,17 @@
} \
}
- /* ?? NAME SIZE ADDR_IN_OIMAGE */
- FIND(need_symtab, ".symtab", o_symtab_sz, o_symtab)
- FIND(need_symtab, ".strtab", o_strtab_sz, o_strtab)
- FIND(1, ".stab", stab_sz, stab)
- FIND(1, ".stabstr", stabstr_sz, stabstr)
- FIND(1, ".debug_line", debug_line_sz, debug_line)
- FIND(1, ".debug_info", debug_info_sz, debug_info)
- FIND(1, ".debug_abbrev", debug_abbv_sz, debug_abbv)
- FIND(1, ".debug_str", debug_str_sz, debug_str)
- FIND(1, ".debug", dwarf1d_sz, dwarf1d)
- FIND(1, ".line", dwarf1l_sz, dwarf1l)
+ /* ?? NAME SIZE IMAGE addr */
+ FIND(need_symtab, ".symtab", symtab_sz, symtab_img)
+ FIND(need_symtab, ".strtab", strtab_sz, strtab_img)
+ FIND(1, ".stab", stab_sz, stab_img)
+ FIND(1, ".stabstr", stabstr_sz, stabstr_img)
+ FIND(1, ".debug_line", debug_line_sz, debug_line_img)
+ FIND(1, ".debug_info", debug_info_sz, debug_info_img)
+ FIND(1, ".debug_abbrev", debug_abbv_sz, debug_abbv_img)
+ FIND(1, ".debug_str", debug_str_sz, debug_str_img)
+ FIND(1, ".debug", dwarf1d_sz, dwarf1d_img)
+ FIND(1, ".line", dwarf1l_sz, dwarf1l_img)
# undef FIND
}
@@ -1200,8 +1201,8 @@
}
/* Check some sizes */
- vg_assert((o_dynsym_sz % sizeof(ElfXX_Sym)) == 0);
- vg_assert((o_symtab_sz % sizeof(ElfXX_Sym)) == 0);
+ vg_assert((dynsym_sz % sizeof(ElfXX_Sym)) == 0);
+ vg_assert((symtab_sz % sizeof(ElfXX_Sym)) == 0);
/* Read symbols */
{
@@ -1213,27 +1214,29 @@
read_elf_symtab = read_elf_symtab__normal;
# endif
read_elf_symtab(si, "symbol table",
- o_symtab, o_symtab_sz, o_symtab_offset,
- o_strtab, o_strtab_sz, opd_filea, opd_offset);
+ symtab_img, symtab_sz, symtab_offset,
+ strtab_img, strtab_sz,
+ opd_filea_img, opd_offset);
read_elf_symtab(si, "dynamic symbol table",
- o_dynsym, o_dynsym_sz, o_dynsym_offset,
- o_dynstr, o_dynstr_sz, opd_filea, opd_offset);
+ dynsym_img, dynsym_sz, dynsym_offset,
+ dynstr_img, dynstr_sz,
+ opd_filea_img, opd_offset);
}
/* Read .eh_frame (call-frame-info) if any */
- if (ehframe) {
+ if (ehframe_img) {
ML_(read_callframe_info_dwarf2)
- ( si, ehframe/*image*/, ehframe_sz, ehframe_avma );
+ ( si, ehframe_img, ehframe_sz, ehframe_avma );
}
/* Read the stabs and/or dwarf2 debug information, if any. It
appears reading stabs stuff on amd64-linux doesn't work, so
we ignore it. */
# if !defined(VGP_amd64_linux)
- if (stab && stabstr) {
- ML_(read_debuginfo_stabs) ( si, debug_offset, stab, stab_sz,
- stabstr, stabstr_sz );
+ if (stab_img && stabstr_img) {
+ ML_(read_debuginfo_stabs) ( si, debug_offset, stab_img, stab_sz,
+ stabstr_img, stabstr_sz );
}
# endif
/* jrs 2006-01-01: icc-8.1 has been observed to generate
@@ -1241,16 +1244,17 @@
debuginfo reading for that reason, but, in
read_unitinfo_dwarf2, do check that debugstr is non-NULL
before using it. */
- if (debug_info && debug_abbv && debug_line /* && debug_str */) {
+ if (debug_info_img && debug_abbv_img && debug_line_img
+ /* && debug_str_img */) {
ML_(read_debuginfo_dwarf2) ( si, debug_offset,
- debug_info, debug_info_sz,
- debug_abbv,
- debug_line, debug_line_sz,
- debug_str );
+ debug_info_img, debug_info_sz,
+ debug_abbv_img,
+ debug_line_img, debug_line_sz,
+ debug_str_img );
}
- if (dwarf1d && dwarf1l) {
- ML_(read_debuginfo_dwarf1) ( si, dwarf1d, dwarf1d_sz,
- dwarf1l, dwarf1l_sz );
+ if (dwarf1d_img && dwarf1l_img) {
+ ML_(read_debuginfo_dwarf1) ( si, dwarf1d_img, dwarf1d_sz,
+ dwarf1l_img, dwarf1l_sz );
}
}
res = True;
diff --git a/coregrind/m_debuginfo/storage.c b/coregrind/m_debuginfo/storage.c
index aef37f4..4f3095f 100644
--- a/coregrind/m_debuginfo/storage.c
+++ b/coregrind/m_debuginfo/storage.c
@@ -397,7 +397,7 @@
so we can misdescribe memcmp() as bcmp()). This is hard to avoid.
It's mentioned in the FAQ file.
*/
-static DiSym* prefersym ( DiSym* a, DiSym* b )
+static DiSym* prefersym ( struct _SegInfo* si, DiSym* a, DiSym* b )
{
Int lena, lenb; /* full length */
Int vlena, vlenb; /* length without version */
@@ -476,7 +476,7 @@
n_merged++;
/* merge the two into one */
si->symtab[si->symtab_used++]
- = *prefersym(&si->symtab[i], &si->symtab[i+1]);
+ = *prefersym(si, &si->symtab[i], &si->symtab[i+1]);
i++;
} else {
si->symtab[si->symtab_used++] = si->symtab[i];
@@ -499,7 +499,7 @@
continue;
/* There's an overlap. Truncate one or the other. */
- if (VG_(clo_trace_symtab)) {
+ if (si->trace_symtab) {
VG_(printf)("overlapping address ranges in symbol table\n\t");
ML_(ppSym)( i, &si->symtab[i] );
VG_(printf)("\t");
@@ -683,7 +683,7 @@
si->cfsi_maxaddr = here_max;
}
- if (VG_(clo_trace_cfi))
+ if (si->trace_cfi)
VG_(printf)("canonicaliseCfiSI: %d entries, %p .. %p\n",
si->cfsi_used,
si->cfsi_minaddr, si->cfsi_maxaddr);
diff --git a/coregrind/m_main.c b/coregrind/m_main.c
index 8e38b9b..5c5c564 100644
--- a/coregrind/m_main.c
+++ b/coregrind/m_main.c
@@ -159,7 +159,11 @@
" --trace-syscalls=no|yes show all system calls? [no]\n"
" --trace-signals=no|yes show signal handling details? [no]\n"
" --trace-symtab=no|yes show symbol table details? [no]\n"
+" --trace-symtab-patt=<patt> limit debuginfo tracing to obj name <patt>\n"
" --trace-cfi=no|yes show call-frame-info details? [no]\n"
+" --debug-dump=syms mimic /usr/bin/readelf --syms\n"
+" --debug-dump=line mimic /usr/bin/readelf --debug-dump=line\n"
+" --debug-dump=frames mimic /usr/bin/readelf --debug-dump=frames\n"
" --trace-redir=no|yes show redirection details? [no]\n"
" --trace-sched=no|yes show thread scheduler details? [no]\n"
" --wait-for-gdb=yes|no pause on startup to wait for gdb attach\n"
@@ -352,12 +356,16 @@
else VG_BOOL_CLO(arg, "--trace-sched", VG_(clo_trace_sched))
else VG_BOOL_CLO(arg, "--trace-signals", VG_(clo_trace_signals))
else VG_BOOL_CLO(arg, "--trace-symtab", VG_(clo_trace_symtab))
+ else VG_STR_CLO (arg, "--trace-symtab-patt", VG_(clo_trace_symtab_patt))
else VG_BOOL_CLO(arg, "--trace-cfi", VG_(clo_trace_cfi))
+ else VG_XACT_CLO(arg, "--debug-dump=syms", VG_(clo_debug_dump_syms))
+ else VG_XACT_CLO(arg, "--debug-dump=line", VG_(clo_debug_dump_line))
+ else VG_XACT_CLO(arg, "--debug-dump=frames", VG_(clo_debug_dump_frames))
else VG_BOOL_CLO(arg, "--trace-redir", VG_(clo_trace_redir))
+
else VG_BOOL_CLO(arg, "--trace-syscalls", VG_(clo_trace_syscalls))
else VG_BOOL_CLO(arg, "--trace-pthreads", VG_(clo_trace_pthreads))
else VG_BOOL_CLO(arg, "--wait-for-gdb", VG_(clo_wait_for_gdb))
-
else VG_STR_CLO (arg, "--db-command", VG_(clo_db_command))
else VG_STR_CLO (arg, "--sim-hints", VG_(clo_sim_hints))
else VG_BOOL_CLO(arg, "--sym-offsets", VG_(clo_sym_offsets))
diff --git a/coregrind/m_options.c b/coregrind/m_options.c
index 3ec68d5..030f78c 100644
--- a/coregrind/m_options.c
+++ b/coregrind/m_options.c
@@ -63,7 +63,11 @@
Bool VG_(clo_trace_syscalls) = False;
Bool VG_(clo_trace_signals) = False;
Bool VG_(clo_trace_symtab) = False;
+HChar* VG_(clo_trace_symtab_patt) = "*";
Bool VG_(clo_trace_cfi) = False;
+Bool VG_(clo_debug_dump_syms) = False;
+Bool VG_(clo_debug_dump_line) = False;
+Bool VG_(clo_debug_dump_frames) = False;
Bool VG_(clo_trace_redir) = False;
Bool VG_(clo_trace_sched) = False;
Bool VG_(clo_trace_pthreads) = False;
diff --git a/coregrind/pub_core_options.h b/coregrind/pub_core_options.h
index 60bd58c..0d0cb5a 100644
--- a/coregrind/pub_core_options.h
+++ b/coregrind/pub_core_options.h
@@ -112,8 +112,16 @@
extern Bool VG_(clo_trace_signals);
/* DEBUG: print symtab details? default: NO */
extern Bool VG_(clo_trace_symtab);
+/* DEBUG: restrict symtab etc details to object name pattern. Default: "*" */
+extern HChar* VG_(clo_trace_symtab_patt);
/* DEBUG: print call-frame-info details? default: NO */
extern Bool VG_(clo_trace_cfi);
+/* DEBUG: mimic /usr/bin/readelf --syms? default: NO */
+extern Bool VG_(clo_debug_dump_syms);
+/* DEBUG: mimic /usr/bin/readelf --debug-dump=line? default: NO */
+extern Bool VG_(clo_debug_dump_line);
+/* DEBUG: mimic /usr/bin/readelf --debug-dump=frames? default: NO */
+extern Bool VG_(clo_debug_dump_frames);
/* DEBUG: print redirection details? default: NO */
extern Bool VG_(clo_trace_redir);
/* DEBUG: print thread scheduling events? default: NO */
diff --git a/include/pub_tool_options.h b/include/pub_tool_options.h
index cbd97c0..00c7bcb 100644
--- a/include/pub_tool_options.h
+++ b/include/pub_tool_options.h
@@ -63,6 +63,12 @@
if ((qq_var) > (qq_hi)) (qq_var) = (qq_hi); \
}
+/* Bool arg whose value is denoted by the exact presence of the given string. */
+#define VG_XACT_CLO(qq_arg, qq_option, qq_var) \
+ if (VG_CLO_STREQ(qq_arg, qq_option)) { \
+ (qq_var) = True; \
+ } /* else leave it alone */
+
/* Verbosity level: 0 = silent, 1 (default), > 1 = more verbose. */
extern Int VG_(clo_verbosity);