mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-22 11:00:01 +08:00
PowerPC64 localentry:0 plt calls
These don't need a following nop. Also, a localentry:0 plt call marked with an R_PPC64_TOCSAVE reloc should ignore the tocsave. There's no need to save r2 in the prologue for such calls. * elf64-ppc.c (ppc64_elf_size_stubs): Test for localentry:0 plt calls before tocsave calls. (ppc64_elf_relocate_section): Allow localentry:0 plt calls without following nop.
This commit is contained in:
@ -1,3 +1,10 @@
|
|||||||
|
2017-06-21 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
|
* elf64-ppc.c (ppc64_elf_size_stubs): Test for localentry:0 plt
|
||||||
|
calls before tocsave calls.
|
||||||
|
(ppc64_elf_relocate_section): Allow localentry:0 plt calls without
|
||||||
|
following nop.
|
||||||
|
|
||||||
2017-06-21 Nick Clifton <nickc@redhat.com>
|
2017-06-21 Nick Clifton <nickc@redhat.com>
|
||||||
|
|
||||||
PR binutils/21645
|
PR binutils/21645
|
||||||
|
@ -12634,18 +12634,19 @@ ppc64_elf_size_stubs (struct bfd_link_info *info)
|
|||||||
|
|
||||||
if (stub_type == ppc_stub_plt_call)
|
if (stub_type == ppc_stub_plt_call)
|
||||||
{
|
{
|
||||||
if (irela + 1 < irelaend
|
if (!htab->opd_abi
|
||||||
|
&& htab->params->plt_localentry0 != 0
|
||||||
|
&& is_elfv2_localentry0 (&hash->elf))
|
||||||
|
htab->has_plt_localentry0 = 1;
|
||||||
|
else if (irela + 1 < irelaend
|
||||||
&& irela[1].r_offset == irela->r_offset + 4
|
&& irela[1].r_offset == irela->r_offset + 4
|
||||||
&& ELF64_R_TYPE (irela[1].r_info) == R_PPC64_TOCSAVE)
|
&& (ELF64_R_TYPE (irela[1].r_info)
|
||||||
|
== R_PPC64_TOCSAVE))
|
||||||
{
|
{
|
||||||
if (!tocsave_find (htab, INSERT,
|
if (!tocsave_find (htab, INSERT,
|
||||||
&local_syms, irela + 1, input_bfd))
|
&local_syms, irela + 1, input_bfd))
|
||||||
goto error_ret_free_internal;
|
goto error_ret_free_internal;
|
||||||
}
|
}
|
||||||
else if (!htab->opd_abi
|
|
||||||
&& htab->params->plt_localentry0 != 0
|
|
||||||
&& is_elfv2_localentry0 (&hash->elf))
|
|
||||||
htab->has_plt_localentry0 = 1;
|
|
||||||
else
|
else
|
||||||
stub_type = ppc_stub_plt_call_r2save;
|
stub_type = ppc_stub_plt_call_r2save;
|
||||||
}
|
}
|
||||||
@ -14212,10 +14213,19 @@ ppc64_elf_relocate_section (bfd *output_bfd,
|
|||||||
{
|
{
|
||||||
bfd_boolean can_plt_call = FALSE;
|
bfd_boolean can_plt_call = FALSE;
|
||||||
|
|
||||||
|
if (stub_entry->stub_type == ppc_stub_plt_call
|
||||||
|
&& !htab->opd_abi
|
||||||
|
&& htab->params->plt_localentry0 != 0
|
||||||
|
&& is_elfv2_localentry0 (&h->elf))
|
||||||
|
{
|
||||||
|
/* The function doesn't use or change r2. */
|
||||||
|
can_plt_call = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/* All of these stubs may modify r2, so there must be a
|
/* All of these stubs may modify r2, so there must be a
|
||||||
branch and link followed by a nop. The nop is
|
branch and link followed by a nop. The nop is
|
||||||
replaced by an insn to restore r2. */
|
replaced by an insn to restore r2. */
|
||||||
if (rel->r_offset + 8 <= input_section->size)
|
else if (rel->r_offset + 8 <= input_section->size)
|
||||||
{
|
{
|
||||||
unsigned long br;
|
unsigned long br;
|
||||||
|
|
||||||
@ -14237,13 +14247,6 @@ ppc64_elf_relocate_section (bfd *output_bfd,
|
|||||||
{
|
{
|
||||||
/* Special stub used, leave nop alone. */
|
/* Special stub used, leave nop alone. */
|
||||||
}
|
}
|
||||||
else if (stub_entry->stub_type == ppc_stub_plt_call
|
|
||||||
&& !htab->opd_abi
|
|
||||||
&& htab->params->plt_localentry0 != 0
|
|
||||||
&& is_elfv2_localentry0 (&h->elf))
|
|
||||||
{
|
|
||||||
/* The function doesn't use or change r2. */
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
bfd_put_32 (input_bfd,
|
bfd_put_32 (input_bfd,
|
||||||
LD_R2_0R1 + STK_TOC (htab),
|
LD_R2_0R1 + STK_TOC (htab),
|
||||||
|
Reference in New Issue
Block a user