This is the mail archive of the binutils@sourceware.org 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]

Re: [PATCH,SPU] Add new relocation, R_SPU_ADD_PIC


Forgot the patch, here it is.

Trevor

* Trevor Smigiel <Trevor_Smigiel@playstation.sony.com> [2009-07-16 15:04]:
> Hi,
> 
> When generating position independent code for Cell SPU, we generate the
> following instruction sequence to compute the address of "symbol":
> 
>     # Compute the base PIC offset
>     ila $2,.+8
>     brsl $3,.+4
>     sf   $126,$2,$3
> 
>     # Add base PIC offset to absolute symbol address
>     ila  $5,symbol
>     a    $5,$5,$126
>     
> When "symbol" is weak and undefined, we want a final value of 0, but the
> above sequence would generate the base PIC offset.
> 
> Also, if DLL's were supported on SPU, we could not simply patch
> relocations at run time and get the correct result.  The DLL loader
> could try subtracting the base PIC offset from symbols when patching,
> but would sometimes end up with a negative number which can not be
> loaded by 1 instruction (that would replace the ila).
> 
> To address both of these issues, we mark the "a" instruction with a
> relocation to indicate that it is adding the base PIC offset to "symbol.
> 
>     # Add base PIC offset to absolute symbol address
>     ila  $5,symbol
>     .reloc .,SPU_ADD_PIC,symbol
>     a    $5,$5,$126
> 
> When the linker see the SPU_ADD_PIC relocation, it checks if "symbol" is
> weak and undefined, or will be dynamically resolved.  If yes, it will
> change the "a" instruction so it becomes a copy instruction.  Thus, the
> value computed in the 'ila' instruction will be correct.  For example,
> change the above "a" to:
> 
>     ai    $5,$5,0  # Add immediate 0
> 
> For this to work the ABI must also specify that it is the third register
> in the 'a' instruction that contains the base PIC offset.
> 
> Currently, binutils does nothing to address these issues.  It just
> generates incorrect values.
> 
> I used an old patch from Alan Modra which had a similar relocation
> called SPU_PIC as a reference and modified his test cases to suit this
> new relocation.
> 
> The attached patch has been tested on SPU and x86 with no new failures.
> 
> Ok?
> 
> Trevor
> 
> 2009-07-10  Trevor Smigiel  <Trevor_Smigiel@playstation.sony.com>
>             Alan Modra  <amodra@bigpond.net.au>
> 
> include/elf/
> 	* spu.h (R_SPU_ADD_PIC): New.
> bfd/
> 	* reloc.c (BFD_RELOC_SPU_ADD_PIC): Define.
> 	* bfd-in2.h: Regenerate.
> 	* libbfd.h: Regenerate.
> 	* elf32-spu.c (elf_howto_table): Add entries SPU_ADD_PIC.
> 	(spu_elf_bfd_to_reloc_type): Handle SPU_ADD_PIC.
> 	(spu_elf_relocate_section): Patch instructions marked by SPU_ADD_PIC.
> gas/
> 	* config/tc-spu.c (md_apply_fix): Handle SPU_ADD_PIC.
> 	* config/tc-spu.h (tc_fix_adjustable): Don't adjust for SPU_ADD_PIC.
> 	(TC_FORCE_RELOCATION): Emit relocs for SPU_ADD_PIC.
> ld/testsuite/
> 	* ld-spu/pic.d: New.
> 	* ld-spu/pic.s: New.
> 	* ld-spu/picdef.s: New.
> 
diff -rNup src.orig/bfd/bfd-in2.h src/bfd/bfd-in2.h
--- src.orig/bfd/bfd-in2.h	2009-07-10 11:38:26.000000000 -0700
+++ src/bfd/bfd-in2.h	2009-07-15 18:28:29.000000000 -0700
@@ -2545,6 +2545,7 @@ relocation types already defined.  */
   BFD_RELOC_SPU_HI16,
   BFD_RELOC_SPU_PPU32,
   BFD_RELOC_SPU_PPU64,
