This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

powerpc ld -relax fix


ld -relax on powerpc supports insertion of branch trampolines to reach
locations that would otherwise cause reloc overflows.  However, there
was a problem with trampolines to reach the PLT:  The calculation in
relocate_section for such trampolines didn't use the proper destination
value, resulting in branches to zero.

I've also removed the howto entries for R_PPC_RELAX* relocs since they
aren't used anywhere.

include/elf/
	* ppc.h (R_PPC_RELAX32_PLT, R_PPC_RELAX32PC_PLT): Define.
	(R_PPC_RELAX32, R_PPC_RELAX32PC): Adjust value.
bfd/
	* elf32-ppc.c (ppc_elf_howto_raw): Delete RELAX32* entries.
	(ppc_elf_relax_section): Use PLT variants of RELAX32 relocs for
	reaching PLT.
	(ppc_elf_relocate_section): Handle R_PPC_RELAX32_PLT and
	R_PPC_RELAX32PC_PLT.

Index: include/elf/ppc.h
===================================================================
RCS file: /cvs/src/src/include/elf/ppc.h,v
retrieving revision 1.13
diff -u -p -r1.13 ppc.h
--- include/elf/ppc.h	6 Nov 2003 02:57:08 -0000	1.13
+++ include/elf/ppc.h	12 Jan 2005 11:09:46 -0000
@@ -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)
Index: bfd/elf32-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-ppc.c,v
retrieving revision 1.133
diff -u -p -r1.133 elf32-ppc.c
--- bfd/elf32-ppc.c	11 Jan 2005 09:32:49 -0000	1.133
+++ bfd/elf32-ppc.c	12 Jan 2005 11:09:49 -0000
@@ -1533,35 +1533,6 @@ static reloc_howto_type ppc_elf_howto_ra
 	 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 */
@@ -1867,6 +1838,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),
@@ -5422,12 +5399,27 @@ ppc_elf_relocate_section (bfd *output_bf
 	    }
 	  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;

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]