]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
dwarflint: Avoid repeating once failed tests
authorPetr Machata <pmachata@redhat.com>
Mon, 26 Oct 2009 14:44:46 +0000 (15:44 +0100)
committerPetr Machata <pmachata@redhat.com>
Wed, 18 Aug 2010 12:55:12 +0000 (14:55 +0200)
src/Makefile.am
src/dwarflint/check_debug_abbrev.cc
src/dwarflint/check_debug_line.cc
src/dwarflint/check_expected_trees.cc
src/dwarflint/check_matching_ranges.cc
src/dwarflint/check_range_out_of_scope.cc
src/dwarflint/checks-high.hh
src/dwarflint/checks-low.cc
src/dwarflint/checks.cc [deleted file]
src/dwarflint/checks.hh
src/dwarflint/dwarflint.hh

index 87fbf4a01bb0fe662be23fbe27382d9fbd91fd2c..d69be90947583b1822d0ea633bbbc954ccbd2d8e 100644 (file)
@@ -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 \
index 17b32956cc2caccc0b7a4c6f67eacbeacf3efaf7..46e8751e90c2f3d6d45481674a0f54c2f78a8042 100644 (file)
@@ -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 ();
                }
            }
 
index 06b4c4f78071e8ec2eef620fcccc5969d861dfdf..1932919feb084f318ef154d31522a17d3e7559e8 100644 (file)
@@ -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);
index 58907452f335413e3582e1cc8cea920782226e5e..f10926e56616959c381482376b2c6d0485dc1034 100644 (file)
@@ -160,8 +160,9 @@ check_expected_trees::check_expected_trees (dwarflint &lint)
   // XXX more specific class when <dwarf> 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 ();
     }
 }
index f15eb6386c99a7d639a84c3956ee7467cf7d35df..426aa4064557a17ec3385677c698f1bd7a1d739d 100644 (file)
@@ -22,7 +22,7 @@ check_matching_ranges::check_matching_ranges (dwarflint &lint)
   : highlevel_check<check_matching_ranges> (lint)
 {
   if (be_tolerant || be_gnu)
-    throw check_base::unscheduled;
+    throw check_base::unscheduled ();
 
   lint.check<check_debug_ranges> ();
   lint.check<check_debug_aranges> ();
@@ -78,8 +78,9 @@ check_matching_ranges::check_matching_ranges (dwarflint &lint)
   // XXX more specific class when <dwarf> 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 ();
     }
 }
index d62ce39a06c7f9d2a663a5e3f56f32ced377aa5e..9dcdb37a36922d08ae1489864fa98459a0c7ae66 100644 (file)
@@ -212,8 +212,9 @@ check_range_out_of_scope::check_range_out_of_scope (dwarflint &lint)
   // XXX more specific class when <dwarf> 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 ();
     }
 }
index 7f938849c4e3ca59a90b9d33302fde017e76d994..1723aac99d906945acf475c762eda72806c15eeb 100644 (file)
@@ -18,7 +18,7 @@ public:
     , dw (_m_handle)
   {
     if (!do_high_level)
-      throw check_base::unscheduled;
+      throw check_base::unscheduled ();
   }
 
   ~highlevel_check ()
index a9d7ee7c4609bd83b52505e2f2c0f289d32af359..1505b8d9ec187d9b024410ccff2c3302d3f35269 100644 (file)
@@ -29,6 +29,7 @@
 
 #include "checks-low.hh"
 #include "low.h"
+#include "config.h"
 #include <map>
 #include <sstream>
 #include <cstring>
@@ -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 (file)
index afb16c8..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "checks.hh"
-check_base::failed check_base::unscheduled ("the check is not scheduled");
index b41b7459daf7656b41a3286d14f797f98bb648a4..84296b1813f931216ea9a07e47e6bf4f03b10a18 100644 (file)
@@ -1,23 +1,14 @@
 #ifndef DWARFLINT_CHECKS_HH
 #define DWARFLINT_CHECKS_HH
 
-#include <stdexcept>
 #include <string>
-#include <iostream>
 #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<class T>
@@ -31,6 +22,39 @@ public:
   }
 };
 
+template <class T>
+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 <T *> (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 <class T>
 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;
     }
 }
index d292888da79c5cd99d5efe187e91f387224788f7..f1684ecafd94e161685efbc9584fc78eed942681 100644 (file)
@@ -46,23 +46,7 @@ public:
   dwarflint (Elf *elf);
   Elf *elf () { return _m_elf; }
 
-  template <class T>
-  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 <T *> (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 <class T> T *check ();
 
   template <class T>
   T *