summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJosh Stone <jistone@redhat.com>2013-10-03 12:38:25 -0700
committerJosh Stone <jistone@redhat.com>2013-10-03 12:38:25 -0700
commit5dbbc5e32cc1fb3a7cf33e52e0bfc6f47097f3fe (patch)
tree7d2904feb5d3c00f8c6dde4bd284c9e95dbab241
parentacf126799e73e10f571da6c9be487b84a0a46f23 (diff)
downloadelfutils-5dbbc5e32cc1fb3a7cf33e52e0bfc6f47097f3fe.tar.gz
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>
-rw-r--r--libdw/ChangeLog6
-rw-r--r--libdw/dwarf_formref_die.c1
-rw-r--r--libdw/libdw_findcu.c3
-rw-r--r--tests/ChangeLog7
-rw-r--r--tests/Makefile.am3
-rwxr-xr-xtests/run-typeiter.sh4
-rw-r--r--tests/typeiter2.c89
7 files changed, 111 insertions, 2 deletions
diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index 951f1cba..e8580965 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 b1af2abf..b54e2166 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 70e24a03..c0bff2af 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 622af0c9..71bcfc10 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 0024395d..de98e456 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 b85839ce..605ee2a2 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 00000000..6ddfa388
--- /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);
+ }
+}