aboutsummaryrefslogtreecommitdiff
path: root/bfd/elf64-ppc.c
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:03:23 +1030
commitb32547cd11bec3baf53e0dedf3c733cd3e0839f6 (patch)
treea860c8023616b7cb4f509453f5c850bab0329ec5 /bfd/elf64-ppc.c
parentec6944f206b5503c3abfbe36008addc2761d6cd5 (diff)
downloadgdb-b32547cd11bec3baf53e0dedf3c733cd3e0839f6.zip
gdb-b32547cd11bec3baf53e0dedf3c733cd3e0839f6.tar.gz
gdb-b32547cd11bec3baf53e0dedf3c733cd3e0839f6.tar.bz2
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.
Diffstat (limited to 'bfd/elf64-ppc.c')
-rw-r--r--bfd/elf64-ppc.c58
1 files changed, 31 insertions, 27 deletions
diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c
index f0bcee1..a9f66d6 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;
}