+  BFD_RELOC_SPU_ADD_PIC,
 
 /* Alpha ECOFF and ELF relocations.  Some of these treat the symbol or
 "addend" in some special way.
diff -rNup src.orig/bfd/elf32-spu.c src/bfd/elf32-spu.c
--- src.orig/bfd/elf32-spu.c	2009-07-10 07:00:38.000000000 -0700
+++ src/bfd/elf32-spu.c	2009-07-15 20:37:05.000000000 -0700
@@ -88,6 +88,9 @@ static reloc_howto_type elf_howto_table[
   HOWTO (R_SPU_PPU64,      0, 4, 64, FALSE,  0, complain_overflow_dont,
 	 bfd_elf_generic_reloc, "SPU_PPU64",
 	 FALSE, 0, -1, FALSE),
+  HOWTO (R_SPU_ADD_PIC,      0, 0, 0, FALSE,  0, complain_overflow_dont,
+	 bfd_elf_generic_reloc, "SPU_ADD_PIC",
+	 FALSE, 0, 0x00000000, FALSE),
 };
 
 static struct bfd_elf_special_section const spu_elf_special_sections[] = {
@@ -135,6 +138,8 @@ spu_elf_bfd_to_reloc_type (bfd_reloc_cod
       return R_SPU_PPU32;
     case BFD_RELOC_SPU_PPU64:
       return R_SPU_PPU64;
+    case BFD_RELOC_SPU_ADD_PIC:
+      return R_SPU_ADD_PIC;
     }
 }
 
@@ -4841,6 +4846,17 @@ spu_elf_relocate_section (bfd *output_bf
       if (info->relocatable)
 	continue;
 
+      /* Change "a rt,ra,rb" to "ai rt,ra,0" */
+      if (r_type == R_SPU_ADD_PIC && h
+	  && (h->root.type == bfd_link_hash_undefweak
+	      || h->root.type == bfd_link_hash_undefined))
+	{
+	  bfd_byte *loc = contents + rel->r_offset;
+	  loc[0] = 0x1c; 
+	  loc[1] = 0x00; 
+	  loc[2] &= 0x3f;
+	}
+
       is_ea_sym = (ea != NULL
 		   && sec != NULL
 		   && sec->output_section == ea);
diff -rNup src.orig/bfd/libbfd.h src/bfd/libbfd.h
--- src.orig/bfd/libbfd.h	2009-06-12 02:15:45.000000000 -0700
+++ src/bfd/libbfd.h	2009-07-15 18:28:29.000000000 -0700
@@ -951,6 +951,7 @@ static const char *const bfd_reloc_code_
   "BFD_RELOC_SPU_HI16",
   "BFD_RELOC_SPU_PPU32",
   "BFD_RELOC_SPU_PPU64",
+  "BFD_RELOC_SPU_ADD_PIC",
   "BFD_RELOC_ALPHA_GPDISP_HI16",
   "BFD_RELOC_ALPHA_GPDISP_LO16",
   "BFD_RELOC_ALPHA_GPDISP",
diff -rNup src.orig/bfd/reloc.c src/bfd/reloc.c
--- src.orig/bfd/reloc.c	2009-07-01 08:02:28.000000000 -0700
+++ src/bfd/reloc.c	2009-07-15 18:28:29.000000000 -0700
@@ -2017,6 +2017,8 @@ ENUMX
   BFD_RELOC_SPU_PPU32
 ENUMX
   BFD_RELOC_SPU_PPU64
+ENUMX
+  BFD_RELOC_SPU_ADD_PIC
 ENUMDOC
   SPU Relocations.
 
diff -rNup src.orig/gas/config/tc-spu.c src/gas/config/tc-spu.c
--- src.orig/gas/config/tc-spu.c	2009-06-22 10:56:02.000000000 -0700
+++ src/gas/config/tc-spu.c	2009-07-15 18:28:29.000000000 -0700
@@ -989,7 +989,8 @@ md_apply_fix (fixS *fixP, valueT *valP, 
   fixP->fx_addnumber = val;
 
   if (fixP->fx_r_type == BFD_RELOC_SPU_PPU32
-      || fixP->fx_r_type == BFD_RELOC_SPU_PPU64)
+      || fixP->fx_r_type == BFD_RELOC_SPU_PPU64
+      || fixP->fx_r_type == BFD_RELOC_SPU_ADD_PIC)
     return;
 
   if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
diff -rNup src.orig/gas/config/tc-spu.h src/gas/config/tc-spu.h
--- src.orig/gas/config/tc-spu.h	2008-08-12 16:39:31.000000000 -0700
+++ src/gas/config/tc-spu.h	2009-07-15 21:00:12.000000000 -0700
@@ -50,7 +50,8 @@ struct tc_fix_info {
 #define tc_fix_adjustable(FIXP) \
   (!(S_IS_FUNCTION ((FIXP)->fx_addsy)			\
      || (FIXP)->fx_r_type == BFD_RELOC_SPU_PPU32	\
-     || (FIXP)->fx_r_type == BFD_RELOC_SPU_PPU64))
+     || (FIXP)->fx_r_type == BFD_RELOC_SPU_PPU64	\
+     || (FIXP)->fx_r_type == BFD_RELOC_SPU_ADD_PIC))
 
 /* Keep relocs on calls.  Branches to function symbols are tail or
    sibling calls.  */
