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 \
-*-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.
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
#include <cassert>
#include <algorithm>
-static reg<check_debug_abbrev> reg_debug_abbrev;
-
-checkdescriptor &
+checkdescriptor const *
check_debug_abbrev::descriptor ()
{
static checkdescriptor cd
"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 *
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;
#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
" - 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)
cu_coverage *_m_cu_coverage;
public:
- static checkdescriptor descriptor ();
+ static checkdescriptor const *descriptor ();
check_debug_aranges (checkstack &stack, dwarflint &lint);
};
#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)> ()
" - that relocations are valid. In ET_REL files that certain fields\n"
" are relocated\n"
));
- return cd;
+ return &cd;
}
namespace
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))
return NULL;
}
-checkdescriptor const &
+checkdescriptor const *
check_debug_info_refs::descriptor ()
{
static checkdescriptor cd
"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,
<< "unresolved reference to .debug_line table "
<< pri::hex (it->stmt_list.addr) << '.' << std::endl;
}
-static reg<check_debug_info_refs> reg_debug_info_refs;
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);
};
: 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;
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; }
check_debug_line *_m_line;
public:
- static checkdescriptor const &descriptor ();
+ static checkdescriptor const *descriptor ();
check_debug_info_refs (checkstack &stack, dwarflint &lint);
};
#include <sstream>
-checkdescriptor const &
+checkdescriptor const *
check_debug_line::descriptor ()
{
static checkdescriptor cd
" 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
{
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; }
#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
" - 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
" - 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
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);
check_debug_info *_m_info;
public:
- static checkdescriptor const &descriptor ();
+ static checkdescriptor const *descriptor ();
check_debug_loc (checkstack &stack, dwarflint &lint);
};
}
-checkdescriptor const &
+checkdescriptor const *
check_debug_pubnames::descriptor ()
{
static checkdescriptor cd
"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
.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);
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)
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)
};
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> > ()
"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);
: 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> > ()
"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)
: 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);
: 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);
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);
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 &
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
{};
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;
}
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;
}
if (c == NULL)
{
- checkdescriptor const &cd = T::descriptor ();
+ checkdescriptor const &cd = *T::descriptor ();
struct popper {
checkstack &guard_stack;
lint.toplev_check <T> (stack);
}
- virtual checkdescriptor descriptor () const
+ virtual checkdescriptor const *descriptor () const
{
return T::descriptor ();
}
#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)
check_debug_ranges *_m_ranges;
public:
- static checkdescriptor const &descriptor ();
+ static checkdescriptor const *descriptor ();
coverage cov;
}
}
+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
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 ();
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 ()
#include "highlevel_check.hh"
#include "messages.h"
+#include "sections.hh"
+#include "lowlevel_checks.hh"
+
namespace
{
inline bool failed (void *ptr) { return ptr == NULL; }
}
}
-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))
{}
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;
{
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;
--- /dev/null
+/* 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);
+}
--- /dev/null
+/* 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
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
#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
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:
return mc_reloc;
// xxx don't have one
- case sec_mac:
case sec_invalid:
case sec_locexpr:
case rel_value:
: public check<load_sections>
{
public:
- static checkdescriptor const &descriptor ();
+ static checkdescriptor const *descriptor ();
elf_file file;
load_sections (checkstack &stack, dwarflint &lint);
sec &get_sec_or_throw (section_id secid);
public:
- static checkdescriptor const &descriptor ();
+ static checkdescriptor const *descriptor ();
sec §
elf_file &file;
, 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)