]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
dwarflint: Move more checks to the new dependency infrastructure
authorPetr Machata <pmachata@redhat.com>
Tue, 20 Oct 2009 15:23:36 +0000 (17:23 +0200)
committerPetr Machata <pmachata@redhat.com>
Wed, 18 Aug 2010 12:55:11 +0000 (14:55 +0200)
src/Makefile.am
src/dwarflint-check_matching_ranges.cc [new file with mode: 0644]
src/dwarflint-check_range_out_of_scope.cc [new file with mode: 0644]
src/dwarflint-checks-high.hh [new file with mode: 0644]
src/dwarflint-checks-low.cc
src/dwarflint-checks-low.hh
src/dwarflint-checks.cc
src/dwarflint-checks.hh
src/dwarflint-hl.cc
src/dwarflint-low.h
src/dwarflint-main.cc

index d89fb8e7ff9f0a61a377e9f766746c9e3b3aaabb..616d00ff8337fa0371926e6a6df03c7c6d770175 100644 (file)
@@ -87,8 +87,11 @@ dwarflint_SOURCES = dwarfstrings.c \
                    dwarflint-messages.cc dwarflint-messages.h \
                    dwarflint-where.c dwarflint-where.h \
                    dwarflint-config.cc dwarflint-config.h \
-                   dwarflint-checks.hh \
-                   dwarflint-checks-low.cc dwarflint-checks-low.hh
+                   dwarflint-checks.cc dwarflint-checks.hh \
+                   dwarflint-checks-low.cc dwarflint-checks-low.hh \
+                   dwarflint-checks-high.hh \
+                   dwarflint-check_matching_ranges.cc \
+                   dwarflint-check_range_out_of_scope.cc
 
 readelf_SOURCES = readelf.c dwarfstrings.c
 
