From 4fd4a7f8d7e29be64f7fea0c324622f4ccb16e4b Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Jul 25 2012 12:43:24 +0000 Subject: 3.7.0-6 handle dwz DWARF compressor output (#842659, KDE#302901) --- diff --git a/valgrind-3.7.0-dwz.patch b/valgrind-3.7.0-dwz.patch new file mode 100644 index 0000000..92e5e03 --- /dev/null +++ b/valgrind-3.7.0-dwz.patch @@ -0,0 +1,909 @@ +diff -ru valgrind-3.7.0.orig/config.h valgrind-3.7.0/config.h +--- valgrind-3.7.0.orig/config.h 2012-07-25 12:33:29.212949007 +0200 ++++ valgrind-3.7.0/config.h 2012-07-25 12:44:42.847307554 +0200 +@@ -29,7 +29,7 @@ + /* #undef GLIBC_2_10 */ + + /* Define to 1 if you're using glibc 2.11.x */ +-#define GLIBC_2_11 1 ++/* #undef GLIBC_2_11 */ + + /* Define to 1 if you're using glibc 2.12.x */ + /* #undef GLIBC_2_12 */ +@@ -38,7 +38,10 @@ + /* #undef GLIBC_2_13 */ + + /* Define to 1 if you're using glibc 2.14.x */ +-/* #undef GLIBC_2_14 */ ++#define GLIBC_2_14 1 ++ ++/* Define to 1 if you're using glibc 2.15.x */ ++/* #undef GLIBC_2_15 */ + + /* Define to 1 if you're using glibc 2.2.x */ + /* #undef GLIBC_2_2 */ +diff -ru valgrind-3.7.0.orig/coregrind/m_debuginfo/d3basics.c valgrind-3.7.0/coregrind/m_debuginfo/d3basics.c +--- valgrind-3.7.0.orig/coregrind/m_debuginfo/d3basics.c 2012-07-25 12:33:29.191948686 +0200 ++++ valgrind-3.7.0/coregrind/m_debuginfo/d3basics.c 2012-07-25 12:44:30.217112438 +0200 +@@ -180,6 +180,8 @@ + case DW_FORM_exprloc: return "DW_FORM_exprloc"; + case DW_FORM_flag_present:return "DW_FORM_flag_present"; + case DW_FORM_ref_sig8: return "DW_FORM_ref_sig8"; ++ case DW_FORM_GNU_ref_alt:return "DW_FORM_GNU_ref_alt"; ++ case DW_FORM_GNU_strp_alt:return "DW_FORM_GNU_strp_alt"; + default: return "DW_FORM_???"; + } + } +diff -ru valgrind-3.7.0.orig/coregrind/m_debuginfo/debuginfo.c valgrind-3.7.0/coregrind/m_debuginfo/debuginfo.c +--- valgrind-3.7.0.orig/coregrind/m_debuginfo/debuginfo.c 2012-07-25 12:33:29.191948686 +0200 ++++ valgrind-3.7.0/coregrind/m_debuginfo/debuginfo.c 2012-07-25 12:44:30.219112468 +0200 +@@ -859,7 +859,7 @@ + + /* We're only interested in mappings of object files. */ + # if defined(VGO_linux) +- if (!ML_(is_elf_object_file)( buf1k, (SizeT)sr_Res(preadres) )) ++ if (!ML_(is_elf_object_file)( buf1k, (SizeT)sr_Res(preadres), False )) + return 0; + # elif defined(VGO_darwin) + if (!ML_(is_macho_object_file)( buf1k, (SizeT)sr_Res(preadres) )) +diff -ru valgrind-3.7.0.orig/coregrind/m_debuginfo/priv_d3basics.h valgrind-3.7.0/coregrind/m_debuginfo/priv_d3basics.h +--- valgrind-3.7.0.orig/coregrind/m_debuginfo/priv_d3basics.h 2012-07-25 12:33:29.192948701 +0200 ++++ valgrind-3.7.0/coregrind/m_debuginfo/priv_d3basics.h 2012-07-25 12:44:30.235112717 +0200 +@@ -199,7 +199,11 @@ + DW_FORM_sec_offset = 0x17, + DW_FORM_exprloc = 0x18, + DW_FORM_flag_present = 0x19, +- DW_FORM_ref_sig8 = 0x20 ++ DW_FORM_ref_sig8 = 0x20, ++ /* Extensions for DWZ multifile. ++ See http://www.dwarfstd.org/ShowIssue.php?issue=120604.1&type=open . */ ++ DW_FORM_GNU_ref_alt = 0x1f20, ++ DW_FORM_GNU_strp_alt = 0x1f21 + } + DW_FORM; + +diff -ru valgrind-3.7.0.orig/coregrind/m_debuginfo/priv_readdwarf3.h valgrind-3.7.0/coregrind/m_debuginfo/priv_readdwarf3.h +--- valgrind-3.7.0.orig/coregrind/m_debuginfo/priv_readdwarf3.h 2012-07-25 12:33:29.192948701 +0200 ++++ valgrind-3.7.0/coregrind/m_debuginfo/priv_readdwarf3.h 2012-07-25 12:44:30.237112747 +0200 +@@ -48,7 +48,11 @@ + UChar* debug_line_img, SizeT debug_line_sz, + UChar* debug_str_img, SizeT debug_str_sz, + UChar* debug_ranges_img, SizeT debug_ranges_sz, +- UChar* debug_loc_img, SizeT debug_loc_sz ++ UChar* debug_loc_img, SizeT debug_loc_sz, ++ UChar* debug_info_alt_img, SizeT debug_info_alt_sz, ++ UChar* debug_abbv_alt_img, SizeT debug_abbv_alt_sz, ++ UChar* debug_line_alt_img, SizeT debug_line_alt_sz, ++ UChar* debug_str_alt_img, SizeT debug_str_alt_sz + ); + + #endif /* ndef __PRIV_READDWARF3_H */ +diff -ru valgrind-3.7.0.orig/coregrind/m_debuginfo/priv_readdwarf.h valgrind-3.7.0/coregrind/m_debuginfo/priv_readdwarf.h +--- valgrind-3.7.0.orig/coregrind/m_debuginfo/priv_readdwarf.h 2012-07-25 12:33:29.192948701 +0200 ++++ valgrind-3.7.0/coregrind/m_debuginfo/priv_readdwarf.h 2012-07-25 12:44:30.238112762 +0200 +@@ -48,7 +48,8 @@ + UChar* debug_types_img, Word debug_types_sz, /* .debug_types */ + UChar* debug_abbv_img, Word debug_abbv_sz, /* .debug_abbrev */ + UChar* debug_line_img, Word debug_line_sz, /* .debug_line */ +- UChar* debug_str_img, Word debug_str_sz ); /* .debug_str */ ++ UChar* debug_str_img, Word debug_str_sz, /* .debug_str */ ++ UChar* debug_str_alt_img, Word debug_str_alt_sz ); /* .debug_str */ + + /* -------------------- + DWARF1 reader +diff -ru valgrind-3.7.0.orig/coregrind/m_debuginfo/priv_readelf.h valgrind-3.7.0/coregrind/m_debuginfo/priv_readelf.h +--- valgrind-3.7.0.orig/coregrind/m_debuginfo/priv_readelf.h 2012-07-25 12:33:29.192948701 +0200 ++++ valgrind-3.7.0/coregrind/m_debuginfo/priv_readelf.h 2012-07-25 12:44:30.239112777 +0200 +@@ -40,7 +40,7 @@ + + /* Identify an ELF object file by peering at the first few bytes of + it. */ +-extern Bool ML_(is_elf_object_file)( void* image, SizeT n_image ); ++extern Bool ML_(is_elf_object_file)( void* image, SizeT n_image, Bool rel_ok ); + + /* The central function for reading ELF debug info. For the + object/exe specified by the SegInfo, find ELF sections, then read +diff -ru valgrind-3.7.0.orig/coregrind/m_debuginfo/readdwarf3.c valgrind-3.7.0/coregrind/m_debuginfo/readdwarf3.c +--- valgrind-3.7.0.orig/coregrind/m_debuginfo/readdwarf3.c 2012-07-25 12:33:29.192948701 +0200 ++++ valgrind-3.7.0/coregrind/m_debuginfo/readdwarf3.c 2012-07-25 12:44:30.240112792 +0200 +@@ -420,6 +420,16 @@ + /* Where is .debug_types? */ + UChar* debug_types_img; + UWord debug_types_sz; ++ /* Where is alternate .debug_info? */ ++ UChar* debug_info_alt_img; ++ UWord debug_info_alt_sz; ++ /* Where is alternate .debug_str ? */ ++ UChar* debug_str_alt_img; ++ UWord debug_str_alt_sz; ++ /* How much to add to .debug_types resp. alternate .debug_info offsets ++ in cook_die*. */ ++ UWord types_cuOff_bias; ++ UWord alt_cuOff_bias; + /* --- Needed so we can add stuff to the string table. --- */ + struct _DebugInfo* di; + /* --- a cache for set_abbv_Cursor --- */ +@@ -440,40 +450,58 @@ + /* Signatured type hash; computed once and then shared by all + CUs. */ + VgHashTable signature_types; ++ ++ /* True if this came from alternate .debug_info; otherwise ++ it came from normal .debug_info or .debug_types. */ ++ Bool is_alt_info; + } + CUConst; + + + /* Return the cooked value of DIE depending on whether CC represents a +- .debug_types unit. To cook a DIE, we pretend that the .debug_info +- and .debug_types sections form a contiguous whole, so that DIEs +- coming from .debug_types are numbered starting at the end of +- .debug_info. */ ++ .debug_types unit. To cook a DIE, we pretend that the .debug_info, ++ .debug_types and optional alternate .debug_info sections form ++ a contiguous whole, so that DIEs coming from .debug_types are numbered ++ starting at the end of .debug_info and DIEs coming from alternate ++ .debug_info are numbered starting at the end of .debug_types. */ + static UWord cook_die( CUConst* cc, UWord die ) + { + if (cc->is_type_unit) +- die += cc->debug_info_sz; ++ die += cc->types_cuOff_bias; ++ else if (cc->is_alt_info) ++ die += cc->alt_cuOff_bias; + return die; + } + + /* Like cook_die, but understand that DIEs coming from a +- DW_FORM_ref_sig8 reference are already cooked. */ ++ DW_FORM_ref_sig8 reference are already cooked. Also, handle ++ DW_FORM_GNU_ref_alt from within primary .debug_info or .debug_types ++ as reference to alternate .debug_info. */ + static UWord cook_die_using_form( CUConst *cc, UWord die, DW_FORM form) + { + if (form == DW_FORM_ref_sig8) + return die; ++ if (form == DW_FORM_GNU_ref_alt) ++ return die + cc->alt_cuOff_bias; + return cook_die( cc, die ); + } + +-/* Return the uncooked offset of DIE and set *FLAG to true if the DIE +- came from the .debug_types section. */ +-static UWord uncook_die( CUConst *cc, UWord die, /*OUT*/Bool *flag ) ++/* Return the uncooked offset of DIE and set *TYPE_FLAG to true if the DIE ++ came from the .debug_types section and *ALT_FLAG to true if the DIE ++ came from alternate .debug_info section. */ ++static UWord uncook_die( CUConst *cc, UWord die, /*OUT*/Bool *type_flag, ++ Bool *alt_flag ) + { ++ *alt_flag = False; ++ *type_flag = False; + if (die >= cc->debug_info_sz) { +- *flag = True; +- die -= cc->debug_info_sz; +- } else { +- *flag = False; ++ if (die >= cc->debug_info_sz + cc->debug_types_sz) { ++ *alt_flag = True; ++ die -= cc->debug_info_sz + cc->debug_types_sz; ++ } else { ++ *type_flag = True; ++ die -= cc->debug_info_sz; ++ } + } + return die; + } +@@ -831,7 +859,8 @@ + Bool td3, + Cursor* c, + UChar* debug_abbv_img, UWord debug_abbv_sz, +- Bool type_unit ) ++ Bool type_unit, ++ Bool alt_info ) + { + UChar address_size; + UWord debug_abbrev_offset; +@@ -870,6 +899,7 @@ + TRACE_D3(" Pointer Size: %d\n", (Int)address_size ); + + cc->is_type_unit = type_unit; ++ cc->is_alt_info = alt_info; + + if (type_unit) { + cc->type_signature = get_ULong( c ); +@@ -1289,6 +1319,37 @@ + (DW_FORM)get_ULEB128(c)); + return; + ++ case DW_FORM_GNU_ref_alt: ++ *cts = get_Dwarfish_UWord(c, cc->is_dw64); ++ *ctsSzB = cc->is_dw64 ? sizeof(ULong) : sizeof(UInt); ++ TRACE_D3("0x%lx", (UWord)*cts); ++ if (0) VG_(printf)("DW_FORM_GNU_ref_alt 0x%lx\n", (UWord)*cts); ++ if (/* the following 2 are surely impossible, but ... */ ++ cc->debug_info_alt_img == NULL || cc->debug_info_alt_sz == 0 ++ || *cts >= (ULong)cc->debug_info_alt_sz) { ++ /* Hmm. Offset is nonsensical for this object's .debug_info ++ section. Be safe and reject it. */ ++ cc->barf("get_Form_contents: DW_FORM_ref_addr points " ++ "outside alternate .debug_info"); ++ } ++ break; ++ ++ case DW_FORM_GNU_strp_alt: { ++ /* this is an offset into alternate .debug_str */ ++ UChar* str; ++ UWord uw = (UWord)get_Dwarfish_UWord( c, cc->is_dw64 ); ++ if (cc->debug_str_alt_img == NULL || uw >= cc->debug_str_alt_sz) ++ cc->barf("get_Form_contents: DW_FORM_GNU_strp_alt " ++ "points outside alternate .debug_str"); ++ /* FIXME: check the entire string lies inside debug_str, ++ not just the first byte of it. */ ++ str = (UChar*)cc->debug_str_alt_img + uw; ++ TRACE_D3("(indirect alt string, offset: 0x%lx): %s", uw, str); ++ *cts = (ULong)(UWord)str; ++ *ctsMemSzB = 1 + (ULong)VG_(strlen)(str); ++ break; ++ } ++ + default: + VG_(printf)( + "get_Form_contents: unhandled %d (%s) at <%lx>\n", +@@ -1579,10 +1640,13 @@ + UWord saved_die_c_offset = get_position_of_Cursor( c_die ); + UWord saved_abbv_c_offset = get_position_of_Cursor( c_abbv ); + Bool debug_types_flag; ++ Bool alt_flag; + + varstack_preen( parser, td3, level-1 ); + +- if (dtag == DW_TAG_compile_unit || dtag == DW_TAG_type_unit) { ++ if (dtag == DW_TAG_compile_unit ++ || dtag == DW_TAG_type_unit ++ || dtag == DW_TAG_partial_unit) { + Bool have_lo = False; + Bool have_hi1 = False; + Bool have_range = False; +@@ -2028,11 +2092,14 @@ + set_position_of_Cursor( c_die, saved_die_c_offset ); + set_position_of_Cursor( c_abbv, saved_abbv_c_offset ); + VG_(printf)("\nparse_var_DIE: confused by:\n"); +- posn = uncook_die( cc, posn, &debug_types_flag ); ++ posn = uncook_die( cc, posn, &debug_types_flag, &alt_flag ); + VG_(printf)(" <%d><%lx>: %s", level, posn, ML_(pp_DW_TAG)( dtag ) ); + if (debug_types_flag) { + VG_(printf)(" (in .debug_types)"); + } ++ else if (alt_flag) { ++ VG_(printf)(" (in alternate .debug_info)"); ++ } + VG_(printf)("\n"); + while (True) { + DW_AT attr = (DW_AT) get_ULEB128( c_abbv ); +@@ -2214,6 +2281,7 @@ + TyEnt fieldE; + TyEnt boundE; + Bool debug_types_flag; ++ Bool alt_flag; + + UWord saved_die_c_offset = get_position_of_Cursor( c_die ); + UWord saved_abbv_c_offset = get_position_of_Cursor( c_abbv ); +@@ -2228,7 +2296,9 @@ + its children. */ + typestack_preen( parser, td3, level-1 ); + +- if (dtag == DW_TAG_compile_unit || dtag == DW_TAG_type_unit) { ++ if (dtag == DW_TAG_compile_unit ++ || dtag == DW_TAG_type_unit ++ || dtag == DW_TAG_partial_unit) { + /* See if we can find DW_AT_language, since it is important for + establishing array bounds (see DW_TAG_subrange_type below in + this fn) */ +@@ -2947,10 +3017,12 @@ + set_position_of_Cursor( c_die, saved_die_c_offset ); + set_position_of_Cursor( c_abbv, saved_abbv_c_offset ); + VG_(printf)("\nparse_type_DIE: confused by:\n"); +- posn = uncook_die( cc, posn, &debug_types_flag ); ++ posn = uncook_die( cc, posn, &debug_types_flag, &alt_flag ); + VG_(printf)(" <%d><%lx>: %s", level, posn, ML_(pp_DW_TAG)( dtag ) ); + if (debug_types_flag) { + VG_(printf)(" (in .debug_types)"); ++ } else if (alt_flag) { ++ VG_(printf)(" (in alternate .debug_info)"); + } + VG_(printf)("\n"); + while (True) { +@@ -3428,7 +3500,11 @@ + UChar* debug_line_img, SizeT debug_line_sz, + UChar* debug_str_img, SizeT debug_str_sz, + UChar* debug_ranges_img, SizeT debug_ranges_sz, +- UChar* debug_loc_img, SizeT debug_loc_sz ++ UChar* debug_loc_img, SizeT debug_loc_sz, ++ UChar* debug_info_alt_img, SizeT debug_info_alt_sz, ++ UChar* debug_abbv_alt_img, SizeT debug_abbv_alt_sz, ++ UChar* debug_line_alt_img, SizeT debug_line_alt_sz, ++ UChar* debug_str_alt_img, SizeT debug_str_alt_sz + ) + { + XArray* /* of TyEnt */ tyents; +@@ -3668,10 +3744,10 @@ + (saC_cache) */ + parse_CU_Header( &cc, td3, &info, + (UChar*)debug_abbv_img, debug_abbv_sz, +- True ); ++ True, False ); + + /* Needed by cook_die. */ +- cc.debug_info_sz = debug_info_sz; ++ cc.types_cuOff_bias = debug_info_sz; + + record_signatured_type( signature_types, cc.type_signature, + cook_die( &cc, cc.type_offset )); +@@ -3689,15 +3765,29 @@ + } + } + +- /* Perform two DIE-reading passes. The first pass reads DIEs from +- .debug_info, and the second pass reads DIEs from .debug_types. ++ /* Perform three DIE-reading passes. The first pass reads DIEs from ++ alternate .debug_info (if any), the second pass reads DIEs from ++ .debug_info, and the third pass reads DIEs from .debug_types. + Moving the body of this loop into a separate function would + require a large number of arguments to be passed in, so it is + kept inline instead. */ +- for (pass = 0; pass < 2; ++pass) { ++ for (pass = 0; pass < 3; ++pass) { + UWord section_size; + + if (pass == 0) { ++ if (debug_info_alt_img == NULL) ++ continue; ++ /* Now loop over the Compilation Units listed in the alternate ++ .debug_info section (see D3SPEC sec 7.5) paras 1 and 2. ++ Each compilation unit contains a Compilation Unit Header ++ followed by precisely one DW_TAG_compile_unit or ++ DW_TAG_partial_unit DIE. */ ++ init_Cursor( &info, debug_info_alt_img, debug_info_alt_sz, 0, barf, ++ "Overrun whilst reading alternate .debug_info section" ); ++ section_size = debug_info_alt_sz; ++ ++ TRACE_D3("\n------ Parsing alternate .debug_info section ------\n"); ++ } else if (pass == 1) { + /* Now loop over the Compilation Units listed in the .debug_info + section (see D3SPEC sec 7.5) paras 1 and 2. Each compilation + unit contains a Compilation Unit Header followed by precisely +@@ -3769,21 +3859,32 @@ + TRACE_D3(" Compilation Unit @ offset 0x%lx:\n", cu_start_offset); + /* parse_CU_header initialises the CU's set_abbv_Cursor cache + (saC_cache) */ +- parse_CU_Header( &cc, td3, &info, +- (UChar*)debug_abbv_img, debug_abbv_sz, +- pass != 0 ); +- cc.debug_str_img = debug_str_img; +- cc.debug_str_sz = debug_str_sz; ++ if (pass == 0) ++ parse_CU_Header( &cc, td3, &info, ++ (UChar*)debug_abbv_alt_img, debug_abbv_alt_sz, ++ False, True ); ++ else ++ parse_CU_Header( &cc, td3, &info, ++ (UChar*)debug_abbv_img, debug_abbv_sz, ++ pass == 2, False ); ++ cc.debug_str_img = pass == 0 ? debug_str_alt_img : debug_str_img; ++ cc.debug_str_sz = pass == 0 ? debug_str_alt_sz : debug_str_sz; + cc.debug_ranges_img = debug_ranges_img; + cc.debug_ranges_sz = debug_ranges_sz; + cc.debug_loc_img = debug_loc_img; + cc.debug_loc_sz = debug_loc_sz; +- cc.debug_line_img = debug_line_img; +- cc.debug_line_sz = debug_line_sz; +- cc.debug_info_img = debug_info_img; +- cc.debug_info_sz = debug_info_sz; ++ cc.debug_line_img = pass == 0 ? debug_line_alt_img : debug_line_img; ++ cc.debug_line_sz = pass == 0 ? debug_line_alt_sz : debug_line_sz; ++ cc.debug_info_img = pass == 0 ? debug_info_alt_img : debug_info_img; ++ cc.debug_info_sz = pass == 0 ? debug_info_alt_sz : debug_info_sz; + cc.debug_types_img = debug_types_img; + cc.debug_types_sz = debug_types_sz; ++ cc.debug_info_alt_img = debug_info_alt_img; ++ cc.debug_info_alt_sz = debug_info_alt_sz; ++ cc.debug_str_alt_img = debug_str_alt_img; ++ cc.debug_str_alt_sz = debug_str_alt_sz; ++ cc.types_cuOff_bias = debug_info_sz; ++ cc.alt_cuOff_bias = debug_info_sz + debug_types_sz; + cc.cu_start_offset = cu_start_offset; + cc.di = di; + /* The CU's svma can be deduced by looking at the AT_low_pc +@@ -3966,10 +4067,19 @@ + vg_assert(dioff_lookup_tab); + + n = VG_(sizeXA)( tempvars ); ++ Word first_primary_var; ++ for (first_primary_var = 0; ++ debug_info_alt_sz && first_primary_var < n; ++ first_primary_var++) { ++ varp = *(TempVar**)VG_(indexXA)( tempvars, first_primary_var ); ++ if (varp->dioff < debug_info_sz + debug_types_sz) ++ break; ++ } + for (i = 0; i < n; i++) { +- varp = *(TempVar**)VG_(indexXA)( tempvars, i ); +- if (i > 0) { +- varp2 = *(TempVar**)VG_(indexXA)( tempvars, i-1 ); ++ varp = *(TempVar**)VG_(indexXA)( tempvars, (i + first_primary_var) % n ); ++ if (i > first_primary_var) { ++ varp2 = *(TempVar**)VG_(indexXA)( tempvars, ++ (i + first_primary_var - 1) % n ); + /* why should this hold? Only, I think, because we've + constructed the array by reading .debug_info sequentially, + and so the array .dioff fields should reflect that, and be +@@ -4223,7 +4333,11 @@ + UChar* debug_line_img, SizeT debug_line_sz, + UChar* debug_str_img, SizeT debug_str_sz, + UChar* debug_ranges_img, SizeT debug_ranges_sz, +- UChar* debug_loc_img, SizeT debug_loc_sz ++ UChar* debug_loc_img, SizeT debug_loc_sz, ++ UChar* debug_info_alt_img, SizeT debug_info_alt_sz, ++ UChar* debug_abbv_alt_img, SizeT debug_abbv_alt_sz, ++ UChar* debug_line_alt_img, SizeT debug_line_alt_sz, ++ UChar* debug_str_alt_img, SizeT debug_str_alt_sz + ) + { + volatile Int jumped; +@@ -4247,7 +4361,11 @@ + debug_line_img, debug_line_sz, + debug_str_img, debug_str_sz, + debug_ranges_img, debug_ranges_sz, +- debug_loc_img, debug_loc_sz ); ++ debug_loc_img, debug_loc_sz, ++ debug_info_alt_img, debug_info_alt_sz, ++ debug_abbv_alt_img, debug_abbv_alt_sz, ++ debug_line_alt_img, debug_line_alt_sz, ++ debug_str_alt_img, debug_str_alt_sz); + d3rd_jmpbuf_valid = False; + TRACE_D3("\n------ .debug_info reading was successful ------\n"); + } else { +diff -ru valgrind-3.7.0.orig/coregrind/m_debuginfo/readdwarf.c valgrind-3.7.0/coregrind/m_debuginfo/readdwarf.c +--- valgrind-3.7.0.orig/coregrind/m_debuginfo/readdwarf.c 2012-07-25 12:33:29.191948686 +0200 ++++ valgrind-3.7.0/coregrind/m_debuginfo/readdwarf.c 2012-07-25 12:44:30.257113055 +0200 +@@ -985,7 +985,8 @@ + void read_unitinfo_dwarf2( /*OUT*/UnitInfo* ui, + UChar* unitblock_img, + UChar* debugabbrev_img, +- UChar* debugstr_img ) ++ UChar* debugstr_img, ++ UChar* debugstr_alt_img ) + { + UInt acode, abcode; + ULong atoffs, blklen; +@@ -1128,6 +1129,14 @@ + case 0x18: /* FORM_exprloc */ p += read_leb128U( &p ); break; + case 0x19: /* FORM_flag_present */break; + case 0x20: /* FORM_ref_sig8 */ p += 8; break; ++ case 0x1f20: /* FORM_GNU_ref_alt */ p += ui->dw64 ? 8 : 4; break; ++ case 0x1f21: /* FORM_GNU_strp_alt */ ++ if (debugstr_alt_img && !ui->dw64) ++ sval = debugstr_alt_img + ML_(read_UInt)(p); ++ if (debugstr_alt_img && ui->dw64) ++ sval = debugstr_alt_img + ML_(read_ULong)(p); ++ p += ui->dw64 ? 8 : 4; ++ break; + + default: + VG_(printf)( "### unhandled dwarf2 abbrev form code 0x%x\n", form ); +@@ -1169,7 +1178,8 @@ + UChar* debug_types_img, Word debug_types_sz, /* .debug_types */ + UChar* debug_abbv_img, Word debug_abbv_sz, /* .debug_abbrev */ + UChar* debug_line_img, Word debug_line_sz, /* .debug_line */ +- UChar* debug_str_img, Word debug_str_sz ) /* .debug_str */ ++ UChar* debug_str_img, Word debug_str_sz, /* .debug_str */ ++ UChar* debug_str_alt_img, Word debug_str_alt_sz ) /* .debug_str */ + { + UnitInfo ui; + UShort ver; +@@ -1218,7 +1228,8 @@ + VG_(printf)( "Reading UnitInfo at 0x%lx.....\n", + block_img - debug_info_img + 0UL ); + read_unitinfo_dwarf2( &ui, block_img, +- debug_abbv_img, debug_str_img ); ++ debug_abbv_img, debug_str_img, ++ debug_str_alt_img ); + if (0) + VG_(printf)( " => LINES=0x%llx NAME=%s DIR=%s\n", + ui.stmt_list, ui.name, ui.compdir ); +diff -ru valgrind-3.7.0.orig/coregrind/m_debuginfo/readelf.c valgrind-3.7.0/coregrind/m_debuginfo/readelf.c +--- valgrind-3.7.0.orig/coregrind/m_debuginfo/readelf.c 2012-07-25 12:33:29.191948686 +0200 ++++ valgrind-3.7.0/coregrind/m_debuginfo/readelf.c 2012-07-25 12:53:09.377151832 +0200 +@@ -111,7 +111,7 @@ + /* Identify an ELF object file by peering at the first few bytes of + it. */ + +-Bool ML_(is_elf_object_file)( void* image, SizeT n_image ) ++Bool ML_(is_elf_object_file)( void* image, SizeT n_image, Bool rel_ok ) + { + ElfXX_Ehdr* ehdr = (ElfXX_Ehdr*)image; + Int ok = 1; +@@ -126,12 +126,14 @@ + ok &= (ehdr->e_ident[EI_CLASS] == VG_ELF_CLASS + && ehdr->e_ident[EI_DATA] == VG_ELF_DATA2XXX + && ehdr->e_ident[EI_VERSION] == EV_CURRENT); +- ok &= (ehdr->e_type == ET_EXEC || ehdr->e_type == ET_DYN); ++ ok &= (ehdr->e_type == ET_EXEC || ehdr->e_type == ET_DYN ++ || (rel_ok && ehdr->e_type == ET_REL)); + ok &= (ehdr->e_machine == VG_ELF_MACHINE); + ok &= (ehdr->e_version == EV_CURRENT); + ok &= (ehdr->e_shstrndx != SHN_UNDEF); + ok &= (ehdr->e_shoff != 0 && ehdr->e_shnum != 0); +- ok &= (ehdr->e_phoff != 0 && ehdr->e_phnum != 0); ++ ok &= ((ehdr->e_phoff != 0 && ehdr->e_phnum != 0) ++ || ehdr->e_type == ET_REL); + + if (ok) + return True; +@@ -887,7 +889,7 @@ + * http://fedoraproject.org/wiki/RolandMcGrath/BuildID + */ + static +-Char *find_buildid(Addr image, UWord n_image) ++Char *find_buildid(Addr image, UWord n_image, Bool rel_ok) + { + Char* buildid = NULL; + __attribute__((unused)) /* on Android, at least */ +@@ -895,7 +897,7 @@ + + #ifdef NT_GNU_BUILD_ID + if (n_image >= sizeof(ElfXX_Ehdr) && +- ML_(is_elf_object_file)(ehdr, n_image)) { ++ ML_(is_elf_object_file)(ehdr, n_image, rel_ok)) { + Word i; + + for (i = 0; i < ehdr->e_phnum; i++) { +@@ -927,7 +929,41 @@ + + ((note->n_descsz + 3) & ~3); + } + } +- } ++ } ++ ++ if (buildid || !rel_ok) ++ return buildid; ++ ++ for (i = 0; i < ehdr->e_shnum; i++) { ++ ElfXX_Shdr* shdr ++ = (ElfXX_Shdr*)(image + ehdr->e_shoff + i * ehdr->e_shentsize); ++ ++ if (shdr->sh_type == SHT_NOTE) { ++ ElfXX_Off offset = shdr->sh_offset; ++ ++ while (offset < shdr->sh_offset + shdr->sh_size) { ++ ElfXX_Nhdr* note = (ElfXX_Nhdr*)(image + offset); ++ Char* name = (Char *)note + sizeof(ElfXX_Nhdr); ++ UChar *desc = (UChar *)name + ((note->n_namesz + 3) & ~3); ++ Word j; ++ ++ if (VG_(strcmp)(name, ELF_NOTE_GNU) == 0 && ++ note->n_type == NT_GNU_BUILD_ID) { ++ buildid = ML_(dinfo_zalloc)("di.fbi.1", ++ note->n_descsz * 2 + 1); ++ ++ for (j = 0; j < note->n_descsz; j++) { ++ VG_(sprintf)(buildid + VG_(strlen)(buildid), ++ "%02x", desc[j]); ++ } ++ } ++ ++ offset = offset + sizeof(ElfXX_Nhdr) ++ + ((note->n_namesz + 3) & ~3) ++ + ((note->n_descsz + 3) & ~3); ++ } ++ } ++ } + } + #endif + +@@ -1009,7 +1045,8 @@ + * not match the value from the main object file. + */ + static +-Addr open_debug_file( Char* name, Char* buildid, UInt crc, /*OUT*/UWord* size ) ++Addr open_debug_file( Char* name, Char* buildid, UInt crc, Bool rel_ok, ++ /*OUT*/UWord* size ) + { + SysRes fd, sres; + struct vg_stat stat_buf; +@@ -1038,7 +1075,7 @@ + return 0; + + if (buildid) { +- Char* debug_buildid = find_buildid(sr_Res(sres), *size); ++ Char* debug_buildid = find_buildid(sr_Res(sres), *size, rel_ok); + if (debug_buildid == NULL || VG_(strcmp)(buildid, debug_buildid) != 0) { + SysRes res = VG_(am_munmap_valgrind)(sr_Res(sres), *size); + vg_assert(!sr_isError(res)); +@@ -1157,7 +1194,7 @@ + static + void find_debug_file( struct _DebugInfo* di, + Char* objpath, Char* buildid, +- Char* debugname, UInt crc, ++ Char* debugname, UInt crc, Bool rel_ok, + /*OUT*/Addr* dimage, + /*OUT*/SizeT* n_dimage ) + { +@@ -1175,13 +1212,14 @@ + VG_(sprintf)(debugpath, "/usr/lib/debug/.build-id/%c%c/%s.debug", + buildid[0], buildid[1], buildid + 2); + +- if ((addr = open_debug_file(debugpath, buildid, 0, &size)) == 0) { ++ if ((addr = open_debug_file(debugpath, buildid, 0, ++ rel_ok, &size)) == 0) { + ML_(dinfo_free)(debugpath); + debugpath = NULL; + } + } + +- if (addr == 0 && debugname != NULL) { ++ if (addr == 0 && debugname != NULL && !rel_ok) { + Char *objdir = ML_(dinfo_strdup)("di.fdf.2", objpath); + Char *objdirptr; + +@@ -1194,11 +1232,11 @@ + + VG_(sprintf)(debugpath, "%s/%s", objdir, debugname); + +- if ((addr = open_debug_file(debugpath, NULL, crc, &size)) == 0) { ++ if ((addr = open_debug_file(debugpath, NULL, crc, rel_ok, &size)) == 0) { + VG_(sprintf)(debugpath, "%s/.debug/%s", objdir, debugname); +- if ((addr = open_debug_file(debugpath, NULL, crc, &size)) == 0) { ++ if ((addr = open_debug_file(debugpath, NULL, crc, rel_ok, &size)) == 0) { + VG_(sprintf)(debugpath, "/usr/lib/debug%s/%s", objdir, debugname); +- addr = open_debug_file(debugpath, NULL, crc, &size); ++ addr = open_debug_file(debugpath, NULL, crc, rel_ok, &size); + } + } + +@@ -1283,7 +1321,7 @@ + /* TOPLEVEL */ + Bool res, ok; + SysRes fd, sres; +- Word i; ++ Word i, j; + Bool dynbss_present = False; + Bool sdynbss_present = False; + +@@ -1295,6 +1333,10 @@ + Addr dimage = 0; + UWord n_dimage = 0; + ++ /* Ditto for alternate ELF debuginfo file that we might happen to load. */ ++ Addr aimage = 0; ++ UWord n_aimage = 0; ++ + /* ELF header for the main file. Should == oimage since is at + start of file. */ + ElfXX_Ehdr* ehdr_img = NULL; +@@ -1417,7 +1459,7 @@ + ehdr_img = (ElfXX_Ehdr*)oimage; + + if (ok) +- ok &= ML_(is_elf_object_file)(ehdr_img, n_oimage); ++ ok &= ML_(is_elf_object_file)(ehdr_img, n_oimage, False); + + if (!ok) { + ML_(symerr)(di, True, "Invalid ELF Header"); +@@ -2068,6 +2110,7 @@ + UChar* dynstr_img = NULL; /* .dynstr */ + ElfXX_Sym* dynsym_img = NULL; /* .dynsym */ + UChar* debuglink_img = NULL; /* .gnu_debuglink */ ++ UChar* debugaltlink_img = NULL; /* .gnu_debugaltlink */ + UChar* stab_img = NULL; /* .stab (stabs) */ + UChar* stabstr_img = NULL; /* .stabstr (stabs) */ + UChar* debug_line_img = NULL; /* .debug_line (dwarf2) */ +@@ -2078,6 +2121,10 @@ + UChar* debug_ranges_img = NULL; /* .debug_ranges (dwarf2) */ + UChar* debug_loc_img = NULL; /* .debug_loc (dwarf2) */ + UChar* debug_frame_img = NULL; /* .debug_frame (dwarf2) */ ++ UChar* debug_line_alt_img = NULL; /* .debug_line (alternate) */ ++ UChar* debug_info_alt_img = NULL; /* .debug_info (alternate) */ ++ UChar* debug_abbv_alt_img = NULL; /* .debug_abbrev (alternate) */ ++ UChar* debug_str_alt_img = NULL; /* .debug_str (alternate) */ + UChar* dwarf1d_img = NULL; /* .debug (dwarf1) */ + UChar* dwarf1l_img = NULL; /* .line (dwarf1) */ + UChar* opd_img = NULL; /* .opd (dwarf2, +@@ -2090,16 +2137,21 @@ + SizeT dynstr_sz = 0; + SizeT dynsym_sz = 0; + SizeT debuglink_sz = 0; ++ SizeT debugaltlink_sz = 0; + SizeT stab_sz = 0; + SizeT stabstr_sz = 0; + SizeT debug_line_sz = 0; + SizeT debug_info_sz = 0; +- SizeT debug_types_sz = 0; ++ SizeT debug_types_sz = 0; + SizeT debug_abbv_sz = 0; + SizeT debug_str_sz = 0; + SizeT debug_ranges_sz = 0; + SizeT debug_loc_sz = 0; + SizeT debug_frame_sz = 0; ++ SizeT debug_line_alt_sz = 0; ++ SizeT debug_info_alt_sz = 0; ++ SizeT debug_abbv_alt_sz = 0; ++ SizeT debug_str_alt_sz = 0; + SizeT dwarf1d_sz = 0; + SizeT dwarf1l_sz = 0; + SizeT opd_sz_unused = 0; +@@ -2164,6 +2216,7 @@ + FIND(".strtab", strtab_sz, strtab_img) + + FIND(".gnu_debuglink", debuglink_sz, debuglink_img) ++ FIND(".gnu_debugaltlink", debugaltlink_sz, debugaltlink_img) + + FIND(".stab", stab_sz, stab_img) + FIND(".stabstr", stabstr_sz, stabstr_img) +@@ -2209,7 +2262,7 @@ + vg_assert(dimage == 0 && n_dimage == 0); + + /* Look for a build-id */ +- buildid = find_buildid(oimage, n_oimage); ++ buildid = find_buildid(oimage, n_oimage, False); + + /* Look for a debug image */ + if (buildid != NULL || debuglink_img != NULL) { +@@ -2225,11 +2278,11 @@ + + /* See if we can find a matching debug file */ + find_debug_file( di, di->fsm.filename, buildid, +- debuglink_img, crc, &dimage, &n_dimage ); ++ debuglink_img, crc, False, &dimage, &n_dimage ); + } else { + /* See if we can find a matching debug file */ + find_debug_file( di, di->fsm.filename, buildid, +- NULL, 0, &dimage, &n_dimage ); ++ NULL, 0, False, &dimage, &n_dimage ); + } + } + +@@ -2252,7 +2305,7 @@ + SVMA/bias/size and image addresses out of it. */ + if (dimage != 0 + && n_dimage >= sizeof(ElfXX_Ehdr) +- && ML_(is_elf_object_file)((void*)dimage, n_dimage)) { ++ && ML_(is_elf_object_file)((void*)dimage, n_dimage, False)) { + + /* Pull out and validate program header and section header info */ + ElfXX_Ehdr* ehdr_dimg = (ElfXX_Ehdr*)dimage; +@@ -2437,6 +2490,8 @@ + FIND(need_dwarf2, ".debug_loc", debug_loc_sz, debug_loc_img) + FIND(need_dwarf2, ".debug_frame", debug_frame_sz, + debug_frame_img) ++ FIND(need_dwarf2, ".gnu_debugaltlink", debugaltlink_sz, ++ debugaltlink_img) + FIND(need_dwarf1, ".debug", dwarf1d_sz, dwarf1d_img) + FIND(need_dwarf1, ".line", dwarf1l_sz, dwarf1l_img) + +@@ -2444,6 +2499,100 @@ + } /* Find all interesting sections */ + } /* do we have a debug image? */ + ++ /* Look for alternate debug image */ ++ if (debugaltlink_img != NULL) { ++ UInt buildid_offset = VG_(strlen)(debugaltlink_img)+1; ++ ++ vg_assert(buildid_offset < debugaltlink_sz); ++ ++ Char *altbuildid ++ = ML_(dinfo_zalloc)("di.fbi.4", ++ (debugaltlink_sz - buildid_offset) ++ * 2 + 1); ++ ++ for (j = 0; j < debugaltlink_sz - buildid_offset; j++) ++ VG_(sprintf)(altbuildid + 2 * j, ++ "%02x", debugaltlink_img[buildid_offset + j]); ++ ++ /* See if we can find a matching debug file */ ++ find_debug_file( di, di->fsm.filename, altbuildid, ++ NULL, 0, True, &aimage, &n_aimage ); ++ ++ ML_(dinfo_free)(altbuildid); ++ } ++ ++ /* TOPLEVEL */ ++ /* If we were successful in finding alternate debug image, pull various ++ size and image addresses out of it. */ ++ if (aimage != 0 ++ && n_aimage >= sizeof(ElfXX_Ehdr) ++ && ML_(is_elf_object_file)((void*)aimage, n_aimage, True)) { ++ ++ /* Pull out and validate program header and section header info */ ++ ElfXX_Ehdr* ehdr_aimg = (ElfXX_Ehdr*)aimage; ++ ElfXX_Shdr* shdr_aimg = (ElfXX_Shdr*)( ((UChar*)ehdr_aimg) ++ + ehdr_aimg->e_shoff ); ++ UWord shdr_dnent = ehdr_aimg->e_shnum; ++ UWord shdr_dent_szB = ehdr_aimg->e_shentsize; ++ UChar* shdr_strtab_aimg = NULL; ++ ++ if (shdr_dnent == 0 ++ || !contained_within( ++ aimage, n_aimage, ++ (Addr)shdr_aimg, shdr_dnent * shdr_dent_szB)) { ++ ML_(symerr)(di, True, ++ "Missing or invalid ELF Section Header Table" ++ " (alternate debuginfo file)"); ++ goto out; ++ } ++ ++ /* Also find the section header's string table, and validate. */ ++ /* checked previously by is_elf_object_file: */ ++ vg_assert( ehdr_aimg->e_shstrndx != SHN_UNDEF ); ++ ++ shdr_strtab_aimg ++ = (UChar*)( ((UChar*)ehdr_aimg) ++ + shdr_aimg[ehdr_aimg->e_shstrndx].sh_offset); ++ if (!contained_within( ++ aimage, n_aimage, ++ (Addr)shdr_strtab_aimg, ++ 1/*bogus, but we don't know the real size*/ )) { ++ ML_(symerr)(di, True, ++ "Invalid ELF Section Header String Table" ++ " (alternate debuginfo file)"); ++ goto out; ++ } ++ ++ /* Find all interesting sections */ ++ for (i = 0; i < ehdr_aimg->e_shnum; i++) { ++ ++# define FIND(sec_name, sec_size, sec_img) \ ++ do { ElfXX_Shdr* shdr \ ++ = INDEX_BIS( shdr_aimg, i, shdr_dent_szB ); \ ++ if (0 == VG_(strcmp)(sec_name, \ ++ shdr_strtab_aimg + shdr->sh_name)) { \ ++ if (0 != sec_img) \ ++ VG_(core_panic)("repeated section!\n"); \ ++ sec_img = (void*)(aimage + shdr->sh_offset); \ ++ sec_size = shdr->sh_size; \ ++ TRACE_SYMTAB( "%18s: aimg %p .. %p\n", \ ++ sec_name, \ ++ (UChar*)sec_img, \ ++ ((UChar*)sec_img) + sec_size - 1); \ ++ } \ ++ } while (0); ++ ++ /* NAME SIZE IMAGE addr */ ++ FIND(".debug_line", debug_line_alt_sz, debug_line_alt_img) ++ FIND(".debug_info", debug_info_alt_sz, debug_info_alt_img) ++ FIND(".debug_abbrev", debug_abbv_alt_sz, debug_abbv_alt_img) ++ FIND(".debug_str", debug_str_alt_sz, debug_str_alt_img) ++ ++# undef FIND ++ } /* Find all interesting sections */ ++ } /* do we have a debug image? */ ++ ++ + /* TOPLEVEL */ + /* Check some sizes */ + vg_assert((dynsym_sz % sizeof(ElfXX_Sym)) == 0); +@@ -2524,7 +2673,8 @@ + debug_types_img, debug_types_sz, + debug_abbv_img, debug_abbv_sz, + debug_line_img, debug_line_sz, +- debug_str_img, debug_str_sz ); ++ debug_str_img, debug_str_sz, ++ debug_str_alt_img, debug_str_alt_sz ); + + /* The new reader: read the DIEs in .debug_info to acquire + information on variable types and locations. But only if +@@ -2539,7 +2689,11 @@ + debug_line_img, debug_line_sz, + debug_str_img, debug_str_sz, + debug_ranges_img, debug_ranges_sz, +- debug_loc_img, debug_loc_sz ++ debug_loc_img, debug_loc_sz, ++ debug_info_alt_img, debug_info_alt_sz, ++ debug_abbv_alt_img, debug_abbv_alt_sz, ++ debug_line_alt_img, debug_line_alt_sz, ++ debug_str_alt_img, debug_str_alt_sz + ); + } + } diff --git a/valgrind.spec b/valgrind.spec index 7eead69..51dcb0a 100644 --- a/valgrind.spec +++ b/valgrind.spec @@ -1,7 +1,7 @@ Summary: Tool for finding memory management bugs in programs Name: valgrind Version: 3.7.0 -Release: 5%{?dist} +Release: 6%{?dist} Epoch: 1 License: GPLv2 URL: http://www.valgrind.org/ @@ -27,6 +27,7 @@ Patch16: valgrind-3.7.0-debug-leak1.patch Patch17: valgrind-3.7.0-debug-leak2.patch Patch18: valgrind-3.7.0-addToXA.patch Patch19: valgrind-3.7.0-debug-types.patch +Patch20: valgrind-3.7.0-dwz.patch Obsoletes: valgrind-callgrind %ifarch x86_64 ppc64 @@ -125,6 +126,7 @@ for details. %patch17 -p1 %patch18 -p1 %patch19 -p1 +%patch20 -p1 touch memcheck/tests/dw4.stdout.exp %build @@ -220,6 +222,9 @@ echo ===============END TESTING=============== %endif %changelog +* Mon Jul 25 2012 Mark Wielaard 3.7.0-6 +- handle dwz DWARF compressor output (#842659, KDE#302901) + * Sun Jul 22 2012 Fedora Release Engineering - 1:3.7.0-5 - Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild