aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2010-01-27 12:44:07 +0000
committerAlan Modra <amodra@gmail.com>2010-01-27 12:44:07 +0000
commitbf102f86b1adeb95ed022cb756b2617f674ea94f (patch)
treecaea4b8a321a20c40bbc666612525a3503d29382
parent4c7dcb841c251467b6460009bcf90ae52149a035 (diff)
downloadgdb-bf102f86b1adeb95ed022cb756b2617f674ea94f.zip
gdb-bf102f86b1adeb95ed022cb756b2617f674ea94f.tar.gz
gdb-bf102f86b1adeb95ed022cb756b2617f674ea94f.tar.bz2
PR ld/11217
* elf64-ppc.c (struct ppc_link_hash_table): Add toc_bfd, toc_first_sec. (ppc64_elf_setup_section_lists): Init them. (ppc64_elf_next_toc_section): Don't partition multi-toc between .got and .toc on the same input file. (ppc64_elf_relocate_section): Correct GOT entry offset.
-rw-r--r--bfd/ChangeLog9
-rw-r--r--bfd/elf64-ppc.c26
2 files changed, 28 insertions, 7 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index d882c17..f8b2e68 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,12 @@
+2010-01-27 Alan Modra <amodra@gmail.com>
+
+ PR ld/11217
+ * elf64-ppc.c (struct ppc_link_hash_table): Add toc_bfd, toc_first_sec.
+ (ppc64_elf_setup_section_lists): Init them.
+ (ppc64_elf_next_toc_section): Don't partition multi-toc between .got
+ and .toc on the same input file.
+ (ppc64_elf_relocate_section): Correct GOT entry offset.
+
2010-01-26 Tristan Gingold <gingold@adacore.com>
* targets.c (BFD_JUMP_TABLE_ARCHIVE): Add initializer for write_ar_hdr.
diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c
index 4a46881..010f384 100644
--- a/bfd/elf64-ppc.c
+++ b/bfd/elf64-ppc.c
@@ -3732,6 +3732,8 @@ struct ppc_link_hash_table
/* Temp used when calculating TOC pointers. */
bfd_vma toc_curr;
+ bfd *toc_bfd;
+ asection *toc_first_sec;
/* Highest input section id. */
int top_id;
@@ -9612,6 +9614,8 @@ ppc64_elf_setup_section_lists (bfd *output_bfd,
htab->stub_group[id].toc_off = TOC_BASE_OFF;
elf_gp (output_bfd) = htab->toc_curr = ppc64_elf_toc (output_bfd);
+ htab->toc_bfd = NULL;
+ htab->toc_first_sec = NULL;
/* We can't use output_bfd->section_count here to find the top output
section index as some sections may have been removed, and
@@ -9646,11 +9650,21 @@ ppc64_elf_next_toc_section (struct bfd_link_info *info, asection *isec)
if (!htab->no_multi_toc)
{
- bfd_vma addr = isec->output_offset + isec->output_section->vma;
- bfd_vma off = addr - htab->toc_curr;
+ bfd_vma addr, off;
+ if (htab->toc_bfd != isec->owner)
+ {
+ htab->toc_bfd = isec->owner;
+ htab->toc_first_sec = isec;
+ }
+ addr = isec->output_offset + isec->output_section->vma;
+ off = addr - htab->toc_curr;
if (off + isec->size > 0x10000)
- htab->toc_curr = addr;
+ {
+ addr = (htab->toc_first_sec->output_offset
+ + htab->toc_first_sec->output_section->vma);
+ htab->toc_curr = addr;
+ }
elf_gp (isec->owner) = (htab->toc_curr
- elf_gp (isec->output_section->owner)
@@ -11745,10 +11759,8 @@ ppc64_elf_relocate_section (bfd *output_bfd,
if (off >= (bfd_vma) -2)
abort ();
- relocation = got->output_offset + off;
-
- /* TOC base (r2) is TOC start plus 0x8000. */
- addend = -TOC_BASE_OFF;
+ relocation = got->output_section->vma + got->output_offset + off;
+ addend = -(TOCstart + htab->stub_group[input_section->id].toc_off);
}
break;