diff --git a/src/dwarflint-check_matching_ranges.cc b/src/dwarflint-check_matching_ranges.cc
new file mode 100644 (file)
index 0000000..d875a9e
--- /dev/null
@@ -0,0 +1,85 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "dwarflint-checks-high.hh"
+
+using elfutils::dwarf;
+
+namespace
+{
+  class check_matching_ranges
+    : public highlevel_check<check_matching_ranges>
+  {
+  public:
+    explicit check_matching_ranges (dwarflint &lint);
+  };
+
+  reg<check_matching_ranges> reg_matching_ranges;
+}
+
+check_matching_ranges::check_matching_ranges (dwarflint &lint)
+  : highlevel_check<check_matching_ranges> (lint)
+{
+  if (be_tolerant || be_gnu)
+    throw check_base::unscheduled;
+
+  lint.check<check_debug_ranges> ();
+  lint.check<check_debug_aranges> ();
+
+  try
+    {
+      struct where where_ref = WHERE (sec_info, NULL);
+      struct where where_ar = WHERE (sec_aranges, NULL);
+      where_ar.ref = &where_ref;
+      struct where where_r = WHERE (sec_ranges, NULL);
+      where_r.ref = &where_ref;
+      char buf[128];
+
+      const dwarf::aranges_map &aranges = dw.aranges ();
+      for (dwarf::aranges_map::const_iterator i = aranges.begin ();
+          i != aranges.end (); ++i)
+       {
+         const dwarf::compile_unit &cu = i->first;
+         where_reset_1 (&where_ref, 0);
+         where_reset_2 (&where_ref, cu.offset ());
+
+         std::set<dwarf::ranges::key_type>
+           cu_aranges = i->second,
+           cu_ranges = cu.ranges ();
+
+         typedef std::vector <dwarf::arange_list::value_type>
+           range_vec;
+         range_vec missing;
+         std::back_insert_iterator <range_vec> i_missing (missing);
+
+         std::set_difference (cu_aranges.begin (), cu_aranges.end (),
+                              cu_ranges.begin (), cu_ranges.end (),
+                              i_missing);
+
+         for (range_vec::iterator it = missing.begin ();
+              it != missing.end (); ++it)
+           wr_message (cat (mc_ranges, mc_aranges, mc_impact_3), &where_r,
+                       ": missing range %s, present in .debug_aranges.\n",
+                       range_fmt (buf, sizeof buf, it->first, it->second));
+
+         missing.clear ();
+         std::set_difference (cu_ranges.begin (), cu_ranges.end (),
+                              cu_aranges.begin (), cu_aranges.end (),
+                              i_missing);
+
+         for (range_vec::iterator it = missing.begin ();
+              it != missing.end (); ++it)
+           wr_message (cat (mc_ranges, mc_aranges, mc_impact_3), &where_ar,
+                       ": missing range %s, present in .debug_ranges.\n",
+                       range_fmt (buf, sizeof buf, it->first, it->second));
+       }
+    }
+  // 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");
+    }
+}
diff --git a/src/dwarflint-check_range_out_of_scope.cc b/src/dwarflint-check_range_out_of_scope.cc
new file mode 100644 (file)
index 0000000..a487551
--- /dev/null
@@ -0,0 +1,223 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "dwarflint-checks-high.hh"
+#include "dwarflint-coverage.hh"
+#include "dwarfstrings.h"
+
+using elfutils::dwarf;
+
+namespace
+{
+  class check_range_out_of_scope
+    : public highlevel_check<check_range_out_of_scope>
+  {
+  public:
+    explicit check_range_out_of_scope (dwarflint &lint);
+  };
+
+  reg<check_range_out_of_scope> reg_matching_ranges;
+}
+
+check_range_out_of_scope::check_range_out_of_scope (dwarflint &lint)
+  : highlevel_check<check_range_out_of_scope> (lint)
+{
+  lint.check <check_debug_loc> ();
+
+  try
+    {
+      typedef std::vector<std::pair< ::Dwarf_Addr, ::Dwarf_Addr> >
+       ranges_t;
+
+      struct
+      {
+       void operator () (dwarf::compile_unit const &cu,
+                         dwarf::debug_info_entry const &die,
+                         ranges_t const &ranges,
+                         where const &wh_parent)
+       {
+         where wh = WHERE (sec_info, NULL);
+         where_reset_1 (&wh, cu.offset ());
+         where_reset_2 (&wh, die.offset ());
+
+         ::Dwarf_Addr low_pc = 0;
+         ::Dwarf_Addr high_pc = -1;
+         ranges_t my_ranges;
+         for (dwarf::debug_info_entry::attributes_type::const_iterator
+                at = die.attributes ().begin ();
+              at != die.attributes ().end (); ++at)
+           {
+             dwarf::attr_value const &value = (*at).second;
+             dwarf::value_space vs = value.what_space ();
+             if ((*at).first == DW_AT_low_pc)
+               low_pc = value.address ();
+             else if ((*at).first == DW_AT_high_pc)
+               high_pc = value.address ();
+             else if (vs == dwarf::VS_rangelistptr)
+               for (dwarf::range_list::const_iterator
+                      it = value.ranges ().begin ();
+                    it != value.ranges ().end (); ++it)
+                 my_ranges.push_back (*it);
+           }
+         if (low_pc != 0 || high_pc != (::Dwarf_Addr)-1)
+           {
+             // Simultaneous appearance of both low_pc/high_pc pair
+             // and rangelist pointer is forbidden by 3.1.1 #1.
+             // Presence of low_pc on itself is OK on compile_unit
+             // and partial_unit DIEs, otherwise it serves the same
+             // purpose as low_pc/high_pc pair that covers one
+             // address point.
+
+             if (high_pc == (::Dwarf_Addr)-1
+                 && die.tag () != DW_TAG_compile_unit
+                 && die.tag () != DW_TAG_partial_unit)
+               high_pc = low_pc + 1;
+
+             if (high_pc != (::Dwarf_Addr)-1)
+               {
+                 if (my_ranges.size () != 0)
+                   wr_message (cat (mc_impact_4, mc_info, mc_error), &wh,
+                               ": both low_pc/high_pc pair and ranges present.\n");
+                 else
+                   my_ranges.push_back (std::make_pair (low_pc, high_pc));
+               }
+           }
+
+         // If my_ranges is non-empty, check that it's a subset of
+         // ranges.
+         if (my_ranges.size () != 0)
+           {
+             // xxx Extract this logic to some table.
+             switch (die.tag ())
+               {
+                 /* These PC-ful DIEs should be wholly contained by
+                    PC-ful parental DIE.  */
+               case DW_TAG_inlined_subroutine:
+               case DW_TAG_lexical_block:
+               case DW_TAG_entry_point:
+               case DW_TAG_label:
+               case DW_TAG_with_stmt:
+               case DW_TAG_try_block:
+               case DW_TAG_catch_block:
+                 {
+                   coverage cov1;
+                   WIPE (cov1);
+
+                   for (ranges_t::const_iterator it = my_ranges.begin ();
+                        it != my_ranges.end (); ++it)
+                     coverage_add (&cov1, (*it).first,
+                                   (*it).second - (*it).first);
+
+                   coverage cov2;
+                   WIPE (cov2);
+                   for (ranges_t::const_iterator it = ranges.begin ();
+                        it != ranges.end (); ++it)
+                     coverage_add (&cov2, (*it).first,
+                                   (*it).second - (*it).first);
+
+                   coverage result;
+                   WIPE (result);
+                   coverage_add_all (&result, &cov1);
+                   coverage_remove_all (&result, &cov2);
+
+                   if (result.size > 0)
+                     {
+                       std::string super_wh = where_fmt (&wh_parent);
+                       {
+                         std::string rs = cov::format_ranges (cov1);
+                         wr_error (&wh, ": PC range %s is not a sub-range of "
+                                   "containing scope.\n", rs.c_str ());
+                       }
+                       {
+                         std::string rs = cov::format_ranges (cov2);
+                         wr_error (&wh_parent, ": in this context: %s\n",
+                                   rs.c_str ());
+                       }
+                     }
+
+                   coverage_free (&result);
+                   coverage_free (&cov2);
+                 }
+               }
+           }
+
+         // xxx building the coverage for each die is a waste of time
+         ranges_t const &use_ranges
+           = my_ranges.size () > 0 ? my_ranges : ranges;
+         coverage cov;
+         WIPE (cov);
+
+         for (ranges_t::const_iterator it = use_ranges.begin ();
+              it != use_ranges.end (); ++it)
+           coverage_add (&cov, (*it).first, (*it).second - (*it).first);
+
+         // Now finally look for location attributes and check that
+         // _their_ PCs form a subset of ranges of this DIE.
+         for (dwarf::debug_info_entry::attributes_type::const_iterator
+                at = die.attributes ().begin ();
+              at != die.attributes ().end (); ++at)
+           {
+             dwarf::attr_value const &value = (*at).second;
+             dwarf::value_space vs = value.what_space ();
+
+             if (vs == dwarf::VS_location)
+               {
+                 dwarf::location_attr const &loc = value.location ();
+                 if (loc.is_list ())
+                   {
+                     bool runoff = false;
+                     for (dwarf::location_attr::const_iterator
+                            lt = loc.begin (); lt != loc.end (); ++lt)
+                       {
+                         ::Dwarf_Addr start = (*lt).first.first; //1st insn
+                         ::Dwarf_Addr end = (*lt).first.second; //1st past end
+                         ::Dwarf_Addr length = end - start;
+                         if (length > 0 // skip empty ranges
+                             && !coverage_is_covered (&cov, start, length))
+                           {
+                             runoff = true;
+                             std::string super_wh = where_fmt (&wh_parent);
+                             wr_error (&wh, ": attribute `%s': PC range %s "
+                                       "outside containing scope\n",
+                                       dwarf_attr_string ((*at).first),
+                                       range_fmt (start, end).c_str ());
+                           }
+                       }
+                     if (runoff)
+                       {
+                         std::string rangestr = cov::format_ranges (cov);
+                         wr_error (&wh_parent, ": in this context: %s\n",
+                                   rangestr.c_str ());
+                       }
+                   }
+               }
+           }
+
+         coverage_free (&cov);
+
+         // Check children recursively.
+         for (dwarf::debug_info_entry::children_type::const_iterator
+                jt = die.children ().begin ();
+              jt != die.children ().end (); ++jt)
+           (*this) (cu, *jt, use_ranges,
+                    my_ranges.size () > 0 ? wh : wh_parent);
+       }
+      } recursively_validate;
+
+      class dwarf::compile_units const &cus = dw.compile_units ();
+      ranges_t r;
+      r.push_back (std::make_pair (0, -1));
+      where wh = WHERE (sec_info, NULL);
+      for (dwarf::compile_units::const_iterator it = cus.begin ();
+          it != cus.end (); ++it)
+       recursively_validate (*it, *it, r, wh);
+    }
+  // 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");
+    }
+}
diff --git a/src/dwarflint-checks-high.hh b/src/dwarflint-checks-high.hh
new file mode 100644 (file)
index 0000000..393315b
--- /dev/null
@@ -0,0 +1,28 @@
+#include "dwarflint-checks-low.hh"
+#include "dwarflint-config.h"
+#include "c++/dwarf"
+
+template<class T>
+class highlevel_check
+  : public check<highlevel_check<T> >
+{
+  ::Dwarf *_m_handle;
+
+public:
+  elfutils::dwarf dw;
+
+  // xxx this will throw an exception on <c++/dwarf> or <libdw.h>
+  // failure.  We need to catch it and convert to check_base::failed.
+  explicit highlevel_check (dwarflint &lint)
+    : _m_handle (dwarf_begin_elf (lint.elf (), DWARF_C_READ, NULL))
+    , dw (_m_handle)
+  {
+    if (!do_high_level)
+      throw check_base::unscheduled;
+  }
+
+  ~highlevel_check ()
+  {
+    dwarf_end (_m_handle);
+  }
+};
index 285045694d7a1910d83e28c17882e1722c6bacf4..5be45f54f0be64672d9ce3823ebfc49f3939daa8 100644 (file)
@@ -313,3 +313,61 @@ check_debug_info::check_debug_info (dwarflint &lint)
   // cu_free (chain); xxx
   cu_chain = chain;
 }
