dwarflint_SOURCES = \
addr-record.cc addr-record.hh \
all-dies-it.hh \
- check_registrar.cc check_registrar.hh check_registrar_i.hh \
+ check_registrar.hh check_registrar_i.hh \
checkdescriptor.cc checkdescriptor.hh checkdescriptor_i.hh \
checked_read.cc checked_read.hh \
checkrule.cc checkrule.hh \
static checkdescriptor cd
(checkdescriptor::create ("check_debug_abbrev")
.groups ("@low")
- .prereq <typeof (*_m_sec_abbr)> ()
- .prereq <typeof (*_m_cu_headers)> ()
+ .schedule (false)
.description (
"Checks for low-level structure of .debug_abbrev. In addition it "
"checks:\n"
return &cd;
}
+static reg<check_debug_abbrev> reg_debug_abbrev;
+
abbrev *
abbrev_table::find_abbrev (uint64_t abbrev_code) const
{
static checkdescriptor cd
(checkdescriptor::create ("check_debug_aranges")
.groups ("@low")
- .prereq<typeof (*_m_sec_aranges)> ()
- .prereq<typeof (*_m_info)> ()
- .prereq<typeof (*_m_cu_coverage)> ()
.description (
"Checks for low-level structure of .debug_aranges. In addition it "
"checks:\n"
return &cd;
}
+static reg<check_debug_aranges> reg_debug_aranges;
+
static struct cu *
cu_find_cu (struct cu *cu_chain, uint64_t offset)
{
{
static checkdescriptor cd
(checkdescriptor::create ("read_cu_headers")
- .prereq<typeof (*_m_sec_info)> ());
+ .hidden ());
return &cd;
}
static checkdescriptor cd
(checkdescriptor::create ("check_debug_info")
.groups ("@low")
+ .schedule (false)
.option (dump_die_offsets)
- .prereq<typeof (*_m_sec_info)> ()
- .prereq<typeof (*_m_sec_str)> ()
- .prereq<typeof (*_m_abbrevs)> ()
- .prereq<typeof (*_m_cu_headers)> ()
.description (
"Checks for low-level structure of .debug_info. In addition it "
"checks:\n"
return &cd;
}
+static reg<check_debug_info> reg_debug_info;
+
namespace
{
bool
static checkdescriptor cd
(checkdescriptor::create ("check_debug_info_refs")
.groups ("@low")
- .prereq<typeof (*_m_info)> ()
- .prereq<typeof (*_m_line)> ()
+ .schedule (false)
.description (
"This pass checks:\n"
" - for outstanding unresolved references from .debug_info to .debug_line\n"
return &cd;
}
+static reg<check_debug_info_refs> reg_debug_info_refs;
+
check_debug_info_refs::check_debug_info_refs (checkstack &stack,
dwarflint &lint)
: _m_info (lint.check (stack, _m_info))
<< "no aranges table is associated with this CU." << std::endl;
}
}
-
-static reg<check_debug_info_refs> reg_debug_info_refs;
static checkdescriptor cd
(checkdescriptor::create ("check_debug_line")
.groups ("@low")
- .prereq<typeof (*_m_sec)> ()
+ .schedule (false)
.description (
"Checks for low-level structure of .debug_line. In addition it\n"
"checks:\n"
return &cd;
}
+static reg<check_debug_line> reg_debug_line;
+
namespace
{
struct include_directory_t
static checkdescriptor cd
(checkdescriptor::create ("check_debug_ranges")
.groups ("@low")
- .prereq<typeof (*_m_sec_ranges)> ()
- .prereq<typeof (*_m_info)> ()
+ .schedule (false)
.description (
"Checks for low-level structure of .debug_ranges. In addition it "
"checks:\n"
return &cd;
}
+static reg<check_debug_ranges> reg_debug_ranges;
+
checkdescriptor const *
check_debug_loc::descriptor ()
{
static checkdescriptor cd
(checkdescriptor::create ("check_debug_loc")
.groups ("@low")
- .prereq<typeof (*_m_sec_loc)> ()
- .prereq<typeof (*_m_info)> ()
+ .schedule (false)
.description (
"Checks for low-level structure of .debug_loc. In addition it "
"makes the same checks as .debug_ranges. For location expressions "
return &cd;
}
+static reg<check_debug_loc> reg_debug_loc;
+
namespace
{
bool
/* Low-level checking of .debug_pub*.
- Copyright (C) 2009, 2010 Red Hat, Inc.
+ Copyright (C) 2009, 2010, 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
static checkdescriptor cd
(checkdescriptor::create ("check_debug_pubnames")
.groups ("@low")
- .prereq<typeof (*_m_sec)> ()
- .prereq<check_debug_info> ()
+ .schedule (false)
.description (
"Checks for low-level structure of .debug_pubnames. In addition it "
"checks:\n"
" - that there's only one pub section per CU\n"));
return &cd;
}
+
template check_debug_pub<sec_pubnames>::check_debug_pub (checkstack &stack,
dwarflint &lint);
+static reg<check_debug_pubnames> reg_debug_pubnames;
+
checkdescriptor const *
check_debug_pubtypes::descriptor ()
{
static checkdescriptor cd
(checkdescriptor::create ("check_debug_pubtypes")
.groups ("@low")
- .prereq<typeof (*_m_sec)> ()
- .prereq<check_debug_info> ()
+ .schedule (false)
.description (
"Checks for low-level structure of .debug_pubtypes. In addition it "
"makes the same checks as check_debug_pubnames.\n"));
return &cd;
}
+
template check_debug_pub<sec_pubtypes>::check_debug_pub (checkstack &stack,
dwarflint &lint);
+static reg<check_debug_pubtypes> reg_debug_pubtypes;
+
+
template <section_id sec_id>
bool
check_debug_pub<sec_id>::check_pub_structural ()
return &inst;
}
};
-
- reg<check_die_tree> reg;
}
void
{
static checkdescriptor cd
(checkdescriptor::create ("check_die_tree")
- .inherit<highlevel_check<check_die_tree> > ()
.hidden ()
.description ("A pass over the DIE tree that dispatches to various per-DIE checks.\n"));
return &cd;
public:
static checkdescriptor const *descriptor ()
{
- static checkdescriptor cd
- (checkdescriptor::create (*T::descriptor ())
- .prereq<typeof (*_m_die_tree_check)> ()
- .inherit<highlevel_check<check_stub> > ());
- return &cd;
+ return T::descriptor ();
}
check_stub (checkstack &stack, dwarflint &lint)
static checkdescriptor const *descriptor () {
static checkdescriptor cd
(checkdescriptor::create ("check_duplicate_DW_tag_variable")
- .inherit<highlevel_check<check_duplicate_DW_tag_variable> > ()
.description (
"Implements a check for two full DW_TAG_variable DIEs with the same "
"DW_AT_name value. This covers duplicate declaration, duplicate "
{
static checkdescriptor cd
(checkdescriptor::create ("check_dups_abstract_origin")
- .inherit<highlevel_check<check_dups_abstract_origin> > ()
.description (
"If a given attribute name is present on a DIE, it is "
"suspicious if that attribute name appears on the DIE that's the "
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"));
{
static checkdescriptor cd
(checkdescriptor::create ("check_linkage_external_die")
- .inherit<highlevel_check<check_linkage_external_die> > ()
- .description (
-"Check that each DIE that has a linkage_name also has an external attribute.\n"
- ));
+ .description ("Check that each DIE that has a linkage_name "
+ "also has an external attribute.\n"));
return &cd;
}
/* Pedantic checking of DWARF files
- Copyright (C) 2009,2010 Red Hat, Inc.
+ Copyright (C) 2009,2010,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
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"
));
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;
+++ /dev/null
-/* Pedantic checking of DWARF files
- 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>. */
-
-#include "check_registrar.hh"
-#include "checkdescriptor.hh"
-#include "dwarflint.hh"
-#include "main.hh"
-#include "wrap.hh"
-
-void
-check_registrar_aux::add_deps (std::set<checkdescriptor const *> &to,
- checkdescriptor const *cd)
-{
- for (std::set<checkdescriptor const *>::const_iterator it
- = cd->prereq ().begin (); it != cd->prereq ().end (); ++it)
- include (to, *it);
-}
-
-void
-check_registrar_aux::include (std::set<checkdescriptor const *> &to,
- checkdescriptor const *cd)
-{
- if (cd->hidden ())
- add_deps (to, cd);
- else
- to.insert (cd);
-}
-
-bool
-check_registrar_aux::be_verbose ()
-{
- // We can hopefully assume that the option doesn't change during
- // execution, so we can simply cache it this was.
- static bool be_verbose = opt_list_checks.value () == "full";
- return be_verbose;
-}
-
-void
-check_registrar_aux::list_one_check (checkdescriptor const &cd)
-{
- const size_t columns = 70;
-
- if (be_verbose ())
- std::cout << "=== " << cd.name () << " ===";
- else
- std::cout << cd.name ();
-
- checkgroups const &groups = cd.groups ();
- if (!groups.empty ())
- {
- if (be_verbose ())
- std::cout << std::endl << "groups: ";
- else
- std::cout << ' ';
- std::cout << groups;
- }
- std::cout << std::endl;
-
- if (be_verbose ())
- {
- prereqs const &prereq = cd.prereq ();
- if (!prereq.empty ())
- std::cout << "prerequisites: " << prereq << std::endl;
-
- char const *desc = cd.description ();
- if (desc != NULL)
- std::cout << wrap_str (desc, columns).join ();
-
- options const &opts = cd.opts ();
- if (!opts.empty ())
- {
- std::cout << "recognized options:" << std::endl;
- argp a = opts.build_argp ();
- argp_help (&a, stdout, ARGP_HELP_LONG, NULL);
- }
-
- std::cout << std::endl;
- }
-}
{
bool be_verbose ();
void list_one_check (checkdescriptor const &cd);
-
- void include (std::set<checkdescriptor const *> &to,
- checkdescriptor const *cd);
- void add_deps (std::set<checkdescriptor const *> &to,
- checkdescriptor const *cd);
}
template <class Item>
checkdescriptors_t
get_descriptors () const
{
- std::set<checkdescriptor const *> descriptors;
+ checkdescriptors_t ret;
for (typename _super_t::const_iterator it = begin (); it != end (); ++it)
- check_registrar_aux::include (descriptors, (*it)->descriptor ());
- return checkdescriptors_t (descriptors.begin (), descriptors.end ());
+ ret.push_back ((*it)->descriptor ());
+ return ret;
}
};
{
static checkdescriptor cd
(checkdescriptor::create ("check_self_referential_die")
- .inherit<highlevel_check<check_self_referential_die> > ()
.description (
"A reference attribute referencing the DIE itself is suspicious.\n"
"One example is a DW_AT_containing_type pointing to itself.\n"
<http://www.openinventionnetwork.com>. */
#include "checkdescriptor.hh"
+#include "wrap.hh"
#include <sstream>
#include <cassert>
return o;
}
-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)
+ , _m_schedule (true)
{}
checkdescriptor::create::create (checkdescriptor const &base)
: _m_groups (base.groups ())
- , _m_prereq (base.prereq ())
, _m_name (base.name ())
, _m_description (base.description ())
, _m_hidden (base.hidden ())
+ , _m_schedule (base.schedule ())
, _m_opts (base.opts ())
{}
return *this;
}
+checkdescriptor::checkdescriptor ()
+ : _m_name (NULL)
+ , _m_description (NULL)
+ , _m_groups ()
+ , _m_hidden (false)
+ , _m_schedule (true)
+ , _m_opts ()
+{}
+
checkdescriptor::checkdescriptor (create const &c)
: _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)
+ , _m_schedule (c._m_schedule)
, _m_opts (c._m_opts)
{}
{
return _m_groups.find (group) != _m_groups.end ();
}
+
+void
+checkdescriptor::list (bool verbose) const
+{
+ const size_t columns = 70;
+
+ if (verbose)
+ std::cout << "=== " << name () << " ===";
+ else
+ std::cout << name ();
+
+ checkgroups const &g = groups ();
+ if (!g.empty ())
+ {
+ if (verbose)
+ std::cout << std::endl << "groups: ";
+ else
+ std::cout << ' ';
+ std::cout << g;
+ }
+ std::cout << std::endl;
+
+ if (verbose)
+ {
+ char const *desc = description ();
+ if (desc != NULL)
+ std::cout << wrap_str (desc, columns).join ();
+
+ options const &o = opts ();
+ if (!o.empty ())
+ {
+ std::cout << "recognized options:" << std::endl;
+ argp a = o.build_argp ();
+ argp_help (&a, stdout, ARGP_HELP_LONG, NULL);
+ }
+
+ std::cout << std::endl;
+ }
+}
{};
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
{
class create
{
friend class checkdescriptor;
checkgroups _m_groups;
- prereqs _m_prereq;
char const *const _m_name;
char const *_m_description;
bool _m_hidden;
+ bool _m_schedule;
options _m_opts;
public:
return *this;
}
- template <class T> create &prereq ();
-
- template <class T> create &inherit ();
-
create hidden ()
{
_m_hidden = true;
_m_opts.add (&opt);
return *this;
}
+
+ create schedule (bool whether)
+ {
+ _m_schedule = whether;
+ return *this;
+ }
};
+ checkdescriptor ();
checkdescriptor (create const &c);
char const *name () const { return _m_name; }
char const *description () const { return _m_description; }
- 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; }
+ bool schedule () const { return _m_schedule; }
options const &opts () const { return _m_opts; }
+ void list (bool verbose) const;
+
private:
char const *const _m_name;
char const *const _m_description;
checkgroups const _m_groups;
- prereqs const _m_prereq;
- bool _m_hidden;
+ bool const _m_hidden;
+ bool const _m_schedule;
options const _m_opts;
};
-template <class T>
-checkdescriptor::create &
-checkdescriptor::create::prereq ()
-{
- _m_prereq.insert (T::descriptor ());
- return *this;
-}
-
-template <class T>
-checkdescriptor::create &
-checkdescriptor::create::inherit ()
-{
- checkdescriptor const &cd = *T::descriptor ();
- for (prereqs::const_iterator it = cd.prereq ().begin ();
- it != cd.prereq ().end (); ++it)
- _m_prereq.insert (*it);
- return *this;
-}
-
#endif//DWARFLINT_CHECKDESCRIPTOR_HH
/* Pedantic checking of DWARF files
- Copyright (C) 2010 Red Hat, Inc.
+ Copyright (C) 2010, 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
{
static checkdescriptor cd
(checkdescriptor::create ("cu_coverage")
- .prereq<typeof (*_m_info)> ()
- .prereq<typeof (*_m_ranges)> ());
+ .hidden ());
return &cd;
}
#include "checks.hh"
#include "check_registrar.hh"
#include "files.hh"
+#include "main.hh"
#include <fcntl.h>
#include <cstring>
main_check_registrar::run (dwarflint &lint)
{
for (const_iterator it = begin (); it != end (); ++it)
- {
- checkstack stack;
- (*it)->run (stack, lint);
- }
+ if ((*it)->descriptor ()->schedule ())
+ {
+ checkstack stack;
+ (*it)->run (stack, lint);
+ }
}
dwarflint::dwarflint (char const *a_fname, checkrules const &a_rules)
namespace
{
+ bool
+ be_verbose ()
+ {
+ // We can hopefully assume that the option doesn't change during
+ // execution, so we can simply cache it this was.
+ static bool be_verbose = opt_list_checks.value () == "full";
+ return be_verbose;
+ }
+
template <class T>
void
list_part_checks (T const &descriptors)
{
for (typename T::const_iterator it = descriptors.begin ();
it != descriptors.end (); ++it)
- check_registrar_aux::list_one_check (**it);
+ if (!(*it)->hidden ())
+ (*it)->list (be_verbose ());
}
}
{
list_part_checks (dwarflint::main_registrar ()->get_descriptors ());
- if (!check_registrar_aux::be_verbose ())
+ if (!be_verbose ())
std::cout
<< "Use --list-checks=full to get more detailed description."
<< std::endl;
open_highlevel_dwarf *_m_loader;
public:
static checkdescriptor const *descriptor () {
- static checkdescriptor cd
- (checkdescriptor::create ("highlevel_check")
- .prereq<typeof (*highlevel_check_i::_m_loader)> ());
+ static checkdescriptor cd ("highlevel_check");
return &cd;
}
/* Scheduler for low_level checks
- Copyright (C) 2010 Red Hat, Inc.
+ Copyright (C) 2010, 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
{
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> ()
- .prereq<check_debug_info_refs> ()
- .hidden ()
- );
+ .hidden ());
return &cd;
}
+
static reg<lowlevel_checks> reg_lowlevel_checks;
namespace
checkdescriptor const *
section_base::descriptor ()
{
- static checkdescriptor cd
- (checkdescriptor::create ()
- .prereq<typeof (*sections)> ());
+ static checkdescriptor cd;
return &cd;
}
/* Low-level section handling.
- Copyright (C) 2009, 2010 Red Hat, Inc.
+ Copyright (C) 2009, 2010, 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
static checkdescriptor const *descriptor () {
static checkdescriptor cd
(checkdescriptor::create (section_name[sec_id])
- .inherit<section_base> ()
.hidden ());
return &cd;
}