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.
This commit is contained in:
parent
d956390245
commit
529fe20eeb
@ -1,3 +1,26 @@
|
||||
2017-11-12 Alan Modra <amodra@gmail.com>
|
||||
|
||||
* 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 <djordje.todorovic@rt-rk.com>
|
||||
|
||||
* elf32-mips.c (elf32_mips_grok_psinfo): Extract core->pid.
|
||||
|
@ -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;
|
||||
|
109
bfd/elf32-ppc.c
109
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;
|
||||
|
@ -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))
|
||||
|
Loading…
x
Reference in New Issue
Block a user