From bf102f86b1adeb95ed022cb756b2617f674ea94f Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Wed, 27 Jan 2010 12:44:07 +0000 Subject: [PATCH] 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. --- bfd/ChangeLog | 9 +++++++++ bfd/elf64-ppc.c | 26 +++++++++++++++++++------- 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index d882c179009..f8b2e68b862 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,12 @@ +2010-01-27 Alan Modra + + 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 * 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 4a468812a50..010f384e363 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; -- 2.30.2