+
+check_debug_ranges::check_debug_ranges (dwarflint &lint)
+  : _m_sec_ranges (lint.check (_m_sec_ranges))
+  , _m_cus (lint.check (_m_cus))
+{
+  if (!check_loc_or_range_structural (&_m_sec_ranges->file,
+                                     &_m_sec_ranges->sect,
+                                     _m_cus->cu_chain,
+                                     &_m_cus->cu_cov))
+    throw check_base::failed (""); //xxx
+}
+
+check_debug_aranges::check_debug_aranges (dwarflint &lint)
+  : _m_sec_aranges (lint.check (_m_sec_aranges))
+  , _m_cus (lint.check (_m_cus))
+{
+  coverage *cov
+    = _m_cus->cu_cov.need_ranges ? NULL : &_m_cus->cu_cov.cov;
+  if (!check_aranges_structural (&_m_sec_aranges->file,
+                                &_m_sec_aranges->sect,
+                                _m_cus->cu_chain, cov))
+    throw check_base::failed (""); //xxx
+}
+
+check_debug_loc::check_debug_loc (dwarflint &lint)
+  : _m_sec_loc (lint.check (_m_sec_loc))
+  , _m_cus (lint.check (_m_cus))
+{
+  if (!check_loc_or_range_structural (&_m_sec_loc->file,
+                                     &_m_sec_loc->sect,
+                                     _m_cus->cu_chain, NULL))
+    throw check_base::failed (""); //xxx
+}
+
+namespace
+{
+  template<section_id sec_id>
+  class check_debug_pub
+    : public check<check_debug_pub<sec_id> >
+  {
+    section<sec_id> *_m_sec;
+    check_debug_info *_m_cus;
+
+  public:
+    explicit check_debug_pub (dwarflint &lint)
+      : _m_sec (lint.check (_m_sec))
+      , _m_cus (lint.check (_m_cus))
+    {
+      if (!check_pub_structural (&_m_sec->file,
+                                &_m_sec->sect,
+                                _m_cus->cu_chain))
+       throw check_base::failed (""); //xxx
+    }
+  };
+
+  reg<check_debug_pub<sec_pubnames> > reg_debug_pubnames;
+  reg<check_debug_pub<sec_pubtypes> > reg_debug_pubtypes;
+}
index 587257044912616e557581a703b63c53f6e159e2..20ff4362feee96e87048a8f3e777849ed219be41 100644 (file)
@@ -39,10 +39,10 @@ public:
   explicit check_debug_abbrev (dwarflint &lint);
 
   // offset -> abbreviations
