aboutsummaryrefslogtreecommitdiff
path: root/bfd/elf64-ppc.c
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2015-04-21 19:18:24 +0930
committerAlan Modra <amodra@gmail.com>2015-04-23 09:49:19 +0930
commita27e685fa0a6480bdb07e3be359558524cec89b7 (patch)
tree770bec6f2f916fac7292a36d2ff3a9bc4c6648b2 /bfd/elf64-ppc.c
parent19947f5fbb8f9153d9681ebc9981cc7bb056e741 (diff)
downloadgdb-a27e685fa0a6480bdb07e3be359558524cec89b7.zip
gdb-a27e685fa0a6480bdb07e3be359558524cec89b7.tar.gz
gdb-a27e685fa0a6480bdb07e3be359558524cec89b7.tar.bz2
Align .TOC. for PowerPC64
This change, with prerequisite 0e5fabeb, provides a toc base aligned to 256 bytes rather than 8 bytes. This is necessary for a minor gcc optimisation, allowing use of d-form instructions to correctly access toc-relative items larger than 8 bytes. bfd/ * elf64-ppc.c (TOC_BASE_ALIGN): Define. (ppc64_elf_next_toc_section): Align multi-got toc base. (ppc64_elf_set_toc): Likewise initial toc base and .TOC. symbol. ld/ * emulparams/elf64ppc.sh (GOT): Align. ld/testsuite/ * ld-powerpc/ambiguousv1b.d: Update for aligned .got. * ld-powerpc/defsym.d: Likewise. * ld-powerpc/elfv2-2exe.d: Likewise. * ld-powerpc/elfv2exe.d: Likewise. * ld-powerpc/elfv2so.d: Likewise. * ld-powerpc/relbrlt.d: Likewise. * ld-powerpc/tls.g: Likewise. * ld-powerpc/tlsexe.d: Likewise. * ld-powerpc/tlsexe.g: Likewise. * ld-powerpc/tlsexe.r: Likewise. * ld-powerpc/tlsexetoc.d: Likewise. * ld-powerpc/tlsexetoc.g: Likewise. * ld-powerpc/tlsexetoc.r: Likewise. * ld-powerpc/tlsso.d: Likewise. * ld-powerpc/tlsso.g: Likewise. * ld-powerpc/tlsso.r: Likewise. * ld-powerpc/tlstoc.g: Likewise. * ld-powerpc/tlstocso.d: Likewise. * ld-powerpc/tlstocso.g: Likewise. * ld-powerpc/tlstocso.r: Likewise. * ld-powerpc/tocopt.d: Likewise. * ld-powerpc/tocopt2.d: Likewise. * ld-powerpc/tocopt3.d: Likewise. * ld-powerpc/tocopt4.d: Likewise. * ld-powerpc/tocopt5.d: Likewise.
Diffstat (limited to 'bfd/elf64-ppc.c')
-rw-r--r--bfd/elf64-ppc.c14
1 files changed, 10 insertions, 4 deletions
diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c
index e7e8820..7be21c7 100644
--- a/bfd/elf64-ppc.c
+++ b/bfd/elf64-ppc.c
@@ -138,6 +138,8 @@ static bfd_vma opd_entry_value
/* TOC base pointers offset from start of TOC. */
#define TOC_BASE_OFF 0x8000
+/* TOC base alignment. */
+#define TOC_BASE_ALIGN 256
/* Offset of tp and dtp pointers from start of TLS block. */
#define TP_OFFSET 0x7000
@@ -11257,6 +11259,7 @@ ppc64_elf_next_toc_section (struct bfd_link_info *info, asection *isec)
addr = (htab->toc_first_sec->output_offset
+ htab->toc_first_sec->output_section->vma);
htab->toc_curr = addr;
+ htab->toc_curr &= -TOC_BASE_ALIGN;
}
/* toc_curr is the base address of this toc group. Set elf_gp
@@ -12535,7 +12538,7 @@ bfd_vma
ppc64_elf_set_toc (struct bfd_link_info *info, bfd *obfd)
{
asection *s;
- bfd_vma TOCstart;
+ bfd_vma TOCstart, adjust;
/* The TOC consists of sections .got, .toc, .tocbss, .plt in that
order. The TOC starts where the first of these sections starts. */
@@ -12583,6 +12586,9 @@ ppc64_elf_set_toc (struct bfd_link_info *info, bfd *obfd)
if (s != NULL)
TOCstart = s->output_section->vma + s->output_offset;
+ /* Force alignment. */
+ adjust = TOCstart & (TOC_BASE_ALIGN - 1);
+ TOCstart -= adjust;
_bfd_set_gp_value (obfd, TOCstart);
if (info != NULL && s != NULL)
@@ -12593,7 +12599,7 @@ ppc64_elf_set_toc (struct bfd_link_info *info, bfd *obfd)
{
if (htab->elf.hgot != NULL)
{
- htab->elf.hgot->root.u.def.value = TOC_BASE_OFF;
+ htab->elf.hgot->root.u.def.value = TOC_BASE_OFF - adjust;
htab->elf.hgot->root.u.def.section = s;
}
}
@@ -12601,8 +12607,8 @@ ppc64_elf_set_toc (struct bfd_link_info *info, bfd *obfd)
{
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);
+ s, TOC_BASE_OFF - adjust,
+ NULL, FALSE, FALSE, &bh);
}
}
return TOCstart;