]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
dwarflint: Add a lowlevel_checks pass
authorPetr Machata <pmachata@redhat.com>
Tue, 7 Sep 2010 21:08:05 +0000 (23:08 +0200)
committerPetr Machata <pmachata@redhat.com>
Tue, 7 Sep 2010 21:08:05 +0000 (23:08 +0200)
- which is where low-level checks are explicitly requested
- and what highlevel checks, also explicitly, depend on

33 files changed:
dwarflint/Makefile.am
dwarflint/TODO
dwarflint/check_debug_abbrev.cc
dwarflint/check_debug_abbrev.hh
dwarflint/check_debug_aranges.cc
dwarflint/check_debug_aranges.hh
dwarflint/check_debug_info.cc
dwarflint/check_debug_info.hh
dwarflint/check_debug_line.cc
dwarflint/check_debug_line.hh
dwarflint/check_debug_loc_range.cc
dwarflint/check_debug_loc_range.hh
dwarflint/check_debug_pub.cc
dwarflint/check_debug_pub.hh
dwarflint/check_duplicate_DW_tag_variable.cc
dwarflint/check_dups_abstract_origin.cc
dwarflint/check_expected_trees.cc
dwarflint/check_matching_ranges.cc
dwarflint/check_range_out_of_scope.cc
dwarflint/checkdescriptor.cc
dwarflint/checkdescriptor.hh
dwarflint/checks.hh
dwarflint/cu_coverage.cc
dwarflint/cu_coverage.hh
dwarflint/dwarflint.cc
dwarflint/dwarflint.hh
dwarflint/highlevel_check.cc
dwarflint/highlevel_check.hh
dwarflint/lowlevel_checks.cc [new file with mode: 0644]
dwarflint/lowlevel_checks.hh [new file with mode: 0644]
dwarflint/messages.h
dwarflint/sections.cc
dwarflint/sections.hh

index c8cb062dc717ea6dea08b110958ac818aaff33f1..1f6c84e20cc66031dfd18114469497685fde16f6 100644 (file)
@@ -64,6 +64,7 @@ dwarflint_SOURCES = \
        check_debug_pub.cc check_debug_pub.hh \
        check_debug_loc_range.cc check_debug_loc_range.hh check_debug_loc_range.ii \
        check_debug_aranges.cc check_debug_aranges.hh \
+       lowlevel_checks.cc lowlevel_checks.hh \
        check_matching_ranges.cc \
        check_range_out_of_scope.cc \
        check_expected_trees.cc \
index 2a2060a100e90ef29be0c35a4d4fc34ba8543a3a..0f374ca24b58cb65f8c739862d01689623d7c5f1 100644 (file)
@@ -1,14 +1,4 @@
 -*-org-*-
-* resolver
-** ordering
-   High-level checks implicitly depend on low-level checks of the
-   sections that they use, but since there is no explicit need to
-   access any of the low-level variables, these dependencies are not
-   visible in the source.  So right now high-level checks will happily
-   run even when no low-level checks passed, and can ever run before
-   any of the low-level checks, since the dependency resolver has no
-   idea that there is a dependency in the first place.
-
 * DWARF 4 support
   This TODO item is actually to go through the DWARF 4 standard and
   add TODO items for individual tasks.
@@ -18,6 +8,13 @@
   can be either constant or *ptr in DWARF<=3 but only sec_offset is
   *ptr in DWARF>=4.
 
+* low-level checks
+** error out on incomplete debuginfo
+   Right now, without --strict, running dwarflint on a binary compiled
+   without debuginfo gives no errors.  On the other hand, with
+   --strict, dwarflint errors out on any debug section that's not
+   there, which is also wrong.  Fix it.
+
 * high-level checks
 
 ** DW_OP_GNU_implicit_pointer
index 8ee63dfb5866c13c243dfae515355fb02639f0b2..ad4c284329516fa5760dbf4961148c4369324a59 100644 (file)
@@ -38,9 +38,7 @@
 #include <cassert>
 #include <algorithm>
 
-static reg<check_debug_abbrev> reg_debug_abbrev;
-
-checkdescriptor &
+checkdescriptor const *
 check_debug_abbrev::descriptor ()
 {
   static checkdescriptor cd
@@ -73,7 +71,7 @@ check_debug_abbrev::descriptor ()
 "many checks will still be done, operating under assumption that what\n"
 "we see is the latest DWARF format.  This may render some checks\n"
 "inaccurate.\n"));
-  return cd;
+  return &cd;
 }
 
 struct abbrev *
index f1aef31ea3e126d021ff04ee9c1fbe358b581b19..11cd1dec87bfb71bfd06fac5165cad461edd7a2e 100644 (file)
@@ -38,7 +38,7 @@ class check_debug_abbrev
   read_cu_headers *_m_cu_headers;
 
 public:
