/* Check for DIEs with attributes referencing the DIE itself. Copyright (C) 2011 Red Hat, Inc. This file is part of elfutils. This file is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. elfutils is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "check_die_tree.hh" #include "pri.hh" #include "messages.hh" using elfutils::dwarf; namespace { class check_self_referential_die : public die_check { public: static checkdescriptor const *descriptor () { static checkdescriptor cd (checkdescriptor::create ("check_self_referential_die") .description ( "A reference attribute referencing the DIE itself is suspicious.\n" "One example is a DW_AT_containing_type pointing to itself.\n" " https://fedorahosted.org/pipermail/elfutils-devel/2011-February/001794.html\n" )); return &cd; } check_self_referential_die (highlevel_check_i *, checkstack &, dwarflint &) { // We don't keep any state for this die check. } virtual void die (all_dies_iterator const &it) { dwarf::debug_info_entry const &entry = *it; for (dwarf::debug_info_entry::attributes_type::const_iterator at = entry.attributes ().begin (); at != entry.attributes ().end (); ++at) { dwarf::attr_value const &val = (*at).second; if (val.what_space () == dwarf::VS_reference) { dwarf::debug_info_entry ref = *val.reference (); if (ref.identity () == entry.identity ()) wr_message (die_locus (entry), mc_impact_3 | mc_acc_suboptimal | mc_die_rel) .id (descriptor ()) << dwarf::tags::name (entry.tag ()) << " attribute " << dwarf::attributes::name ((*at).first) << " references DIE itself." << std::endl; } } } }; reg_die_check reg; }