diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 15f1a3f037..3d09aa4c94 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,13 @@ +2017-08-23 Alan Modra + + PR 21988 + * elf64-ppc.c (ensure_undef_dynamic): Rename from + ensure_undefweak_dynamic. Handle undefined too. + * elf32-ppc.c (ensure_undef_dynamic): Likewise. + * elf32-hppa.c (ensure_undef_dynamic): Likewise. + (allocate_dynrelocs): Discard undefined non-default visibility + relocs first. Make undefined syms dynamic. Tidy goto. + 2017-08-21 Alan Modra H.J. Lu diff --git a/bfd/elf32-hppa.c b/bfd/elf32-hppa.c index f63ff3f862..3adac6d91f 100644 --- a/bfd/elf32-hppa.c +++ b/bfd/elf32-hppa.c @@ -1919,16 +1919,20 @@ elf32_hppa_adjust_dynamic_symbol (struct bfd_link_info *info, return _bfd_elf_adjust_dynamic_copy (info, eh, sec); } -/* Make an undefined weak symbol dynamic. */ +/* If EH is undefined, make it dynamic if that makes sense. */ static bfd_boolean -ensure_undef_weak_dynamic (struct bfd_link_info *info, - struct elf_link_hash_entry *eh) +ensure_undef_dynamic (struct bfd_link_info *info, + struct elf_link_hash_entry *eh) { - if (eh->dynindx == -1 + struct elf_link_hash_table *htab = elf_hash_table (info); + + if (htab->dynamic_sections_created + && (eh->root.type == bfd_link_hash_undefweak + || eh->root.type == bfd_link_hash_undefined) + && eh->dynindx == -1 && !eh->forced_local && eh->type != STT_PARISC_MILLI - && eh->root.type == bfd_link_hash_undefweak && ELF_ST_VISIBILITY (eh->other) == STV_DEFAULT) return bfd_elf_link_record_dynamic_symbol (info, eh); return TRUE; @@ -1957,7 +1961,7 @@ allocate_plt_static (struct elf_link_hash_entry *eh, void *inf) if (htab->etab.dynamic_sections_created && eh->plt.refcount > 0) { - if (!ensure_undef_weak_dynamic (info, eh)) + if (!ensure_undef_dynamic (info, eh)) return FALSE; if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, bfd_link_pic (info), eh)) @@ -2034,7 +2038,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *eh, void *inf) if (eh->got.refcount > 0) { - if (!ensure_undef_weak_dynamic (info, eh)) + if (!ensure_undef_dynamic (info, eh)) return FALSE; sec = htab->etab.sgot; @@ -2070,8 +2074,14 @@ allocate_dynrelocs (struct elf_link_hash_entry *eh, void *inf) changes. */ if (bfd_link_pic (info)) { + /* Discard relocs on undefined syms with non-default visibility. */ + if ((eh->root.type == bfd_link_hash_undefined + || eh->root.type == bfd_link_hash_undefweak) + && ELF_ST_VISIBILITY (eh->other) != STV_DEFAULT) + hh->dyn_relocs = NULL; + #if RELATIVE_DYNRELOCS - if (SYMBOL_CALLS_LOCAL (info, eh)) + else if (SYMBOL_CALLS_LOCAL (info, eh)) { struct elf32_hppa_dyn_reloc_entry **hdh_pp; @@ -2087,15 +2097,9 @@ allocate_dynrelocs (struct elf_link_hash_entry *eh, void *inf) } #endif - /* Also discard relocs on undefined weak syms with non-default - visibility. */ - if (hh->dyn_relocs != NULL - && eh->root.type == bfd_link_hash_undefweak) + if (hh->dyn_relocs != NULL) { - if (ELF_ST_VISIBILITY (eh->other) != STV_DEFAULT) - hh->dyn_relocs = NULL; - - else if (!ensure_undef_weak_dynamic (info, eh)) + if (!ensure_undef_dynamic (info, eh)) return FALSE; } } @@ -2113,19 +2117,14 @@ allocate_dynrelocs (struct elf_link_hash_entry *eh, void *inf) && (eh->root.type == bfd_link_hash_undefweak || eh->root.type == bfd_link_hash_undefined)))) { - if (!ensure_undef_weak_dynamic (info, eh)) + if (!ensure_undef_dynamic (info, eh)) return FALSE; - /* If that succeeded, we know we'll be keeping all the - relocs. */ - if (eh->dynindx != -1) - goto keep; + if (eh->dynindx == -1) + hh->dyn_relocs = NULL; } - - hh->dyn_relocs = NULL; - return TRUE; - - keep: ; + else + hh->dyn_relocs = NULL; } /* Finally, allocate space. */ diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c index f32ba9bf6a..ac3b12bbee 100644 --- a/bfd/elf32-ppc.c +++ b/bfd/elf32-ppc.c @@ -5942,17 +5942,18 @@ allocate_got (struct ppc_elf_link_hash_table *htab, unsigned int need) return where; } -/* If H is undefined weak, make it dynamic if that makes sense. */ +/* If H is undefined, make it dynamic if that makes sense. */ static bfd_boolean -ensure_undefweak_dynamic (struct bfd_link_info *info, - struct elf_link_hash_entry *h) +ensure_undef_dynamic (struct bfd_link_info *info, + struct elf_link_hash_entry *h) { struct elf_link_hash_table *htab = elf_hash_table (info); if (htab->dynamic_sections_created - && info->dynamic_undefined_weak != 0 - && h->root.type == bfd_link_hash_undefweak + && ((info->dynamic_undefined_weak != 0 + && h->root.type == bfd_link_hash_undefweak) + || h->root.type == bfd_link_hash_undefined) && h->dynindx == -1 && !h->forced_local && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT) @@ -5986,9 +5987,8 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) { unsigned int need; - /* Make sure this symbol is output as a dynamic symbol. - Undefined weak syms won't yet be marked as dynamic. */ - if (!ensure_undefweak_dynamic (info, &eh->elf)) + /* Make sure this symbol is output as a dynamic symbol. */ + if (!ensure_undef_dynamic (info, &eh->elf)) return FALSE; need = 0; @@ -6102,9 +6102,8 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) if (eh->dyn_relocs != NULL) { - /* Make sure undefined weak symbols are output as a dynamic - symbol in PIEs. */ - if (!ensure_undefweak_dynamic (info, h)) + /* Make sure this symbol is output as a dynamic symbol. */ + if (!ensure_undef_dynamic (info, h)) return FALSE; } } @@ -6120,9 +6119,8 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) && eh->has_addr16_lo && htab->params->pic_fixup > 0)) { - /* Make sure this symbol is output as a dynamic symbol. - Undefined weak syms won't yet be marked as dynamic. */ - if (!ensure_undefweak_dynamic (info, h)) + /* Make sure this symbol is output as a dynamic symbol. */ + if (!ensure_undef_dynamic (info, h)) return FALSE; if (h->dynindx == -1) diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c index 7f4f7b6b86..f0fde1de32 100644 --- a/bfd/elf64-ppc.c +++ b/bfd/elf64-ppc.c @@ -9743,17 +9743,18 @@ merge_got_entries (struct got_entry **pent) } } -/* If H is undefined weak, make it dynamic if that makes sense. */ +/* If H is undefined, make it dynamic if that makes sense. */ static bfd_boolean -ensure_undefweak_dynamic (struct bfd_link_info *info, - struct elf_link_hash_entry *h) +ensure_undef_dynamic (struct bfd_link_info *info, + struct elf_link_hash_entry *h) { struct elf_link_hash_table *htab = elf_hash_table (info); if (htab->dynamic_sections_created - && info->dynamic_undefined_weak != 0 - && h->root.type == bfd_link_hash_undefweak + && ((info->dynamic_undefined_weak != 0 + && h->root.type == bfd_link_hash_undefweak) + || h->root.type == bfd_link_hash_undefined) && h->dynindx == -1 && !h->forced_local && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT) @@ -9832,9 +9833,8 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) for (gent = h->got.glist; gent != NULL; gent = gent->next) if (!gent->is_indirect) { - /* Make sure this symbol is output as a dynamic symbol. - Undefined weak syms won't yet be marked as dynamic. */ - if (!ensure_undefweak_dynamic (info, h)) + /* Make sure this symbol is output as a dynamic symbol. */ + if (!ensure_undef_dynamic (info, h)) return FALSE; if (!is_ppc64_elf (gent->owner)) @@ -9888,9 +9888,8 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) if (eh->dyn_relocs != NULL) { - /* Make sure this symbol is output as a dynamic symbol. - Undefined weak syms won't yet be marked as dynamic. */ - if (!ensure_undefweak_dynamic (info, h)) + /* Make sure this symbol is output as a dynamic symbol. */ + if (!ensure_undef_dynamic (info, h)) return FALSE; } } @@ -9925,9 +9924,8 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) if (!h->non_got_ref && !h->def_regular) { - /* Make sure this symbol is output as a dynamic symbol. - Undefined weak syms won't yet be marked as dynamic. */ - if (!ensure_undefweak_dynamic (info, h)) + /* Make sure this symbol is output as a dynamic symbol. */ + if (!ensure_undef_dynamic (info, h)) return FALSE; if (h->dynindx == -1)