-  static checkdescriptor &descriptor ();
+  static checkdescriptor const *descriptor ();
 
   // offset -> abbreviations
   typedef std::map< ::Dwarf_Off, abbrev_table> abbrev_map;
index 4d87b4022a1732cde9ee07af575bbaa0d319230c..9918030f832e6e6dfb169b84999c204d66399c55 100644 (file)
@@ -34,9 +34,7 @@
 #include "check_debug_loc_range.hh"
 #include "cu_coverage.hh"
 
-static reg<check_debug_aranges> reg_debug_aranges;
-
-checkdescriptor
+checkdescriptor const *
 check_debug_aranges::descriptor ()
 {
   static checkdescriptor cd
@@ -55,7 +53,7 @@ check_debug_aranges::descriptor ()
 " - for zero-length ranges\n"
 " - that the ranges cover all the address range covered by CUs\n"
                   ));
-  return cd;
+  return &cd;
 }
 
 check_debug_aranges::check_debug_aranges (checkstack &stack, dwarflint &lint)
index 993a221ada9956fd46b5cbf49251334e99528b99..dbd0726eb24009795f65cde21dc0f9e134a31fd1 100644 (file)
@@ -40,7 +40,7 @@ class check_debug_aranges
   cu_coverage *_m_cu_coverage;
 
 public:
-  static checkdescriptor descriptor ();
+  static checkdescriptor const *descriptor ();
   check_debug_aranges (checkstack &stack, dwarflint &lint);
 };
 
index 631083e0b55fbe2182f6f054d9f1edd66c4a6a38..8e8a36f0d9aae9b110203823587cee031bf5a600 100644 (file)
 #include "check_debug_info.hh"
 #include "check_debug_line.hh"
 
-checkdescriptor const &
+checkdescriptor const *
 read_cu_headers::descriptor ()
 {
   static checkdescriptor cd
     (checkdescriptor::create ("read_cu_headers")
      .prereq<typeof (*_m_sec_info)> ());
-  return cd;
+  return &cd;
 }
 
-static reg<check_debug_info> reg_debug_info;
-
-checkdescriptor const &
+checkdescriptor const *
 check_debug_info::descriptor ()
 {
   static checkdescriptor cd
     (checkdescriptor::create ("check_debug_info")
      .groups ("@low")
      .prereq<typeof (*_m_sec_info)> ()
-     .prereq<typeof (*_m_sec_abbrev)> ()
      .prereq<typeof (*_m_sec_str)> ()
      .prereq<typeof (*_m_abbrevs)> ()
      .prereq<typeof (*_m_cu_headers)> ()
@@ -93,7 +90,7 @@ check_debug_info::descriptor ()
 " - that relocations are valid.  In ET_REL files that certain fields\n"
 "   are relocated\n"
                   ));
-  return cd;
+  return &cd;
 }
 
 namespace
@@ -1223,7 +1220,6 @@ check_debug_info::check_info_structural ()
 
 check_debug_info::check_debug_info (checkstack &stack, dwarflint &lint)
   : _m_sec_info (lint.check (stack, _m_sec_info))
-  , _m_sec_abbrev (lint.check (stack, _m_sec_abbrev))
   , _m_sec_str (lint.check (stack, _m_sec_str))
   , _m_file (_m_sec_info->file)
   , _m_abbrevs (lint.check (stack, _m_abbrevs))
@@ -1274,7 +1270,7 @@ check_debug_info::find_cu (::Dwarf_Off offset)
   return NULL;
 }
 
-checkdescriptor const &
+checkdescriptor const *
 check_debug_info_refs::descriptor ()
 {
   static checkdescriptor cd
@@ -1286,7 +1282,7 @@ check_debug_info_refs::descriptor ()
 "This pass checks for outstanding unresolved references from\n"
 ".debug_info to .debug_line (and perhaps others as they are\n"
 "identified).\n"));
-  return cd;
+  return &cd;
 }
 
 check_debug_info_refs::check_debug_info_refs (checkstack &stack,
@@ -1303,4 +1299,3 @@ check_debug_info_refs::check_debug_info_refs (checkstack &stack,
        << "unresolved reference to .debug_line table "
        << pri::hex (it->stmt_list.addr) << '.' << std::endl;
 }
-static reg<check_debug_info_refs> reg_debug_info_refs;
index 81827126fec43f547930a4014427d223a25d4e30..df80baa0c0a73ab1810d0cbfe362e9b163daaa1c 100644 (file)
@@ -40,7 +40,7 @@ class read_cu_headers
   section<sec_info> *_m_sec_info;
 
 public:
-  static checkdescriptor const &descriptor ();
+  static checkdescriptor const *descriptor ();
   std::vector<cu_head> const cu_headers;
   read_cu_headers (checkstack &stack, dwarflint &lint);
 };
