PR ld/12549
authorAlan Modra <amodra@gmail.com>
Mon, 18 Feb 2013 10:40:19 +0000 (10:40 +0000)
committerAlan Modra <amodra@gmail.com>
Mon, 18 Feb 2013 10:40:19 +0000 (10:40 +0000)
* elf-bfd.h (_bfd_elf_strtab_clear_refs): Delete.
(_bfd_elf_strtab_clear_all_refs): Declare.
(_bfd_elf_strtab_resize): Declare.
* elf-strtab.c (_bfd_elf_strtab_clear_refs): Delete.
(_bfd_elf_strtab_clear_all_refs): New function.
(_bfd_elf_strtab_resize): Likewise.
* elflink.c (elf_link_add_object_symbols): Use _bfd_elf_strtab_resize.

bfd/ChangeLog
bfd/elf-bfd.h
bfd/elf-strtab.c
bfd/elflink.c

index 5411140..76558b3 100644 (file)
@@ -1,5 +1,16 @@
 2013-02-18  Alan Modra  <amodra@gmail.com>
 
+       PR ld/12549
+       * elf-bfd.h (_bfd_elf_strtab_clear_refs): Delete.
+       (_bfd_elf_strtab_clear_all_refs): Declare.
+       (_bfd_elf_strtab_resize): Declare.
+       * elf-strtab.c (_bfd_elf_strtab_clear_refs): Delete.
+       (_bfd_elf_strtab_clear_all_refs): New function.
+       (_bfd_elf_strtab_resize): Likewise.
+       * elflink.c (elf_link_add_object_symbols): Use _bfd_elf_strtab_resize.
+
+2013-02-18  Alan Modra  <amodra@gmail.com>
+
        * elf-bfd.h (struct elf_obj_tdata): Move find_line_info, local_stubs,
        local_call_stubs, elf_data_symbol, elf_text_symbol, elf_data_section,
        and elf_text_section to..
index d36c287..c8d2957 100644 (file)
@@ -1927,10 +1927,10 @@ extern void _bfd_elf_strtab_delref
   (struct elf_strtab_hash *, bfd_size_type);
 extern unsigned int _bfd_elf_strtab_refcount
   (struct elf_strtab_hash *, bfd_size_type);
-extern void _bfd_elf_strtab_clear_refs
+extern void _bfd_elf_strtab_clear_all_refs
+  (struct elf_strtab_hash *tab);
+extern void _bfd_elf_strtab_restore_size
   (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 45743f6..61cedae 100644 (file)
@@ -208,10 +208,32 @@ _bfd_elf_strtab_refcount (struct elf_strtab_hash *tab, bfd_size_type idx)
 }
 
 void
-_bfd_elf_strtab_clear_refs (struct elf_strtab_hash *tab, bfd_size_type idx)
+_bfd_elf_strtab_clear_all_refs (struct elf_strtab_hash *tab)
 {
-  while (idx < tab->size)
-    tab->array[idx++]->refcount = 0;
+  bfd_size_type idx;
+
+  for (idx = 1; idx < tab->size; idx++)
+    tab->array[idx]->refcount = 0;
+}
+
+/* Downsizes strtab.  Entries from IDX up to the current size are
+   removed from the array.  */
+void
+_bfd_elf_strtab_restore_size (struct elf_strtab_hash *tab, bfd_size_type idx)
+{
+  bfd_size_type curr_size = tab->size;
+
+  BFD_ASSERT (tab->sec_size == 0);
+  BFD_ASSERT (idx <= curr_size);
+  tab->size = idx;
+  for (; idx < curr_size; ++idx)
+    {
+      /* We don't remove entries from the hash table, just set their
+        REFCOUNT to zero.  Setting LEN zero will result in the size
+        growing if the entry is added again.  See _bfd_elf_strtab_add.  */
+      tab->array[idx]->refcount = 0;
+      tab->array[idx]->len = 0;
+    }
 }
 
 bfd_size_type
index 617c505..b652bec 100644 (file)
@@ -4554,7 +4554,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);
+      _bfd_elf_strtab_restore_size (htab->dynstr, old_dynstr_size);
       for (i = 0; i < htab->root.table.size; i++)
        {
          struct bfd_hash_entry *p;