Fix powerpc64 -r --save-restore-funcs
authorAlan Modra <amodra@gmail.com>
Fri, 26 Feb 2016 12:30:33 +0000 (23:00 +1030)
committerAlan Modra <amodra@gmail.com>
Fri, 26 Feb 2016 12:33:23 +0000 (23:03 +1030)
* elf64-ppc.c (create_linkage_sections): Create sfpr when
save_restore_funcs, rest of sections when not relocatable.
(ppc64_elf_init_stub_bfd): Always call create_linkage_sections.
(sfpr_define): Define all symbols on emitted code.
(ppc64_elf_func_desc_adjust): Adjust for sfpr now being created
when relocatable.  Move sfpr_define loop earlier.

bfd/ChangeLog
bfd/elf64-ppc.c

index c52a0bc..c2fcf00 100644 (file)
@@ -1,3 +1,12 @@
+2016-02-26  Alan Modra  <amodra@gmail.com>
+
+       * elf64-ppc.c (create_linkage_sections): Create sfpr when
+       save_restore_funcs, rest of sections when not relocatable.
+       (ppc64_elf_init_stub_bfd): Always call create_linkage_sections.
+       (sfpr_define): Define all symbols on emitted code.
+       (ppc64_elf_func_desc_adjust): Adjust for sfpr now being created
+       when relocatable.  Move sfpr_define loop earlier.
+
 2016-02-24  H.J. Lu  <hongjiu.lu@intel.com>
 
        * elf64-x86-64.c (elf_x86_64_need_pic): New function.
index f0bcee1..a9f66d6 100644 (file)
@@ -4344,14 +4344,20 @@ create_linkage_sections (bfd *dynobj, struct bfd_link_info *info)
 
   htab = ppc_hash_table (info);
 
-  /* Create .sfpr for code to save and restore fp regs.  */
   flags = (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_READONLY
           | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_LINKER_CREATED);
-  htab->sfpr = bfd_make_section_anyway_with_flags (dynobj, ".sfpr",
-                                                  flags);
-  if (htab->sfpr == NULL
-      || ! bfd_set_section_alignment (dynobj, htab->sfpr, 2))
-    return FALSE;
+  if (htab->params->save_restore_funcs)
+    {
+      /* Create .sfpr for code to save and restore fp regs.  */
+      htab->sfpr = bfd_make_section_anyway_with_flags (dynobj, ".sfpr",
+                                                      flags);
+      if (htab->sfpr == NULL
+         || ! bfd_set_section_alignment (dynobj, htab->sfpr, 2))
+       return FALSE;
+    }
+
+  if (bfd_link_relocatable (info))
+    return TRUE;
 
   /* Create .glink for lazy dynamic linking support.  */
   htab->glink = bfd_make_section_anyway_with_flags (dynobj, ".glink",
@@ -4429,9 +4435,6 @@ ppc64_elf_init_stub_bfd (struct bfd_link_info *info,
   htab->elf.dynobj = params->stub_bfd;
   htab->params = params;
 
-  if (bfd_link_relocatable (info))
-    return TRUE;
-
   return create_linkage_sections (htab->elf.dynobj, info);
 }
 
@@ -6665,7 +6668,7 @@ sfpr_define (struct bfd_link_info *info,
       sym[len + 0] = i / 10 + '0';
       sym[len + 1] = i % 10 + '0';
       h = (struct ppc_link_hash_entry *)
-       elf_link_hash_lookup (&htab->elf, sym, FALSE, FALSE, TRUE);
+       elf_link_hash_lookup (&htab->elf, sym, writing, TRUE, TRUE);
       if (stub_sec != NULL)
        {
          if (h != NULL
@@ -6706,6 +6709,7 @@ sfpr_define (struct bfd_link_info *info,
              h->elf.root.u.def.value = htab->sfpr->size;
              h->elf.type = STT_FUNC;
              h->elf.def_regular = 1;
+             h->elf.non_elf = 0;
              _bfd_elf_link_hash_hide_symbol (info, &h->elf, TRUE);
              writing = TRUE;
              if (htab->sfpr->contents == NULL)
@@ -7050,14 +7054,28 @@ ppc64_elf_func_desc_adjust (bfd *obfd ATTRIBUTE_UNUSED,
                            struct bfd_link_info *info)
 {
   struct ppc_link_hash_table *htab;
-  unsigned int i;
 
   htab = ppc_hash_table (info);
   if (htab == NULL)
     return FALSE;
 
-  if (!bfd_link_relocatable (info)
-      && htab->elf.hgot != NULL)
+  /* Provide any missing _save* and _rest* functions.  */
+  if (htab->sfpr != NULL)
+    {
+      unsigned int i;
+
+      htab->sfpr->size = 0;
+      for (i = 0; i < ARRAY_SIZE (save_res_funcs); i++)
+       if (!sfpr_define (info, &save_res_funcs[i], NULL))
+         return FALSE;
+      if (htab->sfpr->size == 0)
+       htab->sfpr->flags |= SEC_EXCLUDE;
+    }
+
+  if (bfd_link_relocatable (info))
+    return TRUE;
+
+  if (htab->elf.hgot != NULL)
     {
       _bfd_elf_link_hash_hide_symbol (info, htab->elf.hgot, TRUE);
       /* Make .TOC. defined so as to prevent it being made dynamic.
@@ -7076,22 +7094,8 @@ ppc64_elf_func_desc_adjust (bfd *obfd ATTRIBUTE_UNUSED,
                               | STV_HIDDEN);
     }
 
-  if (htab->sfpr == NULL)
-    /* We don't have any relocs.  */
-    return TRUE;
-
-  /* Provide any missing _save* and _rest* functions.  */
-  htab->sfpr->size = 0;
-  if (htab->params->save_restore_funcs)
-    for (i = 0; i < ARRAY_SIZE (save_res_funcs); i++)
-      if (!sfpr_define (info, &save_res_funcs[i], NULL))
-       return FALSE;
-
   elf_link_hash_traverse (&htab->elf, func_desc_adjust, info);
 
-  if (htab->sfpr->size == 0)
-    htab->sfpr->flags |= SEC_EXCLUDE;
-
   return TRUE;
 }