]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Tolerate apparently broken Dwarf3 generated by gcc (GCC) 4.4.0
authorJulian Seward <jseward@acm.org>
Thu, 23 Oct 2008 10:54:40 +0000 (10:54 +0000)
committerJulian Seward <jseward@acm.org>
Thu, 23 Oct 2008 10:54:40 +0000 (10:54 +0000)
20081017 (experimental): accept DW_TAG_enumerator with only a
DW_AT_name but no DW_AT_const_value.  This is in violation of the
Dwarf3 standard.

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@8700

coregrind/m_debuginfo/priv_tytypes.h
coregrind/m_debuginfo/readdwarf3.c
coregrind/m_debuginfo/tytypes.c

index fd7c3593479a93ca16241bdea4ba3f3f8a072c49..4b6f3e8616b3930f6dea5f7bac65abc8430f99ed 100644 (file)
@@ -72,6 +72,7 @@ typedef
          } UNKNOWN;
          struct {
             UChar* name; /* in mallocville */
+            Bool   valueKnown; /* atoms w/ unknown value are possible */
             Long   value;
          } Atom;
          struct {
index a6d432eee8e224fd41d7104d2147602d26a9e7ef..e67d2ec7e14eab618d03acf53f1544d065f02851 100644 (file)
@@ -2226,8 +2226,37 @@ static void parse_type_DIE ( /*MOD*/XArray* /* of TyEnt */ tyents,
       goto acquire_Type;
    }
 
+   /* gcc (GCC) 4.4.0 20081017 (experimental) occasionally produces
+      DW_TAG_enumerator with only a DW_AT_name but no
+      DW_AT_const_value.  This is in violation of the Dwarf3 standard,
+      and appears to be a new "feature" of gcc - versions 4.3.x and
+      earlier do not appear to do this.  So accept DW_TAG_enumerator
+      which only have a name but no value.  An example:
+
+      <1><180>: Abbrev Number: 6 (DW_TAG_enumeration_type)
+         <181>   DW_AT_name        : (indirect string, offset: 0xda70):
+                                     QtMsgType
+         <185>   DW_AT_byte_size   : 4
+         <186>   DW_AT_decl_file   : 14
+         <187>   DW_AT_decl_line   : 1480
+         <189>   DW_AT_sibling     : <0x1a7>
+      <2><18d>: Abbrev Number: 7 (DW_TAG_enumerator)
+         <18e>   DW_AT_name        : (indirect string, offset: 0x9e18):
+                                     QtDebugMsg
+      <2><192>: Abbrev Number: 7 (DW_TAG_enumerator)
+         <193>   DW_AT_name        : (indirect string, offset: 0x1505f):
+                                     QtWarningMsg
+      <2><197>: Abbrev Number: 7 (DW_TAG_enumerator)
+         <198>   DW_AT_name        : (indirect string, offset: 0x16f4a):
+                                     QtCriticalMsg
+      <2><19c>: Abbrev Number: 7 (DW_TAG_enumerator)
+         <19d>   DW_AT_name        : (indirect string, offset: 0x156dd):
+                                     QtFatalMsg
+      <2><1a1>: Abbrev Number: 7 (DW_TAG_enumerator)
+         <1a2>   DW_AT_name        : (indirect string, offset: 0x13660):
+                                     QtSystemMsg
+   */
    if (dtag == DW_TAG_enumerator) {
-      Bool have_value = False;
       VG_(memset)( &atomE, 0, sizeof(atomE) );
       atomE.cuOff = posn;
       atomE.tag   = Te_Atom;
@@ -2244,11 +2273,11 @@ static void parse_type_DIE ( /*MOD*/XArray* /* of TyEnt */ tyents,
          }
          if (attr == DW_AT_const_value && ctsSzB > 0) {
             atomE.Te.Atom.value = cts;
-            have_value = True;
+            atomE.Te.Atom.valueKnown = True;
          }
       }
       /* Do we have something that looks sane? */
-      if ((!have_value) || atomE.Te.Atom.name == NULL)
+      if (atomE.Te.Atom.name == NULL)
          goto bad_DIE;
       /* Do we have a plausible parent? */
       if (typestack_is_empty(parser)) goto bad_DIE;
index 1d2f5fefbf485a90f244dbf1c9c69f7340265bb4..ad80691f7c08d7d69ddffc0abe624a9f21235b99 100644 (file)
@@ -92,7 +92,8 @@ void ML_(pp_TyEnt)( TyEnt* te )
          VG_(printf)("UNKNOWN");
          break;
       case Te_Atom:
-         VG_(printf)("Te_Atom(%lld,\"%s\")",
+         VG_(printf)("Te_Atom(%s%lld,\"%s\")",
+                     te->Te.Atom.valueKnown ? "" : "unknown:",
                      te->Te.Atom.value, te->Te.Atom.name);
          break;
       case Te_Field:
@@ -459,6 +460,8 @@ Word ML_(TyEnt__cmp_by_all_except_cuOff) ( TyEnt* te1, TyEnt* te2 )
       r = UWord__cmp(te1->Te.INDIR.indR, te2->Te.INDIR.indR);
       return r;
    case Te_Atom:
+      r = Bool__cmp(te1->Te.Atom.valueKnown, te2->Te.Atom.valueKnown);
+      if (r != 0) return r;
       r = Long__cmp(te1->Te.Atom.value, te2->Te.Atom.value);
       if (r != 0) return r;
       r = Asciiz__cmp(te1->Te.Atom.name, te2->Te.Atom.name);