summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPetr Machata <[email protected]>2011-03-23 18:44:30 +0100
committerPetr Machata <[email protected]>2011-03-23 18:44:30 +0100
commit3e010bdf21ebb6b8c88cbfe88986bbe20fdee4df (patch)
tree51526ecf45250202f10537dfcee3ac21e543a847
parent4a890d5b2a19e21c5cd1049c4591cc354d9cc5e3 (diff)
dwarflint: Tolerate attributes from all DWARF versions, be less strict
-rw-r--r--dwarflint/Makefile.am6
-rw-r--r--dwarflint/check_debug_abbrev.cc31
-rw-r--r--dwarflint/dwarf_version.cc12
-rw-r--r--dwarflint/dwarf_version.hh3
-rw-r--r--dwarflint/tests/DW_AT-later-version.bz2bin0 -> 591 bytes
-rwxr-xr-xdwarflint/tests/run-DW_AT-later-version.sh35
-rwxr-xr-xdwarflint/tests/run-bad.sh2
-rwxr-xr-xdwarflint/tests/run-libdl-2.12.so.debug.sh10
8 files changed, 77 insertions, 22 deletions
diff --git a/dwarflint/Makefile.am b/dwarflint/Makefile.am
index 4317edc3..2247d0e9 100644
--- a/dwarflint/Makefile.am
+++ b/dwarflint/Makefile.am
@@ -106,7 +106,8 @@ EXTRA_TESTS = tests/run-debug_abbrev-duplicate-attribute.sh \
tests/run-bad.sh \
tests/run-check_self_referential_die.sh \
tests/run-DW_AT_high_pc-relative.sh \
- tests/run-DW_AT_high_pc-below.sh
+ tests/run-DW_AT_high_pc-below.sh \
+ tests/run-DW_AT-later-version.sh
TESTS = $(EXTRA_TESTS) \
tests/test-coverage \
@@ -138,7 +139,8 @@ EXTRA_DIST = $(EXTRA_TESTS) \
tests/garbage-12.bz2 \
tests/check_self_referential_die.bz2 \
tests/DW_AT_high_pc-relative.bz2 \
- tests/DW_AT_high_pc-below.bz2
+ tests/DW_AT_high_pc-below.bz2 \
+ tests/DW_AT-later-version.bz2
installed_TESTS_ENVIRONMENT = libdir=$(DESTDIR)$(libdir) \
bindir=$(DESTDIR)$(bindir) \
diff --git a/dwarflint/check_debug_abbrev.cc b/dwarflint/check_debug_abbrev.cc
index 39b5f316..c8038c6d 100644
--- a/dwarflint/check_debug_abbrev.cc
+++ b/dwarflint/check_debug_abbrev.cc
@@ -156,6 +156,7 @@ namespace
// Tolerate failure here.
dwarf_version const *ver = NULL;
+ static dwarf_version const *latest_ver = dwarf_version::get_latest ();
where.addr1 = 0;
bool failed = false;
@@ -285,7 +286,7 @@ namespace
<< "couldn't load CU headers for processing .debug_abbrev; "
"assuming latest DWARF flavor."
<< std::endl;
- ver = dwarf_version::get_latest ();
+ ver = latest_ver;
}
assert (ver != NULL);
@@ -397,11 +398,24 @@ namespace
attribute const *attribute = ver->get_attribute (attrib_name);
if (attribute == NULL)
{
- wr_error (where)
- << "invalid or unknown name " << pri::hex (attrib_name)
- << '.' << std::endl;
- // libdw should handle unknown attribute, as long as
- // the form is kosher, so don't fail the check.
+ // GCC commonly emits DWARF 2 with trivial extensions
+ // (such as attribute names) from newer versions. In
+ // GNU mode, don't even mind this. In non-gnu, emit
+ // warning. We explicitly don't do this for forms,
+ // where the consumer wouldn't know how to read or
+ // skip the datum.
+ attribute = latest_ver->get_attribute (attrib_name);
+ if (attribute == NULL)
+ // libdw should handle unknown attribute, as long as
+ // the form is kosher, so don't fail the check.
+ wr_message (where, mc_abbrevs | mc_impact_1)
+ << "invalid or unknown name " << pri::hex (attrib_name)
+ << '.' << std::endl;
+ else if (opt_nognu)
+ wr_message (where, mc_abbrevs | mc_impact_1)
+ << "attribute " << *attribute
+ << " from later DWARF version."
+ << std::endl;
}
form const *form = check_debug_abbrev::check_form
@@ -410,7 +424,7 @@ namespace
// Error message has been emitted in check_form.
failed = true;
- if (form == NULL || attribute == NULL)
+ if (form == NULL)
continue;
std::pair<std::map<unsigned, uint64_t>::iterator, bool> inserted
@@ -418,7 +432,8 @@ namespace
if (!inserted.second)
{
wr_error (where)
- << "duplicate attribute " << *attribute
+ << "duplicate attribute "
+ << elfutils::dwarf::attributes::name (attrib_name)
<< " (first was at " << pri::hex (inserted.first->second)
<< ")." << std::endl;
// I think we may allow such files for high-level
diff --git a/dwarflint/dwarf_version.cc b/dwarflint/dwarf_version.cc
index fc4595a6..a74e1699 100644
--- a/dwarflint/dwarf_version.cc
+++ b/dwarflint/dwarf_version.cc
@@ -45,6 +45,9 @@
#include "dwarf_mips.hh"
#include "check_debug_info.hh"
+global_opt<void_option>
+ opt_nognu ("Don't use GNU extension.", "nognu");
+
dw_class_set::dw_class_set (dw_class a, dw_class b, dw_class c,
dw_class d, dw_class e)
{
@@ -118,7 +121,7 @@ form::width (cu_head const *cu_head) const
std::ostream &
operator << (std::ostream &os, form const &obj)
{
- return os << elfutils::dwarf::forms::name (obj.name ());
+ return os << elfutils::dwarf::forms::identifier (obj.name ());
}
namespace
@@ -139,7 +142,7 @@ attribute::attribute (int a_name, dw_class_set const &a_classes)
std::ostream &
operator << (std::ostream &os, attribute const &obj)
{
- return os << elfutils::dwarf::attributes::name (obj.name ());
+ return os << elfutils::dwarf::attributes::identifier (obj.name ());
}
@@ -230,9 +233,6 @@ dwarf_version::extend (dwarf_version const *source,
return new dwarf_version_union (source, extension);
}
-global_opt<void_option>
- nognu ("Don't use GNU extension.", "nognu");
-
namespace
{
dwarf_version const *get_ext ()
@@ -244,7 +244,7 @@ namespace
// need the version to know how to read these attributes in the
// first place.
- if (nognu)
+ if (opt_nognu)
return dwarf_mips_ext ();
else
return dwarf_version::extend (dwarf_mips_ext (), dwarf_gnu_ext ());
diff --git a/dwarflint/dwarf_version.hh b/dwarflint/dwarf_version.hh
index 43df29e9..f130b8d2 100644
--- a/dwarflint/dwarf_version.hh
+++ b/dwarflint/dwarf_version.hh
@@ -31,6 +31,9 @@
#include <iosfwd>
#include "check_debug_info.ii"
#include "dwarf_version.ii"
+#include "option.hh"
+
+extern global_opt<void_option> opt_nognu;
enum dw_class
{
diff --git a/dwarflint/tests/DW_AT-later-version.bz2 b/dwarflint/tests/DW_AT-later-version.bz2
new file mode 100644
index 00000000..2a5690b3
--- /dev/null
+++ b/dwarflint/tests/DW_AT-later-version.bz2
Binary files differ
diff --git a/dwarflint/tests/run-DW_AT-later-version.sh b/dwarflint/tests/run-DW_AT-later-version.sh
new file mode 100755
index 00000000..b2f02658
--- /dev/null
+++ b/dwarflint/tests/run-DW_AT-later-version.sh
@@ -0,0 +1,35 @@
+#! /bin/sh
+# Copyright (C) 2011 Red Hat, Inc.
+# This file is part of Red Hat elfutils.
+#
+# Red Hat elfutils is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by the
+# Free Software Foundation; version 2 of the License.
+#
+# Red Hat elfutils is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with Red Hat elfutils; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA.
+#
+# Red Hat elfutils is an included package of the Open Invention Network.
+# An included package of the Open Invention Network is a package for which
+# Open Invention Network licensees cross-license their patents. No patent
+# license is granted, either expressly or impliedly, by designation as an
+# included package. Should you wish to participate in the Open Invention
+# Network licensing program, please visit www.openinventionnetwork.com
+# <http://www.openinventionnetwork.com>.
+
+. $srcdir/../tests/test-subr.sh
+
+srcdir=$srcdir/tests
+
+testfiles DW_AT-later-version
+
+testrun_compare ./dwarflint --nognu DW_AT-later-version <<EOF
+warning: .debug_abbrev: abbr. attribute 0x15: attribute DW_AT_endianity from later DWARF version.
+warning: .debug_info: DIE 0xb: DW_AT_low_pc value not below DW_AT_high_pc.
+EOF
diff --git a/dwarflint/tests/run-bad.sh b/dwarflint/tests/run-bad.sh
index 6e6db3ff..3080f3e9 100755
--- a/dwarflint/tests/run-bad.sh
+++ b/dwarflint/tests/run-bad.sh
@@ -87,7 +87,7 @@ error: .debug_abbrev: abbr. attribute 0x34: attribute location with invalid form
EOF
testrun_compare ./dwarflint garbage-7 <<EOF
-error: .debug_abbrev: abbr. attribute 0x7e: invalid or unknown name 0x703.
+warning: .debug_abbrev: abbr. attribute 0x7e: invalid or unknown name 0x703.
error: .debug_abbrev: abbr. attribute 0x7e: invalid form 0x0.
error: .debug_abbrev: abbreviation 122: missing zero to mark end-of-table.
EOF
diff --git a/dwarflint/tests/run-libdl-2.12.so.debug.sh b/dwarflint/tests/run-libdl-2.12.so.debug.sh
index c02a8095..f3fbcfb4 100755
--- a/dwarflint/tests/run-libdl-2.12.so.debug.sh
+++ b/dwarflint/tests/run-libdl-2.12.so.debug.sh
@@ -31,11 +31,11 @@ testfiles libdl-2.12.so.debug
# Here we test that dwarflint can tolerate invalid attribute name.
testrun_compare ./dwarflint --check=@low --nognu --ignore-bloat libdl-2.12.so.debug <<EOF
-error: .debug_abbrev: abbr. attribute 0xbe: invalid or unknown name 0x2107.
-error: .debug_abbrev: abbr. attribute 0x330: invalid or unknown name 0x2107.
-error: .debug_abbrev: abbr. attribute 0xa28: invalid or unknown name 0x2107.
-error: .debug_abbrev: abbr. attribute 0x108e: invalid or unknown name 0x2107.
-error: .debug_abbrev: abbr. attribute 0x1300: invalid or unknown name 0x2107.
+warning: .debug_abbrev: abbr. attribute 0xbe: invalid or unknown name 0x2107.
+warning: .debug_abbrev: abbr. attribute 0x330: invalid or unknown name 0x2107.
+warning: .debug_abbrev: abbr. attribute 0xa28: invalid or unknown name 0x2107.
+warning: .debug_abbrev: abbr. attribute 0x108e: invalid or unknown name 0x2107.
+warning: .debug_abbrev: abbr. attribute 0x1300: invalid or unknown name 0x2107.
warning: .debug_info: DIE 0xd9a8: DW_AT_low_pc value not below DW_AT_high_pc.
warning: .debug_info: DIE 0xdcd7: DW_AT_low_pc value not below DW_AT_high_pc.
warning: .debug_info: CU 55709: no aranges table is associated with this CU.