diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 3253c76f6f7..0e74b4a973a 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,12 @@ +2014-07-01 Alan Modra + + * elf64-ppc.c (abiversion, set_abiversion): Move earlier. + (ppc64_elf_branch_reloc): Adjust addend for ELFv2 local offset. + (ppc64_elf_set_toc): Set ".TOC." symbol value when using + generic linker. + (ppc64_elf_relocate_section): Disable ELFv2 function entry + optimisation when --traditional-format. + 2014-07-01 Barney Stratford Senthil Kumar Selvaraj Pitchumani Sivanupandi @@ -188,7 +197,7 @@ 2014-06-04 Will Newton - * elfnn-aarch64.c (tpoff_base): Make test of tls_sec + * elfnn-aarch64.c (tpoff_base): Make test of tls_sec being non-NULL into an assert. (elfNN_aarch64_tls_relax): Remove unused code. diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c index 46cba684175..3e7993e44b6 100644 --- a/bfd/elf64-ppc.c +++ b/bfd/elf64-ppc.c @@ -235,6 +235,19 @@ static bfd_vma opd_entry_value #ifndef NO_OPD_RELOCS #define NO_OPD_RELOCS 0 #endif + +static inline int +abiversion (bfd *abfd) +{ + return elf_elfheader (abfd)->e_flags & EF_PPC64_ABI; +} + +static inline void +set_abiversion (bfd *abfd, int ver) +{ + elf_elfheader (abfd)->e_flags &= ~EF_PPC64_ABI; + elf_elfheader (abfd)->e_flags |= ver & EF_PPC64_ABI; +} #define ONES(n) (((bfd_vma) 1 << ((n) - 1) << 1) - 1) @@ -2487,6 +2500,29 @@ ppc64_elf_branch_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol, + symbol->section->output_section->vma + symbol->section->output_offset); } + else + { + elf_symbol_type *elfsym = (elf_symbol_type *) symbol; + + if (symbol->section->owner != abfd + && abiversion (symbol->section->owner) >= 2) + { + unsigned int i; + + for (i = 0; i < symbol->section->owner->symcount; ++i) + { + asymbol *symdef = symbol->section->owner->outsymbols[i]; + + if (strcmp (symdef->name, symbol->name) == 0) + { + elfsym = (elf_symbol_type *) symdef; + break; + } + } + } + reloc_entry->addend + += PPC64_LOCAL_ENTRY_OFFSET (elfsym->internal_elf_sym.st_other); + } return bfd_reloc_continue; } @@ -2975,19 +3011,6 @@ get_opd_info (asection * sec) return &ppc64_elf_section_data (sec)->u.opd; return NULL; } - -static inline int -abiversion (bfd *abfd) -{ - return elf_elfheader (abfd)->e_flags & EF_PPC64_ABI; -} - -static inline void -set_abiversion (bfd *abfd, int ver) -{ - elf_elfheader (abfd)->e_flags &= ~EF_PPC64_ABI; - elf_elfheader (abfd)->e_flags |= ver & EF_PPC64_ABI; -} /* Parameters for the qsort hook. */ static bfd_boolean synthetic_relocatable; @@ -12394,15 +12417,24 @@ ppc64_elf_set_toc (struct bfd_link_info *info, bfd *obfd) _bfd_set_gp_value (obfd, TOCstart); - if (info != NULL && s != NULL && is_ppc64_elf (obfd)) + if (info != NULL && s != NULL) { struct ppc_link_hash_table *htab = ppc_hash_table (info); - if (htab != NULL - && htab->elf.hgot != NULL) + if (htab != NULL) { - htab->elf.hgot->root.u.def.value = TOC_BASE_OFF; - htab->elf.hgot->root.u.def.section = s; + if (htab->elf.hgot != NULL) + { + htab->elf.hgot->root.u.def.value = TOC_BASE_OFF; + htab->elf.hgot->root.u.def.section = s; + } + } + else + { + struct bfd_link_hash_entry *bh = NULL; + _bfd_generic_link_add_one_symbol (info, obfd, ".TOC.", BSF_GLOBAL, + s, TOC_BASE_OFF, NULL, FALSE, + FALSE, &bh); } } return TOCstart; @@ -13544,6 +13576,7 @@ ppc64_elf_relocate_section (bfd *output_bfd, . addi 2,2,.TOC.@l if .TOC. is in range. */ if (!info->shared + && !info->traditional_format && h != NULL && &h->elf == htab->elf.hgot && rel + 1 < relend && rel[1].r_info == ELF64_R_INFO (r_symndx, R_PPC64_REL16_LO)