PowerPC64: Downgrade ifunc with textrel error to a warning
authorAlan Modra <amodra@gmail.com>
Tue, 9 Jun 2020 00:02:10 +0000 (09:32 +0930)
committerAlan Modra <amodra@gmail.com>
Tue, 9 Jun 2020 00:07:23 +0000 (09:37 +0930)
For ppc64 I set flags when recording the dynamic relocation rather
than when allocating space.  That allows you to distinguish three
cases:
1) The dynamic ifunc relocation is in an executable and will always be
   to an ifunc resolver in the executable.
2) The dynamic ifunc relocation is in a shared library which provides
   an ifunc resolver, but that may be overridden at runtime to use a
   resolver in another binary.
3) The dynamic ifunc relocation is not to a locally defined ifunc
   resolver.

Case (3) won't cause a segfault trying to run resolver code that is
non-exec on older glibc.

I made case (1) an error for ppc64, but since newer glibc ld.so does
allow running ifunc resolvers when segments are writable I suppose I
should downgrade that to a warning like case (2).

* elf64-ppc.c (struct ppc_link_hash_table): Delete
maybe_local_ifunc_resolver field.
(build_global_entry_stubs_and_plt): Set local_ifunc_resolver in
cases where maybe_local_ifunc_resolver was set.
(ppc64_elf_relocate_section): Likewise.
(ppc64_elf_finish_dynamic_sections): Downgrade ifunc with textrel
error to a warning.

bfd/ChangeLog
bfd/elf64-ppc.c

index 7765dd363592687267218986575b6c0cb3913bc9..146045b0b87f38035f70f130f900fe9088233b3f 100644 (file)
@@ -1,3 +1,13 @@
+2020-06-09  Alan Modra  <amodra@gmail.com>
+
+       * elf64-ppc.c (struct ppc_link_hash_table): Delete
+       maybe_local_ifunc_resolver field.
+       (build_global_entry_stubs_and_plt): Set local_ifunc_resolver in
+       cases where maybe_local_ifunc_resolver was set.
+       (ppc64_elf_relocate_section): Likewise.
+       (ppc64_elf_finish_dynamic_sections): Downgrade ifunc with textrel
+       error to a warning.
+
 2020-06-08  H.J. Lu  <hongjiu.lu@intel.com>
 
        * elf-bfd.h (elf_link_hash_entry): Add tlsdesc_plt and
index e28546deb5421ed5ba6a44d2b980576f3e1b983b..9868f6a755a847fb7e1e20141196790d9d08bafb 100644 (file)
@@ -3242,7 +3242,6 @@ struct ppc_link_hash_table
   /* Whether there exist local gnu indirect function resolvers,
      referenced by dynamic relocations.  */
   unsigned int local_ifunc_resolver:1;
-  unsigned int maybe_local_ifunc_resolver:1;
 
   /* Whether plt calls for ELFv2 localentry:0 funcs have been optimized.  */
   unsigned int has_plt_localentry0:1;
@@ -13935,7 +13934,7 @@ build_global_entry_stubs_and_plt (struct elf_link_hash_entry *h, void *inf)
                   + ((ent->plt.offset - PLT_INITIAL_ENTRY_SIZE (htab))
                      / PLT_ENTRY_SIZE (htab) * sizeof (Elf64_External_Rela)));
            if (h->type == STT_GNU_IFUNC && is_static_defined (h))
-             htab->maybe_local_ifunc_resolver = 1;
+             htab->local_ifunc_resolver = 1;
            bfd_elf64_swap_reloca_out (info->output_bfd, &rela, loc);
          }
       }
@@ -16103,10 +16102,8 @@ ppc64_elf_relocate_section (bfd *output_bfd,
                if (ifunc)
                  {
                    relgot = htab->elf.irelplt;
-                   if (indx == 0)
+                   if (indx == 0 || is_static_defined (&h->elf))
                      htab->local_ifunc_resolver = 1;
-                   else if (is_static_defined (&h->elf))
-                     htab->maybe_local_ifunc_resolver = 1;
                  }
                else if (indx != 0
                         || (bfd_link_pic (info)
@@ -16635,10 +16632,8 @@ ppc64_elf_relocate_section (bfd *output_bfd,
                  : ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
                {
                  sreloc = htab->elf.irelplt;
-                 if (indx == 0)
+                 if (indx == 0 || is_static_defined (&h->elf))
                    htab->local_ifunc_resolver = 1;
-                 else if (is_static_defined (&h->elf))
-                   htab->maybe_local_ifunc_resolver = 1;
                }
              if (sreloc == NULL)
                abort ();
@@ -17403,10 +17398,6 @@ ppc64_elf_finish_dynamic_sections (bfd *output_bfd,
 
            case DT_TEXTREL:
              if (htab->local_ifunc_resolver)
-               info->callbacks->einfo
-                 (_("%X%P: text relocations and GNU indirect "
-                    "functions will result in a segfault at runtime\n"));
-             else if (htab->maybe_local_ifunc_resolver)
                info->callbacks->einfo
                  (_("%P: warning: text relocations and GNU indirect "
                     "functions may result in a segfault at runtime\n"));