summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPetr Machata <[email protected]>2010-09-07 23:08:05 +0200
committerPetr Machata <[email protected]>2010-09-07 23:08:05 +0200
commita5411525fce00015f6911094b1013f50b16426ae (patch)
treedb07f98ba2312896bebfac9bbfd51f3b061422c6
parent5ed27fdb82c2b21ca7d7ee2bf7f888e425cd99f0 (diff)
dwarflint: Add a lowlevel_checks pass
- which is where low-level checks are explicitly requested - and what highlevel checks, also explicitly, depend on
-rw-r--r--dwarflint/Makefile.am1
-rw-r--r--dwarflint/TODO17
-rw-r--r--dwarflint/check_debug_abbrev.cc6
-rw-r--r--dwarflint/check_debug_abbrev.hh2
-rw-r--r--dwarflint/check_debug_aranges.cc6
-rw-r--r--dwarflint/check_debug_aranges.hh2
-rw-r--r--dwarflint/check_debug_info.cc17
-rw-r--r--dwarflint/check_debug_info.hh7
-rw-r--r--dwarflint/check_debug_line.cc5
-rw-r--r--dwarflint/check_debug_line.hh2
-rw-r--r--dwarflint/check_debug_loc_range.cc12
-rw-r--r--dwarflint/check_debug_loc_range.hh4
-rw-r--r--dwarflint/check_debug_pub.cc10
-rw-r--r--dwarflint/check_debug_pub.hh4
-rw-r--r--dwarflint/check_duplicate_DW_tag_variable.cc4
-rw-r--r--dwarflint/check_dups_abstract_origin.cc5
-rw-r--r--dwarflint/check_expected_trees.cc4
-rw-r--r--dwarflint/check_matching_ranges.cc4
-rw-r--r--dwarflint/check_range_out_of_scope.cc4
-rw-r--r--dwarflint/checkdescriptor.cc32
-rw-r--r--dwarflint/checkdescriptor.hh47
-rw-r--r--dwarflint/checks.hh4
-rw-r--r--dwarflint/cu_coverage.cc4
-rw-r--r--dwarflint/cu_coverage.hh2
-rw-r--r--dwarflint/dwarflint.cc32
-rw-r--r--dwarflint/dwarflint.hh2
-rw-r--r--dwarflint/highlevel_check.cc10
-rw-r--r--dwarflint/highlevel_check.hh8
-rw-r--r--dwarflint/lowlevel_checks.cc89
-rw-r--r--dwarflint/lowlevel_checks.hh39
-rw-r--r--dwarflint/messages.h1
-rw-r--r--dwarflint/sections.cc10
-rw-r--r--dwarflint/sections.hh8
33 files changed, 292 insertions, 112 deletions
diff --git a/dwarflint/Makefile.am b/dwarflint/Makefile.am
index c8cb062d..1f6c84e2 100644
--- a/dwarflint/Makefile.am
+++ b/dwarflint/Makefile.am
@@ -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 \
diff --git a/dwarflint/TODO b/dwarflint/TODO
index 2a2060a1..0f374ca2 100644
--- a/dwarflint/TODO
+++ b/dwarflint/TODO
@@ -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
diff --git a/dwarflint/check_debug_abbrev.cc b/dwarflint/check_debug_abbrev.cc
index 8ee63dfb..ad4c2843 100644
--- a/dwarflint/check_debug_abbrev.cc
+++ b/dwarflint/check_debug_abbrev.cc
@@ -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 *
diff --git a/dwarflint/check_debug_abbrev.hh b/dwarflint/check_debug_abbrev.hh
index f1aef31e..11cd1dec 100644
--- a/dwarflint/check_debug_abbrev.hh
+++ b/dwarflint/check_debug_abbrev.hh
@@ -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;
diff --git a/dwarflint/check_debug_aranges.cc b/dwarflint/check_debug_aranges.cc
index 4d87b402..9918030f 100644
--- a/dwarflint/check_debug_aranges.cc
+++ b/dwarflint/check_debug_aranges.cc
@@ -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)
diff --git a/dwarflint/check_debug_aranges.hh b/dwarflint/check_debug_aranges.hh
index 993a221a..dbd0726e 100644
--- a/dwarflint/check_debug_aranges.hh
+++ b/dwarflint/check_debug_aranges.hh
@@ -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);
};
diff --git a/dwarflint/check_debug_info.cc b/dwarflint/check_debug_info.cc
index 631083e0..8e8a36f0 100644
--- a/dwarflint/check_debug_info.cc
+++ b/dwarflint/check_debug_info.cc
@@ -41,25 +41,22 @@
#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;
diff --git a/dwarflint/check_debug_info.hh b/dwarflint/check_debug_info.hh
index 81827126..df80baa0 100644
--- a/dwarflint/check_debug_info.hh
+++ b/dwarflint/check_debug_info.hh
@@ -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);
};
diff --git a/dwarflint/check_debug_line.cc b/dwarflint/check_debug_line.cc
index 7445fe74..a383e953 100644
--- a/dwarflint/check_debug_line.cc
+++ b/dwarflint/check_debug_line.cc
@@ -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
{
diff --git a/dwarflint/check_debug_line.hh b/dwarflint/check_debug_line.hh
index fc7aa4df..a70982d1 100644
--- a/dwarflint/check_debug_line.hh
+++ b/dwarflint/check_debug_line.hh
@@ -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; }
diff --git a/dwarflint/check_debug_loc_range.cc b/dwarflint/check_debug_loc_range.cc
index e1b39718..d664122e 100644
--- a/dwarflint/check_debug_loc_range.cc
+++ b/dwarflint/check_debug_loc_range.cc
@@ -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
diff --git a/dwarflint/check_debug_loc_range.hh b/dwarflint/check_debug_loc_range.hh
index c3737e1c..2f8138f9 100644
--- a/dwarflint/check_debug_loc_range.hh
+++ b/dwarflint/check_debug_loc_range.hh
@@ -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);
};
diff --git a/dwarflint/check_debug_pub.cc b/dwarflint/check_debug_pub.cc
index 82eab1d2..0ce3ff60 100644
--- a/dwarflint/check_debug_pub.cc
+++ b/dwarflint/check_debug_pub.cc
@@ -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);
diff --git a/dwarflint/check_debug_pub.hh b/dwarflint/check_debug_pub.hh
index 1f3e35cf..97415f8c 100644
--- a/dwarflint/check_debug_pub.hh
+++ b/dwarflint/check_debug_pub.hh
@@ -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)
diff --git a/dwarflint/check_duplicate_DW_tag_variable.cc b/dwarflint/check_duplicate_DW_tag_variable.cc
index c8a937bd..67f6a294 100644
--- a/dwarflint/check_duplicate_DW_tag_variable.cc
+++ b/dwarflint/check_duplicate_DW_tag_variable.cc
@@ -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);
diff --git a/dwarflint/check_dups_abstract_origin.cc b/dwarflint/check_dups_abstract_origin.cc
index 27745bf9..a45cd660 100644
--- a/dwarflint/check_dups_abstract_origin.cc
+++ b/dwarflint/check_dups_abstract_origin.cc
@@ -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)
diff --git a/dwarflint/check_expected_trees.cc b/dwarflint/check_expected_trees.cc
index 0482919b..c90a488d 100644
--- a/dwarflint/check_expected_trees.cc
+++ b/dwarflint/check_expected_trees.cc
@@ -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);
diff --git a/dwarflint/check_matching_ranges.cc b/dwarflint/check_matching_ranges.cc
index 2361618d..0afdc078 100644
--- a/dwarflint/check_matching_ranges.cc
+++ b/dwarflint/check_matching_ranges.cc
@@ -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);
diff --git a/dwarflint/check_range_out_of_scope.cc b/dwarflint/check_range_out_of_scope.cc
index 779fba88..c930aa21 100644
--- a/dwarflint/check_range_out_of_scope.cc
+++ b/dwarflint/check_range_out_of_scope.cc
@@ -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);
diff --git a/dwarflint/checkdescriptor.cc b/dwarflint/checkdescriptor.cc
index c0a4e364..3ab7a14f 100644
--- a/dwarflint/checkdescriptor.cc
+++ b/dwarflint/checkdescriptor.cc
@@ -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
diff --git a/dwarflint/checkdescriptor.hh b/dwarflint/checkdescriptor.hh
index 5e7d3245..f5131b2a 100644
--- a/dwarflint/checkdescriptor.hh
+++ b/dwarflint/checkdescriptor.hh
@@ -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;
}
diff --git a/dwarflint/checks.hh b/dwarflint/checks.hh
index c819b46f..cba9271d 100644
--- a/dwarflint/checks.hh
+++ b/dwarflint/checks.hh
@@ -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 ();
}
diff --git a/dwarflint/cu_coverage.cc b/dwarflint/cu_coverage.cc
index 8fabcda8..7fb0d3d6 100644
--- a/dwarflint/cu_coverage.cc
+++ b/dwarflint/cu_coverage.cc
@@ -27,14 +27,14 @@
#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)
diff --git a/dwarflint/cu_coverage.hh b/dwarflint/cu_coverage.hh
index 00767e92..273eb336 100644
--- a/dwarflint/cu_coverage.hh
+++ b/dwarflint/cu_coverage.hh
@@ -39,7 +39,7 @@ class cu_coverage
check_debug_ranges *_m_ranges;
public:
- static checkdescriptor const &descriptor ();
+ static checkdescriptor const *descriptor ();
coverage cov;
diff --git a/dwarflint/dwarflint.cc b/dwarflint/dwarflint.cc
index cc11924e..f2116a82 100644
--- a/dwarflint/dwarflint.cc
+++ b/dwarflint/dwarflint.cc
@@ -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 ();
diff --git a/dwarflint/dwarflint.hh b/dwarflint/dwarflint.hh
index 518c33bf..69baff91 100644
--- a/dwarflint/dwarflint.hh
+++ b/dwarflint/dwarflint.hh
@@ -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 ()
diff --git a/dwarflint/highlevel_check.cc b/dwarflint/highlevel_check.cc
index ea8ce05d..8e1db6d4 100644
--- a/dwarflint/highlevel_check.cc
+++ b/dwarflint/highlevel_check.cc
@@ -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))
{}
diff --git a/dwarflint/highlevel_check.hh b/dwarflint/highlevel_check.hh
index 6d57d5fb..5505ae15 100644
--- a/dwarflint/highlevel_check.hh
+++ b/dwarflint/highlevel_check.hh
@@ -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
index 00000000..65349fad
--- /dev/null
+++ b/dwarflint/lowlevel_checks.cc
@@ -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
index 00000000..9892b910
--- /dev/null
+++ b/dwarflint/lowlevel_checks.hh
@@ -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
diff --git a/dwarflint/messages.h b/dwarflint/messages.h
index f5b337f9..af2048b7 100644
--- a/dwarflint/messages.h
+++ b/dwarflint/messages.h
@@ -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
diff --git a/dwarflint/sections.cc b/dwarflint/sections.cc
index b1eb3d50..74685cec 100644
--- a/dwarflint/sections.cc
+++ b/dwarflint/sections.cc
@@ -37,20 +37,20 @@
#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:
diff --git a/dwarflint/sections.hh b/dwarflint/sections.hh
index bb8c8720..48151ae8 100644
--- a/dwarflint/sections.hh
+++ b/dwarflint/sections.hh
@@ -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)