-  std::map < ::Dwarf_Off, abbrev_table> abbrevs;
+  std::map< ::Dwarf_Off, abbrev_table> abbrevs;
   struct abbrev_table *abbrev_chain; // xxx
 };
-static reg <check_debug_abbrev> reg_debug_abbrev;
+static reg<check_debug_abbrev> reg_debug_abbrev;
 
 class check_debug_info
   : public check<check_debug_info>
@@ -54,9 +54,42 @@ class check_debug_info
 
 public:
   cu_coverage cu_cov;
-  std::vector <cu> cus;
+  std::vector<cu> cus;
   cu *cu_chain; // xxx
 
   explicit check_debug_info (dwarflint &lint);
 };
-static reg <check_debug_info> reg_debug_info;
+static reg<check_debug_info> reg_debug_info;
+
+class check_debug_ranges
+  : public check<check_debug_ranges>
+{
+  section<sec_ranges> *_m_sec_ranges;
+  check_debug_info *_m_cus;
+
+public:
+  explicit check_debug_ranges (dwarflint &lint);
+};
+static reg<check_debug_ranges> reg_debug_ranges;
+
+class check_debug_aranges
+  : public check<check_debug_aranges>
+{
+  section<sec_aranges> *_m_sec_aranges;
+  check_debug_info *_m_cus;
+
+public:
+  explicit check_debug_aranges (dwarflint &lint);
+};
+static reg<check_debug_aranges> reg_debug_aranges;
+
+class check_debug_loc
+  : public check<check_debug_loc>
+{
+  section<sec_loc> *_m_sec_loc;
+  check_debug_info *_m_cus;
+
+public:
+  explicit check_debug_loc (dwarflint &lint);
+};
+static reg<check_debug_loc> reg_debug_loc;
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..f332668beca2811ee2c543bfafc706c8c8586813 100644 (file)
@@ -0,0 +1,2 @@
+#include "dwarflint-checks.hh"
+check_base::failed check_base::unscheduled ("the check is not scheduled");
index 4ca86e142d4ff37928686a48e9028e1d227ddcfe..0099db7f562b8efa814c7706897d8f815a1f1658 100644 (file)
@@ -16,6 +16,8 @@ struct check_base
       : std::runtime_error (msg)
     {}
   };
