+2020-09-24  Alan Modra  <amodra@gmail.com>
+
+       PR 26655
+       * elf64-ppc.c (ppc64_elf_func_desc_adjust): Rename to..
+       (ppc64_elf_edit): Call params->edit.
+       (ppc64_elf_tls_setup): Don't call _bfd_elf_tls_setup.  Return a
+       bfd_boolean.
+       * elf64-ppc.h (struct ppc64_elf_params): Add "edit".
+       (ppc64_elf_tls_setup): Update declaration.
+
 2020-09-21  Alan Modra  <amodra@gmail.com>
 
        PR 26569
 
 #define elf_backend_adjust_dynamic_symbol     ppc64_elf_adjust_dynamic_symbol
 #define elf_backend_hide_symbol                      ppc64_elf_hide_symbol
 #define elf_backend_maybe_function_sym       ppc64_elf_maybe_function_sym
-#define elf_backend_always_size_sections      ppc64_elf_func_desc_adjust
+#define elf_backend_always_size_sections      ppc64_elf_edit
 #define elf_backend_size_dynamic_sections     ppc64_elf_size_dynamic_sections
 #define elf_backend_hash_symbol                      ppc64_elf_hash_symbol
 #define elf_backend_init_index_section       _bfd_elf_init_2_index_sections
   };
 
 /* Called near the start of bfd_elf_size_dynamic_sections.  We use
-   this hook to a) provide some gcc support functions, and b) transfer
-   dynamic linking information gathered so far on function code symbol
-   entries, to their corresponding function descriptor symbol entries.  */
+   this hook to a) run the edit functions in this file, b) provide
+   some gcc support functions, and c) transfer dynamic linking
+   information gathered so far on function code symbol entries, to
+   their corresponding function descriptor symbol entries.  */
 
 static bfd_boolean
-ppc64_elf_func_desc_adjust (bfd *obfd ATTRIBUTE_UNUSED,
-                           struct bfd_link_info *info)
+ppc64_elf_edit (bfd *obfd ATTRIBUTE_UNUSED, struct bfd_link_info *info)
 {
   struct ppc_link_hash_table *htab;
 
   if (htab == NULL)
     return FALSE;
 
+  /* Call back into the linker, which then runs the edit functions.  */
+  htab->params->edit ();
+
   /* Provide any missing _save* and _rest* functions.  */
   if (htab->sfpr != NULL)
     {
   return TRUE;
 }
 
-/* Set htab->tls_get_addr and call the generic ELF tls_setup function.  */
+/* Set htab->tls_get_addr and various other info specific to TLS.
+   This needs to run before dynamic symbols are processed in
+   bfd_elf_size_dynamic_sections.  */
 
-asection *
+bfd_boolean
 ppc64_elf_tls_setup (struct bfd_link_info *info)
 {
   struct ppc_link_hash_table *htab;
 
   htab = ppc_hash_table (info);
   if (htab == NULL)
-    return NULL;
+    return FALSE;
 
   if (abiversion (info->output_bfd) == 1)
     htab->opd_abi = 1;
                      _bfd_elf_strtab_delref (elf_hash_table (info)->dynstr,
                                              opt_fd->dynstr_index);
                      if (!bfd_elf_link_record_dynamic_symbol (info, opt_fd))
-                       return NULL;
+                       return FALSE;
                    }
                  if (tga_fd != NULL)
                    {
       && htab->params->no_tls_get_addr_regsave == -1)
     htab->params->no_tls_get_addr_regsave = 0;
 
-  return _bfd_elf_tls_setup (info->output_bfd, info);
+  return TRUE;
 }
 
 /* Return TRUE iff REL is a branch reloc with a global symbol matching
 
   /* Linker call-backs.  */
   asection * (*add_stub_section) (const char *, asection *);
   void (*layout_sections_again) (void);
+  void (*edit) (void);
 
   /* Maximum size of a group of input sections that can be handled by
      one stub section.  A value of +/-1 indicates the bfd back-end
   (struct bfd_link_info *);
 bfd_boolean ppc64_elf_inline_plt
   (struct bfd_link_info *);
-asection *ppc64_elf_tls_setup
+bfd_boolean ppc64_elf_tls_setup
   (struct bfd_link_info *);
 bfd_boolean ppc64_elf_tls_optimize
   (struct bfd_link_info *);
 
+2020-09-24  Alan Modra  <amodra@gmail.com>
+
+       PR 26655
+       * emultempl/ppc64elf.em (params): Add ppc_edit.
+       (ppc_before_allocation): Split off some edit functions to..
+       (ppc_edit): ..this, new function.
+
 2020-09-22  Frediano Ziglio  <fziglio@redhat.com>
 
        * emultempl/pe.em (set_entry_point): Only use the DLL entry point
 
 
 static asection *ppc_add_stub_section (const char *, asection *);
 static void ppc_layout_sections_again (void);
+static void ppc_edit (void);
 
 static struct ppc64_elf_params params = { NULL,
                                          &ppc_add_stub_section,
                                          &ppc_layout_sections_again,
+                                         &ppc_edit,
                                          1, -1, -1, 0,
                                          ${DEFAULT_PLT_STATIC_CHAIN-0}, -1, 5,
                                          -1, -1, 0, 0, -1, -1, 0};
            einfo (_("%X%P: inline PLT: %E\n"));
        }
 
-      if (ppc64_elf_tls_setup (&link_info)
+      if (!ppc64_elf_tls_setup (&link_info))
+       einfo (_("%X%P: TLS problem %E\n"));
+    }
+
+  gld${EMULATION_NAME}_before_allocation ();
+}
+
+static void
+ppc_edit (void)
+{
+  if (stub_file != NULL)
+    {
+      if (elf_hash_table (&link_info)->tls_sec != NULL
          && !no_tls_opt)
        {
          /* Size the sections.  This is premature, but we want to know the
            sort_toc_sections (&toc_os->children, NULL, NULL);
        }
     }
-
-  gld${EMULATION_NAME}_before_allocation ();
 }
 
 struct hook_stub_info