This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: [PATCH,SPU] Add new relocation, R_SPU_ADD_PIC
- From: Trevor_Smigiel at playstation dot sony dot com
- To: binutils at sourceware dot org
- Cc: Alan Modra <amodra at bigpond dot net dot au>, Ulrich Weigand <uweigand at de dot ibm dot com>, andrew_pinski at playstation dot sony dot com
- Date: Thu, 16 Jul 2009 15:05:59 -0700
- Subject: Re: [PATCH,SPU] Add new relocation, R_SPU_ADD_PIC
- References: <20090716220445.GX12536@playstation.sony.com>
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