aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
Diffstat (limited to 'bfd')
-rw-r--r--bfd/ChangeLog6
-rw-r--r--bfd/elf64-ppc.c14
2 files changed, 16 insertions, 4 deletions
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 <amodra@gmail.com>
+
+ * 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 <hongjiu.lu@intel.com>
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;