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.
*/
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;
? 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;
}
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 --------------------- */
#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 */
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;
static
void read_dwarf2_lineblock ( struct _SegInfo* si, OffT debug_offset,
UnitInfo* ui,
- UChar* theBlock,
+ UChar* theBlock, /* IMAGE */
Int noLargerThan )
{
DebugLineInfo info;
*/
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;
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;
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;
}
/* 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++;
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;
/* 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;
*/
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;
}
/* 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;
/* 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 );
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 );
}
}
*/
static Bool summarise_context( /*OUT*/DiCfSI* si,
Addr loc_start,
- UnwindContext* ctx )
+ UnwindContext* ctx,
+ struct _SegInfo* seginfo )
{
Int why = 0;
initCfiSI(si);
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);
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;
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 );
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 );
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 );
/* 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)(
si->text_bias + cfsi->base + cfsi->len - 1
);
}
- if (VG_(clo_trace_cfi))
+ if (si->trace_cfi)
ML_(ppDiCfSI)(cfsi);
}
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);
}
}
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);
}
}
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 );
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
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. */
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);
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)";
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') {
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
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);
}
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;
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;
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) {
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);
}
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);
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,
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,
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,
/* 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,
(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,
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,
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,
/* 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;
-
- OffT o_symtab_offset = offset_oimage;
- OffT o_dynsym_offset = offset_oimage;
+ /* 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 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;
/* 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)
&& 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];
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);
} \
}
- /* ?? 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
}
}
/* 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 */
{
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
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;
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 */
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];
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");
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);
" --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"
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))
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;
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 */
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);