@@ -50,7 +50,6 @@ class check_debug_info
   : public check<check_debug_info>
 {
   section<sec_info> *_m_sec_info;
-  section<sec_abbrev> *_m_sec_abbrev;
   section<sec_str> *_m_sec_str;
   elf_file const &_m_file;
   check_debug_abbrev *_m_abbrevs;
@@ -78,7 +77,7 @@ class check_debug_info
   void check_info_structural ();
 
 public:
-  static checkdescriptor const &descriptor ();
+  static checkdescriptor const *descriptor ();
 
   coverage const &cov () const { return _m_cov; }
   bool need_ranges () const { return _m_need_ranges; }
@@ -101,7 +100,7 @@ class check_debug_info_refs
   check_debug_line *_m_line;
 
 public:
-  static checkdescriptor const &descriptor ();
+  static checkdescriptor const *descriptor ();
   check_debug_info_refs (checkstack &stack, dwarflint &lint);
 };
 
index 7445fe74d5526c8d8590e32210f30bd64e54fafb..a383e953fec47452eec1818afc1a9bb1c3f6402e 100644 (file)
@@ -34,7 +34,7 @@
 
 #include <sstream>
 
-checkdescriptor const &
+checkdescriptor const *
 check_debug_line::descriptor ()
 {
   static checkdescriptor cd
@@ -68,9 +68,8 @@ check_debug_line::descriptor ()
 "   should be consistent in that case, namely is_stmt, basic_block,\n"
 "   end_sequence, prologue_end, epilogue_begin, isa.\n"
                   ));
-  return cd;
+  return &cd;
 }
-static reg<check_debug_line> reg_debug_line;
 
 namespace
 {
index fc7aa4dfd473172b943a7b2944f88533c3fdc9d6..a70982d170d380ce8dd8681919cf42477cd142fe 100644 (file)
@@ -40,7 +40,7 @@ class check_debug_line
   std::set<Dwarf_Off> _m_line_tables;
 
 public:
-  static checkdescriptor const &descriptor ();
+  static checkdescriptor const *descriptor ();
   check_debug_line (checkstack &stack, dwarflint &lint);
 
   std::set<Dwarf_Off> const &line_tables () const { return _m_line_tables; }
index e1b397183945eac2111adb7f488a708de6cfd3e8..d664122e60df62ff7099d895fb8dbf4d741d42dc 100644 (file)
@@ -45,9 +45,7 @@
 #include "../src/dwarf-opcodes.h"
 #include "pri.hh"
 
-static reg<check_debug_ranges> reg_debug_ranges;
-
-checkdescriptor const &
+checkdescriptor const *
 check_debug_ranges::descriptor ()
 {
   static checkdescriptor cd
@@ -67,12 +65,10 @@ check_debug_ranges::descriptor ()
 " - neither or both of range start and range end are expected to be\n"
 "   relocated.  It's expected that they are both relocated against the\n"
 "   same section.\n"));
-  return cd;
+  return &cd;
 }
 
-static reg<check_debug_loc> reg_debug_loc;
-
-checkdescriptor const &
+checkdescriptor const *
 check_debug_loc::descriptor ()
 {
   static checkdescriptor cd
@@ -92,7 +88,7 @@ check_debug_loc::descriptor ()
 " - on 32-bit machines it rejects DW_OP_const8u and DW_OP_const8s\n"
 " - on 32-bit machines it checks that ULEB128-encoded arguments aren't\n"
 "   quantities that don't fit into 32 bits\n"));
-  return cd;
+  return &cd;
 }
 
 namespace
index c3737e1ce56869c4a3f0a0def09d6adcaa0239ad..2f8138f9714083ec12869ebdd15fe979c1f1cf29 100644 (file)
@@ -38,7 +38,7 @@ class check_debug_ranges
   coverage _m_cov;
 
 public:
-  static checkdescriptor const &descriptor ();
+  static checkdescriptor const *descriptor ();
 
   coverage const &cov () const { return _m_cov; }
   check_debug_ranges (checkstack &stack, dwarflint &lint);
@@ -52,7 +52,7 @@ class check_debug_loc
   check_debug_info *_m_info;
 
 public:
-  static checkdescriptor const &descriptor ();
+  static checkdescriptor const *descriptor ();
   check_debug_loc (checkstack &stack, dwarflint &lint);
 };
 
