]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
libdw: Make sure that every debug_types sig8 is hashed
authorJosh Stone <jistone@redhat.com>
Thu, 3 Oct 2013 19:38:25 +0000 (12:38 -0700)
committerJosh Stone <jistone@redhat.com>
Thu, 3 Oct 2013 19:38:25 +0000 (12:38 -0700)
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
libdw/dwarf_formref_die.c
libdw/libdw_findcu.c
tests/ChangeLog
tests/Makefile.am
tests/run-typeiter.sh
tests/typeiter2.c [new file with mode: 0644]

index 951f1cba6e2ccb8bc4416ee8905eaf576e830ff9..e8580965b3325dec5756abe97d107338543c6033 100644 (file)
@@ -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
index b1af2abf269644030e2d137e91d16adcf3b0cf8b..b54e21667a3df1fc76b636ec090b161fc77986ef 100644 (file)
@@ -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);
 
index 70e24a0317a4b8572cf26f2067dbffb8cf75f83e..c0bff2af2a690f3bc0c82cbe3f0e35a1e6adb4d2 100644 (file)
@@ -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)
     {
index 622af0c99c83f81dbba4e110bb6c54c7c9004112..71bcfc106fa54f811a764a2772183fc76259043e 100644 (file)
@@ -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
index 0024395df7b061d42a391c214f33608a57baeaef..de98e456c970257d10e90d82f34363fa5b1ee94c 100644 (file)
@@ -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)
index b85839ce7af9ef6673b1ba5b47ea3f2760e8a665..605ee2a2efa37f9c2877932221922a013a63ccb3 100755 (executable)
@@ -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 (file)
index 0000000..6ddfa38
--- /dev/null
@@ -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);
+    }
+}