From e81b4c933c1b88e29f4b27627dd9ea0bf9189944 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Sun, 5 Aug 2018 19:44:03 +0930 Subject: [PATCH 1/1] __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. --- bfd/ChangeLog | 8 ++++++++ bfd/elf64-ppc.c | 13 +++++++------ 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index b12e02421c..b8fd5be12e 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,11 @@ +2018-08-07 Alan Modra + + * 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. + 2018-08-06 Claudiu Zissulescu * elf32-arc.c (arc_elf_merge_private_bfd_data): Complain about diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c index 008d352b24..5e20bbd971 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) -- 2.34.1