This is the mail archive of the elfutils-devel@sourceware.org mailing list for the elfutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] libdw: Make sure that every debug_types sig8 is hashed


When dwarf_formref_die can't find a sig8 in the hash, it walks
__libdw_intern_next_unit, and was then adding those to the hash.
However, if dwarf_offdie_types is called earlier, which also uses that
next_unit, then they are missed from the hash (and never revisited).

This patch makes __libdw_intern_next_unit do the sig8 hash insert, so no
type unit is ever missed.

Signed-off-by: Josh Stone <jistone@redhat.com>
---
 libdw/ChangeLog           |  6 ++++
 libdw/dwarf_formref_die.c |  1 -
 libdw/libdw_findcu.c      |  3 ++
 tests/ChangeLog           |  7 ++++
 tests/Makefile.am         |  3 +-
 tests/run-typeiter.sh     |  4 +++
 tests/typeiter2.c         | 89 +++++++++++++++++++++++++++++++++++++++++++++++
 7 files changed, 111 insertions(+), 2 deletions(-)
 create mode 100644 tests/typeiter2.c

diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index 951f1cb..e858096 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,3 +1,9 @@
+2013-10-03  Josh Stone  <jistone@redhat.com>
+
+	* dwarf_formref_die.c (dwarf_formref_die): Don't hash the sig8 here.
+	* libdw_findcu.c (__libdw_intern_next_unit): Since this never revisits
+	a unit, make sure to always hash the sig8 here, so none are missed.
+
 2013-09-29  Mark Wielaard  <mjw@redhat.com>
 
 	* dwarf_getlocation.c (store_implicit_value): Cast op->number2 to
diff --git a/libdw/dwarf_formref_die.c b/libdw/dwarf_formref_die.c
index b1af2ab..b54e216 100644
--- a/libdw/dwarf_formref_die.c
+++ b/libdw/dwarf_formref_die.c
@@ -89,7 +89,6 @@ dwarf_formref_die (attr, result)
 				  ?: DWARF_E_INVALID_REFERENCE);
 		return NULL;
 	      }
-	    Dwarf_Sig8_Hash_insert (&cu->dbg->sig8_hash, cu->type_sig8, cu);
 	  }
 	while (cu->type_sig8 != sig);
 
diff --git a/libdw/libdw_findcu.c b/libdw/libdw_findcu.c
index 70e24a0..c0bff2a 100644
--- a/libdw/libdw_findcu.c
+++ b/libdw/libdw_findcu.c
@@ -110,6 +110,9 @@ __libdw_intern_next_unit (dbg, debug_types)
   newp->lines = NULL;
   newp->locs = NULL;
 
