From a4542f1b2305d1ebb7f9f5e9c88e6af826923452 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Fri, 11 Jan 2013 13:55:02 +0000 Subject: PR ld/12549 * elf-bfd.h (_bfd_elf_strtab_clear_refs): Declare. (_bfd_elf_strtab_clear_all_refs): Define. * elf-strtab.c (_bfd_elf_strtab_clear_refs): New function. (_bfd_elf_strtab_clear_all_refs): Delete. * elflink.c (elf_link_add_object_symbols): Clear out added strtab refs. Correct handling of warning common symbols. --- bfd/ChangeLog | 10 ++++++++++ bfd/elf-bfd.h | 6 ++++-- bfd/elf-strtab.c | 8 +++----- bfd/elflink.c | 11 ++++++++--- 4 files changed, 25 insertions(+), 10 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 11027ec..ba90f46 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,13 @@ +2013-01-12 Alan Modra + + PR ld/12549 + * elf-bfd.h (_bfd_elf_strtab_clear_refs): Declare. + (_bfd_elf_strtab_clear_all_refs): Define. + * elf-strtab.c (_bfd_elf_strtab_clear_refs): New function. + (_bfd_elf_strtab_clear_all_refs): Delete. + * elflink.c (elf_link_add_object_symbols): Clear out added + strtab refs. Correct handling of warning common symbols. + 2013-01-10 H.J. Lu * aout0.c: Remove trailing white spaces. diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index 43a077c..85f8f31 100644 --- a/bfd/elf-bfd.h +++ b/bfd/elf-bfd.h @@ -1938,8 +1938,10 @@ extern void _bfd_elf_strtab_addref (struct elf_strtab_hash *, bfd_size_type); extern void _bfd_elf_strtab_delref (struct elf_strtab_hash *, bfd_size_type); -extern void _bfd_elf_strtab_clear_all_refs - (struct elf_strtab_hash *); +extern void _bfd_elf_strtab_clear_refs + (struct elf_strtab_hash *, bfd_size_type); +#define _bfd_elf_strtab_clear_all_refs(tab) \ + do { _bfd_elf_strtab_clear_refs (tab, 1); } while (0) extern bfd_size_type _bfd_elf_strtab_size (struct elf_strtab_hash *); extern bfd_size_type _bfd_elf_strtab_offset diff --git a/bfd/elf-strtab.c b/bfd/elf-strtab.c index 7d2fad4..1526755 100644 --- a/bfd/elf-strtab.c +++ b/bfd/elf-strtab.c @@ -202,12 +202,10 @@ _bfd_elf_strtab_delref (struct elf_strtab_hash *tab, bfd_size_type idx) } void -_bfd_elf_strtab_clear_all_refs (struct elf_strtab_hash *tab) +_bfd_elf_strtab_clear_refs (struct elf_strtab_hash *tab, bfd_size_type idx) { - bfd_size_type idx; - - for (idx = 1; idx < tab->size; ++idx) - tab->array[idx]->refcount = 0; + while (idx < tab->size) + tab->array[idx++]->refcount = 0; } bfd_size_type diff --git a/bfd/elflink.c b/bfd/elflink.c index 7df2775..ee6288a 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -3385,6 +3385,7 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info) struct bfd_link_hash_entry *old_undefs = NULL; struct bfd_link_hash_entry *old_undefs_tail = NULL; long old_dynsymcount = 0; + bfd_size_type old_dynstr_size = 0; size_t tabsize = 0; size_t hashsize = 0; @@ -3834,6 +3835,7 @@ error_free_dyn: old_size = htab->root.table.size; old_count = htab->root.table.count; old_dynsymcount = htab->dynsymcount; + old_dynstr_size = _bfd_elf_strtab_size (htab->dynstr); for (i = 0; i < htab->root.table.size; i++) { @@ -4566,6 +4568,7 @@ error_free_dyn: memcpy (sym_hash, old_hash, hashsize); htab->root.undefs = old_undefs; htab->root.undefs_tail = old_undefs_tail; + _bfd_elf_strtab_clear_refs (htab->dynstr, old_dynstr_size); for (i = 0; i < htab->root.table.size; i++) { struct bfd_hash_entry *p; @@ -4578,12 +4581,13 @@ error_free_dyn: h = (struct elf_link_hash_entry *) p; if (h->root.type == bfd_link_hash_warning) h = (struct elf_link_hash_entry *) h->root.u.i.link; - if (h->dynindx >= old_dynsymcount) + if (h->dynindx >= old_dynsymcount + && h->dynstr_index < old_dynstr_size) _bfd_elf_strtab_delref (htab->dynstr, h->dynstr_index); /* Preserve the maximum alignment and size for common symbols even if this dynamic lib isn't on DT_NEEDED - since it can still be loaded at the run-time by another + since it can still be loaded at run time by another dynamic lib. */ if (h->root.type == bfd_link_hash_common) { @@ -4602,8 +4606,9 @@ error_free_dyn: { memcpy (h->root.u.i.link, old_ent, htab->root.table.entsize); old_ent = (char *) old_ent + htab->root.table.entsize; + h = (struct elf_link_hash_entry *) h->root.u.i.link; } - else if (h->root.type == bfd_link_hash_common) + if (h->root.type == bfd_link_hash_common) { if (size > h->root.u.c.size) h->root.u.c.size = size; -- cgit v1.1