diff options
author | Alan Modra <amodra@gmail.com> | 2018-08-05 19:44:03 +0930 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2018-08-07 18:43:54 +0930 |
commit | e81b4c933c1b88e29f4b27627dd9ea0bf9189944 (patch) | |
tree | c89195d2bf33cb1a0faf7c5e2afcea1f10d9248d /bfd/elf64-ppc.c | |
parent | 99f8774ccaca5b1bfa4a035c6c705bc7ef47e75f (diff) | |
download | gdb-e81b4c933c1b88e29f4b27627dd9ea0bf9189944.zip gdb-e81b4c933c1b88e29f4b27627dd9ea0bf9189944.tar.gz gdb-e81b4c933c1b88e29f4b27627dd9ea0bf9189944.tar.bz2 |
__tls_get_addr_opt stubs and tocsave optimization
This patch fixes a bug in the handling of the __tls_get_addr_opt
stub. Calls via this stub don't have a toc restoring instruction
following the "bl", and the stub itself doesn't have an initial toc
save instruction. Thus it is incorrect to skip over the first
instruction when a __tls_get_addr call is marked with a tocsave
reloc.
* elf64-ppc.c (ppc64_elf_relocate_section): Don't skip first
instruction of __tls_get_addr_opt stub.
(plt_stub_size): Omit ALWAYS_EMIT_R2SAVE condition when
dealing with __tls_get_addr_opt stub.
(build_tls_get_addr_stub, ppc_size_one_stub): Likewise.
Diffstat (limited to 'bfd/elf64-ppc.c')
-rw-r--r-- | bfd/elf64-ppc.c | 13 |
1 files changed, 7 insertions, 6 deletions
diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c index 008d352..5e20bbd 100644 --- a/bfd/elf64-ppc.c +++ b/bfd/elf64-ppc.c @@ -11027,8 +11027,7 @@ plt_stub_size (struct ppc_link_hash_table *htab, && htab->params->tls_get_addr_opt) { size += 7 * 4; - if (ALWAYS_EMIT_R2SAVE - || stub_entry->stub_type == ppc_stub_plt_call_r2save) + if (stub_entry->stub_type == ppc_stub_plt_call_r2save) size += 6 * 4; } return size; @@ -11273,8 +11272,7 @@ build_tls_get_addr_stub (struct ppc_link_hash_table *htab, bfd_put_32 (obfd, MR_R3_R0, p), p += 4; if (r != NULL) r[0].r_offset += 7 * 4; - if (!ALWAYS_EMIT_R2SAVE - && stub_entry->stub_type != ppc_stub_plt_call_r2save) + if (stub_entry->stub_type != ppc_stub_plt_call_r2save) return build_plt_stub (htab, stub_entry, p, offset, r); bfd_put_32 (obfd, MFLR_R11, p), p += 4; @@ -11928,8 +11926,7 @@ ppc_size_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg) && (stub_entry->h == htab->tls_get_addr_fd || stub_entry->h == htab->tls_get_addr) && htab->params->tls_get_addr_opt - && (ALWAYS_EMIT_R2SAVE - || stub_entry->stub_type == ppc_stub_plt_call_r2save)) + && stub_entry->stub_type == ppc_stub_plt_call_r2save) stub_entry->group->tls_get_addr_opt_bctrl = stub_entry->stub_offset + size - 5 * 4; @@ -15336,6 +15333,10 @@ ppc64_elf_relocate_section (bfd *output_bfd, && ALWAYS_EMIT_R2SAVE) || stub_entry->stub_type == ppc_stub_plt_call_r2save || stub_entry->stub_type == ppc_stub_plt_call_both) + && !(h != NULL + && (h == htab->tls_get_addr_fd + || h == htab->tls_get_addr) + && htab->params->tls_get_addr_opt) && rel + 1 < relend && rel[1].r_offset == rel->r_offset + 4 && ELF64_R_TYPE (rel[1].r_info) == R_PPC64_TOCSAVE) |