+  if (debug_types)
+    Dwarf_Sig8_Hash_insert (&dbg->sig8_hash, type_sig8, newp);
+
   /* Add the new entry to the search tree.  */
   if (tsearch (newp, tree, findcu_cb) == NULL)
     {
diff --git a/tests/ChangeLog b/tests/ChangeLog
index 622af0c..71bcfc1 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,3 +1,10 @@
+2013-10-03  Josh Stone  <jistone@redhat.com>
+
+	* typeiter2.c: New file, reversing typeiter.c.
+	* run-typeiter.sh: Also run typeiter2.
+	* Makefile.am (ckeck_PROGRAMS): Add typeiter2.
+	(typeiter2_LDADD): New variable.
+
 2013-09-26  Petr Machata  <pmachata@redhat.com>
 
 	* run-readelf-mixed-corenote.sh: Update output of testfile71
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 0024395..de98e45 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -50,7 +50,7 @@ check_PROGRAMS = arextract arsymtest newfile saridx scnnames sectiondump \
 		  dwfl-addr-sect dwfl-bug-report early-offscn \
 		  dwfl-bug-getmodules dwarf-getmacros addrcfi \
 		  test-flag-nobits dwarf-getstring rerequest_tag \
-		  alldts md5-sha1-test typeiter low_high_pc \
+		  alldts md5-sha1-test typeiter typeiter2 low_high_pc \
 		  test-elf_cntl_gelf_getshdr dwflsyms dwfllines \
 		  dwfl-report-elf-align varlocs
 asm_TESTS = asm-tst1 asm-tst2 asm-tst3 asm-tst4 asm-tst5 \
@@ -332,6 +332,7 @@ rerequest_tag_LDADD = $(libdw) $(libmudflap)
 alldts_LDADD = $(libebl) $(libelf) $(libmudflap)
 md5_sha1_test_LDADD = $(libeu)
 typeiter_LDADD = $(libdw) $(libelf) $(libmudflap)
+typeiter2_LDADD = $(libdw) $(libelf) $(libmudflap)
 low_high_pc_LDADD = $(libdw) $(libelf) $(libmudflap)
 test_elf_cntl_gelf_getshdr_LDADD = $(libelf) $(libmudflap)
 dwflsyms_LDADD = $(libdw) $(libelf) $(libmudflap)
diff --git a/tests/run-typeiter.sh b/tests/run-typeiter.sh
index b85839c..605ee2a 100755
--- a/tests/run-typeiter.sh
+++ b/tests/run-typeiter.sh
@@ -47,4 +47,8 @@ testrun_compare ${abs_builddir}/typeiter testfile59 <<\EOF
 ok
 EOF
 
+testrun_compare ${abs_builddir}/typeiter2 testfile59 <<\EOF
+ok
+EOF
+
 exit 0
diff --git a/tests/typeiter2.c b/tests/typeiter2.c
new file mode 100644
index 0000000..6ddfa38
--- /dev/null
+++ b/tests/typeiter2.c
@@ -0,0 +1,89 @@
+/* Copyright (C) 2012, 2013 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 <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <fcntl.h>
+#include ELFUTILS_HEADER(dw)
+#include <stdio.h>
+#include <unistd.h>
+#include <dwarf.h>
+
+int
+main (int argc, char *argv[])
+{
+  for (int i = 1; i < argc; ++i)
+    {
+      int fd = open (argv[i], O_RDONLY);
+
+      Dwarf *dbg = dwarf_begin (fd, DWARF_C_READ);
+      if (dbg != NULL)
+	{
+	  Dwarf_Off off = 0;
+	  size_t cuhl;
+	  Dwarf_Off noff;
+	  uint64_t type_sig;
+
+	  while (dwarf_next_unit (dbg, off, &noff, &cuhl, NULL, NULL, NULL,
+				  NULL, &type_sig, NULL) == 0)
+	    {
+	      Dwarf_Die die_mem;
+	      dwarf_offdie_types (dbg, off + cuhl, &die_mem);
+	      off = noff;
+	    }
+
+	  off = 0;
+
+	  while (dwarf_nextcu (dbg, off, &noff, &cuhl, NULL, NULL, NULL) == 0)
+	    {
+	      Dwarf_Die die_mem;
+	      Dwarf_Die *die = dwarf_offdie (dbg, off + cuhl, &die_mem);
+
+	      Dwarf_Die iter_mem;
+	      Dwarf_Die *iter = &iter_mem;
+	      dwarf_child (die, &iter_mem);
+
+	      while (1)
+		{
+		  if (dwarf_tag (iter) == DW_TAG_variable)
+		    {
+		      Dwarf_Attribute attr_mem;
+		      Dwarf_Die form_mem, *form;
+		      form = dwarf_formref_die (dwarf_attr (iter, DW_AT_type,
+							    &attr_mem),
+						&form_mem);
+
+		      if (form == NULL)
+			printf ("fail\n");
+		      else
+			printf ("ok\n");
+		    }
+
+		  if (dwarf_siblingof (iter, &iter_mem) != 0)
+		    break;
+		}
+
+	      off = noff;
+	    }
+
+	  dwarf_end (dbg);
+	}
+
+      close (fd);
+    }
+}
-- 
1.8.3.1


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]