aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2014-07-01 13:06:20 +0930
committerAlan Modra <amodra@gmail.com>2014-07-01 20:24:25 +0930
commit810d4e754dad3e5431399de7b5bacb831b899320 (patch)
treef8cf237da60758bc01cc3eb7daafe63b3b63f512
parentf36e88862f94c15a88fa27df7af906ad75a42e7f (diff)
downloadgdb-810d4e754dad3e5431399de7b5bacb831b899320.zip
gdb-810d4e754dad3e5431399de7b5bacb831b899320.tar.gz
gdb-810d4e754dad3e5431399de7b5bacb831b899320.tar.bz2
Linker foreign output format support for PowerPC64 ELFv2
Makes the ld srec tests pass. Uses a horrible scan through symbols to find ELF fields for symbol definitions, but the generic linker doesn't offer anything better. Might be slow. Anyway, sane people will link to ELF output then objcopy to convert formats. * 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.
-rw-r--r--bfd/ChangeLog11
-rw-r--r--bfd/elf64-ppc.c69
2 files changed, 61 insertions, 19 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 3253c76..0e74b4a 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,12 @@
+2014-07-01 Alan Modra <amodra@gmail.com>
+
+ * 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 <barney_stratford@fastmail.fm>
Senthil Kumar Selvaraj <senthil_kumar.selvaraj@atmel.com>
Pitchumani Sivanupandi <pitchumani.s@atmel.com>
@@ -188,7 +197,7 @@
2014-06-04 Will Newton <will.newton@linaro.org>
- * 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 46cba68..3e7993e 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)
+ {
+ if (htab->elf.hgot != NULL)
+ {
+ htab->elf.hgot->root.u.def.value = TOC_BASE_OFF;
+ htab->elf.hgot->root.u.def.section = s;
+ }
+ }
+ else
{
- htab->elf.hgot->root.u.def.value = TOC_BASE_OFF;
- htab->elf.hgot->root.u.def.section = s;
+ 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)