]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
dwarflint: Fix all-dies-it
authorPetr Machata <pmachata@redhat.com>
Thu, 3 Mar 2011 13:24:27 +0000 (14:24 +0100)
committerPetr Machata <pmachata@redhat.com>
Thu, 3 Mar 2011 13:24:27 +0000 (14:24 +0100)
- 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
dwarflint/all-dies-it.hh
dwarflint/tests/hello.bad-2.bz2 [new file with mode: 0644]
dwarflint/tests/run-test-all-dies-it.sh [new file with mode: 0755]
dwarflint/tests/test-all-dies-it.cc [new file with mode: 0644]

index 4b0f592cef6b6d40064bc104d4f5e4fb4990bbf1..75c215a016d8a25d34651ddcb026755a8c148620 100644 (file)
@@ -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 \
index 57257e3eada1c552f0b47d119b4ddab608454cf5..7bcc36f2bf486c9ca41f536ce4b635c4e01c7b9e 100644 (file)
@@ -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 (file)
index 0000000..8ccbe37
Binary files /dev/null and b/dwarflint/tests/hello.bad-2.bz2 differ
diff --git a/dwarflint/tests/run-test-all-dies-it.sh b/dwarflint/tests/run-test-all-dies-it.sh
new file mode 100755 (executable)
index 0000000..fb6f83c
--- /dev/null
@@ -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
+# <http://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 (file)
index 0000000..e6296fa
--- /dev/null
@@ -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
+   <http://www.openinventionnetwork.com>.  */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <cassert>
+
+#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<dwarf> it = all_dies_iterator<dwarf> (dw);
+       it != all_dies_iterator<dwarf> (); ++it)
+    std::cout << std::hex << "0x" << (*it).offset () << std::endl;
+}