+
+  static failed unscheduled;
 };
 
 template<class T>
index c89d08552e4fe5d1faa03850ab24789cb97ef349..33cd885f733f6386ccd1b0ed096461e7181a0268 100644 (file)
@@ -92,68 +92,6 @@ hl_ctx_delete (hl_ctx *hlctx)
 static const expected_at_map expected_at;
 //static const expected_children_map expected_children;
 
-bool
-check_matching_ranges (hl_ctx *hlctx)
-{
-  try
-    {
-      struct where where_ref = WHERE (sec_info, NULL);
-      struct where where_ar = WHERE (sec_aranges, NULL);
-      where_ar.ref = &where_ref;
-      struct where where_r = WHERE (sec_ranges, NULL);
-      where_r.ref = &where_ref;
-      char buf[128];
-
-      const dwarf::aranges_map &aranges = hlctx->dw.aranges ();
-      for (dwarf::aranges_map::const_iterator i = aranges.begin ();
-          i != aranges.end (); ++i)
-       {
-         const dwarf::compile_unit &cu = i->first;
-         where_reset_1 (&where_ref, 0);
-         where_reset_2 (&where_ref, cu.offset ());
-
-         std::set<dwarf::ranges::key_type>
-           cu_aranges = i->second,
-           cu_ranges = cu.ranges ();
-
-         typedef std::vector <dwarf::arange_list::value_type>
-           range_vec;
-         range_vec missing;
-         std::back_insert_iterator <range_vec> i_missing (missing);
-
-         std::set_difference (cu_aranges.begin (), cu_aranges.end (),
-                              cu_ranges.begin (), cu_ranges.end (),
-                              i_missing);
-
-         for (range_vec::iterator it = missing.begin ();
-              it != missing.end (); ++it)
-           wr_message (cat (mc_ranges, mc_aranges, mc_impact_3), &where_r,
-                       ": missing range %s, present in .debug_aranges.\n",
-                       range_fmt (buf, sizeof buf, it->first, it->second));
-
-         missing.clear ();
-         std::set_difference (cu_ranges.begin (), cu_ranges.end (),
-                              cu_aranges.begin (), cu_aranges.end (),
-                              i_missing);
-
-         for (range_vec::iterator it = missing.begin ();
-              it != missing.end (); ++it)
-           wr_message (cat (mc_ranges, mc_aranges, mc_impact_3), &where_ar,
-                       ": missing range %s, present in .debug_ranges.\n",
-                       range_fmt (buf, sizeof buf, it->first, it->second));
-       }
-
-      return true;
-    }
-  // XXX more specific class when <dwarf> has it
-  catch (std::runtime_error &exc)
-    {
-      wr_error (NULL, "Error while checking matching ranges: %s.\n",
-               exc.what ());
-      return false;
-    }
-}
-
 struct name_extractor {
   int operator () (dwarf::attribute const &at) {
     return at.first;
@@ -294,204 +232,3 @@ check_expected_trees (hl_ctx *hlctx)
       return false;
     }
 }
