From b32547cd11bec3baf53e0dedf3c733cd3e0839f6 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Fri, 26 Feb 2016 23:00:33 +1030 Subject: [PATCH] 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. --- bfd/ChangeLog | 9 ++++++++ bfd/elf64-ppc.c | 58 ++++++++++++++++++++++++++----------------------- 2 files changed, 40 insertions(+), 27 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index c52a0bc7b71..c2fcf00bad4 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,12 @@ +2016-02-26 Alan Modra + + * 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 * elf64-x86-64.c (elf_x86_64_need_pic): New function. diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c index f0bcee1687f..a9f66d6e090 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; } -- 2.30.2