From: Petr Machata Date: Mon, 26 Oct 2009 14:44:46 +0000 (+0100) Subject: dwarflint: Avoid repeating once failed tests X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=39137da63492299fe413678bdee31d0bc7051a0a;p=thirdparty%2Felfutils.git dwarflint: Avoid repeating once failed tests --- diff --git a/src/Makefile.am b/src/Makefile.am index 87fbf4a01..d69be9094 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -88,7 +88,7 @@ dwarflint_SOURCES = dwarfstrings.c \ dwarflint/messages.cc dwarflint/messages.h \ dwarflint/where.c dwarflint/where.h \ dwarflint/config.cc dwarflint/config.h \ - dwarflint/checks.cc dwarflint/checks.hh \ + dwarflint/checks.hh \ dwarflint/checks-low.cc dwarflint/checks-low.hh \ dwarflint/addr-record.cc dwarflint/addr-record.h \ dwarflint/reloc.cc dwarflint/reloc.h \ diff --git a/src/dwarflint/check_debug_abbrev.cc b/src/dwarflint/check_debug_abbrev.cc index 17b32956c..46e8751e9 100644 --- a/src/dwarflint/check_debug_abbrev.cc +++ b/src/dwarflint/check_debug_abbrev.cc @@ -158,7 +158,7 @@ check_debug_abbrev::check_debug_abbrev (dwarflint &lint) /* Abbreviation code. */ if (!checked_read_uleb128 (&ctx, &abbr_code, &where, "abbrev code")) - throw check_base::failed (""); //xxx + throw check_base::failed (); /* Note: we generally can't tell the difference between empty table and (excessive) padding. But NUL byte(s) @@ -239,14 +239,14 @@ check_debug_abbrev::check_debug_abbrev (dwarflint &lint) /* Abbreviation tag. */ uint64_t abbr_tag; if (!checked_read_uleb128 (&ctx, &abbr_tag, &where, "abbrev tag")) - throw check_base::failed (""); //xxx + throw check_base::failed (); if (abbr_tag > DW_TAG_hi_user) { std::stringstream ss; ss << ": invalid abbrev tag 0x" << std::hex << abbr_tag << '.'; wr_error (&where, "%s\n", ss.str ().c_str ()); - throw check_base::failed (""); //xxx + throw check_base::failed (); } cur->tag = (typeof (cur->tag))abbr_tag; @@ -255,7 +255,7 @@ check_debug_abbrev::check_debug_abbrev (dwarflint &lint) if (!read_ctx_read_ubyte (&ctx, &has_children)) { wr_error (&where, ": can't read abbrev has_children.\n"); - throw check_base::failed (""); //xxx + throw check_base::failed (); } if (has_children != DW_CHILDREN_no @@ -263,7 +263,7 @@ check_debug_abbrev::check_debug_abbrev (dwarflint &lint) { wr_error (&where, ": invalid has_children value 0x%x.\n", cur->has_children); - throw check_base::failed (""); //xxx + throw check_base::failed (); } cur->has_children = has_children == DW_CHILDREN_yes; @@ -284,11 +284,11 @@ check_debug_abbrev::check_debug_abbrev (dwarflint &lint) /* Load attribute name and form. */ if (!checked_read_uleb128 (&ctx, &attrib_name, &where, "attribute name")) - throw check_base::failed (""); //xxx + throw check_base::failed (); if (!checked_read_uleb128 (&ctx, &attrib_form, &where, "attribute form")) - throw check_base::failed (""); //xxx + throw check_base::failed (); null_attrib = attrib_name == 0 && attrib_form == 0; @@ -301,7 +301,7 @@ check_debug_abbrev::check_debug_abbrev (dwarflint &lint) std::stringstream ss; ss << ": invalid name 0x" << std::hex << attrib_name << '.'; wr_error (&where, "%s\n", ss.str ().c_str ()); - throw check_base::failed (""); //xxx + throw check_base::failed (); } if (!attrib_form_valid (attrib_form)) @@ -309,7 +309,7 @@ check_debug_abbrev::check_debug_abbrev (dwarflint &lint) std::stringstream ss; ss << ": invalid form 0x" << std::hex << attrib_form << '.'; wr_error (&where, "%s\n", ss.str ().c_str ()); - throw check_base::failed (""); //xxx + throw check_base::failed (); } } diff --git a/src/dwarflint/check_debug_line.cc b/src/dwarflint/check_debug_line.cc index 06b4c4f78..1932919fe 100644 --- a/src/dwarflint/check_debug_line.cc +++ b/src/dwarflint/check_debug_line.cc @@ -39,7 +39,7 @@ namespace if (!check_line_structural (&_m_sec->file, &_m_sec->sect, &line_tables)) - throw check_base::failed (""); //xxx + throw check_base::failed (); check_debug_info *info = NULL; info = lint.toplev_check (info); diff --git a/src/dwarflint/check_expected_trees.cc b/src/dwarflint/check_expected_trees.cc index 58907452f..f10926e56 100644 --- a/src/dwarflint/check_expected_trees.cc +++ b/src/dwarflint/check_expected_trees.cc @@ -160,8 +160,9 @@ check_expected_trees::check_expected_trees (dwarflint &lint) // XXX more specific class when has it catch (std::runtime_error &exc) { - throw check_base::failed - (std::string ("Error while checking expected trees: ") - + exc.what () + ".\n"); + wr_error (WHERE (sec_info, NULL)) + << "Exception while checking expected trees: " << exc.what () + << std::endl; + throw check_base::failed (); } } diff --git a/src/dwarflint/check_matching_ranges.cc b/src/dwarflint/check_matching_ranges.cc index f15eb6386..426aa4064 100644 --- a/src/dwarflint/check_matching_ranges.cc +++ b/src/dwarflint/check_matching_ranges.cc @@ -22,7 +22,7 @@ check_matching_ranges::check_matching_ranges (dwarflint &lint) : highlevel_check (lint) { if (be_tolerant || be_gnu) - throw check_base::unscheduled; + throw check_base::unscheduled (); lint.check (); lint.check (); @@ -78,8 +78,9 @@ check_matching_ranges::check_matching_ranges (dwarflint &lint) // XXX more specific class when has it catch (std::runtime_error &exc) { - throw check_base::failed - (std::string ("Error while checking matching ranges:") - + exc.what () + ".\n"); + wr_error (WHERE (sec_info, NULL)) + << "Exception while checking matching ranges: " << exc.what () + << std::endl; + throw check_base::failed (); } } diff --git a/src/dwarflint/check_range_out_of_scope.cc b/src/dwarflint/check_range_out_of_scope.cc index d62ce39a0..9dcdb37a3 100644 --- a/src/dwarflint/check_range_out_of_scope.cc +++ b/src/dwarflint/check_range_out_of_scope.cc @@ -212,8 +212,9 @@ check_range_out_of_scope::check_range_out_of_scope (dwarflint &lint) // XXX more specific class when has it catch (std::runtime_error &exc) { - throw check_base::failed - (std::string ("Error while checking range out of scope: ") - + exc.what () + ".\n"); + wr_error (WHERE (sec_info, NULL)) + << "Exception while checking ranges out of scope: " << exc.what () + << std::endl; + throw check_base::failed (); } } diff --git a/src/dwarflint/checks-high.hh b/src/dwarflint/checks-high.hh index 7f938849c..1723aac99 100644 --- a/src/dwarflint/checks-high.hh +++ b/src/dwarflint/checks-high.hh @@ -18,7 +18,7 @@ public: , dw (_m_handle) { if (!do_high_level) - throw check_base::unscheduled; + throw check_base::unscheduled (); } ~highlevel_check () diff --git a/src/dwarflint/checks-low.cc b/src/dwarflint/checks-low.cc index a9d7ee7c4..1505b8d9e 100644 --- a/src/dwarflint/checks-low.cc +++ b/src/dwarflint/checks-low.cc @@ -29,6 +29,7 @@ #include "checks-low.hh" #include "low.h" +#include "config.h" #include #include #include @@ -264,16 +265,56 @@ load_sections::~load_sections () free (file.sec); } +namespace +{ + message_category + secid_to_cat (section_id secid) + { + switch (secid) + { + case sec_info: return mc_info; + case sec_abbrev: return mc_abbrevs; + case sec_aranges: return mc_aranges; + case sec_str: return mc_strings; + case sec_line: return mc_line; + case sec_loc: return mc_loc; + case sec_ranges: return mc_ranges; + + case sec_pubnames: + case sec_pubtypes: + return mc_pubtables; + + case sec_rel: + case sec_rela: + return mc_reloc; + + // xxx don't have one + case sec_mac: + case sec_invalid: + case sec_locexpr: + case rel_value: + case rel_address: + case rel_exec: + break; + }; + std::stringstream ss; + ss << "Couldn't convert secid " << secid << " to mc."; + throw std::runtime_error (ss.str ()); + } +} sec & section_base::get_sec_or_throw (section_id secid) { if (sec *s = sections->file.debugsec[secid]) return *s; - where wh = WHERE (secid, NULL); - std::stringstream ss; - ss << where_fmt (&wh) << ": data not found."; - throw check_base::failed (ss.str ()); + if (!tolerate_nodebug) + wr_message (WHERE (secid, NULL), + cat (mc_impact_4, mc_acc_suboptimal, mc_elf, + secid_to_cat (secid))) + << ": data not found." << std::endl; + + throw check_base::failed (); } section_base::section_base (dwarflint &lint, section_id secid) @@ -298,7 +339,7 @@ check_debug_info::check_debug_info (dwarflint &lint) _m_sec_str->sect.data, &cu_cov); if (chain == NULL) - throw check_base::failed (""); // xxx + throw check_base::failed (); for (cu *cu = chain; cu != NULL; cu = cu->next) cus.push_back (*cu); @@ -332,7 +373,7 @@ check_debug_ranges::check_debug_ranges (dwarflint &lint) &_m_sec_ranges->sect, &_m_cus->cus.front (), &_m_cus->cu_cov)) - throw check_base::failed (""); //xxx + throw check_base::failed (); } check_debug_aranges::check_debug_aranges (dwarflint &lint) @@ -356,7 +397,7 @@ check_debug_aranges::check_debug_aranges (dwarflint &lint) &_m_sec_aranges->sect, info != NULL ? &info->cus.front () : NULL, cov)) - throw check_base::failed (""); //xxx + throw check_base::failed (); } check_debug_loc::check_debug_loc (dwarflint &lint) @@ -367,7 +408,7 @@ check_debug_loc::check_debug_loc (dwarflint &lint) &_m_sec_loc->sect, &_m_cus->cus.front (), NULL)) - throw check_base::failed (""); //xxx + throw check_base::failed (); } namespace @@ -387,7 +428,7 @@ namespace if (!check_pub_structural (&_m_sec->file, &_m_sec->sect, &_m_cus->cus.front ())) - throw check_base::failed (""); //xxx + throw check_base::failed (); } }; diff --git a/src/dwarflint/checks.cc b/src/dwarflint/checks.cc deleted file mode 100644 index afb16c83c..000000000 --- a/src/dwarflint/checks.cc +++ /dev/null @@ -1,2 +0,0 @@ -#include "checks.hh" -check_base::failed check_base::unscheduled ("the check is not scheduled"); diff --git a/src/dwarflint/checks.hh b/src/dwarflint/checks.hh index b41b7459d..84296b181 100644 --- a/src/dwarflint/checks.hh +++ b/src/dwarflint/checks.hh @@ -1,23 +1,14 @@ #ifndef DWARFLINT_CHECKS_HH #define DWARFLINT_CHECKS_HH -#include #include -#include #include "where.h" #include "dwarflint.hh" struct check_base { - struct failed - : public std::runtime_error - { - failed (std::string const &msg) - : std::runtime_error (msg) - {} - }; - - static failed unscheduled; + struct failed {}; + struct unscheduled: public failed {}; }; template @@ -31,6 +22,39 @@ public: } }; +template +T * +dwarflint::check () +{ + void const *key = T::key (); + check_map::iterator it = _m_checks.find (key); + + T *c; + if (it != _m_checks.end ()) + { + c = static_cast (it->second); + + // We already tried to do the check, but failed. + if (c == NULL) + throw check_base::failed (); + } + else + { + // Put a marker there saying that we tried to do the check, but + // it failed. + if (!_m_checks.insert (std::make_pair (key, (T *)0)).second) + throw std::runtime_error ("duplicate key"); + + // Now do the check. + c = new T (*this); + + // On success, put the actual check object there instead of the + // marker. + _m_checks[key] = c; + } + return c; +} + template inline T * dwarflint::toplev_check (__attribute__ ((unused)) T *tag) @@ -41,7 +65,6 @@ dwarflint::toplev_check (__attribute__ ((unused)) T *tag) } catch (check_base::failed const &f) { - std::cout << f.what () << std::endl; return NULL; } } diff --git a/src/dwarflint/dwarflint.hh b/src/dwarflint/dwarflint.hh index d292888da..f1684ecaf 100644 --- a/src/dwarflint/dwarflint.hh +++ b/src/dwarflint/dwarflint.hh @@ -46,23 +46,7 @@ public: dwarflint (Elf *elf); Elf *elf () { return _m_elf; } - template - T * - check () - { - void const *key = T::key (); - check_map::iterator it = _m_checks.find (key); - T *c; - if (it != _m_checks.end ()) - c = static_cast (it->second); - else - { - c = new T (*this); - if (!_m_checks.insert (std::make_pair (key, c)).second) - throw std::runtime_error ("duplicate key"); - } - return c; - } + template T *check (); template T *