aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2013-01-11 13:55:02 +0000
committerAlan Modra <amodra@gmail.com>2013-01-11 13:55:02 +0000
commita4542f1b2305d1ebb7f9f5e9c88e6af826923452 (patch)
treef729d224c08b43f400e7f6e5ac254c3d0234c385
parentc2e5e6d74e831490fb9afac70a31c79d38a1f812 (diff)
downloadfsf-binutils-gdb-a4542f1b2305d1ebb7f9f5e9c88e6af826923452.zip
fsf-binutils-gdb-a4542f1b2305d1ebb7f9f5e9c88e6af826923452.tar.gz
fsf-binutils-gdb-a4542f1b2305d1ebb7f9f5e9c88e6af826923452.tar.bz2
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.
-rw-r--r--bfd/ChangeLog10
-rw-r--r--bfd/elf-bfd.h6
-rw-r--r--bfd/elf-strtab.c8
-rw-r--r--bfd/elflink.c11
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 <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.
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;