From: Alan Modra Date: Sun, 12 Nov 2017 07:14:15 +0000 (+1030) Subject: non_got_ref after adjust_dynamic_relocs X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=529fe20eeb0030ea5d653d0ebec433f9e3145874;p=binutils-gdb.git non_got_ref after adjust_dynamic_relocs This patch was aimed at a FIXME in elf32-hppa.c, the ludicrous and confusing fact that non_got_ref after adjust_dynamic_relocs in that backend means precisely the inverse of what it means before adjust_dynamic_relocs. Before, when non_got_ref is set it means there are dynamic relocs, after, if non_got_ref is clear it means "keep dynamic relocs" and later, "has dynamic relocs". There is a reason why it was done that way.. Some symbols that may have dynamic relocations pre-allocated in check_relocs turn out to not be dynamic, and then are not seen by the backend adjust_dynamic_symbols. We want those symbols to lose their dynamic relocs when non-pic, so it's handy that non_got_ref means the opposite after adjust_dynamic_relocs. But it's really confusing. Most other targets, like ppc32, don't always set non_got_ref on non-GOT references that have dynamic relocations. This is because the primary purpose of non_got_ref before adjust_dynamic_relocs is to flag symbols that might need to be copied to .dynbss, and there are relocation types that may require dyn_relocs but clearly cannot have symbols copied into .dynbss, for example, TLS relocations. Why do we need a flag after adjust_dynamic_relocs to say "keep dynamic relocations"? Well, you can discard most unwanted dyn_relocs in the backend adjust_dynamic_relocs, and for those symbols that aren't seen by the backend adjust_dynamic_relocs, in allocate_dynrelocs based on a flag set by adjust_dynamic relocs, dynamic_adjusted. That doesn't solve all our difficulties though. relocate_section needs to know whether a symbol has dyn_relocs, and many targets transfer dyn_relocs to a weakdef if the symbol has one. The transfer means relocate_section can't test dyn_relocs itself and the weakdef field has been overwritten by that time. So non_got_ref is used to flag "this symbol has dynamic relocations" for relocate_section. Confused still? Well, let's hope the comments I've added help clarify things.. The patch also fixes a case where we might wrongly emit dynamic relocations in an executable for common and undefined symbols. * elf32-hppa.c (elf32_hppa_adjust_dynamic_symbol): Set non_got_ref to keep dyn_relocs, clear to discard. Comment. (allocate_dynrelocs): Always clear non_got_ref when clearing dyn_relocs in non-pic case. Invert non_got_ref test. Also test dynamic_adjusted and ELF_COMMON_DEF_P. Move code deleting dyn_relocs on undefined syms to handle for non-pic too. (elf32_hppa_relocate_section): Simplify test for non-pic dyn relocs. * elf32-ppc.c (ppc_elf_adjust_dynamic_symbol): Set non_got_ref to keep dyn_relocs, clear to discard. Comment. (allocate_dynrelocs): Always clear non_got_ref when clearing dyn_relocs in non-pic case. Invert non_got_ref test. Also test dynamic_adjusted and ELF_COMMON_DEF_P. Move code deleting dyn_relocs on undefined syms to handle for non-pic too. (ppc_elf_relocate_section): Simplify test for non-pic dyn relocs. * elf64-ppc.c (ppc64_elf_adjust_dynamic_symbol): Discard dyn_relocs here. Don't bother setting non_got_ref. Comment. (allocate_dynrelocs): Delete special handling of non-pic ELFv2 ifuncs. Move code deleting dyn_relocs on undefined symbols to handle for non-pic too. Don't test non_got_ref. Do test dynamic_adjusted and ELF_COMMON_DEF_P. --- diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 8e619290921..735136d7f85 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,26 @@ +2017-11-12 Alan Modra + + * elf32-hppa.c (elf32_hppa_adjust_dynamic_symbol): Set non_got_ref + to keep dyn_relocs, clear to discard. Comment. + (allocate_dynrelocs): Always clear non_got_ref when clearing + dyn_relocs in non-pic case. Invert non_got_ref test. Also test + dynamic_adjusted and ELF_COMMON_DEF_P. Move code deleting + dyn_relocs on undefined syms to handle for non-pic too. + (elf32_hppa_relocate_section): Simplify test for non-pic dyn relocs. + * elf32-ppc.c (ppc_elf_adjust_dynamic_symbol): Set non_got_ref + to keep dyn_relocs, clear to discard. Comment. + (allocate_dynrelocs): Always clear non_got_ref when clearing + dyn_relocs in non-pic case. Invert non_got_ref test. Also test + dynamic_adjusted and ELF_COMMON_DEF_P. Move code deleting + dyn_relocs on undefined syms to handle for non-pic too. + (ppc_elf_relocate_section): Simplify test for non-pic dyn relocs. + * elf64-ppc.c (ppc64_elf_adjust_dynamic_symbol): Discard + dyn_relocs here. Don't bother setting non_got_ref. Comment. + (allocate_dynrelocs): Delete special handling of non-pic ELFv2 + ifuncs. Move code deleting dyn_relocs on undefined symbols to + handle for non-pic too. Don't test non_got_ref. Do test + dynamic_adjusted and ELF_COMMON_DEF_P. + 2017-11-08 Djordje Todorovic * elf32-mips.c (elf32_mips_grok_psinfo): Extract core->pid. diff --git a/bfd/elf32-hppa.c b/bfd/elf32-hppa.c index f9629e4b119..7fc447e2b46 100644 --- a/bfd/elf32-hppa.c +++ b/bfd/elf32-hppa.c @@ -1692,7 +1692,9 @@ elf32_hppa_adjust_dynamic_symbol (struct bfd_link_info *info, if (eh->type == STT_FUNC || eh->needs_plt) { - /* After adjust_dynamic_symbol, non_got_ref set in the non-pic + /* Prior to adjust_dynamic_symbol, non_got_ref set means that + check_relocs generated dyn_relocs for this symbol. + After adjust_dynamic_symbol, non_got_ref clear in the non-pic case means that dyn_relocs for this symbol should be discarded; We either want the symbol to remain undefined, or we have a local definition of some sort. The "local @@ -1700,22 +1702,13 @@ elf32_hppa_adjust_dynamic_symbol (struct bfd_link_info *info, local definition in .dynbss. Unlike other targets, elf32-hppa.c does not define a function symbol in a non-pic executable on PLT stub code, so we don't - have a local definition in that case. dyn_relocs therefore - should not be discarded for function symbols, generally. - However we should discard dyn_relocs if we've decided that an - undefined function symbol is local, for example due to - non-default visibility, or UNDEFWEAK_NO_DYNAMIC_RELOC is - true for an undefined weak symbol. */ + have a local definition in that case. */ bfd_boolean local = (SYMBOL_CALLS_LOCAL (info, eh) || UNDEFWEAK_NO_DYNAMIC_RELOC (info, eh)); - /* Prior to adjust_dynamic_symbol, non_got_ref set means that - check_relocs set up some dyn_relocs for this symbol. - The !non_got_ref term here is saying that if we didn't have - any dyn_relocs set up by check_relocs, then we don't want - relocate_section looking for them. - FIXME: Get rid of the inversion, so non_got_ref set after - dyn_relocs means we do have dyn_relocs. */ - eh->non_got_ref = local || !eh->non_got_ref; + /* Arrange to discard dyn_relocs if we've decided that a + function symbol is local. */ + if (local) + eh->non_got_ref = 0; /* If the symbol is used by a plabel, we must allocate a PLT slot. The refcounts are not reliable when it has been hidden since @@ -1773,24 +1766,17 @@ elf32_hppa_adjust_dynamic_symbol (struct bfd_link_info *info, /* If there are no references to this symbol that do not use the GOT, we don't need to generate a copy reloc. */ if (!eh->non_got_ref) - { - eh->non_got_ref = 1; - return TRUE; - } + return TRUE; /* If -z nocopyreloc was given, we won't generate them either. */ if (info->nocopyreloc) - { - eh->non_got_ref = 0; - return TRUE; - } + return TRUE; if (ELIMINATE_COPY_RELOCS && !readonly_dynrelocs (eh)) { /* If we didn't find any dynamic relocs in read-only sections, then we'll be keeping the dynamic relocs and avoiding the copy reloc. */ - eh->non_got_ref = 0; return TRUE; } @@ -1827,6 +1813,8 @@ elf32_hppa_adjust_dynamic_symbol (struct bfd_link_info *info, eh->needs_copy = 1; } + /* We no longer want dyn_relocs. */ + eh->non_got_ref = 0; return _bfd_elf_adjust_dynamic_copy (info, eh, sec); } @@ -2011,8 +1999,17 @@ allocate_dynrelocs (struct elf_link_hash_entry *eh, void *inf) if (!htab->etab.dynamic_sections_created) hh->dyn_relocs = NULL; + /* Discard relocs on undefined syms with non-default visibility. */ + else if ((eh->root.type == bfd_link_hash_undefined + && ELF_ST_VISIBILITY (eh->other) != STV_DEFAULT) + || UNDEFWEAK_NO_DYNAMIC_RELOC (info, eh)) + hh->dyn_relocs = NULL; + if (hh->dyn_relocs == NULL) - return TRUE; + { + eh->non_got_ref = 0; + return TRUE; + } /* If this is a -Bsymbolic shared link, then we need to discard all space allocated for dynamic pc-relative relocs against symbols @@ -2021,14 +2018,8 @@ 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 - && ELF_ST_VISIBILITY (eh->other) != STV_DEFAULT) - || UNDEFWEAK_NO_DYNAMIC_RELOC (info, eh)) - hh->dyn_relocs = NULL; - #if RELATIVE_DYNRELOCS - else if (SYMBOL_CALLS_LOCAL (info, eh)) + if (SYMBOL_CALLS_LOCAL (info, eh)) { struct elf32_hppa_dyn_reloc_entry **hdh_pp; @@ -2056,17 +2047,25 @@ allocate_dynrelocs (struct elf_link_hash_entry *eh, void *inf) symbols which turn out to need copy relocs or are not dynamic. */ - if (!eh->non_got_ref - && !eh->def_regular) + if (eh->dynamic_adjusted + && eh->non_got_ref + && !eh->def_regular + && !ELF_COMMON_DEF_P (eh)) { if (!ensure_undef_dynamic (info, eh)) return FALSE; if (eh->dynindx == -1) - hh->dyn_relocs = NULL; + { + eh->non_got_ref = 0; + hh->dyn_relocs = NULL; + } } else - hh->dyn_relocs = NULL; + { + eh->non_got_ref = 0; + hh->dyn_relocs = NULL; + } } /* Finally, allocate space. */ @@ -3913,9 +3912,7 @@ elf32_hppa_relocate_section (bfd *output_bfd, || (ELIMINATE_COPY_RELOCS && !bfd_link_pic (info) && hh != NULL - && hh->eh.dynindx != -1 - && !hh->eh.non_got_ref - && !hh->eh.def_regular)) + && hh->eh.non_got_ref)) { Elf_Internal_Rela outrel; bfd_boolean skip; diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c index 40fc1fc47a0..f68a7a4e76b 100644 --- a/bfd/elf32-ppc.c +++ b/bfd/elf32-ppc.c @@ -5474,6 +5474,36 @@ ppc_elf_adjust_dynamic_symbol (struct bfd_link_info *info, || h->type == STT_GNU_IFUNC || h->needs_plt) { + /* Prior to adjust_dynamic_symbol, non_got_ref set means that + we might need to generate a copy reloc for this symbol. + After adjust_dynamic_symbol, non_got_ref is only relevant for + non-pic and means that the symbol might have dynamic + relocations. If it is clear then dyn_relocs for this symbol + should be discarded; We either want the symbol to remain + undefined, or we have a local definition of some sort. The + "local definition" for non-function symbols may be due to + creating a local definition in .dynbss, and for function + symbols, defining the symbol on the PLT call stub code. */ + bfd_boolean local = (SYMBOL_CALLS_LOCAL (info, h) + || UNDEFWEAK_NO_DYNAMIC_RELOC (info, h)); + /* Arrange to discard dyn_relocs if we've decided that a + function symbol is local. It might be possible to discard + dyn_relocs here, but when a symbol has a weakdef they have + been transferred to the weakdef symbol for the benefit of + readonly_dynrelocs. (See ppc_elf_copy_indirect_symbol.) + Not only would we need to handle weakdefs here, but also in + allocate_dynrelocs and relocate_section. The latter is + impossible since the weakdef field has been overwritten by + that time. In relocate_section we need a proxy for + dyn_relocs and non_got_ref is that proxy. + Note that function symbols are not supposed to have weakdefs, + but since symbols may not be correctly typed we handle them + here. */ + h->non_got_ref = (h->u.weakdef != NULL + ? h->u.weakdef->non_got_ref + : !local && (((struct ppc_elf_link_hash_entry *) h) + ->dyn_relocs != NULL)); + /* Clear procedure linkage table information for any symbol that won't need a .plt entry. */ struct plt_entry *ent; @@ -5481,9 +5511,7 @@ ppc_elf_adjust_dynamic_symbol (struct bfd_link_info *info, if (ent->plt.refcount > 0) break; if (ent == NULL - || (h->type != STT_GNU_IFUNC - && (SYMBOL_CALLS_LOCAL (info, h) - || UNDEFWEAK_NO_DYNAMIC_RELOC (info, h)))) + || (h->type != STT_GNU_IFUNC && local)) { /* A PLT entry is not required/allowed when: @@ -5498,16 +5526,6 @@ ppc_elf_adjust_dynamic_symbol (struct bfd_link_info *info, h->plt.plist = NULL; h->needs_plt = 0; h->pointer_equality_needed = 0; - /* After adjust_dynamic_symbol, non_got_ref set in the - non-pic case means that dyn_relocs for this symbol should - be discarded. We either want the symbol to remain - undefined, or we have a local definition of some sort. - The "local definition" for non-function symbols may be - due to creating a local definition in .dynbss, and for - function symbols, defining the symbol on the PLT call - stub code. Set non_got_ref here to ensure undef weaks - stay undefined. */ - h->non_got_ref = 1; } else { @@ -5529,13 +5547,15 @@ ppc_elf_adjust_dynamic_symbol (struct bfd_link_info *info, && !readonly_dynrelocs (h)) { h->pointer_equality_needed = 0; - /* Say that we do want dynamic relocs. */ - h->non_got_ref = 0; /* If we haven't seen a branch reloc then we don't need a plt entry. */ if (!h->needs_plt) h->plt.plist = NULL; } + else + /* We are going to be defining the function symbol on the + plt stub, so no dyn_relocs needed when non-pic. */ + h->non_got_ref = 0; } h->protected_def = 0; /* Function symbols can't have copy relocs. */ @@ -5591,16 +5611,12 @@ ppc_elf_adjust_dynamic_symbol (struct bfd_link_info *info, && htab->params->pic_fixup == 0 && info->disable_target_specific_optimizations <= 1) htab->params->pic_fixup = 1; - h->non_got_ref = 0; return TRUE; } /* If -z nocopyreloc was given, we won't generate them either. */ if (info->nocopyreloc) - { - h->non_got_ref = 0; - return TRUE; - } + return TRUE; /* If we didn't find any dynamic relocs in read-only sections, then we'll be keeping the dynamic relocs and avoiding the copy reloc. @@ -5613,10 +5629,7 @@ ppc_elf_adjust_dynamic_symbol (struct bfd_link_info *info, && !htab->is_vxworks && !h->def_regular && !readonly_dynrelocs (h)) - { - h->non_got_ref = 0; - return TRUE; - } + return TRUE; /* We must allocate the symbol in our .dynbss section, which will become part of the .bss section of the executable. There will be @@ -5658,6 +5671,8 @@ ppc_elf_adjust_dynamic_symbol (struct bfd_link_info *info, h->needs_copy = 1; } + /* We no longer want dyn_relocs. */ + h->non_got_ref = 0; return _bfd_elf_adjust_dynamic_copy (info, h, s); } @@ -5886,8 +5901,18 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) && h->type != STT_GNU_IFUNC) eh->dyn_relocs = NULL; + /* Discard relocs on undefined symbols that must be local. */ + else if (h->root.type == bfd_link_hash_undefined + && ELF_ST_VISIBILITY (h->other) != STV_DEFAULT) + eh->dyn_relocs = NULL; + + /* Also discard relocs on undefined weak syms with non-default + visibility, or when dynamic_undefined_weak says so. */ + else if (UNDEFWEAK_NO_DYNAMIC_RELOC (info, h)) + eh->dyn_relocs = NULL; + if (eh->dyn_relocs == NULL) - ; + h->non_got_ref = 0; /* In the shared -Bsymbolic case, discard space allocated for dynamic pc-relative relocs against symbols which turn out to be @@ -5896,23 +5921,13 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) changes. */ else if (bfd_link_pic (info)) { - /* Discard relocs on undefined symbols that must be local. */ - if (h->root.type == bfd_link_hash_undefined - && ELF_ST_VISIBILITY (h->other) != STV_DEFAULT) - eh->dyn_relocs = NULL; - - /* Also discard relocs on undefined weak syms with non-default - visibility, or when dynamic_undefined_weak says so. */ - else if (UNDEFWEAK_NO_DYNAMIC_RELOC (info, h)) - eh->dyn_relocs = NULL; - /* Relocs that use pc_count are those that appear on a call insn, or certain REL relocs (see must_be_dyn_reloc) that can be generated via assembly. We want calls to protected symbols to resolve directly to the function rather than going via the plt. If people want function pointer comparisons to work as expected then they should avoid writing weird assembly. */ - else if (SYMBOL_CALLS_LOCAL (info, h)) + if (SYMBOL_CALLS_LOCAL (info, h)) { struct elf_dyn_relocs **pp; @@ -5952,8 +5967,10 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) /* For the non-pic case, discard space for relocs against symbols which turn out to need copy relocs or are not dynamic. */ - if (!h->non_got_ref + if (h->dynamic_adjusted + && h->non_got_ref && !h->def_regular + && !ELF_COMMON_DEF_P (h) && !(h->protected_def && eh->has_addr16_ha && eh->has_addr16_lo @@ -5964,10 +5981,16 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) return FALSE; if (h->dynindx == -1) - eh->dyn_relocs = NULL; + { + h->non_got_ref = 0; + eh->dyn_relocs = NULL; + } } else - eh->dyn_relocs = NULL; + { + h->non_got_ref = 0; + eh->dyn_relocs = NULL; + } } /* Allocate space. */ @@ -8743,13 +8766,7 @@ ppc_elf_relocate_section (bfd *output_bfd, || (ELIMINATE_COPY_RELOCS && !bfd_link_pic (info) && h != NULL - && h->dynindx != -1 - && !h->non_got_ref - && !h->def_regular - && !(h->protected_def - && ppc_elf_hash_entry (h)->has_addr16_ha - && ppc_elf_hash_entry (h)->has_addr16_lo - && htab->params->pic_fixup > 0))) + && h->non_got_ref)) { int skip; bfd_byte *loc; diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c index 1cf79641272..181bbdc56df 100644 --- a/bfd/elf64-ppc.c +++ b/bfd/elf64-ppc.c @@ -7177,6 +7177,23 @@ ppc64_elf_adjust_dynamic_symbol (struct bfd_link_info *info, || h->type == STT_GNU_IFUNC || h->needs_plt) { + bfd_boolean local = (((struct ppc_link_hash_entry *) h)->save_res + || SYMBOL_CALLS_LOCAL (info, h) + || UNDEFWEAK_NO_DYNAMIC_RELOC (info, h)); + /* Discard dyn_relocs when non-pic if we've decided that a + function symbol is local and not an ifunc. We keep dynamic + relocs for ifuncs when local rather than always emitting a + plt call stub for them and defining the symbol on the call + stub. We can't do that for ELFv1 anyway (a function symbol + is defined on a descriptor, not code) and it can be faster at + run-time due to not needing to bounce through a stub. The + dyn_relocs for ifuncs will be applied even in a static + executable. */ + if (!bfd_link_pic (info) + && h->type != STT_GNU_IFUNC + && local) + ((struct ppc_link_hash_entry *) h)->dyn_relocs = NULL; + /* Clear procedure linkage table information for any symbol that won't need a .plt entry. */ struct plt_entry *ent; @@ -7184,24 +7201,11 @@ ppc64_elf_adjust_dynamic_symbol (struct bfd_link_info *info, if (ent->plt.refcount > 0) break; if (ent == NULL - || (h->type != STT_GNU_IFUNC - && (SYMBOL_CALLS_LOCAL (info, h) - || UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))) - || ((struct ppc_link_hash_entry *) h)->save_res) + || (h->type != STT_GNU_IFUNC && local)) { h->plt.plist = NULL; h->needs_plt = 0; h->pointer_equality_needed = 0; - /* After adjust_dynamic_symbol, non_got_ref set in the - non-pic case means that dyn_relocs for this symbol should - be discarded. We either want the symbol to remain - undefined, or we have a local definition of some sort. - The "local definition" for non-function symbols may be - due to creating a local definition in .dynbss, and for - ELFv2 function symbols, defining the symbol on the PLT - call stub code. Set non_got_ref here to ensure undef - weaks stay undefined. */ - h->non_got_ref = 1; } else if (abiversion (info->output_bfd) >= 2) { @@ -7212,16 +7216,20 @@ ppc64_elf_adjust_dynamic_symbol (struct bfd_link_info *info, relocs is that calling via a global entry stub costs a few more instructions, and pointer_equality_needed causes extra work in ld.so when resolving these symbols. */ - if (global_entry_stub (h) - && !alias_readonly_dynrelocs (h)) + if (global_entry_stub (h)) { - h->pointer_equality_needed = 0; - /* Say that we do want dynamic relocs. */ - h->non_got_ref = 0; - /* If we haven't seen a branch reloc then we don't need - a plt entry. */ - if (!h->needs_plt) - h->plt.plist = NULL; + if (!alias_readonly_dynrelocs (h)) + { + h->pointer_equality_needed = 0; + /* If we haven't seen a branch reloc then we don't need + a plt entry. */ + if (!h->needs_plt) + h->plt.plist = NULL; + } + else if (!bfd_link_pic (info)) + /* We are going to be defining the function symbol on the + plt stub, so no dyn_relocs needed when non-pic. */ + ((struct ppc_link_hash_entry *) h)->dyn_relocs = NULL; } /* ELFv2 function symbols can't have copy relocs. */ @@ -7234,7 +7242,6 @@ ppc64_elf_adjust_dynamic_symbol (struct bfd_link_info *info, plt entry. */ h->plt.plist = NULL; h->pointer_equality_needed = 0; - h->non_got_ref = 0; return TRUE; } } @@ -7282,10 +7289,7 @@ ppc64_elf_adjust_dynamic_symbol (struct bfd_link_info *info, definition for the variable. Text relocations are preferable to an incorrect program. */ || h->protected_def) - { - h->non_got_ref = 0; - return TRUE; - } + return TRUE; if (h->plt.plist != NULL) { @@ -7333,6 +7337,8 @@ ppc64_elf_adjust_dynamic_symbol (struct bfd_link_info *info, h->needs_copy = 1; } + /* We no longer want dyn_relocs. */ + ((struct ppc_link_hash_entry *) h)->dyn_relocs = NULL; return _bfd_elf_adjust_dynamic_copy (info, h, s); } @@ -9724,6 +9730,11 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) && h->type != STT_GNU_IFUNC) eh->dyn_relocs = NULL; + /* Discard relocs on undefined symbols that must be local. */ + else if (h->root.type == bfd_link_hash_undefined + && ELF_ST_VISIBILITY (h->other) != STV_DEFAULT) + eh->dyn_relocs = NULL; + /* Also discard relocs on undefined weak syms with non-default visibility, or when dynamic_undefined_weak says so. */ else if (UNDEFWEAK_NO_DYNAMIC_RELOC (info, h)) @@ -9768,36 +9779,14 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) return FALSE; } } - else if (h->type == STT_GNU_IFUNC) - { - /* A plt entry is always created when making direct calls to - an ifunc, even when building a static executable, but - that doesn't cover all cases. We may have only an ifunc - initialised function pointer for a given ifunc symbol. - - For ELFv2, dynamic relocations are not required when - generating a global entry PLT stub. */ - if (abiversion (info->output_bfd) >= 2) - { - if (global_entry_stub (h)) - eh->dyn_relocs = NULL; - } - - /* For ELFv1 we have function descriptors. Descriptors need - to be treated like PLT entries and thus have dynamic - relocations. One exception is when the function - descriptor is copied into .dynbss (which should only - happen with ancient versions of gcc). */ - else if (h->needs_copy) - eh->dyn_relocs = NULL; - } - else if (ELIMINATE_COPY_RELOCS) + else if (ELIMINATE_COPY_RELOCS && h->type != STT_GNU_IFUNC) { /* For the non-pic case, discard space for relocs against symbols which turn out to need copy relocs or are not dynamic. */ - if (!h->non_got_ref - && !h->def_regular) + if (h->dynamic_adjusted + && !h->def_regular + && !ELF_COMMON_DEF_P (h)) { /* Make sure this symbol is output as a dynamic symbol. */ if (!ensure_undef_dynamic (info, h))