From: Julian Seward Date: Mon, 12 Feb 2007 17:47:14 +0000 (+0000) Subject: Essentially non-functional tidyings and improvements to debuginfo X-Git-Tag: svn/VALGRIND_3_3_0~376 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0dfa20858885a64142ff952b8b7117435e16ae1e;p=thirdparty%2Fvalgrind.git 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= 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 --- diff --git a/coregrind/m_debuginfo/debuginfo.c b/coregrind/m_debuginfo/debuginfo.c index f651720536..1477efc4a2 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 @@ SegInfo* alloc_SegInfo(Addr start, SizeT size, OffT foffset, 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 @@ SegInfo* alloc_SegInfo(Addr start, SizeT size, OffT 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; } diff --git a/coregrind/m_debuginfo/priv_storage.h b/coregrind/m_debuginfo/priv_storage.h index c0618dc524..dcd488784f 100644 --- a/coregrind/m_debuginfo/priv_storage.h +++ b/coregrind/m_debuginfo/priv_storage.h @@ -194,6 +194,16 @@ struct _SegInfo { 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 @@ extern void ML_(ppDiCfSI) ( DiCfSI* si ); #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 9288df0b5c..58ec6652a1 100644 --- a/coregrind/m_debuginfo/readdwarf.c +++ b/coregrind/m_debuginfo/readdwarf.c @@ -253,12 +253,12 @@ static Int read_leb128S( UChar **data ) 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 @@ Int process_extended_line_op( struct _SegInfo* si, OffT debug_offset, 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 UChar* lookup_abbrev( UChar* p, UInt acode ) */ 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 @@ void read_unitinfo_dwarf2( /*OUT*/UnitInfo* ui, 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 @@ void read_unitinfo_dwarf2( /*OUT*/UnitInfo* ui, 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 @@ void read_unitinfo_dwarf2( /*OUT*/UnitInfo* ui, } /* 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 @@ void read_unitinfo_dwarf2( /*OUT*/UnitInfo* ui, 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 @@ void read_unitinfo_dwarf2( /*OUT*/UnitInfo* ui, /* 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 read_unitinfo_dwarf2( /*OUT*/UnitInfo* ui, */ 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 @@ void ML_(read_debuginfo_dwarf2) } /* 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 @@ void ML_(read_debuginfo_dwarf2) /* 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 @@ void ML_(read_debuginfo_dwarf2) 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 void initCfiSI ( DiCfSI* si ) */ 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 @@ static Bool summarise_context( /*OUT*/DiCfSI* 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); @@ -2042,7 +2048,8 @@ static Addr read_encoded_Addr ( /*OUT*/Int* nbytes, 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 @@ static Int run_CF_instruction ( /*MOD*/UnwindContext* ctx, 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 @@ static Int run_CF_instruction ( /*MOD*/UnwindContext* ctx, 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 @@ static Int run_CF_instruction ( /*MOD*/UnwindContext* ctx, 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 @@ void kludge_then_addDiCfSI ( struct _SegInfo* si, DiCfSI* cfsi ) /* 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 @@ void kludge_then_addDiCfSI ( struct _SegInfo* si, DiCfSI* cfsi ) si->text_bias + cfsi->base + cfsi->len - 1 ); } - if (VG_(clo_trace_cfi)) + if (si->trace_cfi) ML_(ppDiCfSI)(cfsi); } @@ -2605,16 +2612,16 @@ Bool run_CF_instructions ( struct _SegInfo* si, 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 @@ Bool run_CF_instructions ( struct _SegInfo* si, 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 @@ void ML_(read_callframe_info_dwarf2) 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 @@ void ML_(read_callframe_info_dwarf2) 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 @@ void ML_(read_callframe_info_dwarf2) 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 @@ void ML_(read_callframe_info_dwarf2) 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 @@ void ML_(read_callframe_info_dwarf2) 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 @@ void ML_(read_callframe_info_dwarf2) 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 @@ void ML_(read_callframe_info_dwarf2) 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 @@ void ML_(read_callframe_info_dwarf2) 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 @@ void ML_(read_callframe_info_dwarf2) 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 @@ void ML_(read_callframe_info_dwarf2) 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 @@ void ML_(read_callframe_info_dwarf2) 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 @@ void ML_(read_callframe_info_dwarf2) 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 @@ void ML_(read_callframe_info_dwarf2) 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 701936dacd..b540620ce9 100644 --- a/coregrind/m_debuginfo/readelf.c +++ b/coregrind/m_debuginfo/readelf.c @@ -419,7 +419,7 @@ void read_elf_symtab__normal( 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 @@ void read_elf_symtab__normal( 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 @@ void read_elf_symtab__ppc64_linux( 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 @@ void read_elf_symtab__ppc64_linux( /* 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 @@ void read_elf_symtab__ppc64_linux( (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 @@ void read_elf_symtab__ppc64_linux( 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 @@ void read_elf_symtab__ppc64_linux( 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 @@ Bool ML_(read_elf_debug_info) ( struct _SegInfo* si ) /* 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; @@ -1093,45 +1093,46 @@ Bool ML_(read_elf_debug_info) ( struct _SegInfo* si ) /* 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 @@ Bool ML_(read_elf_debug_info) ( struct _SegInfo* si ) && 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 @@ Bool ML_(read_elf_debug_info) ( struct _SegInfo* si ) 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 @@ Bool ML_(read_elf_debug_info) ( struct _SegInfo* si ) } \ } - /* ?? 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 @@ Bool ML_(read_elf_debug_info) ( struct _SegInfo* si ) } /* 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 @@ Bool ML_(read_elf_debug_info) ( struct _SegInfo* si ) 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 @@ Bool ML_(read_elf_debug_info) ( struct _SegInfo* si ) 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 aef37f4b1a..4f3095f92f 100644 --- a/coregrind/m_debuginfo/storage.c +++ b/coregrind/m_debuginfo/storage.c @@ -397,7 +397,7 @@ static Int compare_DiSym ( void* va, void* vb ) 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 @@ static void canonicaliseSymtab ( struct _SegInfo* si ) 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 @@ static void canonicaliseSymtab ( struct _SegInfo* si ) 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 @@ static void canonicaliseCFI ( struct _SegInfo* si ) 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 8e38b9b286..5c5c564d34 100644 --- a/coregrind/m_main.c +++ b/coregrind/m_main.c @@ -159,7 +159,11 @@ static void usage_NORETURN ( Bool debug_help ) " --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= limit debuginfo tracing to obj name \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 @@ static Bool process_cmd_line_options( UInt* client_auxv, const char* toolname ) 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 3ec68d59a0..030f78c70d 100644 --- a/coregrind/m_options.c +++ b/coregrind/m_options.c @@ -63,7 +63,11 @@ Int VG_(clo_trace_notbelow) = 999999999; 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 60bd58cdab..0d0cb5a863 100644 --- a/coregrind/pub_core_options.h +++ b/coregrind/pub_core_options.h @@ -112,8 +112,16 @@ extern Bool VG_(clo_trace_syscalls); 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 cbd97c073c..00c7bcba89 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);