diff --git a/valgrind-3.8.1-abbrev-parsing.patch b/valgrind-3.8.1-abbrev-parsing.patch index 05116ad..28ba51f 100644 --- a/valgrind-3.8.1-abbrev-parsing.patch +++ b/valgrind-3.8.1-abbrev-parsing.patch @@ -1,65 +1,160 @@ -Index: coregrind/m_debuginfo/readdwarf.c -=================================================================== ---- valgrind/coregrind/m_debuginfo/readdwarf.c (revision 12871) -+++ valgrind/coregrind/m_debuginfo/readdwarf.c (working copy) -@@ -945,11 +945,11 @@ - /* Return abbrev for given code - * Returned pointer points to the tag - * */ --static UChar* lookup_abbrev( UChar* p, UInt acode ) -+static UChar* lookup_abbrev( UChar* p, UInt acode, UChar* end_img ) - { - UInt code; - UInt name; -- for( ; ; ) { -+ while( p < end_img ) { - code = read_leb128U( &p ); - if ( code == acode ) - return p; -@@ -959,7 +959,7 @@ - name = read_leb128U( &p ); /* name */ - read_leb128U( &p ); /* form */ - } -- while( name != 0 ); /* until name == form == 0 */ -+ while( name != 0 && p < end_img ); /* until name == form == 0 */ - } - return NULL; +commit 58d9ce4730d95103c9388be264a170ab852432a9 +Author: mjw +Date: Thu Apr 11 17:55:39 2013 +0000 + + read_unitinfo_dwarf2 DW_FORM_ref_addr is address size in DWARF version 2. + + Bug #305513 contained a patch for some extra robustness checks. But + the real cause of crashing in the read_unitinfo_dwarf2 DWARF reader + seemed to have been this issue where DWARF version 2 DWZ partial_units + were read and DW_FORM_ref_addr had an unexpected size. This combination + is rare. DWARF version 4 is the current default version of GCC. + + git-svn-id: svn://svn.valgrind.org/valgrind/trunk@13367 a5019735-40e9-0310-863c-91ae7b9d1cf9 + +diff --git a/coregrind/m_debuginfo/readdwarf.c b/coregrind/m_debuginfo/readdwarf.c +index ce34bc7..52a9099 100644 +--- a/coregrind/m_debuginfo/readdwarf.c ++++ b/coregrind/m_debuginfo/readdwarf.c +@@ -991,7 +991,7 @@ void read_unitinfo_dwarf2( /*OUT*/UnitInfo* ui, + UInt acode, abcode; + ULong atoffs, blklen; + Int level; +- /* UShort ver; */ ++ UShort ver; + + UChar addr_size; + UChar* p = unitblock_img; +@@ -1008,7 +1008,7 @@ void read_unitinfo_dwarf2( /*OUT*/UnitInfo* ui, + p += ui->dw64 ? 12 : 4; + + /* version should be 2, 3 or 4 */ +- /* ver = ML_(read_UShort)(p); */ ++ ver = ML_(read_UShort)(p); + p += 2; + + /* get offset in abbrev */ +@@ -1122,7 +1122,7 @@ void read_unitinfo_dwarf2( /*OUT*/UnitInfo* ui, + case 0x0c: /* FORM_flag */ p++; break; + case 0x0d: /* FORM_sdata */ read_leb128S( &p ); break; + case 0x0f: /* FORM_udata */ read_leb128U( &p ); break; +- case 0x10: /* FORM_ref_addr */ p += ui->dw64 ? 8 : 4; break; ++ case 0x10: /* FORM_ref_addr */ p += (ver == 2) ? addr_size : (ui->dw64 ? 8 : 4); break; + case 0x11: /* FORM_ref1 */ p++; break; + case 0x12: /* FORM_ref2 */ p += 2; break; + case 0x13: /* FORM_ref4 */ p += 4; break; + +commit 4c3b2379fb2cb97f762617df7770b042b1f8a59c +Author: mjw +Date: Wed Apr 17 13:48:29 2013 +0000 + + Simplify read_unitinfo_dwarf2. Only try to read the first DIE. + + Bug #305513. We should only read the first DIE of a compilation unit. + Each compilation unit header is followed by a single DW_TAG_compile_unit + (or DW_TAG_partial_unit, but those aren't important here) and its children. + There is no reason to read any of the children at this point. If the first + DIE isn't a DW_TAG_compile_unit we are done, none of the child DIEs will + provide any useful information. + + git-svn-id: svn://svn.valgrind.org/valgrind/trunk@13369 a5019735-40e9-0310-863c-91ae7b9d1cf9 + +diff --git a/coregrind/m_debuginfo/readdwarf.c b/coregrind/m_debuginfo/readdwarf.c +index 52a9099..764295c 100644 +--- a/coregrind/m_debuginfo/readdwarf.c ++++ b/coregrind/m_debuginfo/readdwarf.c +@@ -965,12 +965,14 @@ static UChar* lookup_abbrev( UChar* p, UInt acode ) } -@@ -985,6 +985,7 @@ - void read_unitinfo_dwarf2( /*OUT*/UnitInfo* ui, - UChar* unitblock_img, - UChar* debugabbrev_img, -+ Word debug_abbv_sz, - UChar* debugstr_img, - UChar* debugstr_alt_img ) + + /* Read general information for a particular compile unit block in +- * the .debug_info section. ++ * the .debug_info section. In particular read the name, compdir and ++ * stmt_list needed to parse the line number information. + * + * Input: - unitblock is the start of a compilation + * unit block in .debuginfo section + * - debugabbrev is start of .debug_abbrev section + * - debugstr is start of .debug_str section ++ * - debugstr_alt_img is start of .debug_str section in alt debug file + * + * Output: Fill members of ui pertaining to the compilation unit: + * - ui->name is the name of the compilation unit +@@ -990,7 +992,6 @@ void read_unitinfo_dwarf2( /*OUT*/UnitInfo* ui, { -@@ -1046,7 +1047,12 @@ - * not triggered since we shortcut the parsing once we have - * read the compile_unit block. This should only occur when - * level > 0 */ -- abbrev_img = lookup_abbrev( debugabbrev_img + atoffs, acode ); -+ abbrev_img = lookup_abbrev( debugabbrev_img + atoffs, acode, -+ debugabbrev_img + debug_abbv_sz ); -+ if ( abbrev_img == NULL ) { -+ VG_(printf)( "### unknown abbrev 0x%x\n", acode ); -+ break; -+ } + UInt acode, abcode; + ULong atoffs, blklen; +- Int level; + UShort ver; + + UChar addr_size; +@@ -1021,39 +1022,32 @@ void read_unitinfo_dwarf2( /*OUT*/UnitInfo* ui, + + 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_img ) { +- Bool has_child; ++ /* Read the compilation unit entry - this is always the first DIE. ++ * See DWARF4 para 7.5. */ ++ if ( p < end_img ) { + UInt tag; + + acode = read_leb128U( &p ); /* abbreviation code */ +- if ( acode == 0 ) { +- /* NULL entry used for padding - or last child for a sequence +- - see para 7.5.3 */ +- level--; +- continue; +- } + + /* Read abbreviation header */ + 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 */ ++ /* This isn't illegal, but somewhat unlikely. Normally the ++ * first abbrev describes the first DIE, the compile_unit. ++ * But maybe this abbrevation data is shared with another ++ * or it is a NULL entry used for padding. See para 7.5.3. */ + abbrev_img = lookup_abbrev( debugabbrev_img + atoffs, acode ); } tag = read_leb128U( &abbrev_img ); -@@ -1056,7 +1062,7 @@ - level++; +- has_child = *(abbrev_img++) == 1; /* DW_CHILDREN_yes */ + +- if ( has_child ) +- level++; ++ if ( tag != 0x0011 /*TAG_compile_unit*/ ) ++ return; /* Not a compile unit (might be partial) or broken DWARF. */ ++ ++ abbrev_img++; /* DW_CHILDREN_yes or DW_CHILDREN_no */ /* And loop on entries */ -- for ( ; ; ) { -+ while( p < end_img ) { - /* Read entry definition */ - UInt name, form; - ULong cval = -1LL; /* Constant value read */ -@@ -1221,4 +1227,4 @@ - read_unitinfo_dwarf2( &ui, block_img, -- debug_abbv_img, debug_str_img, -+ debug_abbv_img, debug_abbv_sz, debug_str_img, - debug_str_alt_img ); - if (0) - VG_(printf)( " => LINES=0x%llx NAME=%s DIR=%s\n", + for ( ; ; ) { +@@ -1151,16 +1145,9 @@ void read_unitinfo_dwarf2( /*OUT*/UnitInfo* ui, + else if ( name == 0x10 ) ui->stmt_list = cval; /* DW_AT_stmt_list */ + } + } +- /* Shortcut the parsing once we have read the compile_unit block +- * That's enough info for us, and we are not gdb ! */ +- if ( tag == 0x0011 /*TAG_compile_unit*/ ) +- break; +- } /* Loop on each sub block */ +- +- /* This test would be valid if we were not shortcutting the parsing +- if (level != 0) +- VG_(printf)( "#### Exiting debuginfo block at level %d !!!\n", level ); +- */ ++ } /* Just read the first DIE, if that wasn't the compile_unit then ++ * this might have been a partial unit or broken DWARF info. ++ * That's enough info for us, and we are not gdb ! */ + } + + diff --git a/valgrind.spec b/valgrind.spec index af26117..5037fbf 100644 --- a/valgrind.spec +++ b/valgrind.spec @@ -46,7 +46,7 @@ Patch10: valgrind-3.8.1-x86-backtrace.patch # KDE#305431 - Use find_buildid shdr fallback for separate .debug files Patch11: valgrind-3.8.1-find-buildid.patch -# KDE#305513 - Robustify abbrev reading (part already upstream). +# KDE#305513 - Fix readdwarf.c read_unitinfo_dwarf2 abbrev reading Patch12: valgrind-3.8.1-abbrev-parsing.patch # KDE#307038 - DWARF2 CFI reader: unhandled DW_OP_ opcode 0x8 (DW_OP_const1u)