From 8943b874760d9cf35b71890a70af9866e4fab2a6 Mon Sep 17 00:00:00 2001 From: Doug Evans Date: Tue, 12 Nov 2013 09:43:17 -0800 Subject: [PATCH] Work around gold/15646. * dwarf2read.c (read_index_from_section): Update comment. (struct dw2_symtab_iterator): New member global_seen. (dw2_symtab_iter_init): Initialize it. (dw2_symtab_iter_next): Skip duplicate global symbols. (dw2_expand_symtabs_matching): Ditto. --- gdb/ChangeLog | 9 +++++++++ gdb/dwarf2read.c | 43 ++++++++++++++++++++++++++++++++++++------- 2 files changed, 45 insertions(+), 7 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index cc97bbef70d..654183738c8 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,12 @@ +2013-11-12 Doug Evans + + Work around gold/15646. + * dwarf2read.c (read_index_from_section): Update comment. + (struct dw2_symtab_iterator): New member global_seen. + (dw2_symtab_iter_init): Initialize it. + (dw2_symtab_iter_next): Skip duplicate global symbols. + (dw2_expand_symtabs_matching): Ditto. + 2013-11-12 Joel Brobecker * mi/mi-cmds.h (mi_cmd_info_ada_exceptions): Add declaration. diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index 7e87ed9adde..c5c3b5c2254 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -3034,9 +3034,12 @@ to use the section anyway."), return 0; } /* Version 7 indices generated by gold refer to the CU for a symbol instead - of the TU (for symbols coming from TUs). It's just a performance bug, and - we can't distinguish gdb-generated indices from gold-generated ones, so - nothing to do here. */ + of the TU (for symbols coming from TUs), + http://sourceware.org/bugzilla/show_bug.cgi?id=15021. + Plus gold-generated indices can have duplicate entries for global symbols, + http://sourceware.org/bugzilla/show_bug.cgi?id=15646. + These are just performance bugs, and we can't distinguish gdb-generated + indices from gold-generated ones, so issue no warning here. */ /* Indexes with higher version than the one supported by GDB may be no longer backward compatible. */ @@ -3448,6 +3451,11 @@ struct dw2_symtab_iterator int next; /* The number of elements in VEC, or zero if there is no match. */ int length; + /* Have we seen a global version of the symbol? + If so we can ignore all further global instances. + This is to work around gold/15646, inefficient gold-generated + indices. */ + int global_seen; }; /* Initialize the index symtab iterator ITER. @@ -3467,6 +3475,7 @@ dw2_symtab_iter_init (struct dw2_symtab_iterator *iter, iter->block_index = block_index; iter->domain = domain; iter->next = 0; + iter->global_seen = 0; if (find_slot_in_mapped_hash (index, name, &iter->vec)) iter->length = MAYBE_SWAP (*iter->vec); @@ -3518,10 +3527,18 @@ dw2_symtab_iter_next (struct dw2_symtab_iterator *iter) if (per_cu->v.quick->symtab) continue; - if (attrs_valid - && iter->want_specific_block - && want_static != is_static) - continue; + /* Check static vs global. */ + if (attrs_valid) + { + if (iter->want_specific_block + && want_static != is_static) + continue; + /* Work around gold/15646. */ + if (!is_static && iter->global_seen) + continue; + if (!is_static) + iter->global_seen = 1; + } /* Only check the symbol's kind if it has one. */ if (attrs_valid) @@ -3849,6 +3866,7 @@ dw2_expand_symtabs_matching offset_type idx = 2 * iter; const char *name; offset_type *vec, vec_len, vec_idx; + int global_seen = 0; if (index->symbol_table[idx] == 0 && index->symbol_table[idx + 1] == 0) continue; @@ -3867,6 +3885,8 @@ dw2_expand_symtabs_matching { struct dwarf2_per_cu_data *per_cu; offset_type cu_index_and_attrs = MAYBE_SWAP (vec[vec_idx + 1]); + /* This value is only valid for index versions >= 7. */ + int is_static = GDB_INDEX_SYMBOL_STATIC_VALUE (cu_index_and_attrs); gdb_index_symbol_kind symbol_kind = GDB_INDEX_SYMBOL_KIND_VALUE (cu_index_and_attrs); int cu_index = GDB_INDEX_CU_VALUE (cu_index_and_attrs); @@ -3878,6 +3898,15 @@ dw2_expand_symtabs_matching (index->version >= 7 && symbol_kind != GDB_INDEX_SYMBOL_KIND_NONE); + /* Work around gold/15646. */ + if (attrs_valid) + { + if (!is_static && global_seen) + continue; + if (!is_static) + global_seen = 1; + } + /* Only check the symbol's kind if it has one. */ if (attrs_valid) { -- 2.30.2