index 82eab1d2773483ba35583ad1f60c50b5c199e006..0ce3ff60e97e723f6067802e47fd16134783f870 100644 (file)
@@ -47,7 +47,7 @@ check_debug_pub<sec_id>::check_debug_pub (checkstack &stack, dwarflint &lint)
 }
 
 
-checkdescriptor const &
+checkdescriptor const *
 check_debug_pubnames::descriptor ()
 {
   static checkdescriptor cd
@@ -64,13 +64,12 @@ check_debug_pubnames::descriptor ()
 "Furthermore, if .debug_info is valid, it is checked:\n"
 " - that references point to actual CUs and DIEs\n"
 " - that there's only one pub section per CU\n"));
-  return cd;
+  return &cd;
 }
-static reg<check_debug_pubnames> reg_debug_pubnames;
 template check_debug_pub<sec_pubnames>::check_debug_pub (checkstack &stack,
                                                         dwarflint &lint);
 
-checkdescriptor const &
+checkdescriptor const *
 check_debug_pubtypes::descriptor ()
 {
   static checkdescriptor cd
@@ -81,9 +80,8 @@ check_debug_pubtypes::descriptor ()
      .description (
 "Checks for low-level structure of .debug_pubtypes.  In addition it\n"
 "makes the same checks as check_debug_pubnames.\n"));
-  return cd;
+  return &cd;
 }
-static reg<check_debug_pubtypes> reg_debug_pubtypes;
 template check_debug_pub<sec_pubtypes>::check_debug_pub (checkstack &stack,
                                                         dwarflint &lint);
 