@@ -63,6 +64,7 @@ struct tc_fix_info {
        && S_IS_FUNCTION ((FIXP)->fx_addsy))		\
    || (FIXP)->fx_r_type == BFD_RELOC_SPU_PPU32		\
    || (FIXP)->fx_r_type == BFD_RELOC_SPU_PPU64		\
+   || (FIXP)->fx_r_type == BFD_RELOC_SPU_ADD_PIC	\
    || generic_force_reloc (FIXP))
 
 /* Values passed to md_apply_fix don't include symbol values.  */
diff -rNup src.orig/include/elf/spu.h src/include/elf/spu.h
--- src.orig/include/elf/spu.h	2007-05-11 23:45:32.000000000 -0700
+++ src/include/elf/spu.h	2009-07-15 18:28:29.000000000 -0700
@@ -42,6 +42,7 @@ START_RELOC_NUMBERS (elf_spu_reloc_type)
      RELOC_NUMBER (R_SPU_ADDR16X,	14)
      RELOC_NUMBER (R_SPU_PPU32,		15)
      RELOC_NUMBER (R_SPU_PPU64,		16)
+     RELOC_NUMBER (R_SPU_ADD_PIC,	17)
 END_RELOC_NUMBERS (R_SPU_max)
 
 /* Program header extensions */
