From: Petr Machata Date: Thu, 16 Sep 2010 22:52:14 +0000 (+0200) Subject: dwarflint: In all_dies_iterator, replace parent () with stack () X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=77b808fca7f884d347b248ed328f2ee0d5e5fb19;p=thirdparty%2Felfutils.git dwarflint: In all_dies_iterator, replace parent () with stack () - use it in locstats to find the nearest parental DIE with non-empty ranges --- diff --git a/dwarflint/all-dies-it.hh b/dwarflint/all-dies-it.hh index 615825762..10619e6ad 100644 --- a/dwarflint/all-dies-it.hh +++ b/dwarflint/all-dies-it.hh @@ -122,11 +122,19 @@ public: return *_m_die_it; } - typename T::debug_info_entry const &parent () + std::vector stack () const { - if (_m_die_it_stack.empty ()) - throw std::runtime_error ("no parent"); - return *_m_die_it_stack.back ().first; + std::vector ret; + for (auto it = _m_die_it_stack.begin (); + it != _m_die_it_stack.end (); ++it) + ret.push_back (*it->first); + ret.push_back (*_m_die_it); + return ret; + } + + typename T::compile_unit cu () const + { + return *_m_cu_it; } typename T::debug_info_entry const *operator-> () const diff --git a/dwarflint/locstats.cc b/dwarflint/locstats.cc index fe7f57f69..32f3010fe 100644 --- a/dwarflint/locstats.cc +++ b/dwarflint/locstats.cc @@ -26,6 +26,8 @@ #include "highlevel_check.hh" #include "all-dies-it.hh" #include "option.hh" +#include "messages.h" +#include "pri.hh" #include @@ -120,6 +122,19 @@ namespace return at (0).start == value; } }; + + class no_ranges {}; + + // Look through the stack of parental dies and return the non-empty + // ranges instance closest to the stack top (i.e. die_stack.end ()). + dwarf::ranges + find_ranges (std::vector const &die_stack) + { + for (auto it = die_stack.rbegin (); it != die_stack.rend (); ++it) + if (!it->ranges ().empty ()) + return it->ranges (); + throw no_ranges (); + } } locstats::locstats (checkstack &stack, dwarflint &lint) @@ -143,8 +158,6 @@ locstats::locstats (checkstack &stack, dwarflint &lint) if (!is_formal_parameter && die.tag () != DW_TAG_variable) continue; - dwarf::debug_info_entry const &parent = it.parent (); - dwarf::debug_info_entry::attributes_type const &attrs = die.attributes (); @@ -154,9 +167,10 @@ locstats::locstats (checkstack &stack, dwarflint &lint) // Of formal parameters we ignore those that are children of // subprograms that are themselves declarations. + std::vector const &die_stack = it.stack (); if (is_formal_parameter) { - if (parent.attributes ().find (DW_AT_declaration) + if (die_stack.back ().attributes ().find (DW_AT_declaration) != die.attributes ().end ()) continue; } @@ -207,34 +221,41 @@ locstats::locstats (checkstack &stack, dwarflint &lint) // Globals and statics have non-list location that is a // singleton DW_OP_addr expression. continue; - coverage = 100; + coverage = (len == 0) ? 0 : 100; } // location list else { - dwarf::ranges const &ranges - = die.ranges ().empty () ? parent.ranges () : die.ranges (); - if (ranges.empty ()) - // what? - continue; - - size_t length = 0; - size_t covered = 0; - for (dwarf::ranges::const_iterator rit = ranges.begin (); - rit != ranges.end (); ++rit) + try + { + dwarf::ranges ranges (find_ranges (die_stack)); + size_t length = 0; + size_t covered = 0; + for (dwarf::ranges::const_iterator rit = ranges.begin (); + rit != ranges.end (); ++rit) + { + Dwarf_Addr low = (*rit).first; + Dwarf_Addr high = (*rit).second; + length += high - low; + /*std::cerr << std::endl << " " << low << ".." << high + << std::endl;*/ + for (Dwarf_Addr addr = low; addr < high; ++addr) + if (dwarf_getlocation_addr (locattr, addr, + NULL, NULL, 0) > 0) + covered++; + } + coverage = 100 * covered / length; + } + catch (no_ranges const &e) { - Dwarf_Addr low = (*rit).first; - Dwarf_Addr high = (*rit).second; - length += high - low; - /*std::cerr << std::endl << " " << low << ".." << high - << std::endl;*/ - for (Dwarf_Addr addr = low; addr < high; ++addr) - if (dwarf_getlocation_addr (locattr, addr, - NULL, NULL, 0) > 0) - covered++; + struct where where = WHERE (sec_info, NULL); + where_reset_1 (&where, it.cu ().offset ()); + where_reset_2 (&where, die.offset ()); + wr_error (where) + << "no ranges for this DIE." << std::endl; + continue; } - coverage = 100 * covered / length; } tally[coverage]++;