mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-24 04:00:07 +08:00
PowerPC64 dynamic symbol tweaks
In check_relocs, bfd_link_pic true means ld is producing a shared library or a position independent executable. !bfd_link_pic means a fixed position (ie. static) executable since the relocatable linking case is excluded. So it is appropriate to continue using bfd_link_pic when testing whether non-pcrelative relocations should be dynamic, and !bfd_link_pic for the special case of ifunc in static executables. However, -Bsymbolic shouldn't affect PIEs (they are executables so none of their symbols should be overridden) and PIEs can support copy relocations, thus bfd_link_executable should be used in those cases rather than bfd_link_pic. I've also removed the test of ELIMINATE_COPY_RELOCS in check_relocs. We can sort out what to do regarding copy relocs later, which allows the code in check_relocs to be simplified. * elf64-ppc.c (ppc64_elf_check_relocs): Use bfd_link_executable in choosing between different actions for shared library and non-shared library cases. Delete ELIMINATE_COPY_RELOCS test. (dec_dynrel_count): Likewise. Account for ifunc special case. (ppc64_elf_adjust_dynamic_symbol): Copy relocs are for executables, not non-pic. (allocate_dynrelocs): Comment fixes. Delete ELIMINATE_COPY_RELOCS test.
This commit is contained in:
@ -1,3 +1,14 @@
|
|||||||
|
2019-09-23 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
|
* elf64-ppc.c (ppc64_elf_check_relocs): Use bfd_link_executable
|
||||||
|
in choosing between different actions for shared library and
|
||||||
|
non-shared library cases. Delete ELIMINATE_COPY_RELOCS test.
|
||||||
|
(dec_dynrel_count): Likewise. Account for ifunc special case.
|
||||||
|
(ppc64_elf_adjust_dynamic_symbol): Copy relocs are for executables,
|
||||||
|
not non-pic.
|
||||||
|
(allocate_dynrelocs): Comment fixes. Delete ELIMINATE_COPY_RELOCS
|
||||||
|
test.
|
||||||
|
|
||||||
2019-09-23 Alan Modra <amodra@gmail.com>
|
2019-09-23 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
* Makefile.am (SOURCE_HFILES): Add many missing .h files.
|
* Makefile.am (SOURCE_HFILES): Add many missing .h files.
|
||||||
|
@ -4836,7 +4836,7 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
|||||||
case R_PPC64_TOC16_HA:
|
case R_PPC64_TOC16_HA:
|
||||||
case R_PPC64_TOC16_LO_DS:
|
case R_PPC64_TOC16_LO_DS:
|
||||||
sec->has_toc_reloc = 1;
|
sec->has_toc_reloc = 1;
|
||||||
if (h != NULL && !bfd_link_pic (info))
|
if (h != NULL && bfd_link_executable (info))
|
||||||
{
|
{
|
||||||
/* We may need a copy reloc. */
|
/* We may need a copy reloc. */
|
||||||
h->non_got_ref = 1;
|
h->non_got_ref = 1;
|
||||||
@ -5076,7 +5076,7 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
|||||||
case R_PPC64_UADDR32:
|
case R_PPC64_UADDR32:
|
||||||
case R_PPC64_UADDR64:
|
case R_PPC64_UADDR64:
|
||||||
case R_PPC64_TOC:
|
case R_PPC64_TOC:
|
||||||
if (h != NULL && !bfd_link_pic (info))
|
if (h != NULL && bfd_link_executable (info))
|
||||||
/* We may need a copy reloc. */
|
/* We may need a copy reloc. */
|
||||||
h->non_got_ref = 1;
|
h->non_got_ref = 1;
|
||||||
|
|
||||||
@ -5106,17 +5106,14 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
|||||||
dynamic library if we manage to avoid copy relocs for the
|
dynamic library if we manage to avoid copy relocs for the
|
||||||
symbol. */
|
symbol. */
|
||||||
dodyn:
|
dodyn:
|
||||||
if ((bfd_link_pic (info)
|
if ((h != NULL
|
||||||
&& (must_be_dyn_reloc (info, r_type)
|
|
||||||
|| (h != NULL
|
|
||||||
&& (!SYMBOLIC_BIND (info, h)
|
|
||||||
|| h->root.type == bfd_link_hash_defweak
|
|
||||||
|| !h->def_regular))))
|
|
||||||
|| (ELIMINATE_COPY_RELOCS
|
|
||||||
&& !bfd_link_pic (info)
|
|
||||||
&& h != NULL
|
|
||||||
&& (h->root.type == bfd_link_hash_defweak
|
&& (h->root.type == bfd_link_hash_defweak
|
||||||
|| !h->def_regular))
|
|| !h->def_regular))
|
||||||
|
|| (h != NULL
|
||||||
|
&& !bfd_link_executable (info)
|
||||||
|
&& !SYMBOLIC_BIND (info, h))
|
||||||
|
|| (bfd_link_pic (info)
|
||||||
|
&& must_be_dyn_reloc (info, r_type))
|
||||||
|| (!bfd_link_pic (info)
|
|| (!bfd_link_pic (info)
|
||||||
&& ifunc != NULL))
|
&& ifunc != NULL))
|
||||||
{
|
{
|
||||||
@ -6425,7 +6422,7 @@ ppc64_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
|
|||||||
only references to the symbol are via the global offset table.
|
only references to the symbol are via the global offset table.
|
||||||
For such cases we need not do anything here; the relocations will
|
For such cases we need not do anything here; the relocations will
|
||||||
be handled correctly by relocate_section. */
|
be handled correctly by relocate_section. */
|
||||||
if (bfd_link_pic (info))
|
if (!bfd_link_executable (info))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
/* If there are no references to this symbol that do not use the
|
/* If there are no references to this symbol that do not use the
|
||||||
@ -6904,17 +6901,18 @@ dec_dynrel_count (bfd_vma r_info,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((bfd_link_pic (info)
|
if ((h != NULL
|
||||||
&& (must_be_dyn_reloc (info, r_type)
|
|
||||||
|| (h != NULL
|
|
||||||
&& (!SYMBOLIC_BIND (info, h)
|
|
||||||
|| h->root.type == bfd_link_hash_defweak
|
|
||||||
|| !h->def_regular))))
|
|
||||||
|| (ELIMINATE_COPY_RELOCS
|
|
||||||
&& !bfd_link_pic (info)
|
|
||||||
&& h != NULL
|
|
||||||
&& (h->root.type == bfd_link_hash_defweak
|
&& (h->root.type == bfd_link_hash_defweak
|
||||||
|| !h->def_regular)))
|
|| !h->def_regular))
|
||||||
|
|| (h != NULL
|
||||||
|
&& !bfd_link_executable (info)
|
||||||
|
&& !SYMBOLIC_BIND (info, h))
|
||||||
|
|| (bfd_link_pic (info)
|
||||||
|
&& must_be_dyn_reloc (info, r_type))
|
||||||
|
|| (!bfd_link_pic (info)
|
||||||
|
&& (h != NULL
|
||||||
|
? h->type == STT_GNU_IFUNC
|
||||||
|
: ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)))
|
||||||
;
|
;
|
||||||
else
|
else
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@ -9403,7 +9401,8 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
|
|||||||
for (gent = h->got.glist; gent != NULL; gent = gent->next)
|
for (gent = h->got.glist; gent != NULL; gent = gent->next)
|
||||||
if (!gent->is_indirect)
|
if (!gent->is_indirect)
|
||||||
{
|
{
|
||||||
/* Make sure this symbol is output as a dynamic symbol. */
|
/* Ensure we catch all the cases where this symbol should
|
||||||
|
be made dynamic. */
|
||||||
if (!ensure_undef_dynamic (info, h))
|
if (!ensure_undef_dynamic (info, h))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
@ -9438,7 +9437,6 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
|
|||||||
be defined in regular objects. For the normal shared case,
|
be defined in regular objects. For the normal shared case,
|
||||||
discard space for relocs that have become local due to symbol
|
discard space for relocs that have become local due to symbol
|
||||||
visibility changes. */
|
visibility changes. */
|
||||||
|
|
||||||
if (bfd_link_pic (info))
|
if (bfd_link_pic (info))
|
||||||
{
|
{
|
||||||
/* Relocs that use pc_count are those that appear on a call
|
/* Relocs that use pc_count are those that appear on a call
|
||||||
@ -9463,24 +9461,27 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
|
|||||||
|
|
||||||
if (eh->dyn_relocs != NULL)
|
if (eh->dyn_relocs != NULL)
|
||||||
{
|
{
|
||||||
/* Make sure this symbol is output as a dynamic symbol. */
|
/* Ensure we catch all the cases where this symbol
|
||||||
|
should be made dynamic. */
|
||||||
if (!ensure_undef_dynamic (info, h))
|
if (!ensure_undef_dynamic (info, h))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (ELIMINATE_COPY_RELOCS && h->type != STT_GNU_IFUNC)
|
|
||||||
|
/* For a fixed position executable, discard space for
|
||||||
|
relocs against symbols which are not dynamic. */
|
||||||
|
else if (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->dynamic_adjusted
|
if (h->dynamic_adjusted
|
||||||
&& !h->def_regular
|
&& !h->def_regular
|
||||||
&& !ELF_COMMON_DEF_P (h))
|
&& !ELF_COMMON_DEF_P (h))
|
||||||
{
|
{
|
||||||
/* Make sure this symbol is output as a dynamic symbol. */
|
/* Ensure we catch all the cases where this symbol
|
||||||
|
should be made dynamic. */
|
||||||
if (!ensure_undef_dynamic (info, h))
|
if (!ensure_undef_dynamic (info, h))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
/* But if that didn't work out, discard dynamic relocs. */
|
||||||
if (h->dynindx == -1)
|
if (h->dynindx == -1)
|
||||||
eh->dyn_relocs = NULL;
|
eh->dyn_relocs = NULL;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user