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
--- /dev/null
+#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");
+ }
+}
--- /dev/null
+#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");
+ }
+}
--- /dev/null
+#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);
+ }
+};
// 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;
+}
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>
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;
+#include "dwarflint-checks.hh"
+check_base::failed check_base::unscheduled ("the check is not scheduled");
: std::runtime_error (msg)
{}
};
+
+ static failed unscheduled;
};
template<class T>
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;
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;
- }
-}
/* 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
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
#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)