diff options
author | Alan Modra <amodra@gmail.com> | 2012-05-27 13:55:45 +0000 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2012-05-27 13:55:45 +0000 |
commit | f5eda4731e902851d30f1bd99fa890d2a7de41b9 (patch) | |
tree | 2c5d7549240da9e15b649c71174426897d3db741 /bfd | |
parent | 39dc1b2e6acf14c9447b62517cdf5a1694563b2c (diff) | |
download | binutils-f5eda4731e902851d30f1bd99fa890d2a7de41b9.zip binutils-f5eda4731e902851d30f1bd99fa890d2a7de41b9.tar.gz binutils-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.
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/ChangeLog | 9 | ||||
-rw-r--r-- | bfd/elflink.c | 31 |
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; |