summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2016-02-26 23:00:33 +1030
committerAlan Modra <amodra@gmail.com>2016-02-26 23:36:11 +1030
commit57b8887652e833a7fef8c3cf871d733d3d5fc289 (patch)
treef617908c0961b24c6c4323bdbcc5143b5a38a719
parent239803398de94a92fdcef24b5d7914842dcc5797 (diff)
downloadbinutils-gdb-57b8887652e833a7fef8c3cf871d733d3d5fc289.tar.gz
Fix powerpc64 -r --save-restore-funcs
* 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.
-rw-r--r--bfd/ChangeLog9
-rw-r--r--bfd/elf64-ppc.c58
2 files changed, 40 insertions, 27 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 01aebb11b97..e15bada205b 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -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-25 Jiong Wang <jiong.wang@arm.com>
Backport from master
diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c
index 162862c06cf..ffe23e62e17 100644
--- a/bfd/elf64-ppc.c
+++ b/bfd/elf64-ppc.c
@@ -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;
}