aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2012-05-27 13:55:45 +0000
committerAlan Modra <amodra@gmail.com>2012-05-27 13:55:45 +0000
commitf5eda4731e902851d30f1bd99fa890d2a7de41b9 (patch)
tree2c5d7549240da9e15b649c71174426897d3db741
parent39dc1b2e6acf14c9447b62517cdf5a1694563b2c (diff)
downloadgdb-f5eda4731e902851d30f1bd99fa890d2a7de41b9.zip
gdb-f5eda4731e902851d30f1bd99fa890d2a7de41b9.tar.gz
gdb-f5eda4731e902851d30f1bd99fa890d2a7de41b9.tar.bz2
PR ld/14170
* elflink.c (_bfd_elf_merge_symbol): When a symbol defined in a dynamic library finds a new instance with non-default visibility in a regular object, correctly handle symbols already on the undefs list and undo dynamic symbol state when the new symbol is hidden or internal.
-rw-r--r--bfd/ChangeLog9
-rw-r--r--bfd/elflink.c31
2 files changed, 28 insertions, 12 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 9834aab..4abe5f2 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,12 @@
+2012-05-27 Alan Modra <amodra@gmail.com>
+
+ PR ld/14170
+ * elflink.c (_bfd_elf_merge_symbol): When a symbol defined in
+ a dynamic library finds a new instance with non-default
+ visibility in a regular object, correctly handle symbols
+ already on the undefs list and undo dynamic symbol state when
+ the new symbol is hidden or internal.
+
2012-05-25 H.J. Lu <hongjiu.lu@intel.com>
* elf32-i386.c (elf_i386_create_dynamic_sections): Don't use
diff --git a/bfd/elflink.c b/bfd/elflink.c
index 7f35e7f..e715942 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -1216,15 +1216,15 @@ _bfd_elf_merge_symbol (bfd *abfd,
h = *sym_hash;
}
- if ((h->root.u.undef.next || info->hash->undefs_tail == &h->root)
- && bfd_is_und_section (sec))
- {
- /* If the new symbol is undefined and the old symbol was
- also undefined before, we need to make sure
- _bfd_generic_link_add_one_symbol doesn't mess
- up the linker hash table undefs list. Since the old
- definition came from a dynamic object, it is still on the
- undefs list. */
+ /* If the old symbol was undefined before, then it will still be
+ on the undefs list. If the new symbol is undefined or
+ common, we can't make it bfd_link_hash_new here, because new
+ undefined or common symbols will be added to the undefs list
+ by _bfd_generic_link_add_one_symbol. Symbols may not be
+ added twice to the undefs list. Also, if the new symbol is
+ undefweak then we don't want to lose the strong undef. */
+ if (h->root.u.undef.next || info->hash->undefs_tail == &h->root)
+ {
h->root.type = bfd_link_hash_undefined;
h->root.u.undef.abfd = abfd;
}
@@ -1234,11 +1234,18 @@ _bfd_elf_merge_symbol (bfd *abfd,
h->root.u.undef.abfd = NULL;
}
- if (h->def_dynamic)
+ if (ELF_ST_VISIBILITY (sym->st_other) != STV_PROTECTED)
{
- h->def_dynamic = 0;
- h->ref_dynamic = 1;
+ /* If the new symbol is hidden or internal, completely undo
+ any dynamic link state. */
+ (*bed->elf_backend_hide_symbol) (info, h, TRUE);
+ h->forced_local = 0;
+ h->ref_dynamic = 0;
}
+ else
+ h->ref_dynamic = 1;
+ h->def_dynamic = 0;
+ h->dynamic_def = 0;
/* FIXME: Should we check type and size for protected symbol? */
h->size = 0;
h->type = 0;