diff -rNup src.orig/ld/testsuite/ld-spu/pic.d src/ld/testsuite/ld-spu/pic.d
--- src.orig/ld/testsuite/ld-spu/pic.d	1969-12-31 16:00:00.000000000 -0800
+++ src/ld/testsuite/ld-spu/pic.d	2009-07-15 20:49:25.000000000 -0700
@@ -0,0 +1,105 @@
+#source: pic.s
+#source: picdef.s
+#ld: --emit-relocs
+#objdump: -D -r
+
+.*elf32-spu
+
+
+Disassembly of section \.text:
+
+00000000 <before>:
+	\.\.\.
+
+00000008 <_start>:
+   8:	42 00 08 02 	ila	\$2,10 <_start\+0x8>
+			8: SPU_ADDR18	\.text\+0x10
+   c:	33 00 00 fe 	brsl	\$126,10 <_start\+0x8>
+			c: SPU_REL16	\.text\+0x10
+  10:	08 1f 81 7e 	sf	\$126,\$2,\$126
+  14:	42 00 02 04 	ila	\$4,4 <before\+0x4>
+			14: SPU_ADDR18	\.text\+0x4
+  18:	42 00 42 05 	ila	\$5,84 <end>
+			18: SPU_ADDR18	\.text\+0x84
+  1c:	42 00 04 06 	ila	\$6,8 <_start>
+			1c: SPU_ADDR18	_start
+  20:	42 00 42 07 	ila	\$7,84 <end>
+			20: SPU_ADDR18	\.text\+0x84
+  24:	18 1f 82 04 	a	\$4,\$4,\$126
+			24: SPU_ADD_PIC	before\+0x4
+  28:	18 1f 82 85 	a	\$5,\$5,\$126
+			28: SPU_ADD_PIC	after\+0xfffffffc
+  2c:	18 1f 83 06 	a	\$6,\$6,\$126
+			2c: SPU_ADD_PIC	_start
+  30:	18 1f 83 87 	a	\$7,\$7,\$126
+			30: SPU_ADD_PIC	end
+  34:	42 00 00 0e 	ila	\$14,0
+			34: SPU_ADDR18	\.text
+  38:	18 1f 87 0e 	a	\$14,\$14,\$126
+			38: SPU_ADD_PIC	before
+  3c:	42 00 00 03 	ila	\$3,0
+			3c: SPU_ADDR18	undef
+  40:	1c 00 01 83 	ai	\$3,\$3,0
+			40: SPU_ADD_PIC	undef
+  44:	41 00 00 07 	ilhu	\$7,0
+			44: SPU_ADDR16_HI	ext
+  48:	60 ab 3c 07 	iohl	\$7,22136	# 5678
+			48: SPU_ADDR16_LO	ext
+  4c:	18 1f 83 84 	a	\$4,\$7,\$126
+			4c: SPU_ADD_PIC	ext
+  50:	42 00 80 09 	ila	\$9,100 <loc>
+			50: SPU_ADDR18	\.data
+  54:	18 1f 84 85 	a	\$5,\$9,\$126
+			54: SPU_ADD_PIC	loc
+  58:	42 00 88 08 	ila	\$8,110 <glob>
+			58: SPU_ADDR18	glob
+  5c:	18 1f 84 06 	a	\$6,\$8,\$126
+			5c: SPU_ADD_PIC	glob
+  60:	42 00 90 09 	ila	\$9,120 <__bss_start>
+			60: SPU_ADDR18	_end
+  64:	18 1f 84 89 	a	\$9,\$9,\$126
+			64: SPU_ADD_PIC	_end
+  68:	12 02 39 85 	hbrr	7c <acall>,1234 <abscall>	# 1234
+			68: SPU_REL16	abscall
+  6c:	33 ff f2 82 	lqr	\$2,0 <before>
+			6c: SPU_REL16	undef
+  70:	23 ff f2 02 	stqr	\$2,0 <before>
+			70: SPU_REL16	undef
+  74:	33 8a c0 83 	lqr	\$3,5678 <ext>	# 5678
+			74: SPU_REL16	ext
+  78:	33 8a c2 04 	lqr	\$4,5688 <ext\+0x10>	# 5688
+			78: SPU_REL16	ext\+0x10
+
+0000007c <acall>:
+  7c:	33 02 37 00 	brsl	\$0,1234 <abscall>	# 1234
+			7c: SPU_REL16	abscall
+  80:	32 02 36 80 	br	1234 <abscall>	# 1234
+			80: SPU_REL16	abscall
+
+00000084 <end>:
+  84:	00 00 00 00 	stop
+
+00000088 <after>:
+  88:	00 00 00 00 	stop
+
+Disassembly of section \.data:
+
+00000100 <loc>:
+ 100:	00 00 00 01 	stop
+	\.\.\.
+
+00000110 <glob>:
+ 110:	00 00 00 02 	stop
+	\.\.\.
+
+Disassembly of section \.note\.spu_name:
+
+00000000 <\.note\.spu_name>:
+.*
+.*
+.*
+.*
+.*
+.*
+.*
+#pass
diff -rNup src.orig/ld/testsuite/ld-spu/pic.s src/ld/testsuite/ld-spu/pic.s
--- src.orig/ld/testsuite/ld-spu/pic.s	1969-12-31 16:00:00.000000000 -0800
+++ src/ld/testsuite/ld-spu/pic.s	2009-07-15 19:19:45.000000000 -0700
@@ -0,0 +1,68 @@
+ .global _end
+ .global _start
+ .global glob
+ .weak undef
+
+ .section .text.a,"ax"
+before:
+ .long 0
+ .long 0
+
+ .section .text.b,"ax"
+_start:
+ ila 2,.+8
+ brsl 126,.+4
+ sf 126,2,126
+ ila 4,before+4
+ ila 5,after-4
+ ila 6,_start
+ ila 7,end
+ .reloc .,SPU_ADD_PIC,before+4
+ a 4,4,126
+ .reloc .,SPU_ADD_PIC,after-4
+ a 5,5,126
+ .reloc .,SPU_ADD_PIC,_start
+ a 6,6,126
+ .reloc .,SPU_ADD_PIC,end
+ a 7,7,126
+ ila 14,before
+ .reloc .,SPU_ADD_PIC,before
+ a 14,14,126
+
+ ila 3,undef
+ .reloc .,SPU_ADD_PIC,undef
+ a 3,3,126
+ ilhu 7,ext@h
+ iohl 7,ext@l
+ .reloc .,SPU_ADD_PIC,ext
+ a 4,7,126
+ ila 9,loc
+ .reloc .,SPU_ADD_PIC,loc
+ a 5,9,126
+ ila 8,glob
+ .reloc .,SPU_ADD_PIC,glob
+ a 6,8,126
+ ila 9,_end
+ .reloc .,SPU_ADD_PIC,_end
+ a 9,9,126
+
+ hbrr acall,abscall
+ lqr 2,undef
+ stqr 2,undef
+ lqr 3,ext
+ lqr 4,ext+16
+acall:
+ brsl 0,abscall
+ br abscall
+end:
+
+ .section .text.c,"ax"
+ .long 0
+after:
+ .long 0
+
+ .data
+loc:
+ .long 1,0,0,0
+glob:
+ .long 2,0,0,0
diff -rNup src.orig/ld/testsuite/ld-spu/picdef.s src/ld/testsuite/ld-spu/picdef.s
--- src.orig/ld/testsuite/ld-spu/picdef.s	1969-12-31 16:00:00.000000000 -0800
+++ src/ld/testsuite/ld-spu/picdef.s	2009-07-15 19:11:25.000000000 -0700
@@ -0,0 +1,5 @@
+ .global abscall
+ .global ext
+
+abscall = 0x1234
+ext = 0x5678

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