summaryrefslogtreecommitdiff
path: root/gnu/usr.bin
diff options
context:
space:
mode:
authorLandry Breuil <landry@cvs.openbsd.org>2012-11-05 17:52:16 +0000
committerLandry Breuil <landry@cvs.openbsd.org>2012-11-05 17:52:16 +0000
commitfb03a12ff586af9afe897cfaf73ae3fa85a71722 (patch)
tree042ad91b0f2e61bc354a394a1642d6c24412e685 /gnu/usr.bin
parent6bff42cbf2fd11eba1dd8f7fdbe75f50224908d9 (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.c50
-rw-r--r--gnu/usr.bin/binutils/include/elf/ppc.h6
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)