__tls_get_addr_opt stubs and tocsave optimization
authorAlan Modra <amodra@gmail.com>
Sun, 5 Aug 2018 10:14:03 +0000 (19:44 +0930)
committerAlan Modra <amodra@gmail.com>
Tue, 7 Aug 2018 09:13:54 +0000 (18:43 +0930)
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
bfd/elf64-ppc.c

index b12e02421cf6d47a133ceec8a157a53c7c4f8cb2..b8fd5be12eceff2927a5f55ac3402daee78dddbb 100644 (file)
@@ -1,3 +1,11 @@
+2018-08-07  Alan Modra  <amodra@gmail.com>
+
+       * 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  <claziss@synopsys.com>
 
        * elf32-arc.c (arc_elf_merge_private_bfd_data): Complain about
index 008d352b242dd0e81e3109664e11b327c8e974bd..5e20bbd971a6551c7ad5f5612a7e18d5fa1b75ab 100644 (file)
@@ -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)