From a27e685fa0a6480bdb07e3be359558524cec89b7 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Tue, 21 Apr 2015 19:18:24 +0930 Subject: 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. --- bfd/ChangeLog | 6 ++++++ bfd/elf64-ppc.c | 14 ++++++++++---- 2 files changed, 16 insertions(+), 4 deletions(-) (limited to 'bfd') diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 94aca52..d0b8e04 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,9 @@ +2015-04-23 Alan Modra + + * 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. + 2015-04-22 H.J. Lu PR ld/18289 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; -- cgit v1.1