Tolerate apparently broken Dwarf3 generated by gcc (GCC) 4.4.0
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 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/coregrind/m_debuginfo/priv_tytypes.h b/coregrind/m_debuginfo/priv_tytypes.h
index fd7c359..4b6f3e8 100644
--- a/coregrind/m_debuginfo/priv_tytypes.h
+++ b/coregrind/m_debuginfo/priv_tytypes.h
@@ -72,6 +72,7 @@
} UNKNOWN;
struct {
UChar* name; /* in mallocville */
+ Bool valueKnown; /* atoms w/ unknown value are possible */
Long value;
} Atom;
struct {
diff --git a/coregrind/m_debuginfo/readdwarf3.c b/coregrind/m_debuginfo/readdwarf3.c
index a6d432e..e67d2ec 100644
--- a/coregrind/m_debuginfo/readdwarf3.c
+++ b/coregrind/m_debuginfo/readdwarf3.c
@@ -2226,8 +2226,37 @@
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 @@
}
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;
diff --git a/coregrind/m_debuginfo/tytypes.c b/coregrind/m_debuginfo/tytypes.c
index 1d2f5fe..ad80691 100644
--- a/coregrind/m_debuginfo/tytypes.c
+++ b/coregrind/m_debuginfo/tytypes.c
@@ -92,7 +92,8 @@
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 @@
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);