-
-bool
-check_range_out_of_scope (hl_ctx *hlctx)
-{
-  try
-    {
-      typedef std::vector<std::pair< ::Dwarf_Addr, ::Dwarf_Addr> >
-       ranges_t;
-
-      struct
-      {
-       void operator () (dwarf::compile_unit const &cu,
-                         dwarf::debug_info_entry const &die,
-                         ranges_t const &ranges,
-                         where const &wh_parent)
-       {
-         where wh = WHERE (sec_info, NULL);
-         where_reset_1 (&wh, cu.offset ());
-         where_reset_2 (&wh, die.offset ());
-
-         ::Dwarf_Addr low_pc = 0;
-         ::Dwarf_Addr high_pc = -1;
-         ranges_t my_ranges;
-         for (dwarf::debug_info_entry::attributes_type::const_iterator
-                at = die.attributes ().begin ();
-              at != die.attributes ().end (); ++at)
-           {
-             dwarf::attr_value const &value = (*at).second;
-             dwarf::value_space vs = value.what_space ();
-             if ((*at).first == DW_AT_low_pc)
-               low_pc = value.address ();
-             else if ((*at).first == DW_AT_high_pc)
-               high_pc = value.address ();
-             else if (vs == dwarf::VS_rangelistptr)
-               for (dwarf::range_list::const_iterator
-                      it = value.ranges ().begin ();
-                    it != value.ranges ().end (); ++it)
-                 my_ranges.push_back (*it);
-           }
-         if (low_pc != 0 || high_pc != (::Dwarf_Addr)-1)
-           {
-             // Simultaneous appearance of both low_pc/high_pc pair
-             // and rangelist pointer is forbidden by 3.1.1 #1.
-             // Presence of low_pc on itself is OK on compile_unit
-             // and partial_unit DIEs, otherwise it serves the same
-             // purpose as low_pc/high_pc pair that covers one
-             // address point.
-
-             if (high_pc == (::Dwarf_Addr)-1
-                 && die.tag () != DW_TAG_compile_unit
-                 && die.tag () != DW_TAG_partial_unit)
-               high_pc = low_pc + 1;
-
-             if (high_pc != (::Dwarf_Addr)-1)
-               {
-                 if (my_ranges.size () != 0)
-                   wr_message (cat (mc_impact_4, mc_info, mc_error), &wh,
-                               ": both low_pc/high_pc pair and ranges present.\n");
-                 else
-                   my_ranges.push_back (std::make_pair (low_pc, high_pc));
-               }
-           }
-
-         // If my_ranges is non-empty, check that it's a subset of
-         // ranges.
-         if (my_ranges.size () != 0)
-           {
-             // xxx Extract this logic to some table.
-             switch (die.tag ())
-               {
-                 /* These PC-ful DIEs should be wholly contained by
-                    PC-ful parental DIE.  */
-               case DW_TAG_inlined_subroutine:
-               case DW_TAG_lexical_block:
-               case DW_TAG_entry_point:
-               case DW_TAG_label:
-               case DW_TAG_with_stmt:
-               case DW_TAG_try_block:
-               case DW_TAG_catch_block:
-                 {
-                   coverage cov1;
-                   WIPE (cov1);
-
-                   for (ranges_t::const_iterator it = my_ranges.begin ();
-                        it != my_ranges.end (); ++it)
-                     coverage_add (&cov1, (*it).first,
-                                   (*it).second - (*it).first);
-
-                   coverage cov2;
-                   WIPE (cov2);
-                   for (ranges_t::const_iterator it = ranges.begin ();
-                        it != ranges.end (); ++it)
-                     coverage_add (&cov2, (*it).first,
-                                   (*it).second - (*it).first);
-
-                   coverage result;
-                   WIPE (result);
-                   coverage_add_all (&result, &cov1);
-                   coverage_remove_all (&result, &cov2);
-
-                   if (result.size > 0)
-                     {
-                       std::string super_wh = where_fmt (&wh_parent);
-                       {
-                         std::string rs = cov::format_ranges (cov1);
-                         wr_error (&wh, ": PC range %s is not a sub-range of "
-                                   "containing scope.\n", rs.c_str ());
-                       }
-                       {
-                         std::string rs = cov::format_ranges (cov2);
-                         wr_error (&wh_parent, ": in this context: %s\n",
-                                   rs.c_str ());
-                       }
-                     }
-
-                   coverage_free (&result);
-                   coverage_free (&cov2);
-                 }
-               }
-           }
-
-         // xxx building the coverage for each die is a waste of time
-         ranges_t const &use_ranges
-           = my_ranges.size () > 0 ? my_ranges : ranges;
-         coverage cov;
-         WIPE (cov);
-
-         for (ranges_t::const_iterator it = use_ranges.begin ();
-              it != use_ranges.end (); ++it)
-           coverage_add (&cov, (*it).first, (*it).second - (*it).first);
-
-         // Now finally look for location attributes and check that
-         // _their_ PCs form a subset of ranges of this DIE.
-         for (dwarf::debug_info_entry::attributes_type::const_iterator
-                at = die.attributes ().begin ();
-              at != die.attributes ().end (); ++at)
-           {
-             dwarf::attr_value const &value = (*at).second;
-             dwarf::value_space vs = value.what_space ();
-
-             if (vs == dwarf::VS_location)
-               {
-                 dwarf::location_attr const &loc = value.location ();
-                 if (loc.is_list ())
-                   {
-                     bool runoff = false;
-                     for (dwarf::location_attr::const_iterator
-                            lt = loc.begin (); lt != loc.end (); ++lt)
-                       {
-                         ::Dwarf_Addr start = (*lt).first.first; //1st insn
-                         ::Dwarf_Addr end = (*lt).first.second; //1st past end
-                         ::Dwarf_Addr length = end - start;
-                         if (length > 0 // skip empty ranges
-                             && !coverage_is_covered (&cov, start, length))
-                           {
-                             runoff = true;
-                             std::string super_wh = where_fmt (&wh_parent);
-                             wr_error (&wh, ": attribute `%s': PC range %s "
-                                       "outside containing scope\n",
-                                       dwarf_attr_string ((*at).first),
-                                       range_fmt (start, end).c_str ());
-                           }
-                       }
-                     if (runoff)
-                       {
-                         std::string rangestr = cov::format_ranges (cov);
-                         wr_error (&wh_parent, ": in this context: %s\n",
-                                   rangestr.c_str ());
-                       }
-                   }
-               }
-           }
-
-         coverage_free (&cov);
-
-         // Check children recursively.
-         for (dwarf::debug_info_entry::children_type::const_iterator
-                jt = die.children ().begin ();
-              jt != die.children ().end (); ++jt)
-           (*this) (cu, *jt, use_ranges,
-                    my_ranges.size () > 0 ? wh : wh_parent);
-       }
-      } recursively_validate;
-
-      class dwarf::compile_units const &cus = hlctx->dw.compile_units ();
-      ranges_t r;
-      r.push_back (std::make_pair (0, -1));
-      where wh = WHERE (sec_info, NULL);
-      for (dwarf::compile_units::const_iterator it = cus.begin ();
-          it != cus.end (); ++it)
-       recursively_validate (*it, *it, r, wh);
-      return true;
-    }
-  // XXX more specific class when <dwarf> has it
-  catch (std::runtime_error &exc)
-    {
-      wr_error (NULL, "Error while checking range out of scope: %s.\n",
-               exc.what ());
-      return false;
-    }
-}
index 3e60389a12a66bcb35bb609c468269bccc818c04..bba57167d48672a385f6931b3ccddbfc4eb5c373 100644 (file)
@@ -99,9 +99,7 @@ extern "C"
   /* Check that .debug_aranges and .debug_ranges match.  */
   extern struct hl_ctx *hl_ctx_new (Elf *elf);
   extern void hl_ctx_delete (struct hl_ctx *hlctx);
