]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
dwarflint: Check for dup attribs between DIE and its DW_AT_abstract_origin
authorPetr Machata <pmachata@redhat.com>
Tue, 27 Oct 2009 15:40:32 +0000 (16:40 +0100)
committerPetr Machata <pmachata@redhat.com>
Wed, 18 Aug 2010 12:55:12 +0000 (14:55 +0200)
src/Makefile.am
src/dwarflint/check_dups_abstract_origin.cc [new file with mode: 0644]
src/dwarflint/checks-high.hh
src/dwarflint/messages.cc
src/dwarflint/messages.h

index 05c994eebbd0dc4671937581a415cc83f02bf282..1a7d10df2e512dea6c463b77459a6b7b48a7f488 100644 (file)
@@ -98,7 +98,8 @@ dwarflint_SOURCES = dwarfstrings.c \
                    dwarflint/check_debug_line.cc \
                    dwarflint/check_matching_ranges.cc \
                    dwarflint/check_range_out_of_scope.cc \
-                   dwarflint/check_expected_trees.cc
+                   dwarflint/check_expected_trees.cc \
+                   dwarflint/check_dups_abstract_origin.cc
 
 readelf_SOURCES = readelf.c dwarfstrings.c
 
diff --git a/src/dwarflint/check_dups_abstract_origin.cc b/src/dwarflint/check_dups_abstract_origin.cc
new file mode 100644 (file)
index 0000000..867779e
--- /dev/null
@@ -0,0 +1,102 @@
+/* Pedantic checking of DWARF files.
+   Copyright (C) 2009 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>.  */
+
+// Implements a check for
+//  https://bugzilla.redhat.com/show_bug.cgi?id=527430
+//
+// Roland: If a given attribute name is present on a DIE, it is
+// suspicious if that attribute name appears on the DIE that's the
+// first DIE's DW_AT_abstract_origin or DW_AT_specification.
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "checks-high.hh"
+#include "dwarfstrings.h"
+#include "all-dies-it.hh"
+#include <map>
+
+using elfutils::dwarf;
+
+namespace
+{
+  class check_dups_abstract_origin
+    : public highlevel_check<check_dups_abstract_origin>
+  {
+  public:
+    explicit check_dups_abstract_origin (dwarflint &lint)
+      : highlevel_check<check_dups_abstract_origin> (lint)
+    {
+      struct {
+       void operator () (dwarf::debug_info_entry const &die,
+                         dwarf::attribute const &attr)
+       {
+         std::map<unsigned int, dwarf::attr_value> m;
+         for (dwarf::debug_info_entry::attributes_type::const_iterator
+                at = die.attributes ().begin ();
+              at != die.attributes ().end (); ++at)
+           m.insert (std::make_pair ((*at).first, (*at).second));
+
+         dwarf::attr_value const &val = attr.second;
+         // xxx Referree can't be const&, gives memory errors.
+         dwarf::debug_info_entry referree = *val.reference ();
+
+         std::map<unsigned int, dwarf::attr_value>::const_iterator at2;
+         for (dwarf::debug_info_entry::attributes_type::const_iterator
+                at = referree.attributes ().begin ();
+              at != referree.attributes ().end (); ++at)
+           if ((at2 = m.find ((*at).first)) != m.end ())
+             wr_message (to_where (die),
+                         cat (mc_impact_3, mc_acc_bloat, mc_die_rel))
+               << "Attribute " << dwarf_attr_string (at2->first)
+               << " is duplicated at " << dwarf_attr_string (attr.first)
+               << " (" << pri::ref (referree) << ")"
+               << (at2->second == (*at).second
+                   ? "." : " with different value.")
+               << std::endl;
+       }
+      } check;
+
+      for (all_dies_iterator<dwarf> it = all_dies_iterator<dwarf> (dw);
+          it != all_dies_iterator<dwarf> (); ++it)
+       {
+         // Do we have DW_AT_abstract_origin or DW_AT_specification?
+         dwarf::debug_info_entry const &die = *it;
+         for (dwarf::debug_info_entry::attributes_type::const_iterator
+                at = die.attributes ().begin ();
+              at != die.attributes ().end (); ++at)
+           if ((*at).first == DW_AT_abstract_origin
+               || (*at).first == DW_AT_specification)
+             {
+               assert ((*at).second.what_space () == dwarf::VS_reference);
+               check (die, *at);
+             }
+       }
+    }
+  };
+
+  reg<check_dups_abstract_origin> reg;
+}
index 1723aac99d906945acf475c762eda72806c15eeb..6e1a63ec989fe21dcd0936d015dd2e306d36a1b5 100644 (file)
@@ -1,3 +1,28 @@
+/* Pedantic checking of DWARF files.
+   Copyright (C) 2009 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>.  */
+
 #include "checks-low.hh"
 #include "config.h"
 #include "c++/dwarf"
@@ -26,3 +51,13 @@ public:
     dwarf_end (_m_handle);
   }
 };
+
+template <class T>
+inline where
+to_where (T const &die)
+{
+  where ret = WHERE (sec_info, NULL);
+  where_reset_1 (&ret, 0);
+  where_reset_2 (&ret, die.offset ());
+  return ret;
+}
index 83e9c94fc6393223a824b9f3dc9246619c57f451..afed6b7645d5aadf74f33487d6bc93e8d4ab490f 100644 (file)
@@ -310,3 +310,11 @@ pri::operator << (std::ostream &os, pri::pribase const &obj)
 {
   return os << obj.m_a << obj.m_b << obj.m_c;
 }
+
+std::ostream &
+pri::operator << (std::ostream &os, pri::ref const &obj)
+{
+  std::stringstream ss;
+  ss << std::hex << "DIE " << obj.off;
+  return os << ss.str ();
+}
index e920e4ffd376b8497d5e8fc9dffc42443ac96f18..8b595f28490772ddc923330383efd5e27edfab8e 100644 (file)
@@ -2,6 +2,7 @@
 #define DWARFLINT_MESSAGES_H
 
 #include "where.h"
+#include "libdw.h"
 
 #ifdef __cplusplus
 # define IF_CPLUSPLUS(X) X
@@ -180,6 +181,18 @@ namespace pri
       : pribase (what, " seems to lack a relocation")
     {}
   };
+
+  class ref
+  {
+    Dwarf_Off off;
+  public:
+    template <class T>
+    ref (T const &die)
+      : off (die.offset ())
+    {}
+    friend std::ostream &operator << (std::ostream &os, ref const &obj);
+  };
+  std::ostream &operator << (std::ostream &os, ref const &obj);
 }
 #endif