Mark Wielaard ca683f
commit 58d9ce4730d95103c9388be264a170ab852432a9
Mark Wielaard ca683f
Author: mjw <mjw@a5019735-40e9-0310-863c-91ae7b9d1cf9>
Mark Wielaard ca683f
Date:   Thu Apr 11 17:55:39 2013 +0000
Mark Wielaard ca683f
Mark Wielaard ca683f
    read_unitinfo_dwarf2 DW_FORM_ref_addr is address size in DWARF version 2.
Mark Wielaard ca683f
    
Mark Wielaard ca683f
    Bug #305513 contained a patch for some extra robustness checks. But
Mark Wielaard ca683f
    the real cause of crashing in the read_unitinfo_dwarf2 DWARF reader
Mark Wielaard ca683f
    seemed to have been this issue where DWARF version 2 DWZ partial_units
Mark Wielaard ca683f
    were read and DW_FORM_ref_addr had an unexpected size. This combination
Mark Wielaard ca683f
    is rare. DWARF version 4 is the current default version of GCC.
Mark Wielaard ca683f
    
Mark Wielaard ca683f
    git-svn-id: svn://svn.valgrind.org/valgrind/trunk@13367 a5019735-40e9-0310-863c-91ae7b9d1cf9
Mark Wielaard ca683f
Mark Wielaard ca683f
diff --git a/coregrind/m_debuginfo/readdwarf.c b/coregrind/m_debuginfo/readdwarf.c
Mark Wielaard ca683f
index ce34bc7..52a9099 100644
Mark Wielaard ca683f
--- a/coregrind/m_debuginfo/readdwarf.c
Mark Wielaard ca683f
+++ b/coregrind/m_debuginfo/readdwarf.c
Mark Wielaard ca683f
@@ -991,7 +991,7 @@ void read_unitinfo_dwarf2( /*OUT*/UnitInfo* ui,
Mark Wielaard ca683f
    UInt   acode, abcode;
Mark Wielaard ca683f
    ULong  atoffs, blklen;
Mark Wielaard ca683f
    Int    level;
Mark Wielaard ca683f
-   /* UShort ver; */
Mark Wielaard ca683f
+   UShort ver;
Mark Wielaard ca683f
 
Mark Wielaard ca683f
    UChar addr_size;
Mark Wielaard ca683f
    UChar* p = unitblock_img;
Mark Wielaard ca683f
@@ -1008,7 +1008,7 @@ void read_unitinfo_dwarf2( /*OUT*/UnitInfo* ui,
Mark Wielaard ca683f
    p += ui->dw64 ? 12 : 4;
Mark Wielaard ca683f
 
Mark Wielaard ca683f
    /* version should be 2, 3 or 4 */
Mark Wielaard ca683f
-   /* ver = ML_(read_UShort)(p); */
Mark Wielaard ca683f
+   ver = ML_(read_UShort)(p);
Mark Wielaard ca683f
    p += 2;
Mark Wielaard ca683f
 
Mark Wielaard ca683f
    /* get offset in abbrev */
Mark Wielaard ca683f
@@ -1122,7 +1122,7 @@ void read_unitinfo_dwarf2( /*OUT*/UnitInfo* ui,
Mark Wielaard ca683f
             case 0x0c: /* FORM_flag */      p++; break;
Mark Wielaard ca683f
             case 0x0d: /* FORM_sdata */     read_leb128S( &p ); break;
Mark Wielaard ca683f
             case 0x0f: /* FORM_udata */     read_leb128U( &p ); break;
Mark Wielaard ca683f
-            case 0x10: /* FORM_ref_addr */  p += ui->dw64 ? 8 : 4; break;
Mark Wielaard ca683f
+            case 0x10: /* FORM_ref_addr */  p += (ver == 2) ? addr_size : (ui->dw64 ? 8 : 4); break;
Mark Wielaard ca683f
             case 0x11: /* FORM_ref1 */      p++; break;
Mark Wielaard ca683f
             case 0x12: /* FORM_ref2 */      p += 2; break;
Mark Wielaard ca683f
             case 0x13: /* FORM_ref4 */      p += 4; break;
Mark Wielaard ca683f
Mark Wielaard ca683f
commit 4c3b2379fb2cb97f762617df7770b042b1f8a59c
Mark Wielaard ca683f
Author: mjw <mjw@a5019735-40e9-0310-863c-91ae7b9d1cf9>
Mark Wielaard ca683f
Date:   Wed Apr 17 13:48:29 2013 +0000
Mark Wielaard ca683f
Mark Wielaard ca683f
    Simplify read_unitinfo_dwarf2. Only try to read the first DIE.
Mark Wielaard ca683f
    
Mark Wielaard ca683f
    Bug #305513. We should only read the first DIE of a compilation unit.
Mark Wielaard ca683f
    Each compilation unit header is followed by a single DW_TAG_compile_unit
Mark Wielaard ca683f
    (or DW_TAG_partial_unit, but those aren't important here) and its children.
Mark Wielaard ca683f
    There is no reason to read any of the children at this point. If the first
Mark Wielaard ca683f
    DIE isn't a DW_TAG_compile_unit we are done, none of the child DIEs will
Mark Wielaard ca683f
    provide any useful information.
Mark Wielaard ca683f
    
Mark Wielaard ca683f
    git-svn-id: svn://svn.valgrind.org/valgrind/trunk@13369 a5019735-40e9-0310-863c-91ae7b9d1cf9
Mark Wielaard ca683f
Mark Wielaard ca683f
diff --git a/coregrind/m_debuginfo/readdwarf.c b/coregrind/m_debuginfo/readdwarf.c
Mark Wielaard ca683f
index 52a9099..764295c 100644
Mark Wielaard ca683f
--- a/coregrind/m_debuginfo/readdwarf.c
Mark Wielaard ca683f
+++ b/coregrind/m_debuginfo/readdwarf.c
Mark Wielaard ca683f
@@ -965,12 +965,14 @@ static UChar* lookup_abbrev( UChar* p, UInt acode )
Mark Wielaard ee9108
 }
Mark Wielaard ca683f
 
Mark Wielaard ca683f
 /* Read general information for a particular compile unit block in
Mark Wielaard ca683f
- * the .debug_info section.
Mark Wielaard ca683f
+ * the .debug_info section. In particular read the name, compdir and
Mark Wielaard ca683f
+ * stmt_list needed to parse the line number information.
Mark Wielaard ca683f
  * 
Mark Wielaard ca683f
  * Input: - unitblock is the start of a compilation
Mark Wielaard ca683f
  *          unit block in .debuginfo section
Mark Wielaard ca683f
  *        - debugabbrev is start of .debug_abbrev section
Mark Wielaard ca683f
  *        - debugstr is start of .debug_str section
Mark Wielaard ca683f
+ *        - debugstr_alt_img is start of .debug_str section in alt debug file
Mark Wielaard ca683f
  *        
Mark Wielaard ca683f
  * Output: Fill members of ui pertaining to the compilation unit:
Mark Wielaard ca683f
  *         - ui->name is the name of the compilation unit
Mark Wielaard ca683f
@@ -990,7 +992,6 @@ void read_unitinfo_dwarf2( /*OUT*/UnitInfo* ui,
Mark Wielaard ee9108
 {
Mark Wielaard ca683f
    UInt   acode, abcode;
Mark Wielaard ca683f
    ULong  atoffs, blklen;
Mark Wielaard ca683f
-   Int    level;
Mark Wielaard ca683f
    UShort ver;
Mark Wielaard ca683f
 
Mark Wielaard ca683f
    UChar addr_size;
Mark Wielaard ca683f
@@ -1021,39 +1022,32 @@ void read_unitinfo_dwarf2( /*OUT*/UnitInfo* ui,
Mark Wielaard ca683f
 
Mark Wielaard ca683f
    end_img     = unitblock_img 
Mark Wielaard ca683f
                  + blklen + (ui->dw64 ? 12 : 4); /* End of this block */
Mark Wielaard ca683f
-   level       = 0;                        /* Level in the abbrev tree */
Mark Wielaard ca683f
    abbrev_img  = debugabbrev_img 
Mark Wielaard ca683f
                  + atoffs; /* Abbreviation data for this block */
Mark Wielaard ca683f
    
Mark Wielaard ca683f
-   /* Read the compilation unit entries */
Mark Wielaard ca683f
-   while ( p < end_img ) {
Mark Wielaard ca683f
-      Bool has_child;
Mark Wielaard ca683f
+   /* Read the compilation unit entry - this is always the first DIE.
Mark Wielaard ca683f
+    * See DWARF4 para 7.5. */
Mark Wielaard ca683f
+   if ( p < end_img ) {
Mark Wielaard ca683f
       UInt tag;
Mark Wielaard ca683f
 
Mark Wielaard ca683f
       acode = read_leb128U( &p ); /* abbreviation code */
Mark Wielaard ca683f
-      if ( acode == 0 ) {
Mark Wielaard ca683f
-         /* NULL entry used for padding - or last child for a sequence
Mark Wielaard ca683f
-            - see para 7.5.3 */
Mark Wielaard ca683f
-         level--;
Mark Wielaard ca683f
-         continue;
Mark Wielaard ca683f
-      }
Mark Wielaard ca683f
       
Mark Wielaard ca683f
       /* Read abbreviation header */
Mark Wielaard ca683f
       abcode = read_leb128U( &abbrev_img ); /* abbreviation code */
Mark Wielaard ca683f
       if ( acode != abcode ) {
Mark Wielaard ca683f
-         /* We are in in children list, and must rewind to a
Mark Wielaard ca683f
-          * previously declared abbrev code.  This code works but is
Mark Wielaard ca683f
-          * not triggered since we shortcut the parsing once we have
Mark Wielaard ca683f
-          * read the compile_unit block.  This should only occur when
Mark Wielaard ca683f
-          * level > 0 */
Mark Wielaard ca683f
+         /* This isn't illegal, but somewhat unlikely. Normally the
Mark Wielaard ca683f
+          * first abbrev describes the first DIE, the compile_unit.
Mark Wielaard ca683f
+          * But maybe this abbrevation data is shared with another
Mark Wielaard ca683f
+          * or it is a NULL entry used for padding. See para 7.5.3. */
Mark Wielaard ca683f
          abbrev_img = lookup_abbrev( debugabbrev_img + atoffs, acode );
Mark Wielaard ee9108
       }
Mark Wielaard ee9108
 
Mark Wielaard ee9108
       tag = read_leb128U( &abbrev_img );
Mark Wielaard ca683f
-      has_child = *(abbrev_img++) == 1; /* DW_CHILDREN_yes */
Mark Wielaard ca683f
 
Mark Wielaard ca683f
-      if ( has_child )
Mark Wielaard ca683f
-         level++;
Mark Wielaard ca683f
+      if ( tag != 0x0011 /*TAG_compile_unit*/ )
Mark Wielaard ca683f
+         return; /* Not a compile unit (might be partial) or broken DWARF. */
Mark Wielaard ca683f
+
Mark Wielaard ca683f
+      abbrev_img++; /* DW_CHILDREN_yes or DW_CHILDREN_no */
Mark Wielaard ee9108
 
Mark Wielaard ee9108
       /* And loop on entries */
Mark Wielaard ca683f
       for ( ; ; ) {
Mark Wielaard ca683f
@@ -1151,16 +1145,9 @@ void read_unitinfo_dwarf2( /*OUT*/UnitInfo* ui,
Mark Wielaard ca683f
             else if ( name == 0x10 ) ui->stmt_list = cval; /* DW_AT_stmt_list */
Mark Wielaard ca683f
          }
Mark Wielaard ca683f
       }
Mark Wielaard ca683f
-      /* Shortcut the parsing once we have read the compile_unit block
Mark Wielaard ca683f
-       * That's enough info for us, and we are not gdb ! */
Mark Wielaard ca683f
-      if ( tag == 0x0011 /*TAG_compile_unit*/ )
Mark Wielaard ca683f
-         break;
Mark Wielaard ca683f
-   } /* Loop on each sub block */
Mark Wielaard ca683f
-
Mark Wielaard ca683f
-   /* This test would be valid if we were not shortcutting the parsing
Mark Wielaard ca683f
-   if (level != 0)
Mark Wielaard ca683f
-      VG_(printf)( "#### Exiting debuginfo block at level %d !!!\n", level );
Mark Wielaard ca683f
-   */
Mark Wielaard ca683f
+   } /* Just read the first DIE, if that wasn't the compile_unit then
Mark Wielaard ca683f
+      * this might have been a partial unit or broken DWARF info.
Mark Wielaard ca683f
+      * That's enough info for us, and we are not gdb ! */
Mark Wielaard ca683f
 }
Mark Wielaard ca683f
 
Mark Wielaard ca683f