diff options
author | Alan Modra <amodra@gmail.com> | 2016-05-30 09:43:44 +0930 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2016-06-02 12:28:39 +0930 |
commit | 5b677558bc6c7b2477bb33c709e6017e68e7ae8c (patch) | |
tree | a2de1189d6388b1a57720e0efee53831055dba30 /bfd/elf-strtab.c | |
parent | c273521c9aad56a596202dfaedc54182cf5543eb (diff) | |
download | gdb-5b677558bc6c7b2477bb33c709e6017e68e7ae8c.zip gdb-5b677558bc6c7b2477bb33c709e6017e68e7ae8c.tar.gz gdb-5b677558bc6c7b2477bb33c709e6017e68e7ae8c.tar.bz2 |
Revert PR16467 change
This reverts the pr16467 change, which was incorrect due to faulty
analysis of the pr16467 testcase. The failure was not due to a
mismatch in symbol type (ifunc/non-ifunc) but due to a symbol loop
being set up.
See https://sourceware.org/ml/binutils/2016-06/msg00013.html for some
rambling on versioned symbols and ELF shared library symbol overriding
that explain this patch.
bfd/
PR ld/20159
PR ld/16467
* elflink.c (_bfd_elf_merge_symbol): Revert PR16467 change.
(_bfd_elf_add_default_symbol): Don't indirect to/from defined
symbol given a version by a script different to the version
of the symbol being added.
(elf_link_add_object_symbols): Use _bfd_elf_strtab_save and
_bfd_elf_strtab_restore. Don't fudge dynstr references.
* elf-strtab.c (_bfd_elf_strtab_restore_size): Delete.
(struct strtab_save): New.
(_bfd_elf_strtab_save, _bfd_elf_strtab_restore): New functions.
* elf-bfd.h (_bfd_elf_strtab_restore_size): Delete.
(_bfd_elf_strtab_save, _bfd_elf_strtab_restore): Declare.
Diffstat (limited to 'bfd/elf-strtab.c')
-rw-r--r-- | bfd/elf-strtab.c | 41 |
1 files changed, 35 insertions, 6 deletions
diff --git a/bfd/elf-strtab.c b/bfd/elf-strtab.c index ca8ac33..19b0ad8 100644 --- a/bfd/elf-strtab.c +++ b/bfd/elf-strtab.c @@ -215,16 +215,45 @@ _bfd_elf_strtab_clear_all_refs (struct elf_strtab_hash *tab) tab->array[idx]->refcount = 0; } -/* Downsizes strtab. Entries from IDX up to the current size are - removed from the array. */ +/* Save strtab refcounts prior to adding --as-needed library. */ + +struct strtab_save +{ + bfd_size_type size; + unsigned int refcount[1]; +}; + +void * +_bfd_elf_strtab_save (struct elf_strtab_hash *tab) +{ + struct strtab_save *save; + bfd_size_type idx, size; + + size = sizeof (*save) + (tab->size - 1) * sizeof (save->refcount[0]); + save = bfd_malloc (size); + if (save == NULL) + return save; + + save->size = tab->size; + for (idx = 1; idx < tab->size; idx++) + save->refcount[idx] = tab->array[idx]->refcount; + return save; +} + +/* Restore strtab refcounts on finding --as-needed library not needed. */ + void -_bfd_elf_strtab_restore_size (struct elf_strtab_hash *tab, bfd_size_type idx) +_bfd_elf_strtab_restore (struct elf_strtab_hash *tab, void *buf) { - bfd_size_type curr_size = tab->size; + bfd_size_type idx, curr_size = tab->size; + struct strtab_save *save = (struct strtab_save *) buf; BFD_ASSERT (tab->sec_size == 0); - BFD_ASSERT (idx <= curr_size); - tab->size = idx; + BFD_ASSERT (save->size <= curr_size); + tab->size = save->size; + for (idx = 1; idx < save->size; ++idx) + tab->array[idx]->refcount = save->refcount[idx]; + for (; idx < curr_size; ++idx) { /* We don't remove entries from the hash table, just set their |