PR ld/12549
authorAlan Modra <amodra@gmail.com>
Fri, 11 Jan 2013 13:55:02 +0000 (13:55 +0000)
committerAlan Modra <amodra@gmail.com>
Fri, 11 Jan 2013 13:55:02 +0000 (13:55 +0000)
* 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
bfd/elf-bfd.h
bfd/elf-strtab.c
bfd/elflink.c

index 11027ec9316136bc75c0caf42cea193c93325e59..ba90f46a8841e0fe79abcfb0d74d0762f5cddbdb 100644 (file)
@@ -1,3 +1,13 @@
+2013-01-12  Alan Modra  <amodra@gmail.com>
+
+       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  <hongjiu.lu@intel.com>
 
        * aout0.c: Remove trailing white spaces.
index 43a077cfd89d0bf451f6e0d0f7ef8ca196994fdb..85f8f31e5809313a9adbf0d0c763f6efee392873 100644 (file)
@@ -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
index 7d2fad4e51762ecd052a3300db5ffd5e5656c112..1526755ab7da5b24c87bd67905a48c4bb5de0493 100644 (file)
@@ -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
index 7df2775a7bd6f335150f5efe04efa8bd75b033bc..ee6288ad0762846e8954d49a488e8d37087175e5 100644 (file)
@@ -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;