From 61cdaa8098037898b62656a268b3c6d5985de4e3 Mon Sep 17 00:00:00 2001 From: Petr Machata Date: Thu, 3 Mar 2011 14:24:27 +0100 Subject: [PATCH] dwarflint: Fix all-dies-it - Account for the case that die.has_children and at the same time die.children().begin() == die.children().end() - Change the algorithm to iterate DIEs acually in pre-order - Add a test case --- dwarflint/Makefile.am | 9 ++-- dwarflint/all-dies-it.hh | 58 ++++++++++++------------ dwarflint/tests/hello.bad-2.bz2 | Bin 0 -> 2703 bytes dwarflint/tests/run-test-all-dies-it.sh | 38 ++++++++++++++++ dwarflint/tests/test-all-dies-it.cc | 54 ++++++++++++++++++++++ 5 files changed, 128 insertions(+), 31 deletions(-) create mode 100644 dwarflint/tests/hello.bad-2.bz2 create mode 100755 dwarflint/tests/run-test-all-dies-it.sh create mode 100644 dwarflint/tests/test-all-dies-it.cc diff --git a/dwarflint/Makefile.am b/dwarflint/Makefile.am index 4b0f592ce..75c215a01 100644 --- a/dwarflint/Makefile.am +++ b/dwarflint/Makefile.am @@ -1,6 +1,6 @@ ## Process this file with automake to create Makefile.in ## -## Copyright (C) 1996-2010 Red Hat, Inc. +## Copyright (C) 1996-2011 Red Hat, Inc. ## This file is part of Red Hat elfutils. ## ## Red Hat elfutils is free software; you can redistribute it and/or modify @@ -36,7 +36,7 @@ AM_LDFLAGS = -Wl,-rpath-link,../libelf:../libdw no_mudflap.os = -fmudflap bin_PROGRAMS = dwarflint -noinst_PROGRAMS = tests/test-coverage tests/test-wrap +noinst_PROGRAMS = tests/test-coverage tests/test-wrap tests/test-all-dies-it dwarflint_SOURCES = \ addr-record.cc addr-record.hh \ @@ -91,6 +91,7 @@ tests_test_coverage_SOURCES = tests/test-coverage.cc coverage.cc pri.cc \ ../src/dwarfstrings.c tests_test_wrap_SOURCES = tests/test-wrap.cc wrap.cc +tests_test_all_dies_it_SOURCES = tests/test-all-dies-it.cc EXTRA_TESTS = tests/run-debug_abbrev-duplicate-attribute.sh \ tests/run-check_duplicate_DW_tag_variable.sh \ @@ -99,7 +100,8 @@ EXTRA_TESTS = tests/run-debug_abbrev-duplicate-attribute.sh \ tests/run-check_range_out_of_scope.sh \ tests/run-check_debug_info_refs.sh \ tests/run-aranges_terminate_early.sh \ - tests/run-libdl-2.12.so.debug.sh + tests/run-libdl-2.12.so.debug.sh \ + tests/run-test-all-dies-it.sh TESTS = $(EXTRA_TESTS) \ tests/test-coverage \ @@ -148,6 +150,7 @@ libdwpp = ../libdw/libdwpp.a $(libdw) dwarflint_LDADD = $(libebl) $(libelf) $(libdwpp) $(libeu) $(libmudflap) -ldl tests_test_coverage_LDADD = $(libebl) $(libelf) $(libdwpp) $(libeu) $(libmudflap) -ldl +tests_test_all_dies_it_LDADD = $(libdwpp) installcheck-binPROGRAMS: $(bin_PROGRAMS) bad=0; pid=$$$$; list="$(bin_PROGRAMS)"; for p in $$list; do \ diff --git a/dwarflint/all-dies-it.hh b/dwarflint/all-dies-it.hh index 57257e3ea..7bcc36f2b 100644 --- a/dwarflint/all-dies-it.hh +++ b/dwarflint/all-dies-it.hh @@ -1,5 +1,5 @@ /* Pedantic checking of DWARF files. - Copyright (C) 2009, 2010 Red Hat, Inc. + Copyright (C) 2009, 2010, 2011 Red Hat, Inc. This file is part of Red Hat elfutils. Red Hat elfutils is free software; you can redistribute it and/or modify @@ -41,23 +41,19 @@ class all_dies_iterator die_it_stack_t _m_die_it_stack; bool _m_atend; - void nest () + void start () { - while (_m_die_it->has_children ()) + if (_m_cu_it == _m_cu_it_end) + _m_atend = true; + else { - _m_die_it_stack.push_back (std::make_pair (_m_die_it, _m_die_it_end)); - _m_die_it_end = (*_m_die_it).children ().end (); - _m_die_it = (*_m_die_it).children ().begin (); + _m_die_it = die_it_t (*_m_cu_it); + _m_die_it_end = die_it_t (); + ++_m_cu_it; + assert (_m_die_it != _m_die_it_end); } } - void start () - { - _m_die_it = die_it_t (*_m_cu_it); - _m_die_it_end = die_it_t (); - nest (); - } - public: // An end iterator. all_dies_iterator () @@ -67,9 +63,10 @@ public: explicit all_dies_iterator (T const &dw) : _m_cu_it (dw.compile_units ().begin ()) , _m_cu_it_end (dw.compile_units ().end ()) - , _m_atend (false) + , _m_atend (_m_cu_it == _m_cu_it_end) { - start (); + if (!_m_atend) + start (); } bool operator== (all_dies_iterator const &other) @@ -89,21 +86,26 @@ public: { if (!_m_atend) { - if (++_m_die_it == _m_die_it_end) + if (_m_die_it->has_children () + && _m_die_it->children ().begin () != _m_die_it->children ().end ()) { - if (_m_die_it_stack.size () > 0) - { - _m_die_it = _m_die_it_stack.back ().first; - _m_die_it_end = _m_die_it_stack.back ().second; - _m_die_it_stack.pop_back (); - } - else if (++_m_cu_it == _m_cu_it_end) - _m_atend = true; - else - start (); + _m_die_it_stack.push_back (std::make_pair (_m_die_it, _m_die_it_end)); + _m_die_it_end = _m_die_it->children ().end (); + _m_die_it = _m_die_it->children ().begin (); } else - nest (); + while (++_m_die_it == _m_die_it_end) + + { + if (_m_die_it_stack.size () == 0) + { + start (); + break; + } + _m_die_it = _m_die_it_stack.back ().first; + _m_die_it_end = _m_die_it_stack.back ().second; + _m_die_it_stack.pop_back (); + } } return *this; } @@ -117,7 +119,7 @@ public: typename T::debug_info_entry const &operator* () const { - if (/*unlikely*/ (_m_atend)) + if (unlikely (_m_atend)) throw std::runtime_error ("dereferencing end iterator"); return *_m_die_it; } diff --git a/dwarflint/tests/hello.bad-2.bz2 b/dwarflint/tests/hello.bad-2.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..8ccbe37b27903b0683d1ab77aadb81de0df3627d GIT binary patch literal 2703 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 JBon=}pa8aa<#_-A literal 0 Hc-jL100001 diff --git a/dwarflint/tests/run-test-all-dies-it.sh b/dwarflint/tests/run-test-all-dies-it.sh new file mode 100755 index 000000000..fb6f83ce9 --- /dev/null +++ b/dwarflint/tests/run-test-all-dies-it.sh @@ -0,0 +1,38 @@ +#! /bin/sh +# Copyright (C) 2011 Red Hat, Inc. +# This file is part of Red Hat elfutils. +# +# Red Hat elfutils 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; version 2 of the License. +# +# Red Hat 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 Red Hat elfutils; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. +# +# Red Hat elfutils is an included package of the Open Invention Network. +# An included package of the Open Invention Network is a package for which +# Open Invention Network licensees cross-license their patents. No patent +# license is granted, either expressly or impliedly, by designation as an +# included package. Should you wish to participate in the Open Invention +# Network licensing program, please visit www.openinventionnetwork.com +# . + +. $srcdir/../tests/test-subr.sh + +srcdir=$srcdir/tests + +testfiles hello.bad-2 + +../src/readelf -winfo ./tests/test-all-dies-it | grep '^ \[ *[0-9a-f]*\]' | + sed 's/ \[ *\([0-9a-f]\+\).*/0x\1/' | + testrun_compare ./tests/test-all-dies-it ./tests/test-all-dies-it + +../src/readelf -winfo hello.bad-2 | grep '^ \[ *[0-9a-f]*\]' | + sed 's/ \[ *\([0-9a-f]\+\).*/0x\1/' | + testrun_compare ./tests/test-all-dies-it hello.bad-2 diff --git a/dwarflint/tests/test-all-dies-it.cc b/dwarflint/tests/test-all-dies-it.cc new file mode 100644 index 000000000..e6296fa10 --- /dev/null +++ b/dwarflint/tests/test-all-dies-it.cc @@ -0,0 +1,54 @@ +/* + Copyright (C) 2011 Red Hat, Inc. + This file is part of Red Hat elfutils. + + Red Hat elfutils 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; version 2 of the License. + + Red Hat 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 Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + . */ + +#include +#include +#include +#include + +#include "config.h" +#include "../all-dies-it.hh" +#include "../../libdw/c++/dwarf" + +using namespace elfutils; + +int +main (int argc, char ** argv) +{ + assert (argc == 2); + char const *fn = argv[1]; + assert (fn != NULL); + + int fd = open (fn, O_RDONLY); + assert (fd >= 0); + + Dwarf *cdw = dwarf_begin (fd, DWARF_C_READ); + assert (cdw != NULL); + + dwarf dw = cdw; + for (all_dies_iterator it = all_dies_iterator (dw); + it != all_dies_iterator (); ++it) + std::cout << std::hex << "0x" << (*it).offset () << std::endl; +} -- 2.47.2