-  extern bool check_matching_ranges (struct hl_ctx *hlctx);
   extern bool check_expected_trees (struct hl_ctx *hlctx);
-  extern bool check_range_out_of_scope (struct hl_ctx *hlctx);
   extern bool elf_file_init (struct elf_file *file, Elf *elf);
 
   // xxx some of that will go away
index 131649387146f7e619ba14b969bdf1b7590b9f82..9162bf3cb3dffb212324f5cea85e2e4e88a18308 100644 (file)
@@ -270,7 +270,6 @@ dwarflint::dwarflint (Elf *a_elf)
   check_debug_info *check_info = check (check_info);
   // xxx check_expected_trees
   cu *cu_chain = check_info->cu_chain;
-  read_ctx ctx;
 
   /* Don't attempt to do high-level checks if we couldn't initialize
      high-level context.  The wrapper takes care of printing out error
@@ -280,51 +279,6 @@ dwarflint::dwarflint (Elf *a_elf)
 #define SEC(sec) (file.debugsec[sec_##sec])
 #define HAS_SEC(sec) (SEC(sec) != NULL && SEC(sec)->data != NULL)
 
-  bool ranges_sound;
-  if (HAS_SEC(ranges) && cu_chain != NULL)
-    ranges_sound = check_loc_or_range_structural (&file, SEC(ranges),
-                                                 cu_chain, &check_info->cu_cov);
-  else
-    ranges_sound = false;
-
-  if (HAS_SEC(loc) && cu_chain != NULL
-      && check_loc_or_range_structural (&file, SEC(loc), cu_chain, NULL)
-      && cu_chain != NULL && hlctx != NULL)
-    check_range_out_of_scope (hlctx);
-
-  if (HAS_SEC(aranges))
-    {
-      read_ctx_init (&ctx, SEC(aranges)->data, file.other_byte_order);
-
-      /* If ranges were needed and not loaded, don't pass them down
-        for CU/aranges coverage analysis. */
-      struct coverage *cov
-       = check_info->cu_cov.need_ranges ? NULL
-       : &check_info->cu_cov.cov;
-
-      if (check_aranges_structural (&file, SEC(aranges), cu_chain, cov)
-         && ranges_sound && hlctx != NULL && !be_tolerant && !be_gnu)
-       check_matching_ranges (hlctx);
-    }
-
-  if (HAS_SEC(pubnames))
-    check_pub_structural (&file, SEC(pubnames), cu_chain);
-  else if (!tolerate_nodebug)
-    {
-      where wh = WHERE (sec_pubnames, NULL);
-      wr_message (mc_impact_4 | mc_acc_suboptimal | mc_elf,
-                 &wh, ": data not found.\n");
-    }
-
-  if (HAS_SEC(pubtypes))
-    check_pub_structural (&file, SEC(pubtypes), cu_chain);
-  else if (!tolerate_nodebug)
-    {
-      where wh = WHERE (sec_pubtypes, NULL);
-      wr_message (mc_impact_4 | mc_acc_suboptimal | mc_elf | mc_pubtypes,
-                 &wh, ": data not found.\n");
-    }
-
   if (HAS_SEC(line))
     check_line_structural (&file, SEC(line), cu_chain);
   else if (!tolerate_nodebug)