diff --git a/valgrind-3.7.0-debug-types.patch b/valgrind-3.7.0-debug-types.patch new file mode 100644 index 0000000..c4b7895 --- /dev/null +++ b/valgrind-3.7.0-debug-types.patch @@ -0,0 +1,1012 @@ +--- valgrind-3.7.0/memcheck/tests/Makefile.am (revision 12490) ++++ valgrind-3.7.0/memcheck/tests/Makefile.am (revision 12491) +@@ -76,6 +76,7 @@ EXTRA_DIST = \ + deep_templates.stdout.exp deep_templates.stderr.exp \ + describe-block.stderr.exp describe-block.vgtest \ + doublefree.stderr.exp doublefree.vgtest \ ++ dw4.vgtest dw4.stderr.exp dw4.stdout.exp \ + err_disable1.vgtest err_disable1.stderr.exp \ + err_disable2.vgtest err_disable2.stderr.exp \ + err_disable3.vgtest err_disable3.stderr.exp \ +@@ -281,6 +282,9 @@ check_PROGRAMS = \ + wrap1 wrap2 wrap3 wrap4 wrap5 wrap6 wrap7 wrap7so.so wrap8 \ + writev1 + ++if DWARF4 ++check_PROGRAMS += dw4 ++endif + + AM_CFLAGS += $(AM_FLAG_M3264_PRI) + AM_CXXFLAGS += $(AM_FLAG_M3264_PRI) +@@ -299,6 +303,8 @@ endif + deep_templates_SOURCES = deep_templates.cpp + deep_templates_CXXFLAGS = $(AM_CFLAGS) -O -gstabs + ++dw4_CFLAGS = $(AM_CFLAGS) -gdwarf-4 -fdebug-types-section ++ + err_disable3_LDADD = -lpthread + err_disable4_LDADD = -lpthread + +--- valgrind-3.7.0/memcheck/tests/dw4.c (revision 0) ++++ valgrind-3.7.0/memcheck/tests/dw4.c (revision 12491) +@@ -0,0 +1,54 @@ ++ ++/* Check of variable location identification when using .debug_types. */ ++ ++/* Relevant compile flags are: ++ ++ -Wall -g -I$prefix/include/valgrind -gdwarf-4 -fdebug-types-section ++ ++ eg -Wall -g -I`pwd`/Inst/include/valgrind -gdwarf-4 -fdebug-types-section ++*/ ++ ++#include ++#include ++#include ++#include "memcheck/memcheck.h" ++ ++/* Cause memcheck to complain about the address "a" and so to print ++ its best guess as to what "a" actually is. a must be ++ addressible. */ ++ ++void croak ( void* aV ) ++{ ++ char* a = (char*)aV; ++ char* undefp = malloc(1); ++ char saved = *a; ++ assert(undefp); ++ *a = *undefp; ++ VALGRIND_CHECK_MEM_IS_DEFINED(a, 1); ++ *a = saved; ++ free(undefp); ++} ++ ++struct s1 ++{ ++ char c; ++ short s; ++ int i; ++ long l; ++ float f; ++ double d; ++}; ++ ++struct s1 S2[30]; ++ ++int main ( void ) ++{ ++ struct s1 local; ++ struct s1* onheap = malloc(sizeof (struct s1)); ++ assert(onheap); ++ croak(&onheap->i); ++ ++ croak( &S2[0].i ); ++ croak( &local.i ); ++ return 0; ++} +--- valgrind-3.7.0/memcheck/tests/dw4.stderr.exp (revision 0) ++++ valgrind-3.7.0/memcheck/tests/dw4.stderr.exp (revision 12491) +@@ -0,0 +1,19 @@ ++Uninitialised byte(s) found during client check request ++ at 0x........: croak (dw4.c:27) ++ by 0x........: main (dw4.c:49) ++ Address 0x........ is 4 bytes inside a block of size 32 alloc'd ++ at 0x........: malloc (vg_replace_malloc.c:...) ++ by 0x........: main (dw4.c:47) ++ ++Uninitialised byte(s) found during client check request ++ at 0x........: croak (dw4.c:27) ++ by 0x........: main (dw4.c:51) ++ Location 0x........ is 0 bytes inside S2[0].i, ++ a global variable declared at dw4.c:42 ++ ++Uninitialised byte(s) found during client check request ++ at 0x........: croak (dw4.c:27) ++ by 0x........: main (dw4.c:52) ++ Location 0x........ is 0 bytes inside local.i, ++ declared at dw4.c:46, in frame #1 of thread 1 ++ +--- valgrind-3.7.0/memcheck/tests/dw4.vgtest (revision 0) ++++ valgrind-3.7.0/memcheck/tests/dw4.vgtest (revision 12491) +@@ -0,0 +1,2 @@ ++prog: dw4 ++vgopts: --read-var-info=yes -q +--- valgrind-3.7.0/configure.in (revision 12490) ++++ valgrind-3.7.0/configure.in (revision 12491) +@@ -1453,6 +1453,26 @@ AC_MSG_RESULT([no]) + CFLAGS=$safe_CFLAGS + + ++# does this compiler support -gdwarf-4 -fdebug-types-section ? ++ ++AC_MSG_CHECKING([if gcc accepts -gdwarf-4 -fdebug-types-section]) ++ ++safe_CFLAGS=$CFLAGS ++CFLAGS="-gdwarf-4 -fdebug-types-section" ++ ++AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ ]], [[ ++ return 0; ++]])], [ ++ac_have_dwarf4=yes ++AC_MSG_RESULT([yes]) ++], [ ++ac_have_dwarf4=no ++AC_MSG_RESULT([no]) ++]) ++AM_CONDITIONAL(DWARF4, test x$ac_have_dwarf4 = xyes) ++CFLAGS=$safe_CFLAGS ++ ++ + # does the linker support -Wl,--build-id=none ? Note, it's + # important that we test indirectly via whichever C compiler + # is selected, rather than testing /usr/bin/ld or whatever +--- valgrind-3.7.0/coregrind/m_debuginfo/readdwarf.c (revision 12490) ++++ valgrind-3.7.0/coregrind/m_debuginfo/readdwarf.c (revision 12491) +@@ -1166,6 +1166,7 @@ void read_unitinfo_dwarf2( /*OUT*/UnitIn + void ML_(read_debuginfo_dwarf3) + ( struct _DebugInfo* di, + UChar* debug_info_img, Word debug_info_sz, /* .debug_info */ ++ 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 */ +--- valgrind-3.7.0/coregrind/m_debuginfo/readelf.c (revision 12490) ++++ valgrind-3.7.0/coregrind/m_debuginfo/readelf.c (revision 12491) +@@ -2072,6 +2072,7 @@ Bool ML_(read_elf_debug_info) ( struct _ + UChar* stabstr_img = NULL; /* .stabstr (stabs) */ + UChar* debug_line_img = NULL; /* .debug_line (dwarf2) */ + UChar* debug_info_img = NULL; /* .debug_info (dwarf2) */ ++ UChar* debug_types_img = NULL; /* .debug_types (dwarf4) */ + UChar* debug_abbv_img = NULL; /* .debug_abbrev (dwarf2) */ + UChar* debug_str_img = NULL; /* .debug_str (dwarf2) */ + UChar* debug_ranges_img = NULL; /* .debug_ranges (dwarf2) */ +@@ -2093,6 +2094,7 @@ Bool ML_(read_elf_debug_info) ( struct _ + SizeT stabstr_sz = 0; + SizeT debug_line_sz = 0; + SizeT debug_info_sz = 0; ++ SizeT debug_types_sz = 0; + SizeT debug_abbv_sz = 0; + SizeT debug_str_sz = 0; + SizeT debug_ranges_sz = 0; +@@ -2168,6 +2170,7 @@ Bool ML_(read_elf_debug_info) ( struct _ + + FIND(".debug_line", debug_line_sz, debug_line_img) + FIND(".debug_info", debug_info_sz, debug_info_img) ++ FIND(".debug_types", debug_types_sz, debug_types_img) + FIND(".debug_abbrev", debug_abbv_sz, debug_abbv_img) + FIND(".debug_str", debug_str_sz, debug_str_img) + FIND(".debug_ranges", debug_ranges_sz, debug_ranges_img) +@@ -2425,6 +2428,8 @@ Bool ML_(read_elf_debug_info) ( struct _ + FIND(need_stabs, ".stabstr", stabstr_sz, stabstr_img) + FIND(need_dwarf2, ".debug_line", debug_line_sz, debug_line_img) + FIND(need_dwarf2, ".debug_info", debug_info_sz, debug_info_img) ++ FIND(need_dwarf2, ".debug_types", debug_types_sz, ++ debug_types_img) + FIND(need_dwarf2, ".debug_abbrev", debug_abbv_sz, debug_abbv_img) + FIND(need_dwarf2, ".debug_str", debug_str_sz, debug_str_img) + FIND(need_dwarf2, ".debug_ranges", debug_ranges_sz, +@@ -2516,6 +2521,7 @@ Bool ML_(read_elf_debug_info) ( struct _ + /* The old reader: line numbers and unwind info only */ + ML_(read_debuginfo_dwarf3) ( di, + debug_info_img, debug_info_sz, ++ debug_types_img, debug_types_sz, + debug_abbv_img, debug_abbv_sz, + debug_line_img, debug_line_sz, + debug_str_img, debug_str_sz ); +@@ -2528,6 +2534,7 @@ Bool ML_(read_elf_debug_info) ( struct _ + || VG_(clo_read_var_info) /* the user asked for it */) { + ML_(new_dwarf3_reader)( + di, debug_info_img, debug_info_sz, ++ debug_types_img, debug_types_sz, + debug_abbv_img, debug_abbv_sz, + debug_line_img, debug_line_sz, + debug_str_img, debug_str_sz, +--- valgrind-3.7.0/coregrind/m_debuginfo/priv_readdwarf.h (revision 12490) ++++ valgrind-3.7.0/coregrind/m_debuginfo/priv_readdwarf.h (revision 12491) +@@ -45,6 +45,7 @@ extern + void ML_(read_debuginfo_dwarf3) + ( struct _DebugInfo* di, + UChar* debug_info_img, Word debug_info_sz, /* .debug_info */ ++ 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 */ +--- valgrind-3.7.0/coregrind/m_debuginfo/readdwarf3.c (revision 12490) ++++ valgrind-3.7.0/coregrind/m_debuginfo/readdwarf3.c (revision 12491) +@@ -140,6 +140,7 @@ + #include "pub_core_libcassert.h" + #include "pub_core_libcprint.h" + #include "pub_core_libcsetjmp.h" // setjmp facilities ++#include "pub_core_hashtable.h" + #include "pub_core_options.h" + #include "pub_core_tooliface.h" /* VG_(needs) */ + #include "pub_core_xarray.h" +@@ -415,6 +416,9 @@ typedef + /* Where is .debug_info? */ + UChar* debug_info_img; + UWord debug_info_sz; ++ /* Where is .debug_types? */ ++ UChar* debug_types_img; ++ UWord debug_types_sz; + /* --- Needed so we can add stuff to the string table. --- */ + struct _DebugInfo* di; + /* --- a cache for set_abbv_Cursor --- */ +@@ -422,10 +426,57 @@ typedef + struct { ULong abbv_code; UWord posn; } saC_cache[N_ABBV_CACHE]; + UWord saC_cache_queries; + UWord saC_cache_misses; ++ ++ /* True if this came from .debug_types; otherwise it came from ++ .debug_info. */ ++ Bool is_type_unit; ++ /* For a unit coming from .debug_types, these hold the TU's type ++ signature and the uncooked DIE offset of the TU's signatured ++ type. For a unit coming from .debug_info, these are unused. */ ++ ULong type_signature; ++ ULong type_offset; ++ ++ /* Signatured type hash; computed once and then shared by all ++ CUs. */ ++ VgHashTable signature_types; + } + 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. */ ++static UWord cook_die( CUConst* cc, UWord die ) ++{ ++ if (cc->is_type_unit) ++ die += cc->debug_info_sz; ++ return die; ++} ++ ++/* Like cook_die, but understand that DIEs coming from a ++ DW_FORM_ref_sig8 reference are already cooked. */ ++static UWord cook_die_using_form( CUConst *cc, UWord die, DW_FORM form) ++{ ++ if (form == DW_FORM_ref_sig8) ++ return die; ++ 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 ) ++{ ++ if (die >= cc->debug_info_sz) { ++ *flag = True; ++ die -= cc->debug_info_sz; ++ } else { ++ *flag = False; ++ } ++ return die; ++} ++ + /*------------------------------------------------------------*/ + /*--- ---*/ + /*--- Helper functions for Guarded Expressions ---*/ +@@ -778,7 +829,8 @@ static __attribute__((noinline)) + void parse_CU_Header ( /*OUT*/CUConst* cc, + Bool td3, + Cursor* c, +- UChar* debug_abbv_img, UWord debug_abbv_sz ) ++ UChar* debug_abbv_img, UWord debug_abbv_sz, ++ Bool type_unit ) + { + UChar address_size; + UWord debug_abbrev_offset; +@@ -816,6 +868,13 @@ void parse_CU_Header ( /*OUT*/CUConst* c + cc->barf( "parse_CU_Header: invalid address_size" ); + TRACE_D3(" Pointer Size: %d\n", (Int)address_size ); + ++ cc->is_type_unit = type_unit; ++ ++ if (type_unit) { ++ cc->type_signature = get_ULong( c ); ++ cc->type_offset = get_Dwarfish_UWord( c, cc->is_dw64 ); ++ } ++ + /* Set up so that cc->debug_abbv points to the relevant table for + this CU. Set the szB so that at least we can't read off the end + of the debug_abbrev section -- potentially (and quite likely) +@@ -926,6 +985,50 @@ void set_abbv_Cursor ( /*OUT*/Cursor* c, + cc->saC_cache[N_ABBV_CACHE/2].posn = get_position_of_Cursor(c); + } + ++/* This represents a single signatured type. It maps a type signature ++ (a ULong) to a cooked DIE offset. Objects of this type are stored ++ in the type signature hash table. */ ++typedef ++ struct D3SignatureType { ++ struct D3SignatureType *next; ++ UWord data; ++ ULong type_signature; ++ UWord die; ++ } ++ D3SignatureType; ++ ++/* Record a signatured type in the hash table. */ ++static void record_signatured_type ( VgHashTable tab, ++ ULong type_signature, ++ UWord die ) ++{ ++ D3SignatureType *dstype = ML_(dinfo_zalloc) ( "di.readdwarf3.sigtype", ++ sizeof(D3SignatureType) ); ++ dstype->data = (UWord) type_signature; ++ dstype->type_signature = type_signature; ++ dstype->die = die; ++ VG_(HT_add_node) ( tab, dstype ); ++} ++ ++/* Given a type signature hash table and a type signature, return the ++ cooked DIE offset of the type. If the type cannot be found, call ++ BARF. */ ++static UWord lookup_signatured_type ( VgHashTable tab, ++ ULong type_signature, ++ void (*barf)( HChar* ) __attribute__((noreturn)) ) ++{ ++ D3SignatureType *dstype = VG_(HT_lookup) ( tab, (UWord) type_signature ); ++ /* This may be unwarranted chumminess with the hash table ++ implementation. */ ++ while ( dstype != NULL && dstype->type_signature != type_signature) ++ dstype = dstype->next; ++ if (dstype == NULL) { ++ barf("lookup_signatured_type: could not find signatured type"); ++ /*NOTREACHED*/ ++ vg_assert(0); ++ } ++ return dstype->die; ++} + + /* From 'c', get the Form data into the lowest 1/2/4/8 bytes of *cts. + +@@ -1164,14 +1267,20 @@ void get_Form_contents ( /*OUT*/ULong* c + } + case DW_FORM_ref_sig8: { + ULong u64b; +- UChar* block = get_address_of_Cursor(c); ++ ULong signature = get_ULong (c); ++ ULong work = signature; + TRACE_D3("8 byte signature: "); + for (u64b = 8; u64b > 0; u64b--) { +- UChar u8 = get_UChar(c); ++ UChar u8 = work & 0xff; + TRACE_D3("%x ", (UInt)u8); ++ work >>= 8; + } +- *cts = (ULong)(UWord)block; +- *ctsMemSzB = 8; ++ /* Due to the way that the hash table is constructed, the ++ resulting DIE offset here is already "cooked". See ++ cook_die_using_form. */ ++ *cts = lookup_signatured_type (cc->signature_types, signature, ++ c->barf); ++ *ctsSzB = sizeof(UWord); + break; + } + case DW_FORM_indirect: +@@ -1468,10 +1577,11 @@ static void parse_var_DIE ( + + 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; + + varstack_preen( parser, td3, level-1 ); + +- if (dtag == DW_TAG_compile_unit) { ++ if (dtag == DW_TAG_compile_unit || dtag == DW_TAG_type_unit) { + Bool have_lo = False; + Bool have_hi1 = False; + Bool have_range = False; +@@ -1685,7 +1795,7 @@ static void parse_var_DIE ( + VG_(addToXA)(gexprs, &gexpr); + } + if (attr == DW_AT_type && ctsSzB > 0) { +- typeR = (UWord)cts; ++ typeR = cook_die_using_form( cc, (UWord)cts, form ); + } + if (attr == DW_AT_external && ctsSzB > 0 && cts > 0) { + external = True; +@@ -1917,7 +2027,12 @@ static void parse_var_DIE ( + 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"); +- VG_(printf)(" <%d><%lx>: %s\n", level, posn, ML_(pp_DW_TAG)( dtag ) ); ++ posn = uncook_die( cc, posn, &debug_types_flag ); ++ VG_(printf)(" <%d><%lx>: %s", level, posn, ML_(pp_DW_TAG)( dtag ) ); ++ if (debug_types_flag) { ++ VG_(printf)(" (in .debug_types)"); ++ } ++ VG_(printf)("\n"); + while (True) { + DW_AT attr = (DW_AT) get_ULEB128( c_abbv ); + DW_FORM form = (DW_FORM)get_ULEB128( c_abbv ); +@@ -2097,6 +2212,7 @@ static void parse_type_DIE ( /*MOD*/XArr + TyEnt atomE; + TyEnt fieldE; + TyEnt boundE; ++ Bool debug_types_flag; + + UWord saved_die_c_offset = get_position_of_Cursor( c_die ); + UWord saved_abbv_c_offset = get_position_of_Cursor( c_abbv ); +@@ -2111,7 +2227,7 @@ static void parse_type_DIE ( /*MOD*/XArr + its children. */ + typestack_preen( parser, td3, level-1 ); + +- if (dtag == DW_TAG_compile_unit) { ++ if (dtag == DW_TAG_compile_unit || dtag == DW_TAG_type_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) */ +@@ -2272,7 +2388,7 @@ static void parse_type_DIE ( /*MOD*/XArr + typeE.Te.TyPorR.szB = cts; + } + if (attr == DW_AT_type && ctsSzB > 0) { +- typeE.Te.TyPorR.typeR = (UWord)cts; ++ typeE.Te.TyPorR.typeR = cook_die_using_form( cc, (UWord)cts, form ); + } + } + /* Do we have something that looks sane? */ +@@ -2317,8 +2433,23 @@ static void parse_type_DIE ( /*MOD*/XArr + /* we must know the size */ + /* but not for Ada, which uses such dummy + enumerations as helper for gdb ada mode. */ +- && parser->language != 'A') +- goto bad_DIE; ++ && parser->language != 'A') { ++ /* GCC has been seen to put an odd DIE like this into ++ .debug_types: ++ ++ <1>: DW_TAG_enumeration_type (in .debug_types) ++ DW_AT_name : (indirect string, offset: 0x3374a): exec_direction_kind ++ DW_AT_declaration : 1 ++ ++ It isn't clear what this means, but we accept it and ++ assume that the enum is int-sized. */ ++ if (cc->is_type_unit) { ++ typeE.Te.TyEnum.szB = sizeof(int); ++ } else { ++ goto bad_DIE; ++ } ++ } ++ + /* On't stack! */ + typestack_push( cc, parser, td3, &typeE, level ); + goto acquire_Type; +@@ -2487,7 +2618,7 @@ static void parse_type_DIE ( /*MOD*/XArr + (UChar*)(UWord)cts ); + } + if (attr == DW_AT_type && ctsSzB > 0) { +- fieldE.Te.Field.typeR = (UWord)cts; ++ fieldE.Te.Field.typeR = cook_die_using_form( cc, (UWord)cts, form ); + } + /* There are 2 different cases for DW_AT_data_member_location. + If it is a constant class attribute, it contains byte offset +@@ -2567,7 +2698,8 @@ static void parse_type_DIE ( /*MOD*/XArr + get_Form_contents( &cts, &ctsSzB, &ctsMemSzB, + cc, c_die, False/*td3*/, form ); + if (attr == DW_AT_type && ctsSzB > 0) { +- typeE.Te.TyArray.typeR = (UWord)cts; ++ typeE.Te.TyArray.typeR = cook_die_using_form( cc, (UWord)cts, ++ form ); + } + } + if (typeE.Te.TyArray.typeR == D3_INVALID_CUOFF) +@@ -2690,7 +2822,8 @@ static void parse_type_DIE ( /*MOD*/XArr + (UChar*)(UWord)cts ); + } + if (attr == DW_AT_type && ctsSzB > 0) { +- typeE.Te.TyTyDef.typeR = (UWord)cts; ++ typeE.Te.TyTyDef.typeR = cook_die_using_form( cc, (UWord)cts, ++ form ); + } + } + /* Do we have something that looks sane? */ +@@ -2733,7 +2866,7 @@ static void parse_type_DIE ( /*MOD*/XArr + get_Form_contents( &cts, &ctsSzB, &ctsMemSzB, + cc, c_die, False/*td3*/, form ); + if (attr == DW_AT_type && ctsSzB > 0) { +- typeE.Te.TyQual.typeR = (UWord)cts; ++ typeE.Te.TyQual.typeR = cook_die_using_form( cc, (UWord)cts, form ); + have_ty++; + } + } +@@ -2813,7 +2946,12 @@ static void parse_type_DIE ( /*MOD*/XArr + 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"); +- VG_(printf)(" <%d><%lx>: %s\n", level, posn, ML_(pp_DW_TAG)( dtag ) ); ++ posn = uncook_die( cc, posn, &debug_types_flag ); ++ VG_(printf)(" <%d><%lx>: %s", level, posn, ML_(pp_DW_TAG)( dtag ) ); ++ if (debug_types_flag) { ++ VG_(printf)(" (in .debug_types)"); ++ } ++ VG_(printf)("\n"); + while (True) { + DW_AT attr = (DW_AT) get_ULEB128( c_abbv ); + DW_FORM form = (DW_FORM)get_ULEB128( c_abbv ); +@@ -3186,7 +3324,7 @@ static void read_DIE ( + UWord after_die_c_offset, after_abbv_c_offset; + + /* --- Deal with this DIE --- */ +- posn = get_position_of_Cursor( c ); ++ posn = cook_die( cc, get_position_of_Cursor( c ) ); + abbv_code = get_ULEB128( c ); + set_abbv_Cursor( &abbv, td3, cc, abbv_code ); + atag = get_ULEB128( &abbv ); +@@ -3284,6 +3422,7 @@ void new_dwarf3_reader_wrk ( + struct _DebugInfo* di, + __attribute__((noreturn)) void (*barf)( HChar* ), + UChar* debug_info_img, SizeT debug_info_sz, ++ UChar* debug_types_img, SizeT debug_types_sz, + UChar* debug_abbv_img, SizeT debug_abbv_sz, + UChar* debug_line_img, SizeT debug_line_sz, + UChar* debug_str_img, SizeT debug_str_sz, +@@ -3310,6 +3449,8 @@ void new_dwarf3_reader_wrk ( + Word i, j, n; + Bool td3 = di->trace_symtab; + XArray* /* of TempVar* */ dioff_lookup_tab; ++ Int pass; ++ VgHashTable signature_types; + #if 0 + /* This doesn't work properly because it assumes all entries are + packed end to end, with no holes. But that doesn't always +@@ -3443,13 +3584,6 @@ void new_dwarf3_reader_wrk ( + } + TRACE_SYMTAB("\n"); + +- /* 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 +- one DW_TAG_compile_unit or DW_TAG_partial_unit DIE. */ +- init_Cursor( &info, debug_info_img, debug_info_sz, 0, barf, +- "Overrun whilst reading .debug_info section" ); +- + /* We'll park the harvested type information in here. Also create + a fake "void" entry with offset D3_FAKEVOID_CUOFF, so we always + have at least one type entry to refer to. D3_FAKEVOID_CUOFF is +@@ -3511,158 +3645,234 @@ void new_dwarf3_reader_wrk ( + VG_(memset)( &varparser, 0, sizeof(varparser) ); + varparser.sp = -1; + +- TRACE_D3("\n------ Parsing .debug_info section ------\n"); +- while (True) { +- UWord cu_start_offset, cu_offset_now; +- CUConst cc; +- /* It may be that the stated size of this CU is larger than the +- amount of stuff actually in it. icc9 seems to generate CUs +- thusly. We use these variables to figure out if this is +- indeed the case, and if so how many bytes we need to skip to +- get to the start of the next CU. Not skipping those bytes +- causes us to misidentify the start of the next CU, and it all +- goes badly wrong after that (not surprisingly). */ +- UWord cu_size_including_IniLen, cu_amount_used; +- +- /* It seems icc9 finishes the DIE info before debug_info_sz +- bytes have been used up. So be flexible, and declare the +- sequence complete if there is not enough remaining bytes to +- hold even the smallest conceivable CU header. (11 bytes I +- reckon). */ +- /* JRS 23Jan09: I suspect this is no longer necessary now that +- the code below contains a 'while (cu_amount_used < +- cu_size_including_IniLen ...' style loop, which skips over +- any leftover bytes at the end of a CU in the case where the +- CU's stated size is larger than its actual size (as +- determined by reading all its DIEs). However, for prudence, +- I'll leave the following test in place. I can't see that a +- CU header can be smaller than 11 bytes, so I don't think +- there's any harm possible through the test -- it just adds +- robustness. */ +- Word avail = get_remaining_length_Cursor( &info ); +- if (avail < 11) { +- if (avail > 0) +- TRACE_D3("new_dwarf3_reader_wrk: warning: " +- "%ld unused bytes after end of DIEs\n", avail); +- break; +- } ++ signature_types = VG_(HT_construct) ("signature_types"); ++ ++ /* Do an initial pass to scan the .debug_types section, if any, and ++ fill in the signatured types hash table. This lets us handle ++ mapping from a type signature to a (cooked) DIE offset directly ++ in get_Form_contents. */ ++ if (debug_types_img != NULL) { ++ init_Cursor( &info, debug_types_img, debug_types_sz, 0, barf, ++ "Overrun whilst reading .debug_types section" ); ++ TRACE_D3("\n------ Collecting signatures from .debug_types section ------\n"); + +- /* Check the varparser's stack is in a sane state. */ +- vg_assert(varparser.sp == -1); +- for (i = 0; i < N_D3_VAR_STACK; i++) { +- vg_assert(varparser.ranges[i] == NULL); +- vg_assert(varparser.level[i] == 0); +- } +- for (i = 0; i < N_D3_TYPE_STACK; i++) { +- vg_assert(typarser.qparentE[i].cuOff == D3_INVALID_CUOFF); +- vg_assert(typarser.qparentE[i].tag == Te_EMPTY); +- vg_assert(typarser.qlevel[i] == 0); ++ while (True) { ++ UWord cu_start_offset, cu_offset_now; ++ CUConst cc; ++ ++ cu_start_offset = get_position_of_Cursor( &info ); ++ TRACE_D3("\n"); ++ 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, ++ True ); ++ ++ /* Needed by cook_die. */ ++ cc.debug_info_sz = debug_info_sz; ++ ++ record_signatured_type( signature_types, cc.type_signature, ++ cook_die( &cc, cc.type_offset )); ++ ++ /* Until proven otherwise we assume we don't need the icc9 ++ workaround in this case; see the DIE-reading loop below ++ for details. */ ++ cu_offset_now = (cu_start_offset + cc.unit_length ++ + (cc.is_dw64 ? 12 : 4)); ++ ++ if (cu_offset_now == debug_types_sz) ++ break; ++ ++ set_position_of_Cursor ( &info, cu_offset_now ); + } ++ } + +- cu_start_offset = get_position_of_Cursor( &info ); +- TRACE_D3("\n"); +- 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 ); +- cc.debug_str_img = debug_str_img; +- cc.debug_str_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.cu_start_offset = cu_start_offset; +- cc.di = di; +- /* The CU's svma can be deduced by looking at the AT_low_pc +- value in the top level TAG_compile_unit, which is the topmost +- DIE. We'll leave it for the 'varparser' to acquire that info +- and fill it in -- since it is the only party to want to know +- it. */ +- cc.cu_svma_known = False; +- cc.cu_svma = 0; +- +- /* Create a fake outermost-level range covering the entire +- address range. So we always have *something* to catch all +- variable declarations. */ +- varstack_push( &cc, &varparser, td3, +- unitary_range_list(0UL, ~0UL), +- -1, False/*isFunc*/, NULL/*fbGX*/ ); +- +- /* And set up the file name table. When we come across the top +- level DIE for this CU (which is what the next call to +- read_DIE should process) we will copy all the file names out +- of the .debug_line img area and use this table to look up the +- copies when we later see filename numbers in DW_TAG_variables +- etc. */ +- vg_assert(!varparser.filenameTable ); +- varparser.filenameTable +- = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.ndrw.5", +- ML_(dinfo_free), +- sizeof(UChar*) ); +- vg_assert(varparser.filenameTable); ++ /* Perform two DIE-reading passes. The first pass reads DIEs from ++ .debug_info, and the second 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) { ++ UWord section_size; ++ ++ if (pass == 0) { ++ /* 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 ++ one DW_TAG_compile_unit or DW_TAG_partial_unit DIE. */ ++ init_Cursor( &info, debug_info_img, debug_info_sz, 0, barf, ++ "Overrun whilst reading .debug_info section" ); ++ section_size = debug_info_sz; + +- /* Now read the one-and-only top-level DIE for this CU. */ +- vg_assert(varparser.sp == 0); +- read_DIE( rangestree, +- tyents, tempvars, gexprs, +- &typarser, &varparser, +- &info, td3, &cc, 0 ); +- +- cu_offset_now = get_position_of_Cursor( &info ); +- +- if (0) VG_(printf)("Travelled: %lu size %llu\n", +- cu_offset_now - cc.cu_start_offset, +- cc.unit_length + (cc.is_dw64 ? 12 : 4)); +- +- /* How big the CU claims it is .. */ +- cu_size_including_IniLen = cc.unit_length + (cc.is_dw64 ? 12 : 4); +- /* .. vs how big we have found it to be */ +- cu_amount_used = cu_offset_now - cc.cu_start_offset; +- +- if (1) TRACE_D3("offset now %ld, d-i-size %ld\n", +- cu_offset_now, debug_info_sz); +- if (cu_offset_now > debug_info_sz) +- barf("toplevel DIEs beyond end of CU"); +- +- /* If the CU is bigger than it claims to be, we've got a serious +- problem. */ +- if (cu_amount_used > cu_size_including_IniLen) +- barf("CU's actual size appears to be larger than it claims it is"); +- +- /* If the CU is smaller than it claims to be, we need to skip some +- bytes. Loop updates cu_offset_new and cu_amount_used. */ +- while (cu_amount_used < cu_size_including_IniLen +- && get_remaining_length_Cursor( &info ) > 0) { +- if (0) VG_(printf)("SKIP\n"); +- (void)get_UChar( &info ); +- cu_offset_now = get_position_of_Cursor( &info ); +- cu_amount_used = cu_offset_now - cc.cu_start_offset; ++ TRACE_D3("\n------ Parsing .debug_info section ------\n"); ++ } else { ++ if (debug_types_img == NULL) ++ continue; ++ init_Cursor( &info, debug_types_img, debug_types_sz, 0, barf, ++ "Overrun whilst reading .debug_types section" ); ++ section_size = debug_types_sz; ++ ++ TRACE_D3("\n------ Parsing .debug_types section ------\n"); + } + +- /* Preen to level -2. DIEs have level >= 0 so -2 cannot occur +- anywhere else at all. Our fake the-entire-address-space +- range is at level -1, so preening to -2 should completely +- empty the stack out. */ +- TRACE_D3("\n"); +- varstack_preen( &varparser, td3, -2 ); +- /* Similarly, empty the type stack out. */ +- typestack_preen( &typarser, td3, -2 ); ++ while (True) { ++ UWord cu_start_offset, cu_offset_now; ++ CUConst cc; ++ /* It may be that the stated size of this CU is larger than the ++ amount of stuff actually in it. icc9 seems to generate CUs ++ thusly. We use these variables to figure out if this is ++ indeed the case, and if so how many bytes we need to skip to ++ get to the start of the next CU. Not skipping those bytes ++ causes us to misidentify the start of the next CU, and it all ++ goes badly wrong after that (not surprisingly). */ ++ UWord cu_size_including_IniLen, cu_amount_used; ++ ++ /* It seems icc9 finishes the DIE info before debug_info_sz ++ bytes have been used up. So be flexible, and declare the ++ sequence complete if there is not enough remaining bytes to ++ hold even the smallest conceivable CU header. (11 bytes I ++ reckon). */ ++ /* JRS 23Jan09: I suspect this is no longer necessary now that ++ the code below contains a 'while (cu_amount_used < ++ cu_size_including_IniLen ...' style loop, which skips over ++ any leftover bytes at the end of a CU in the case where the ++ CU's stated size is larger than its actual size (as ++ determined by reading all its DIEs). However, for prudence, ++ I'll leave the following test in place. I can't see that a ++ CU header can be smaller than 11 bytes, so I don't think ++ there's any harm possible through the test -- it just adds ++ robustness. */ ++ Word avail = get_remaining_length_Cursor( &info ); ++ if (avail < 11) { ++ if (avail > 0) ++ TRACE_D3("new_dwarf3_reader_wrk: warning: " ++ "%ld unused bytes after end of DIEs\n", avail); ++ break; ++ } ++ ++ /* Check the varparser's stack is in a sane state. */ ++ vg_assert(varparser.sp == -1); ++ for (i = 0; i < N_D3_VAR_STACK; i++) { ++ vg_assert(varparser.ranges[i] == NULL); ++ vg_assert(varparser.level[i] == 0); ++ } ++ for (i = 0; i < N_D3_TYPE_STACK; i++) { ++ vg_assert(typarser.qparentE[i].cuOff == D3_INVALID_CUOFF); ++ vg_assert(typarser.qparentE[i].tag == Te_EMPTY); ++ vg_assert(typarser.qlevel[i] == 0); ++ } ++ ++ cu_start_offset = get_position_of_Cursor( &info ); ++ TRACE_D3("\n"); ++ 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; ++ 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_types_img = debug_types_img; ++ cc.debug_types_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 ++ value in the top level TAG_compile_unit, which is the topmost ++ DIE. We'll leave it for the 'varparser' to acquire that info ++ and fill it in -- since it is the only party to want to know ++ it. */ ++ cc.cu_svma_known = False; ++ cc.cu_svma = 0; ++ ++ cc.signature_types = signature_types; ++ ++ /* Create a fake outermost-level range covering the entire ++ address range. So we always have *something* to catch all ++ variable declarations. */ ++ varstack_push( &cc, &varparser, td3, ++ unitary_range_list(0UL, ~0UL), ++ -1, False/*isFunc*/, NULL/*fbGX*/ ); ++ ++ /* And set up the file name table. When we come across the top ++ level DIE for this CU (which is what the next call to ++ read_DIE should process) we will copy all the file names out ++ of the .debug_line img area and use this table to look up the ++ copies when we later see filename numbers in DW_TAG_variables ++ etc. */ ++ vg_assert(!varparser.filenameTable ); ++ varparser.filenameTable ++ = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.ndrw.5", ++ ML_(dinfo_free), ++ sizeof(UChar*) ); ++ vg_assert(varparser.filenameTable); ++ ++ /* Now read the one-and-only top-level DIE for this CU. */ ++ vg_assert(varparser.sp == 0); ++ read_DIE( rangestree, ++ tyents, tempvars, gexprs, ++ &typarser, &varparser, ++ &info, td3, &cc, 0 ); + +- if (cu_offset_now == debug_info_sz) +- break; +- /* else keep going */ ++ cu_offset_now = get_position_of_Cursor( &info ); + +- TRACE_D3("set_abbv_Cursor cache: %lu queries, %lu misses\n", +- cc.saC_cache_queries, cc.saC_cache_misses); ++ if (0) VG_(printf)("Travelled: %lu size %llu\n", ++ cu_offset_now - cc.cu_start_offset, ++ cc.unit_length + (cc.is_dw64 ? 12 : 4)); ++ ++ /* How big the CU claims it is .. */ ++ cu_size_including_IniLen = cc.unit_length + (cc.is_dw64 ? 12 : 4); ++ /* .. vs how big we have found it to be */ ++ cu_amount_used = cu_offset_now - cc.cu_start_offset; + +- vg_assert(varparser.filenameTable ); +- VG_(deleteXA)( varparser.filenameTable ); +- varparser.filenameTable = NULL; ++ if (1) TRACE_D3("offset now %ld, d-i-size %ld\n", ++ cu_offset_now, section_size); ++ if (cu_offset_now > section_size) ++ barf("toplevel DIEs beyond end of CU"); ++ ++ /* If the CU is bigger than it claims to be, we've got a serious ++ problem. */ ++ if (cu_amount_used > cu_size_including_IniLen) ++ barf("CU's actual size appears to be larger than it claims it is"); ++ ++ /* If the CU is smaller than it claims to be, we need to skip some ++ bytes. Loop updates cu_offset_new and cu_amount_used. */ ++ while (cu_amount_used < cu_size_including_IniLen ++ && get_remaining_length_Cursor( &info ) > 0) { ++ if (0) VG_(printf)("SKIP\n"); ++ (void)get_UChar( &info ); ++ cu_offset_now = get_position_of_Cursor( &info ); ++ cu_amount_used = cu_offset_now - cc.cu_start_offset; ++ } ++ ++ /* Preen to level -2. DIEs have level >= 0 so -2 cannot occur ++ anywhere else at all. Our fake the-entire-address-space ++ range is at level -1, so preening to -2 should completely ++ empty the stack out. */ ++ TRACE_D3("\n"); ++ varstack_preen( &varparser, td3, -2 ); ++ /* Similarly, empty the type stack out. */ ++ typestack_preen( &typarser, td3, -2 ); ++ ++ TRACE_D3("set_abbv_Cursor cache: %lu queries, %lu misses\n", ++ cc.saC_cache_queries, cc.saC_cache_misses); ++ ++ vg_assert(varparser.filenameTable ); ++ VG_(deleteXA)( varparser.filenameTable ); ++ varparser.filenameTable = NULL; ++ ++ if (cu_offset_now == section_size) ++ break; ++ /* else keep going */ ++ } + } + + /* From here on we're post-processing the stuff we got +@@ -3973,14 +4183,10 @@ void new_dwarf3_reader_wrk ( + ML_(dinfo_free)( tyents_to_keep_cache ); + tyents_to_keep_cache = NULL; + +- /* and the file name table (just the array, not the entries +- themselves). (Apparently, 2008-Oct-23, varparser.filenameTable +- can be NULL here, for icc9 generated Dwarf3. Not sure what that +- signifies (a deeper problem with the reader?)) */ +- if (varparser.filenameTable) { +- VG_(deleteXA)( varparser.filenameTable ); +- varparser.filenameTable = NULL; +- } ++ vg_assert( varparser.filenameTable == NULL ); ++ ++ /* And the signatured type hash. */ ++ VG_(HT_destruct) ( signature_types, ML_(dinfo_free) ); + + /* record the GExprs in di so they can be freed later */ + vg_assert(!di->admin_gexprs); +@@ -4011,6 +4217,7 @@ void + ML_(new_dwarf3_reader) ( + struct _DebugInfo* di, + UChar* debug_info_img, SizeT debug_info_sz, ++ UChar* debug_types_img, SizeT debug_types_sz, + UChar* debug_abbv_img, SizeT debug_abbv_sz, + UChar* debug_line_img, SizeT debug_line_sz, + UChar* debug_str_img, SizeT debug_str_sz, +@@ -4034,6 +4241,7 @@ ML_(new_dwarf3_reader) ( + /* try this ... */ + new_dwarf3_reader_wrk( di, barf, + debug_info_img, debug_info_sz, ++ debug_types_img, debug_types_sz, + debug_abbv_img, debug_abbv_sz, + debug_line_img, debug_line_sz, + debug_str_img, debug_str_sz, +--- valgrind-3.7.0/coregrind/m_debuginfo/readmacho.c (revision 12490) ++++ valgrind-3.7.0/coregrind/m_debuginfo/readmacho.c (revision 12491) +@@ -1068,6 +1068,7 @@ Bool ML_(read_macho_debug_info)( struct + /* The old reader: line numbers and unwind info only */ + ML_(read_debuginfo_dwarf3) ( di, + debug_info_img, debug_info_sz, ++ NULL, 0, + debug_abbv_img, debug_abbv_sz, + debug_line_img, debug_line_sz, + debug_str_img, debug_str_sz ); +@@ -1080,6 +1081,7 @@ Bool ML_(read_macho_debug_info)( struct + || VG_(clo_read_var_info) /* the user asked for it */) { + ML_(new_dwarf3_reader)( + di, debug_info_img, debug_info_sz, ++ NULL, 0, + debug_abbv_img, debug_abbv_sz, + debug_line_img, debug_line_sz, + debug_str_img, debug_str_sz, +--- valgrind-3.7.0/coregrind/m_debuginfo/priv_readdwarf3.h (revision 12490) ++++ valgrind-3.7.0/coregrind/m_debuginfo/priv_readdwarf3.h (revision 12491) +@@ -43,6 +43,7 @@ void + ML_(new_dwarf3_reader) ( + struct _DebugInfo* di, + UChar* debug_info_img, SizeT debug_info_sz, ++ UChar* debug_types_img, SizeT debug_types_sz, + UChar* debug_abbv_img, SizeT debug_abbv_sz, + UChar* debug_line_img, SizeT debug_line_sz, + UChar* debug_str_img, SizeT debug_str_sz, diff --git a/valgrind-3.7.0-enable-armv5.patch b/valgrind-3.7.0-enable-armv5.patch index 38dba50..845111e 100644 --- a/valgrind-3.7.0-enable-armv5.patch +++ b/valgrind-3.7.0-enable-armv5.patch @@ -1,4 +1,3 @@ -diff -r -u valgrind-3.7.0.old/configure valgrind-3.7.0/configure --- valgrind-3.7.0.old/configure 2012-03-05 15:16:23.000000000 -0500 +++ valgrind-3.7.0/configure 2012-03-05 13:49:04.000000000 -0500 @@ -5279,7 +5279,7 @@ diff --git a/valgrind-3.7.0-ldso-supp.patch b/valgrind-3.7.0-ldso-supp.patch new file mode 100644 index 0000000..1f999b8 --- /dev/null +++ b/valgrind-3.7.0-ldso-supp.patch @@ -0,0 +1,28 @@ +--- valgrind-3.7.0/glibc-2.X.supp.in.jj 2011-10-26 23:24:45.000000000 +0200 ++++ valgrind-3.7.0/glibc-2.X.supp.in 2012-05-07 10:55:20.395942656 +0200 +@@ -124,7 +124,7 @@ + glibc-2.5.x-on-SUSE-10.2-(PPC)-2a + Memcheck:Cond + fun:index +- obj:*ld-@GLIBC_VERSION@.*.so ++ obj:*ld-@GLIBC_VERSION@*.so + } + { + glibc-2.5.x-on-SuSE-10.2-(PPC)-2b +@@ -136,14 +136,14 @@ + glibc-2.5.5-on-SuSE-10.2-(PPC)-2c + Memcheck:Addr4 + fun:index +- obj:*ld-@GLIBC_VERSION@.*.so ++ obj:*ld-@GLIBC_VERSION@*.so + } + { + glibc-2.3.5-on-SuSE-10.1-(PPC)-3 + Memcheck:Addr4 + fun:*wordcopy_fwd_dest_aligned* + fun:mem*cpy +- obj:*lib*@GLIBC_VERSION@.*.so ++ obj:*lib*@GLIBC_VERSION@*.so + } + + { diff --git a/valgrind-3.7.0-unspecified-type.patch b/valgrind-3.7.0-unspecified-type.patch new file mode 100644 index 0000000..f1940cc --- /dev/null +++ b/valgrind-3.7.0-unspecified-type.patch @@ -0,0 +1,24 @@ +--- valgrind-3.7.0/coregrind/m_debuginfo/readdwarf3.c (revision 12337) ++++ valgrind-3.7.0/coregrind/m_debuginfo/readdwarf3.c (revision 12338) +@@ -2723,6 +2723,21 @@ static void parse_type_DIE ( /*MOD*/XArr + goto bad_DIE; + } + ++ /* ++ * Treat DW_TAG_unspecified_type as type void. An example of DW_TAG_unspecified_type: ++ * ++ * $ readelf --debug-dump /usr/lib/debug/usr/lib/libstdc++.so.6.0.16.debug ++ * <1><10d4>: Abbrev Number: 53 (DW_TAG_unspecified_type) ++ * <10d5> DW_AT_name : (indirect string, offset: 0xdb7): decltype(nullptr) ++ */ ++ if (dtag == DW_TAG_unspecified_type) { ++ VG_(memset)(&typeE, 0, sizeof(typeE)); ++ typeE.cuOff = D3_INVALID_CUOFF; ++ typeE.tag = Te_TyQual; ++ typeE.Te.TyQual.typeR = D3_FAKEVOID_CUOFF; ++ goto acquire_Type; ++ } ++ + /* else ignore this DIE */ + return; + /*NOTREACHED*/ diff --git a/valgrind.spec b/valgrind.spec index 1afbc4d..94052ba 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: 2%{?dist} +Release: 3%{?dist} Epoch: 1 License: GPLv2 URL: http://www.valgrind.org/ @@ -20,6 +20,9 @@ Patch9: valgrind-3.7.0-tests.patch Patch10: valgrind-3.7.0-f-sgetown-ex.patch Patch11: valgrind-3.7.0-scsi-ioctls.patch Patch12: valgrind-3.7.0-enable-armv5.patch +Patch13: valgrind-3.7.0-ldso-supp.patch +Patch14: valgrind-3.7.0-unspecified-type.patch +Patch15: valgrind-3.7.0-debug-types.patch Obsoletes: valgrind-callgrind %ifarch x86_64 ppc64 @@ -110,7 +113,10 @@ for details. %patch9 -p1 %patch10 -p1 %patch11 -p1 -%patch12 -p1 -b .arm +%patch12 -p1 +%patch13 -p1 +%patch14 -p1 +%patch15 -p1 %build CC=gcc @@ -205,7 +211,12 @@ echo ===============END TESTING=============== %endif %changelog -* Sun Mar 4 2012 Peter Robinson - 3.7.0-2 +* Mon May 7 2012 Jakub Jelinek 3.7.0-3 +- adjust suppressions so that it works even with ld-2.15.so (#806854) +- handle DW_TAG_unspecified_type (#810284, KDE#278313) +- handle .debug_types sections (#810286, KDE#284124) + +* Sun Mar 4 2012 Peter Robinson 3.7.0-2 - Fix building on ARM platform * Fri Jan 27 2012 Jakub Jelinek 3.7.0-1