From: Petr Machata Date: Mon, 2 Feb 2009 16:38:03 +0000 (+0100) Subject: Implement check for ranges/aranges mismatch X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=eb78983032d03357346d886313b5ecfc325fd8b8;p=thirdparty%2Felfutils.git Implement check for ranges/aranges mismatch --- diff --git a/src/dwarflint-hl.cc b/src/dwarflint-hl.cc index 1b7a1ab49..c499a18bf 100644 --- a/src/dwarflint-hl.cc +++ b/src/dwarflint-hl.cc @@ -29,17 +29,73 @@ #endif #include -#include -#include +#include #include +#include #include "dwarflint.h" #include "c++/dwarf" #include "../libdw/libdwP.h" +namespace +{ + message_category cat (message_category c1, + message_category c2, + message_category c3) + { + return static_cast (c1 | c2 | c3); + } +} bool -check_aranges_hl (Dwarf *dwarf) +check_matching_ranges (Dwarf *dwarf) { + elfutils::dwarf dw(dwarf); + + 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; + + const elfutils::dwarf::aranges_map &aranges = dw.aranges (); + for (elfutils::dwarf::aranges_map::const_iterator i = aranges.begin (); + i != aranges.end (); ++i) + { + const elfutils::dwarf::compile_unit &cu = i->first; + where_reset_1 (&where_ref, 0); + where_reset_2 (&where_ref, cu.offset ()); + + const elfutils::dwarf::arange_list &cu_aranges = i->second; + const elfutils::dwarf::ranges &cu_ranges = cu.ranges (); + + typedef std::vector range_vec; + range_vec missing; + std::back_insert_iterator 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 %#" PRIx64 "..%#" PRIx64 + ", present in .debug_aranges.\n", + 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 %#" PRIx64 "..%#" PRIx64 + ", present in .debug_ranges.\n", + it->first, it->second); + } + return dwarf != NULL; } diff --git a/src/dwarflint.c b/src/dwarflint.c index f4b4913a4..5f87c7cf7 100644 --- a/src/dwarflint.c +++ b/src/dwarflint.c @@ -757,7 +757,8 @@ process_file (int fd __attribute__((unused)), { read_ctx_init (&ctx, dwarf, aranges_data); if (check_aranges_structural (&ctx, cu_chain)) - check_aranges_hl (dwarf); + /* XXX only do this if .debug_ranges are also OK. */ + check_matching_ranges (dwarf); } if (pubnames_data != NULL) diff --git a/src/dwarflint.h b/src/dwarflint.h index 5f2b8fc12..411fe816c 100644 --- a/src/dwarflint.h +++ b/src/dwarflint.h @@ -11,7 +11,9 @@ extern "C" #endif /* Entry points for high-level checks. */ - extern bool check_aranges_hl (Dwarf *dwarf); + + /* Check that .debug_aranges and .debug_ranges match. */ + extern bool check_matching_ranges (Dwarf *dwarf); /* Functions and data structures describing location in Dwarf. */