diff options
-rw-r--r-- | dwarflint/Makefile.am | 2 | ||||
-rw-r--r-- | dwarflint/TODO | 3 | ||||
-rw-r--r-- | dwarflint/check_debug_info.cc | 8 | ||||
-rw-r--r-- | dwarflint/check_debug_loc_range.cc | 5 | ||||
-rw-r--r-- | dwarflint/check_matching_ranges.cc | 3 | ||||
-rw-r--r-- | dwarflint/check_nodebug.cc | 7 | ||||
-rw-r--r-- | dwarflint/checks.cc | 8 | ||||
-rw-r--r-- | dwarflint/dwarflint.cc | 10 | ||||
-rw-r--r-- | dwarflint/highlevel_check.hh | 8 | ||||
-rw-r--r-- | dwarflint/low.c | 6 | ||||
-rw-r--r-- | dwarflint/main.cc | 270 | ||||
-rw-r--r-- | dwarflint/main.hh (renamed from dwarflint/options.h) | 30 | ||||
-rw-r--r-- | dwarflint/option.cc | 133 | ||||
-rw-r--r-- | dwarflint/option.hh | 147 | ||||
-rw-r--r-- | dwarflint/options.cc | 43 | ||||
-rw-r--r-- | dwarflint/sections.cc | 3 | ||||
-rwxr-xr-x | dwarflint/tests/run-nodebug.sh | 7 | ||||
-rw-r--r-- | dwarflint/where.c | 5 |
18 files changed, 421 insertions, 277 deletions
diff --git a/dwarflint/Makefile.am b/dwarflint/Makefile.am index a44751f7..faaedb62 100644 --- a/dwarflint/Makefile.am +++ b/dwarflint/Makefile.am @@ -49,7 +49,7 @@ dwarflint_SOURCES = \ messages.cc messages.h \ section_id.cc section_id.h \ where.c where.h \ - options.cc options.h \ + option.cc option.hh \ addr-record.cc addr-record.h \ reloc.cc reloc.h \ tables.cc tables.hh tables.h \ diff --git a/dwarflint/TODO b/dwarflint/TODO index e47c6122..99069b67 100644 --- a/dwarflint/TODO +++ b/dwarflint/TODO @@ -110,6 +110,9 @@ there to be frequent additions to this "quirks table", so it should be fairly easy to extend this. + The current option --tolerant will go away when this is implemented. + I don't think it even works anyway. + * multi-file mode While dwarflint manages checking several files (meaning you can put diff --git a/dwarflint/check_debug_info.cc b/dwarflint/check_debug_info.cc index 8e8a36f0..d99fdadb 100644 --- a/dwarflint/check_debug_info.cc +++ b/dwarflint/check_debug_info.cc @@ -1,6 +1,6 @@ /* Routines related to .debug_info. - Copyright (C) 2009 Red Hat, Inc. + Copyright (C) 2009, 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 @@ -34,7 +34,7 @@ #include "messages.h" #include "pri.hh" -#include "options.h" +#include "option.hh" #include "sections.hh" #include "check_debug_loc_range.hh" #include "check_debug_abbrev.hh" @@ -93,6 +93,10 @@ check_debug_info::descriptor () return &cd; } +static void_option + dump_die_offsets ("Dump DIE offsets to stderr as the tree is iterated.", + "dump-offsets"); + namespace { bool diff --git a/dwarflint/check_debug_loc_range.cc b/dwarflint/check_debug_loc_range.cc index d664122e..5a3f1268 100644 --- a/dwarflint/check_debug_loc_range.cc +++ b/dwarflint/check_debug_loc_range.cc @@ -1,6 +1,6 @@ /* Routines related to .debug_loc and .debug_range. - Copyright (C) 2009 Red Hat, Inc. + Copyright (C) 2009, 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 @@ -38,13 +38,14 @@ #include "../libdw/dwarf.h" #include "low.h" -#include "options.h" #include "check_debug_loc_range.hh" #include "check_debug_info.hh" #include "sections.hh" #include "../src/dwarf-opcodes.h" #include "pri.hh" +bool do_range_coverage = false; // currently no option + checkdescriptor const * check_debug_ranges::descriptor () { diff --git a/dwarflint/check_matching_ranges.cc b/dwarflint/check_matching_ranges.cc index 0afdc078..f9c05962 100644 --- a/dwarflint/check_matching_ranges.cc +++ b/dwarflint/check_matching_ranges.cc @@ -59,9 +59,6 @@ check_matching_ranges::check_matching_ranges (checkstack &stack, dwarflint &lint) : highlevel_check<check_matching_ranges> (stack, lint) { - if (be_tolerant || be_gnu) - throw check_base::unscheduled (); - lint.check<check_debug_ranges> (stack); lint.check<check_debug_aranges> (stack); diff --git a/dwarflint/check_nodebug.cc b/dwarflint/check_nodebug.cc index e26d3dfb..fe9fbb0e 100644 --- a/dwarflint/check_nodebug.cc +++ b/dwarflint/check_nodebug.cc @@ -24,9 +24,9 @@ <http://www.openinventionnetwork.com>. */ #include "checks.hh" -#include "options.h" #include "messages.h" #include "sections.hh" +#include "option.hh" class check_nodebug : public check<check_nodebug> @@ -62,10 +62,13 @@ private: }; static reg<check_nodebug> reg_nodebug; +static void_option ignore_missing + ("Don't complain if files have no DWARF at all", + "ignore-missing", 'i'); check_nodebug::check_nodebug (checkstack &stack, dwarflint &lint) { - if (tolerate_nodebug) + if (ignore_missing) return; // We demand .debug_info and .debug_abbrev, the rest is optional. diff --git a/dwarflint/checks.cc b/dwarflint/checks.cc index 16b7abe1..76ca27ae 100644 --- a/dwarflint/checks.cc +++ b/dwarflint/checks.cc @@ -24,7 +24,11 @@ <http://www.openinventionnetwork.com>. */ #include "checks.hh" -#include "options.h" +#include "option.hh" + +static void_option show_progress + ("Print out checks as they are performed, their context and result.", + "show-progress"); reporter::reporter (checkstack const &s, checkdescriptor const &a_cd) : stack (s) @@ -36,7 +40,7 @@ reporter::reporter (checkstack const &s, checkdescriptor const &a_cd) void reporter::operator () (char const *what, bool ext) { - if (!be_verbose) + if (!show_progress) return; if (false) diff --git a/dwarflint/dwarflint.cc b/dwarflint/dwarflint.cc index bbd17b5f..9c21dbcc 100644 --- a/dwarflint/dwarflint.cc +++ b/dwarflint/dwarflint.cc @@ -1,5 +1,5 @@ /* Dwarflint check scheduler. - Copyright (C) 2008,2009 Red Hat, Inc. + Copyright (C) 2008,2009,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 @@ -26,7 +26,7 @@ #include "dwarflint.hh" #include "messages.h" #include "checks.hh" -#include "options.h" +#include "main.hh" #include <fcntl.h> #include <cstring> @@ -122,6 +122,7 @@ namespace void dwarflint::check_registrar::list_checks () const { + bool be_verbose = opt_list_checks.value () == "full"; typedef std::set<checkdescriptor const *> descset; descset descriptors; for (std::vector <item *>::const_iterator it = _m_items.begin (); @@ -160,8 +161,9 @@ dwarflint::check_registrar::list_checks () const } } if (!be_verbose) - std::cout << "Use --list-checks --verbose " - "to get detailed description of each check." << std::endl; + std::cout + << "Use --list-checks=full to get more detailed description." + << std::endl; } namespace diff --git a/dwarflint/highlevel_check.hh b/dwarflint/highlevel_check.hh index 5505ae15..7fb7b128 100644 --- a/dwarflint/highlevel_check.hh +++ b/dwarflint/highlevel_check.hh @@ -1,5 +1,5 @@ /* Pedantic checking of DWARF files. - Copyright (C) 2009 Red Hat, Inc. + Copyright (C) 2009, 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 @@ -31,7 +31,6 @@ #endif #include "checks.hh" -#include "options.h" #include "c++/dwarf" #include "../libdwfl/libdwfl.h" @@ -69,10 +68,7 @@ public: explicit highlevel_check (checkstack &stack, dwarflint &lint) : _m_loader (lint.check (stack, _m_loader)) , dw (_m_loader->dw) - { - if (!do_high_level) - throw check_base::unscheduled (); - } + {} }; template <class T> diff --git a/dwarflint/low.c b/dwarflint/low.c index d5950e14..9872d4ae 100644 --- a/dwarflint/low.c +++ b/dwarflint/low.c @@ -1,5 +1,5 @@ /* Pedantic checking of DWARF files - Copyright (C) 2008,2009 Red Hat, Inc. + Copyright (C) 2008,2009,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 @@ -46,7 +46,6 @@ #include "../src/dwarfstrings.h" #include "low.h" #include "readctx.h" -#include "options.h" #include "tables.h" #define PRI_CU "CU 0x%" PRIx64 @@ -331,8 +330,7 @@ check_aranges_structural (struct elf_file *file, inline void aranges_coverage_add (uint64_t begin, uint64_t length) { - if (coverage_is_overlap (aranges_coverage, begin, length) - && !be_gnu && !be_tolerant) + if (coverage_is_overlap (aranges_coverage, begin, length)) { char buf[128]; /* Not a show stopper, this shouldn't derail high-level. */ diff --git a/dwarflint/main.cc b/dwarflint/main.cc index 05070d23..61a080be 100644 --- a/dwarflint/main.cc +++ b/dwarflint/main.cc @@ -1,5 +1,5 @@ /* Main entry point for dwarflint, a pedantic checker for DWARF files. - Copyright (C) 2008,2009 Red Hat, Inc. + Copyright (C) 2008,2009,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 @@ -26,7 +26,6 @@ #ifdef HAVE_CONFIG_H # include <config.h> #endif -#include <argp.h> #include <libintl.h> #include <sys/stat.h> #include <sys/types.h> @@ -35,58 +34,10 @@ #include <sstream> #include "low.h" -#include "options.h" #include "dwarflint.hh" #include "readctx.h" #include "checks.hh" - -/* Bug report address. */ -const char *argp_program_bug_address = PACKAGE_BUGREPORT; - -#define ARGP_strict 300 -#define ARGP_gnu 301 -#define ARGP_tolerant 302 -#define ARGP_ref 303 -#define ARGP_nohl 304 -#define ARGP_dump_off 305 -#define ARGP_check 306 -#define ARGP_list_checks 307 - -/* Definitions of arguments for argp functions. */ -static const struct argp_option options[] = -{ - { "strict", ARGP_strict, NULL, 0, - N_("Be extremely strict, flag level 2 features."), 0 }, - { "quiet", 'q', NULL, 0, N_("Do not print anything if successful"), 0 }, - { "ignore-missing", 'i', NULL, 0, - N_("Don't complain if files have no DWARF at all"), 0 }, - { "gnu", ARGP_gnu, NULL, 0, - N_("Binary has been created with GNU toolchain and is therefore known to be \ -broken in certain ways"), 0 }, - { "tolerant", ARGP_tolerant, NULL, 0, - N_("Don't output certain common error messages"), 0 }, - { "ref", ARGP_ref, NULL, 0, - N_("When validating .debug_loc and .debug_ranges, display information about \ -the DIE referring to the entry in consideration"), 0 }, - { "nohl", ARGP_nohl, NULL, 0, - N_("Don't run high-level tests"), 0 }, - { "verbose", 'v', NULL, 0, - N_("Be verbose"), 0 }, - { "dump-offsets", ARGP_dump_off, NULL, 0, - N_("Dump DIE offsets to stderr as the tree is iterated."), 0 }, - { "check", ARGP_check, "[+-][@]name,...", 0, - N_("Only run selected checks."), 0 }, - { "list-checks", ARGP_list_checks, NULL, 0, - N_("List all the available checks."), 0 }, - { NULL, 0, NULL, 0, NULL, 0 } -}; - -/* Short description of program. */ -static const char doc[] = N_("\ -Pedantic checking of DWARF stored in ELF files."); - -/* Strings for arguments in help texts. */ -static const char args_doc[] = N_("FILE..."); +#include "option.hh" /* Messages that are accepted (and made into warning). */ struct message_criteria warning_criteria; @@ -94,142 +45,94 @@ struct message_criteria warning_criteria; /* Accepted (warning) messages, that are turned into errors. */ struct message_criteria error_criteria; -/* Whether to list available checks and exit. */ -static bool just_list_checks = false; - - -static error_t parse_opt (int key, char *arg, struct argp_state *state); - -/* Data structure to communicate with argp functions. */ -static struct argp argp = -{ - options, parse_opt, args_doc, doc, NULL, NULL, NULL -}; - -struct initial_check_rules - : public check_rules -{ - initial_check_rules () { - push_back (check_rule ("@all", check_rule::request)); - push_back (check_rule ("@nodefault", check_rule::forbid)); - } -} rules; - -/* Handle program arguments. */ -static error_t -parse_opt (int key, char *arg __attribute__ ((unused)), - struct argp_state *state __attribute__ ((unused))) +struct check_option_t + : public option_common { - switch (key) - { - case ARGP_strict: - be_strict = true; - break; - - case ARGP_gnu: - be_gnu = true; - break; - - case ARGP_tolerant: - be_tolerant = true; - break; - - case ARGP_ref: - show_refs = true; - break; + struct initial_check_rules + : public check_rules + { + initial_check_rules () { + push_back (check_rule ("@all", check_rule::request)); + push_back (check_rule ("@nodefault", check_rule::forbid)); + } + } rules; - case ARGP_nohl: - do_high_level = false; - break; + check_option_t () + : option_common ("Only run selected checks.", + "[+-][@]name,...", "check", 0) + {} - case ARGP_dump_off: - dump_die_offsets = true; - break; + error_t parse_opt (char *arg, __attribute__ ((unused)) argp_state *state) + { + static bool first = true; + std::stringstream ss (arg); + std::string item; - case ARGP_check: + while (std::getline (ss, item, ',')) { - static bool first = true; - std::stringstream ss (arg); - std::string item; + if (item.empty ()) + continue; - while (std::getline (ss, item, ',')) + enum { + forbid, + request, + replace + } act; + + // If the first rule has no operator, we assume the user + // wants to replace the implicit set of checks. + if (first) { - if (item.empty ()) - continue; - - enum { - forbid, - request, - replace - } act; - - // If the first rule has no operator, we assume the user - // wants to replace the implicit set of checks. - if (first) - { - act = replace; - first = false; - } - else - // Otherwise the rules are implicitly requesting, even - // without the '+' operator. - act = request; - - bool minus = item[0] == '-'; - bool plus = item[0] == '+'; - if (plus || minus) - item = item.substr (1); - if (plus) - act = request; - if (minus) - act = forbid; - - if (act == replace) - { - rules.clear (); - act = request; - } - - check_rule::action_t action - = act == request ? check_rule::request : check_rule::forbid; - rules.push_back (check_rule (item, action)); + act = replace; + first = false; + } + else + // Otherwise the rules are implicitly requesting, even + // without the '+' operator. + act = request; + + bool minus = item[0] == '-'; + bool plus = item[0] == '+'; + if (plus || minus) + item = item.substr (1); + if (plus) + act = request; + if (minus) + act = forbid; + + if (act == replace) + { + rules.clear (); + act = request; } - } - break; - - case ARGP_list_checks: - just_list_checks = true; - break; - case 'i': - tolerate_nodebug = true; - break; + check_rule::action_t action + = act == request ? check_rule::request : check_rule::forbid; + rules.push_back (check_rule (item, action)); + } + return 0; + } +} check_option; - case 'q': - be_quiet = true; - be_verbose = false; - break; +void_option be_quiet ("Do not print anything if successful", + "quiet", 'q'); - case 'v': - be_quiet = false; - be_verbose = true; - break; +string_option opt_list_checks ("List all the available checks.", + "full", "list-checks", 0, + OPTION_ARG_OPTIONAL); - case ARGP_KEY_NO_ARGS: - if (!just_list_checks) - { - fputs (gettext ("Missing file name.\n"), stderr); - argp_help (&argp, stderr, ARGP_HELP_SEE | ARGP_HELP_EXIT_ERR, - program_invocation_short_name); - exit (1); - } - break; +// xxx The following three should go away when we introduce the +// message filtering. Or should be preserved, but in a way that makes +// more sense, right now they are simply a misnomer. +void_option ignore_bloat ("Ignore messages related to bloat.", "ignore-bloat"); +void_option be_strict ("Be somewhat stricter.", "strict"); +void_option be_tolerant ("Be somewhat more tolerant.", "tolerant"); - default: - return ARGP_ERR_UNKNOWN; - } - return 0; -} +// xxx as soon as where is in c++, this can move there +void_option opt_show_refs = void_option ( +"When validating .debug_loc and .debug_ranges, display information about \ +the DIE referring to the entry in consideration", "ref"); +extern "C" bool show_refs () { return (bool)opt_show_refs; } int main (int argc, char *argv[]) @@ -241,14 +144,22 @@ main (int argc, char *argv[]) textdomain (PACKAGE_TARNAME); /* Parse and process arguments. */ + struct argp argp = options::registered ().build_argp (); int remaining; argp_parse (&argp, argc, argv, 0, &remaining, NULL); - if (just_list_checks) + if (opt_list_checks.seen ()) { dwarflint::check_registrar::inst ()->list_checks (); std::exit (0); } + else if (remaining == argc) + { + fputs (gettext ("Missing file name.\n"), stderr); + argp_help (&argp, stderr, ARGP_HELP_SEE | ARGP_HELP_EXIT_ERR, + program_invocation_short_name); + std::exit (1); + } /* Initialize warning & error criteria. */ warning_criteria |= message_term (mc_none, mc_none); @@ -257,10 +168,7 @@ main (int argc, char *argv[]) error_criteria |= message_term (mc_error, mc_none); /* Configure warning & error criteria according to configuration. */ - if (tolerate_nodebug) - warning_criteria &= message_term (mc_none, mc_elf); - - if (be_gnu) + if (ignore_bloat) warning_criteria &= message_term (mc_none, mc_acc_bloat); if (!be_strict) @@ -277,7 +185,7 @@ main (int argc, char *argv[]) warning_criteria &= message_term (mc_none, mc_ranges); } - if (be_verbose) + if (false) // for debugging { std::cout << "warning criteria: " << warning_criteria.str () << std::endl; std::cout << "error criteria: " << error_criteria.str () << std::endl; @@ -297,7 +205,7 @@ main (int argc, char *argv[]) unsigned int prev_error_count = error_count; if (!only_one) std::cout << std::endl << fname << ":" << std::endl; - dwarflint lint (fname, rules); + dwarflint lint (fname, check_option.rules); if (prev_error_count == error_count && !be_quiet) puts (gettext ("No errors")); diff --git a/dwarflint/options.h b/dwarflint/main.hh index 157d56f5..0651895d 100644 --- a/dwarflint/options.h +++ b/dwarflint/main.hh @@ -1,5 +1,5 @@ -/* - Copyright (C) 2008,2009 Red Hat, Inc. +/* Pedantic checker for DWARF files + 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 @@ -23,26 +23,10 @@ Network licensing program, please visit www.openinventionnetwork.com <http://www.openinventionnetwork.com>. */ -#ifdef __cplusplus -extern "C" -{ -#else -#include <stdbool.h> -#endif +#ifndef DWARFLINT_MAIN_HH +#define DWARFLINT_MAIN_HH - /* Whole-program options. */ - extern bool tolerate_nodebug; - extern bool be_quiet; /* -q */ - extern bool be_verbose; /* -v */ - extern bool be_strict; /* --strict */ - extern bool be_gnu; /* --gnu */ - extern bool be_tolerant; /* --tolerant */ - extern bool show_refs; /* --ref */ - extern bool do_high_level; /* ! --nohl */ - extern bool dump_die_offsets; /* --dump-offsets */ +#include "option.hh" +extern string_option opt_list_checks; - extern bool do_range_coverage; - -#ifdef __cplusplus -} -#endif +#endif//DWARFLINT_MAIN_HH diff --git a/dwarflint/option.cc b/dwarflint/option.cc new file mode 100644 index 00000000..6fadf9ab --- /dev/null +++ b/dwarflint/option.cc @@ -0,0 +1,133 @@ +/* Pedantic checking of DWARF files + Copyright (C) 2009,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>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include "option.hh" +#include <cassert> +#include <cstring> +#include <iostream> + +option_common * +options::opt (int key) const +{ + const_iterator it = find (key); + if (it == end ()) + return NULL; + return it->second; +} + +option_common const * +options::getopt (int key) const +{ + return opt (key); +} + +error_t +options::parse_opt (int key, char *arg, + __attribute__ ((unused)) argp_state *state) +{ + option_common *o = registered ().opt (key); + if (o == NULL) + return ARGP_ERR_UNKNOWN; + return o->parse_opt (arg, state); +} + +struct last_option + : public argp_option +{ + last_option () { + std::memset (this, 0, sizeof (*this)); + } +}; + +/* Bug report address. */ +const char *argp_program_bug_address = PACKAGE_BUGREPORT; + +argp +options::build_argp () +{ + _m_opts.clear (); + for (const_iterator it = begin (); it != end (); ++it) + _m_opts.push_back (it->second->build_option ()); + _m_opts.push_back (last_option ()); + argp a = { + &_m_opts.front (), + &options::parse_opt, + "FILE...", + "\ +Pedantic checking of DWARF stored in ELF files.", + NULL, NULL, NULL + }; + return a; +} + + +int option_common::_m_last_opt = 300; + +options & +options::registered () +{ + static options opts; + return opts; +} + +int +option_common::get_short_option (char opt_short) +{ + if (opt_short) + return opt_short; + return _m_last_opt++; +} + +namespace +{ + argp_option argp_option_ctor (char const *name, int key, + char const *arg, int flags, + char const *doc, int group) + { + assert (name != NULL); + assert (doc != NULL); + argp_option opt = { + name, key, arg, flags, doc, group + }; + return opt; + } +} + +option_common::option_common (char const *description, + char const *arg_description, + char const *opt_long, char opt_short, + int flags) + : _m_opt (argp_option_ctor (opt_long, get_short_option (opt_short), + arg_description, flags, + description, 0)) + , _m_seen (false) +{ + assert (options::registered ().getopt (_m_opt.key) == NULL); + options::registered ()[_m_opt.key] = this; +} diff --git a/dwarflint/option.hh b/dwarflint/option.hh new file mode 100644 index 00000000..aa256d62 --- /dev/null +++ b/dwarflint/option.hh @@ -0,0 +1,147 @@ +/* Pedantic checker for DWARF files + 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_OPTION_HH +#define DWARFLINT_OPTION_HH + +#include <string> +#include <argp.h> +#include <map> +#include <vector> +#include <cassert> + +#include <iostream> + +class option_common; + +class options + : private std::map<int, option_common *> +{ + friend class option_common; + std::vector<argp_option> _m_opts; + + option_common *opt (int key) const; + static error_t parse_opt (int key, char *arg, argp_state *state); + +public: + static options ®istered (); + option_common const *getopt (int key) const; + argp build_argp (); +}; + +class option_common +{ + argp_option _m_opt; + + static int _m_last_opt; + static int get_short_option (char opt_short); + +protected: + bool _m_seen; + + option_common (char const *description, + char const *arg_description, + char const *opt_long, char opt_short, + int flags = 0); + +public: // consumer interface + bool seen () const { return _m_seen; } + +public: // option handler interface + argp_option const &build_option () const { return _m_opt; } + virtual error_t parse_opt (char *arg, argp_state *state) = 0; +}; + +template<class arg_type> +class value_converter; + +template<class arg_type> +class xoption + : public option_common +{ + arg_type _m_arg; + +public: + xoption (char const *description, + char const *arg_description, + char const *opt_long, char opt_short = 0, + int flags = 0) + : option_common (description, arg_description, opt_long, opt_short, flags) + { + } + + arg_type const &value () const + { + return _m_arg; + } + + error_t parse_opt (char *arg, __attribute__ ((unused)) argp_state *state) + { + _m_seen = true; + _m_arg = value_converter<arg_type>::convert (arg); + return 0; + } +}; + +template<> +class xoption<void> + : public option_common +{ +public: + xoption (char const *description, + char const *opt_long, char opt_short = 0, int flags = 0) + : option_common (description, NULL, opt_long, opt_short, flags) + { + } + + error_t parse_opt (char *arg, __attribute__ ((unused)) argp_state *state) + { + assert (arg == NULL); + _m_seen = true; + return 0; + } + + // This shouldn't be promoted to option_common, as + // e.g. xoption<bool> will naturally have a different + // implementation. + operator bool () { return seen (); } +}; + +template<> +struct value_converter<std::string> +{ + static std::string convert (char const *arg) + { + if (arg == NULL) + return ""; + else + return arg; + } +}; + +typedef xoption<void> void_option; +typedef xoption<std::string> string_option; + +#endif//DWARFLINT_OPTION_HH diff --git a/dwarflint/options.cc b/dwarflint/options.cc deleted file mode 100644 index ff3b5e2c..00000000 --- a/dwarflint/options.cc +++ /dev/null @@ -1,43 +0,0 @@ -/* - Copyright (C) 2008,2009 Red Hat, Inc. - This file is part of Red Hat elfutils. - - Red Hat elfutils is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by the - Free Software Foundation; version 2 of the License. - - Red Hat elfutils is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License along - with Red Hat elfutils; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. - - Red Hat elfutils is an included package of the Open Invention Network. - An included package of the Open Invention Network is a package for which - Open Invention Network licensees cross-license their patents. No patent - license is granted, either expressly or impliedly, by designation as an - included package. Should you wish to participate in the Open Invention - Network licensing program, please visit www.openinventionnetwork.com - <http://www.openinventionnetwork.com>. */ - -#include "options.h" - -/* If true, we accept silently files without debuginfo. */ -bool tolerate_nodebug = false; - -/* True if no message is to be printed if the run is succesful. */ -bool be_quiet = false; /* -q */ -bool be_verbose = false; /* -v */ -bool be_strict = false; /* --strict */ -bool be_gnu = false; /* --gnu */ -bool be_tolerant = false; /* --tolerant */ -bool show_refs = false; /* --ref */ -bool do_high_level = true; /* ! --nohl */ -bool dump_die_offsets = false; /* --dump-offsets */ - -/* True if coverage analysis of .debug_ranges vs. ELF sections should - be done. */ -bool do_range_coverage = false; // currently no option diff --git a/dwarflint/sections.cc b/dwarflint/sections.cc index a8932334..1e07987e 100644 --- a/dwarflint/sections.cc +++ b/dwarflint/sections.cc @@ -1,5 +1,5 @@ /* Low-level section handling. - Copyright (C) 2009 Red Hat, Inc. + Copyright (C) 2009, 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 @@ -34,7 +34,6 @@ #include "sections.hh" #include "messages.h" #include "pri.hh" -#include "options.h" checkdescriptor const * load_sections::descriptor () diff --git a/dwarflint/tests/run-nodebug.sh b/dwarflint/tests/run-nodebug.sh index f853e13c..a595433c 100755 --- a/dwarflint/tests/run-nodebug.sh +++ b/dwarflint/tests/run-nodebug.sh @@ -33,3 +33,10 @@ testrun_compare ./dwarflint nodebug <<EOF error: .debug_abbrev: data not found. error: .debug_info: data not found. EOF + +testrun_compare ./dwarflint -i nodebug <<EOF +No errors +EOF + +testrun_compare ./dwarflint -q -i nodebug <<EOF +EOF diff --git a/dwarflint/where.c b/dwarflint/where.c index 3e284565..ca9f0cd5 100644 --- a/dwarflint/where.c +++ b/dwarflint/where.c @@ -24,7 +24,6 @@ <http://www.openinventionnetwork.com>. */ #include "where.h" -#include "options.h" #include <inttypes.h> #include <assert.h> @@ -32,6 +31,8 @@ #include <stdio.h> #include <string.h> +extern bool show_refs (void); + const char * where_fmt (const struct where *wh, char *ptr) { @@ -189,7 +190,7 @@ where_fmt (const struct where *wh, char *ptr) void where_fmt_chain (const struct where *wh, const char *severity) { - if (wh != NULL && show_refs) + if (wh != NULL && show_refs ()) for (struct where const *it = wh->next; it != NULL; it = it->next) printf ("%s: %s: caused by this reference.\n", severity, where_fmt (it, NULL)); |