* elf64-ppc.c (ppc_build_one_stub): Don't duplicate relocs

emitted for ".brlt" entries.
	(toc_adjusting_stub_needed): Don't treat ".fixup" specially here..
	(ppc64_elf_next_input_section): ..instead do so here.
This commit is contained in:
Alan Modra
2007-10-23 12:54:17 +00:00
parent 7b3200f9ae
commit f94498ff0f
2 changed files with 61 additions and 46 deletions

View File

@ -1,3 +1,10 @@
2007-10-23 Alan Modra <amodra@bigpond.net.au>
* elf64-ppc.c (ppc_build_one_stub): Don't duplicate relocs
emitted for ".brlt" entries.
(toc_adjusting_stub_needed): Don't treat ".fixup" specially here..
(ppc64_elf_next_input_section): ..instead do so here.
2007-10-19 Nick Clifton <nickc@redhat.com> 2007-10-19 Nick Clifton <nickc@redhat.com>
* config.bfd: Recognise am34-linux-gnu target. * config.bfd: Recognise am34-linux-gnu target.

View File

@ -8387,6 +8387,10 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
bfd_put_64 (htab->brlt->owner, off, bfd_put_64 (htab->brlt->owner, off,
htab->brlt->contents + br_entry->offset); htab->brlt->contents + br_entry->offset);
if (br_entry->iter == htab->stub_iteration)
{
br_entry->iter = 0;
if (htab->relbrlt != NULL) if (htab->relbrlt != NULL)
{ {
/* Create a reloc for the branch lookup table entry. */ /* Create a reloc for the branch lookup table entry. */
@ -8400,7 +8404,8 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
rela.r_addend = off; rela.r_addend = off;
rl = htab->relbrlt->contents; rl = htab->relbrlt->contents;
rl += htab->relbrlt->reloc_count++ * sizeof (Elf64_External_Rela); rl += (htab->relbrlt->reloc_count++
* sizeof (Elf64_External_Rela));
bfd_elf64_swap_reloca_out (htab->relbrlt->owner, &rela, rl); bfd_elf64_swap_reloca_out (htab->relbrlt->owner, &rela, rl);
} }
else if (info->emitrelocations) else if (info->emitrelocations)
@ -8418,9 +8423,11 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
if (relocs == NULL) if (relocs == NULL)
return FALSE; return FALSE;
elfsec_data->relocs = relocs; elfsec_data->relocs = relocs;
elfsec_data->rel_hdr.sh_size = (stub_entry->stub_sec->reloc_count elfsec_data->rel_hdr.sh_size
= (stub_entry->stub_sec->reloc_count
* sizeof (Elf64_External_Rela)); * sizeof (Elf64_External_Rela));
elfsec_data->rel_hdr.sh_entsize = sizeof (Elf64_External_Rela); elfsec_data->rel_hdr.sh_entsize
= sizeof (Elf64_External_Rela);
htab->brlt->reloc_count = 0; htab->brlt->reloc_count = 0;
} }
r = relocs + htab->brlt->reloc_count; r = relocs + htab->brlt->reloc_count;
@ -8431,6 +8438,7 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
r->r_info = ELF64_R_INFO (0, R_PPC64_RELATIVE); r->r_info = ELF64_R_INFO (0, R_PPC64_RELATIVE);
r->r_addend = off; r->r_addend = off;
} }
}
off = (br_entry->offset off = (br_entry->offset
+ htab->brlt->output_offset + htab->brlt->output_offset
@ -8865,11 +8873,6 @@ toc_adjusting_stub_needed (struct bfd_link_info *info, asection *isec)
if (isec->output_section == NULL) if (isec->output_section == NULL)
return 0; return 0;
/* Hack for linux kernel. .fixup contains branches, but only back to
the function that hit an exception. */
if (strcmp (isec->name, ".fixup") == 0)
return 0;
if (isec->reloc_count == 0) if (isec->reloc_count == 0)
return 0; return 0;
@ -9074,8 +9077,13 @@ ppc64_elf_next_input_section (struct bfd_link_info *info, asection *isec)
/* If a code section has a function that uses the TOC then we need /* If a code section has a function that uses the TOC then we need
to use the right TOC (obviously). Also, make sure that .opd gets to use the right TOC (obviously). Also, make sure that .opd gets
the correct TOC value for R_PPC64_TOC relocs that don't have or the correct TOC value for R_PPC64_TOC relocs that don't have or
can't find their function symbol (shouldn't ever happen now). */ can't find their function symbol (shouldn't ever happen now).
if (isec->has_toc_reloc || (isec->flags & SEC_CODE) == 0) Also specially treat .fixup for the linux kernel. .fixup
contains branches, but only back to the function that hit an
exception. */
if (isec->has_toc_reloc
|| (isec->flags & SEC_CODE) == 0
|| strcmp (isec->name, ".fixup") == 0)
{ {
if (elf_gp (isec->owner) != 0) if (elf_gp (isec->owner) != 0)
htab->toc_curr = elf_gp (isec->owner); htab->toc_curr = elf_gp (isec->owner);