index 1f3e35cfd065845c039e9d45590bebdbbe6e57bf..97415f8c81574de6df7047e0f9a52f4ee7f5f9cd 100644 (file)
@@ -51,7 +51,7 @@ public:
 struct check_debug_pubnames
   : public check_debug_pub<sec_pubnames>
 {
-  static checkdescriptor const &descriptor ();
+  static checkdescriptor const *descriptor ();
 
   check_debug_pubnames (checkstack &stack, dwarflint &lint)
     : check_debug_pub<sec_pubnames> (stack, lint)
@@ -61,7 +61,7 @@ struct check_debug_pubnames
 struct check_debug_pubtypes
   : public check_debug_pub<sec_pubtypes>
 {
-  static checkdescriptor const &descriptor ();
+  static checkdescriptor const *descriptor ();
 
   check_debug_pubtypes (checkstack &stack, dwarflint &lint)
     : check_debug_pub<sec_pubtypes> (stack, lint)
index c8a937bd26ca2f9d667099f934d1e0ab9bb970d7..67f6a2942c47bf439b571961ade83669645c552b 100644 (file)
@@ -57,7 +57,7 @@ namespace
     };
 
   public:
-    static checkdescriptor descriptor () {
+    static checkdescriptor const *descriptor () {
       static checkdescriptor cd
        (checkdescriptor::create ("check_duplicate_DW_tag_variable")
         .inherit<highlevel_check<check_duplicate_DW_tag_variable> > ()
@@ -67,7 +67,7 @@ namespace
 "definition and declaration with definition.\n"
 " https://fedorahosted.org/pipermail/elfutils-devel/2010-July/001497.html\n"
 " http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39524\n"));
-      return cd;
+      return &cd;
     }
 
     check_duplicate_DW_tag_variable (checkstack &stack, dwarflint &lint);
index 27745bf9b85098624a38b301d0bc7b36c75d9956..a45cd66065bfc2e9aa027a72b804908bac335bb1 100644 (file)
@@ -42,7 +42,8 @@ namespace
     : public highlevel_check<check_dups_abstract_origin>
   {
   public:
-    static checkdescriptor descriptor () {
+    static checkdescriptor const *descriptor ()
+    {
       static checkdescriptor cd
        (checkdescriptor::create ("check_dups_abstract_origin")
         .inherit<highlevel_check<check_dups_abstract_origin> > ()
@@ -51,7 +52,7 @@ namespace
 "suspicious if that attribute name appears on the DIE that's the\n"
 "first DIE's DW_AT_abstract_origin or DW_AT_specification.\n"
 " https://bugzilla.redhat.com/show_bug.cgi?id=527430\n"));
-      return cd;
+      return &cd;
     }
 
     explicit check_dups_abstract_origin (checkstack &stack, dwarflint &lint)
index 0482919b2497e398c49efa966972e1d397f5e819..c90a488dc94522dfa932f91e852cdce6bf232df7 100644 (file)
@@ -42,14 +42,14 @@ namespace
     : public highlevel_check<check_expected_trees>
   {
   public:
-    static checkdescriptor descriptor () {
+    static checkdescriptor const *descriptor () {
       static checkdescriptor cd
        (checkdescriptor::create ("check_expected_trees")
         .inherit<highlevel_check<check_expected_trees> > ()
         .description (
 "Checks whether all DIEs have the right attributes and the right children.\n"
 "Currently this is very much a work in progress.\n"));
-      return cd;
+      return &cd;
     }
 
     check_expected_trees (checkstack &stack, dwarflint &lint);
index 2361618db5cfb98dde6808980be26c21cf0df52d..0afdc0788083116dfbfb8fc5b4d012bd31389e45 100644 (file)
@@ -39,14 +39,14 @@ namespace
     : public highlevel_check<check_matching_ranges>
   {
   public:
-    static checkdescriptor descriptor () {
+    static checkdescriptor const *descriptor () {
       static checkdescriptor cd
        (checkdescriptor::create ("check_matching_ranges")
         .inherit<highlevel_check<check_matching_ranges> > ()
         .description (
 "Check that the ranges in .debug_aranges and .debug_ranges match.\n"
 ));
-      return cd;
+      return &cd;
     }
 
     check_matching_ranges (checkstack &stack, dwarflint &lint);
index 779fba88abd3cd2651c82f3e06532ae9d41f3376..c930aa2105f50b3ced8f7f82cf3b6aa8b69001b7 100644 (file)
@@ -48,13 +48,13 @@ namespace
                                      where const &wh_parent);
 
   public:
-    static checkdescriptor descriptor () {
+    static checkdescriptor const *descriptor () {
       static checkdescriptor cd
        (checkdescriptor::create ("check_range_out_of_scope")
         .inherit<highlevel_check<check_range_out_of_scope> > ()
         .description (
 "Check whether PC ranges reported at DIEs fall into the containing scope.\n"));
-      return cd;
+      return &cd;
     }
 
     check_range_out_of_scope (checkstack &stack, dwarflint &lint);
index c0a4e364ded8cf108390a3be888f659a35bca7a8..3ab7a14f46bea65cecd5428875ad01f3e419b55f 100644 (file)
@@ -42,9 +42,24 @@ operator << (std::ostream &o, checkgroups const &groups)
   return o;
 }
 
-checkdescriptor::create::create (char const *a_name)
-  : name (a_name)
-  , desc (NULL)
+std::ostream &
+operator << (std::ostream &o, prereqs const &p)
+{
+  o << "(";
+  for (prereqs::const_iterator it = p.begin (); it != p.end (); ++it)
+    {
+      if (it != p.begin ())
+       o << ',';
+      o << (*it)->name ();
+    }
+  o << ")";
+  return o;
+}
+
+checkdescriptor::create::create (char const *name)
+  : _m_name (name)
+  , _m_description (NULL)
+  , _m_hidden (false)
 {}
 
 checkdescriptor::create &
@@ -53,15 +68,16 @@ checkdescriptor::create::groups (char const *a_groups)
   std::stringstream ss (a_groups);
   std::string group;
   while (ss >> group)
-    g.insert (group);
+    _m_groups.insert (group);
   return *this;
 }
 
 checkdescriptor::checkdescriptor (create const &c)
-  : _m_name (c.name)
-  , _m_description (c.desc)
-  , _m_groups (c.g)
-  , _m_prereq (c.p)
+  : _m_name (c._m_name)
+  , _m_description (c._m_description)
+  , _m_groups (c._m_groups)
+  , _m_prereq (c._m_prereq)
+  , _m_hidden (c._m_hidden)
 {}
 
 bool
index 5e7d32450e407ec79f158010a6a87896881a3724..f5131b2a1ec2d7dcc767a4ec0c3a18662fab7c8a 100644 (file)
@@ -35,46 +35,69 @@ struct checkgroups
 {};
 std::ostream &operator << (std::ostream &o, checkgroups const &groups);
 
+struct checkdescriptor;
+
+struct prereqs
+  : public std::set<checkdescriptor const *>
+{};
+std::ostream &operator << (std::ostream &o, prereqs const &p);
+
 struct checkdescriptor
 {
-  struct create
+  class create
   {
-    checkgroups g;
-    checkgroups p;
-    char const *const name;
-    char const *desc;
+    friend class checkdescriptor;
+    checkgroups _m_groups;
+    prereqs _m_prereq;
+    char const *const _m_name;
+    char const *_m_description;
+    bool _m_hidden;
+
+  public:
     create (char const *name = NULL);
     create &groups (char const *name);
 
     create &description (char const *d)
-    { desc = d; return *this; }
+    {
+      _m_description = d;
+      return *this;
+    }
 
     template <class T> create &prereq ();
 
     template <class T> create &inherit ();
+
+    create hidden ()
+    {
+      _m_hidden = true;
+      return *this;
+    }
   };
 
   checkdescriptor (create const &c);
 
   char const *name () const { return _m_name; }
   char const *description () const { return _m_description; }
-  checkgroups const &prereq () const { return _m_prereq; }
+  prereqs const &prereq () const { return _m_prereq; }
 
   checkgroups const &groups () const { return _m_groups; }
   bool in_group (std::string const &group) const;
 
+  bool hidden () const { return _m_hidden; }
+
 private:
   char const *const _m_name;
   char const *const _m_description;
   checkgroups const _m_groups;
-  checkgroups const _m_prereq;
+  prereqs const _m_prereq;
+  bool _m_hidden;
 };
 
 template <class T>
 checkdescriptor::create &
 checkdescriptor::create::prereq ()
 {
-  p.insert (T::descriptor ().name ());
+  _m_prereq.insert (T::descriptor ());
   return *this;
 }
 
@@ -82,10 +105,10 @@ template <class T>
 checkdescriptor::create &
 checkdescriptor::create::inherit ()
 {
-  checkdescriptor const &cd = T::descriptor ();
-  for (checkgroups::const_iterator it = cd.prereq ().begin ();
+  checkdescriptor const &cd = *T::descriptor ();
+  for (prereqs::const_iterator it = cd.prereq ().begin ();
        it != cd.prereq ().end (); ++it)
-    p.insert (*it);
+    _m_prereq.insert (*it);
   return *this;
 }
 
index c819b46f0b1567357d9fd8d9a9952d879390502a..cba9271dd2009a8c2ae22f41962ee470171e9192 100644 (file)
@@ -70,7 +70,7 @@ dwarflint::check (checkstack &stack)
 
   if (c == NULL)
     {
-      checkdescriptor const &cd = T::descriptor ();
+      checkdescriptor const &cd = *T::descriptor ();
 
       struct popper {
        checkstack &guard_stack;
@@ -148,7 +148,7 @@ struct reg
     lint.toplev_check <T> (stack);
   }
 
-  virtual checkdescriptor descriptor () const
+  virtual checkdescriptor const *descriptor () const
   {
     return T::descriptor ();
   }
index 8fabcda81cd6e53cb2199b23ad693c13c4ff7be4..7fb0d3d614939e1bf4cda43e1b2af981acc7b000 100644 (file)
 #include "check_debug_info.hh"
 #include "check_debug_loc_range.hh"
 
-checkdescriptor const &
+checkdescriptor const *
 cu_coverage::descriptor ()
 {
   static checkdescriptor cd
     (checkdescriptor::create ("cu_coverage")
      .prereq<typeof (*_m_info)> ()
      .prereq<typeof (*_m_ranges)> ());
-  return cd;
+  return &cd;
 }
 
 cu_coverage::cu_coverage (checkstack &stack, dwarflint &lint)
index 00767e9226bcc717cb8854ee180bb2fee49b0791..273eb33627285c103508751d73f3d8c291792278 100644 (file)
@@ -39,7 +39,7 @@ class cu_coverage
   check_debug_ranges *_m_ranges;
 
 public:
-  static checkdescriptor const &descriptor ();
+  static checkdescriptor const *descriptor ();
 
   coverage cov;
 
index cc11924e790f669e14ebd4f27895a72d2bf68bc1..f2116a82377829a1a7226a37c74778d31f748633 100644 (file)
@@ -97,13 +97,41 @@ dwarflint::check_registrar::enroll (dwarflint &lint)
     }
 }
 
+namespace
+{
+  template <class T> void include (T &to, checkdescriptor const *cd);
+
+  template <class T>
+  void add_deps (T &to, checkdescriptor const *cd)
+  {
+    for (typename T::const_iterator it = cd->prereq ().begin ();
+        it != cd->prereq ().end (); ++it)
+      include (to, *it);
+  }
+
+  template <class T>
+  void include (T &to, checkdescriptor const *cd)
+  {
+    if (cd->hidden ())
+      add_deps (to, cd);
+    else
+      to.insert (cd);
+  }
+}
+
 void
 dwarflint::check_registrar::list_checks () const
 {
+  typedef std::set<checkdescriptor const *> descset;
+  descset descriptors;
   for (std::vector <item *>::const_iterator it = _m_items.begin ();
        it != _m_items.end (); ++it)
+    include (descriptors, (*it)->descriptor ());
+
+  for (descset::const_iterator it = descriptors.begin ();
+       it != descriptors.end (); ++it)
     {
-      checkdescriptor const &cd = (*it)->descriptor ();
+      checkdescriptor const &cd = **it;
       if (be_verbose)
        std::cout << "=== " << cd.name () << " ===";
       else
@@ -122,7 +150,7 @@ dwarflint::check_registrar::list_checks () const
 
       if (be_verbose)
        {
-         checkgroups const &prereq = cd.prereq ();
+         prereqs const &prereq = cd.prereq ();
          if (!prereq.empty ())
            std::cout << "prerequisites: " << prereq << std::endl;
          char const *desc = cd.description ();
index 518c33bf00585a6f8b8f538d5fc6a683d41aca06..69baff91c13e31c3817fa1618068f25bc3a27c6f 100644 (file)
@@ -86,7 +86,7 @@ public:
     struct item
     {
       virtual void run (checkstack &stack, dwarflint &lint) = 0;
-      virtual checkdescriptor descriptor () const = 0;
+      virtual checkdescriptor const *descriptor () const = 0;
     };
 
     static check_registrar *inst ()
index ea8ce05d64b7eab8d394d4b83dca2f65299e7d2c..8e1db6d4620db56aef8d4cfae5d422cbee503932 100644 (file)
@@ -26,6 +26,9 @@
 #include "highlevel_check.hh"
 #include "messages.h"
 
+#include "sections.hh"
+#include "lowlevel_checks.hh"
+
 namespace
 {
   inline bool failed (void *ptr) { return ptr == NULL; }
@@ -128,10 +131,9 @@ namespace
   }
 }
 
-open_highlevel_dwarf::open_highlevel_dwarf (checkstack &stack
-                                             __attribute__ ((unused)),
-                                           dwarflint &lint)
-  : _m_dwfl (open_dwfl ())
+open_highlevel_dwarf::open_highlevel_dwarf (checkstack &stack, dwarflint &lint)
+  : _m_dwfl ((lint.check<lowlevel_checks> (stack),
+             open_dwfl ()))
   , _m_dw (open_dwarf (_m_dwfl, lint.fname (), lint.fd ()))
   , dw (open_hl_dwarf (_m_dw))
 {}
index 6d57d5fb1ad9fc9bf8ff468565878ca2e549ee46..5505ae1524a0487501c19cdd750699280cac2d91 100644 (file)
@@ -41,9 +41,9 @@ class open_highlevel_dwarf
   Dwfl *const _m_dwfl;
   Dwarf *const _m_dw;
 public:
-  static checkdescriptor descriptor () {
+  static checkdescriptor const *descriptor () {
     static checkdescriptor cd ("open_highlevel_dwarf");
-    return cd;
+    return &cd;
   }
 
   elfutils::dwarf const dw;
@@ -57,11 +57,11 @@ class highlevel_check
 {
   open_highlevel_dwarf *_m_loader;
 public:
-  static checkdescriptor const &descriptor () {
+  static checkdescriptor const *descriptor () {
     static checkdescriptor cd
       (checkdescriptor::create ("open_highlevel_dwarf")
        .prereq<typeof (*_m_loader)> ());
-    return cd;
+    return &cd;
   }
 
   elfutils::dwarf const &dw;
diff --git a/dwarflint/lowlevel_checks.cc b/dwarflint/lowlevel_checks.cc
new file mode 100644 (file)
index 0000000..65349fa
--- /dev/null
@@ -0,0 +1,89 @@
+/* Scheduler for low_level checks
+   Copyright (C) 2010 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 "lowlevel_checks.hh"
+#include "sections.hh"
+#include "check_debug_info.hh"
+#include "check_debug_abbrev.hh"
+#include "check_debug_aranges.hh"
+#include "check_debug_pub.hh"
+#include "check_debug_loc_range.hh"
+#include "check_debug_line.hh"
+
+checkdescriptor const *
+lowlevel_checks::descriptor ()
+{
+  static checkdescriptor cd
+    (checkdescriptor::create ("lowlevel_checks")
+     .prereq<check_debug_info> ()
+     .prereq<check_debug_abbrev> ()
+     .prereq<check_debug_aranges> ()
+     .prereq<check_debug_pubnames> ()
+     .prereq<check_debug_pubtypes> ()
+     .prereq<check_debug_line> ()
+     .prereq<check_debug_loc> ()
+     .prereq<check_debug_ranges> ()
+     .hidden ()
+     );
+  return &cd;
+}
+static reg<lowlevel_checks> reg_lowlevel_checks;
+
+namespace
+{
+  template<class T> struct do_check {
+    static void check (checkstack &stack, dwarflint &lint) {
+      lint.check<T> (stack);
+    }
+  };
+
+  // There is no separate check_debug_str pass.  Make a stub so that
+  // we can do it all in one macro-expanded sweep below.
+#define STUBBED_CHECK(NAME)                                            \
+  struct check_debug_##NAME {};                                                \
+  template<> struct do_check<check_debug_##NAME> {                     \
+    static void check (__attribute__ ((unused)) checkstack &stack,     \
+                      __attribute__ ((unused)) dwarflint &lint) {}     \
+  }
+  STUBBED_CHECK(str);
+  STUBBED_CHECK(mac);
+#undef STUBBED_CHECK
+}
+
+lowlevel_checks::lowlevel_checks (checkstack &stack, dwarflint &lint)
+{
+  // Then check whatever else is there.  For each existing section
+  // request that the check passes.  Re-requesting already-passed
+  // checks is OK, the scheduler caches it.
+#define SEC(NAME)                                                      \
+  section<sec_##NAME> *NAME =                                          \
+    lint.toplev_check<section<sec_##NAME> > (stack);                   \
+  if (NAME != NULL)                                                    \
+    do_check<check_debug_##NAME>::check (stack, lint);
+  DEBUGINFO_SECTIONS;
+#undef SEC
+
+  lint.check<check_debug_info_refs> (stack);
+}
diff --git a/dwarflint/lowlevel_checks.hh b/dwarflint/lowlevel_checks.hh
new file mode 100644 (file)
index 0000000..9892b91
--- /dev/null
@@ -0,0 +1,39 @@
+/* Scheduler for low_level checks
+   Copyright (C) 2010 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>.  */
+
+#ifndef DWARFLINT_LOWLEVEL_CHECKS_HH
+#define DWARFLINT_LOWLEVEL_CHECKS_HH
+
+#include "checks.hh"
+
+class lowlevel_checks
+  : public check<lowlevel_checks>
+{
+public:
+  static checkdescriptor const *descriptor ();
+  lowlevel_checks (checkstack &stack, dwarflint &lint);
+};
+
+#endif//DWARFLINT_LOWLEVEL_CHECKS_HH
index f5b337f92e7b09ab9dda8c920dad880d2af20942..af2048b7560ced8d6191a8896ae337ead5ce99bc 100644 (file)
@@ -66,6 +66,7 @@ extern "C"
   MC (line,      19) /* messages related to .debug_line */             \
   MC (reloc,     20) /* messages related to relocation handling */     \
   MC (header,    21) /* messages related to header portions in general */ \
+  MC (mac,       22) /* messages related to .debug_mac */ \
   MC (other,     31) /* messages unrelated to any of the above */
 
   enum message_category
index b1eb3d50858e80ab9f10bdd762aac36400eee7cf..74685cecd79fdc6d7f261fb5b03a3150b495ae73 100644 (file)
 #include "pri.hh"
 #include "options.h"
 
-checkdescriptor const &
+checkdescriptor const *
 load_sections::descriptor ()
 {
   static checkdescriptor cd ("load_sections");
-  return cd;
+  return &cd;
 }
 
-checkdescriptor const &
+checkdescriptor const *
 section_base::descriptor ()
 {
   static checkdescriptor cd
     (checkdescriptor::create ()
      .prereq<typeof (*sections)> ());
-  return cd;
+  return &cd;
 }
 
 namespace
@@ -435,6 +435,7 @@ namespace
       case sec_line: return mc_line;
       case sec_loc: return mc_loc;
       case sec_ranges: return mc_ranges;
+      case sec_mac: return mc_mac;
 
       case sec_pubnames:
       case sec_pubtypes:
@@ -445,7 +446,6 @@ namespace
        return mc_reloc;
 
        // xxx don't have one
-      case sec_mac:
       case sec_invalid:
       case sec_locexpr:
       case rel_value:
index bb8c872062c4950733219e1bdb14ef6247a1d4df..48151ae84b1c9fafd7e5ace3889140d54ee8553b 100644 (file)
@@ -33,7 +33,7 @@ class load_sections
   : public check<load_sections>
 {
 public:
-  static checkdescriptor const &descriptor ();
+  static checkdescriptor const *descriptor ();
 
   elf_file file;
   load_sections (checkstack &stack, dwarflint &lint);
@@ -46,7 +46,7 @@ class section_base
   sec &get_sec_or_throw (section_id secid);
 
 public:
-  static checkdescriptor const &descriptor ();
+  static checkdescriptor const *descriptor ();
 
   sec &sect;
   elf_file &file;
@@ -65,11 +65,11 @@ class section
   , public check<section<sec_id> >
 {
 public:
-  static checkdescriptor const &descriptor () {
+  static checkdescriptor const *descriptor () {
     static checkdescriptor cd
       (checkdescriptor::create (section_name[sec_id])
        .inherit<section_base> ());
-    return cd;
+    return &cd;
   }
 
   explicit section (checkstack &stack, dwarflint &lint)