diff options
author | Josh Stone <jistone@redhat.com> | 2013-10-03 12:38:25 -0700 |
---|---|---|
committer | Josh Stone <jistone@redhat.com> | 2013-10-03 12:38:25 -0700 |
commit | 5dbbc5e32cc1fb3a7cf33e52e0bfc6f47097f3fe (patch) | |
tree | 7d2904feb5d3c00f8c6dde4bd284c9e95dbab241 | |
parent | acf126799e73e10f571da6c9be487b84a0a46f23 (diff) | |
download | elfutils-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/ChangeLog | 6 | ||||
-rw-r--r-- | libdw/dwarf_formref_die.c | 1 | ||||
-rw-r--r-- | libdw/libdw_findcu.c | 3 | ||||
-rw-r--r-- | tests/ChangeLog | 7 | ||||
-rw-r--r-- | tests/Makefile.am | 3 | ||||
-rwxr-xr-x | tests/run-typeiter.sh | 4 | ||||
-rw-r--r-- | tests/typeiter2.c | 89 |
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); + } +} |