diff options
author | Landry Breuil <landry@cvs.openbsd.org> | 2012-11-05 17:52:16 +0000 |
---|---|---|
committer | Landry Breuil <landry@cvs.openbsd.org> | 2012-11-05 17:52:16 +0000 |
commit | fb03a12ff586af9afe897cfaf73ae3fa85a71722 (patch) | |
tree | 042ad91b0f2e61bc354a394a1642d6c24412e685 /gnu/usr.bin | |
parent | 6bff42cbf2fd11eba1dd8f7fdbe75f50224908d9 (diff) |
Backport a powerpc --relax fix present in binutils 2.17.
This allows mozilla trunk to finally link again on ppc (with --relax),
otherwise it fails badly with relocations overflow.
From http://sourceware.org/ml/binutils/2005-01/msg00115.html
ok kettenis@, no objection miod@
Diffstat (limited to 'gnu/usr.bin')
-rw-r--r-- | gnu/usr.bin/binutils/bfd/elf32-ppc.c | 50 | ||||
-rw-r--r-- | gnu/usr.bin/binutils/include/elf/ppc.h | 6 |
2 files changed, 25 insertions, 31 deletions
diff --git a/gnu/usr.bin/binutils/bfd/elf32-ppc.c b/gnu/usr.bin/binutils/bfd/elf32-ppc.c index 4eb08ad3e67..201f4198d62 100644 --- a/gnu/usr.bin/binutils/bfd/elf32-ppc.c +++ b/gnu/usr.bin/binutils/bfd/elf32-ppc.c @@ -1532,35 +1532,6 @@ static reloc_howto_type ppc_elf_howto_raw[] = { 0xffff, /* dst_mask */ FALSE), /* pcrel_offset */ - /* Phony relocs to handle branch stubs. */ - HOWTO (R_PPC_RELAX32, /* type */ - 0, /* rightshift */ - 0, /* size */ - 0, /* bitsize */ - FALSE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_RELAX32", /* name */ - FALSE, /* partial_inplace */ - 0, /* src_mask */ - 0, /* dst_mask */ - FALSE), /* pcrel_offset */ - - HOWTO (R_PPC_RELAX32PC, /* type */ - 0, /* rightshift */ - 0, /* size */ - 0, /* bitsize */ - FALSE, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ - "R_PPC_RELAX32PC", /* name */ - FALSE, /* partial_inplace */ - 0, /* src_mask */ - 0, /* dst_mask */ - FALSE), /* pcrel_offset */ - /* GNU extension to record C++ vtable hierarchy. */ HOWTO (R_PPC_GNU_VTINHERIT, /* type */ 0, /* rightshift */ @@ -1851,6 +1822,12 @@ ppc_elf_relax_section (bfd *abfd, stub_rtype = R_PPC_RELAX32; } + if (R_PPC_RELAX32_PLT - R_PPC_RELAX32 + != R_PPC_RELAX32PC_PLT - R_PPC_RELAX32PC) + abort (); + if (tsec == ppc_info->plt) + stub_rtype += R_PPC_RELAX32_PLT - R_PPC_RELAX32; + /* Hijack the old relocation. Since we need two relocations for this use a "composite" reloc. */ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), @@ -5411,12 +5388,27 @@ ppc_elf_relocate_section (bfd *output_bfd, } break; + case R_PPC_RELAX32PC_PLT: + case R_PPC_RELAX32_PLT: + BFD_ASSERT (h != NULL + && h->plt.offset != (bfd_vma) -1 + && htab->plt != NULL); + + relocation = (htab->plt->output_section->vma + + htab->plt->output_offset + + h->plt.offset); + if (r_type == R_PPC_RELAX32_PLT) + goto relax32; + /* Fall thru */ + case R_PPC_RELAX32PC: relocation -= (input_section->output_section->vma + input_section->output_offset + rel->r_offset - 4); /* Fall thru */ + case R_PPC_RELAX32: + relax32: { unsigned long t0; unsigned long t1; diff --git a/gnu/usr.bin/binutils/include/elf/ppc.h b/gnu/usr.bin/binutils/include/elf/ppc.h index b510f441c65..f512630c718 100644 --- a/gnu/usr.bin/binutils/include/elf/ppc.h +++ b/gnu/usr.bin/binutils/include/elf/ppc.h @@ -122,8 +122,10 @@ START_RELOC_NUMBERS (elf_ppc_reloc_type) /* Fake relocations for branch stubs. This will keep them together. */ -#define R_PPC_RELAX32 251 -#define R_PPC_RELAX32PC 252 +#define R_PPC_RELAX32 249 +#define R_PPC_RELAX32PC 250 +#define R_PPC_RELAX32_PLT 251 +#define R_PPC_RELAX32PC_PLT 252 /* These are GNU extensions to enable C++ vtable garbage collection. */ RELOC_NUMBER (R_PPC_GNU_VTINHERIT, 253) |