diff options
author | Alan Modra <amodra@gmail.com> | 2017-06-21 15:03:25 +0930 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2017-06-21 22:45:15 +0930 |
commit | 6e1816be66892d06e1a983f08407135fa7f7fc17 (patch) | |
tree | 0a2d291a1e35252d38fee88b05a438d43b07311b /bfd | |
parent | 81209eff905bf76a01bbc3dc07b8973d1d0cdaad (diff) | |
download | gdb-6e1816be66892d06e1a983f08407135fa7f7fc17.zip gdb-6e1816be66892d06e1a983f08407135fa7f7fc17.tar.gz gdb-6e1816be66892d06e1a983f08407135fa7f7fc17.tar.bz2 |
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.
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/ChangeLog | 7 | ||||
-rw-r--r-- | bfd/elf64-ppc.c | 33 |
2 files changed, 25 insertions, 15 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 1d9ba02..7b2927f 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -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> PR binutils/21645 diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c index 42abb96..319d58f 100644 --- a/bfd/elf64-ppc.c +++ b/bfd/elf64-ppc.c @@ -12634,18 +12634,19 @@ ppc64_elf_size_stubs (struct bfd_link_info *info) if (stub_type == ppc_stub_plt_call) { - if (irela + 1 < irelaend - && irela[1].r_offset == irela->r_offset + 4 - && ELF64_R_TYPE (irela[1].r_info) == R_PPC64_TOCSAVE) + 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 + && (ELF64_R_TYPE (irela[1].r_info) + == R_PPC64_TOCSAVE)) { if (!tocsave_find (htab, INSERT, &local_syms, irela + 1, input_bfd)) 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 stub_type = ppc_stub_plt_call_r2save; } @@ -14212,10 +14213,19 @@ ppc64_elf_relocate_section (bfd *output_bfd, { 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 branch and link followed by a nop. The nop is 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; @@ -14237,13 +14247,6 @@ ppc64_elf_relocate_section (bfd *output_bfd, { /* 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 bfd_put_32 (input_bfd, LD_R2_0R1 + STK_TOC (htab), |