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]

[Patch]: xcoff: fix 16 bit relative branches


Hello,

now that tc-ppc.c uses bfd_reloc_type_lookup, xcoff needs to
support BFD_RELOC_PPC_B16 and to support it correctly.

I have added a small testcase, from a reproducer. Before the
patch, gas crashes.  With the patch, the reproducer is correctly
assembled and could be run on an AIX machine.

Ok for trunk ?

Tristan.

bfd/
2013-07-10  Tristan Gingold  <gingold@adacore.com>

	* coff-rs6000.c (xcoff_howto_table): Fix R_RBR size and pc_relative.
	(_bfd_xcoff_reloc_type_lookup): Handle BFD_RELOC_PPC_B16.
	* coff64-rs6000.c (xcoff64_howto_table): Fix R_RBR size and pc_relative.
	(_xcoff64_reloc_type_lookup): Handle BFD_RELOC_PPC_B16.

gas/testsuite/
2013-07-10  Tristan Gingold  <gingold@adacore.com>

	* gas/ppc/test2xcoff32.d, gas/ppc/test2xcoff32.s: New files.
	* gas/ppc/ppc.exp: Add test2xcoff32.

diff --git a/bfd/coff-rs6000.c b/bfd/coff-rs6000.c
index 9abe04d..ed92778 100644
--- a/bfd/coff-rs6000.c
+++ b/bfd/coff-rs6000.c
@@ -1090,9 +1090,9 @@ reloc_howto_type xcoff_howto_table[] =
   /* Modifiable branch relative.  */
   HOWTO (R_RBR,			/* type */
 	 0,			/* rightshift */
-	 1,			/* size (0 = byte, 1 = short, 2 = long) */
+	 2,			/* size (0 = byte, 1 = short, 2 = long) */
 	 16,			/* bitsize */
-	 FALSE,			/* pc_relative */
+	 TRUE,			/* pc_relative */
 	 0,			/* bitpos */
 	 complain_overflow_signed, /* complain_on_overflow */
 	 0,			/* special_function */
@@ -1166,6 +1166,8 @@ _bfd_xcoff_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
     case BFD_RELOC_16:
       /* Note that this relocation is only internally used by gas.  */
       return &xcoff_howto_table[0xc];
+    case BFD_RELOC_PPC_B16:
+      return &xcoff_howto_table[0x1d];
     case BFD_RELOC_32:
     case BFD_RELOC_CTOR:
       return &xcoff_howto_table[0];
diff --git a/bfd/coff64-rs6000.c b/bfd/coff64-rs6000.c
index 56a0d25..1219206 100644
--- a/bfd/coff64-rs6000.c
+++ b/bfd/coff64-rs6000.c
@@ -1746,9 +1746,9 @@ reloc_howto_type xcoff64_howto_table[] =
   /* Modifiable branch relative.  */
   HOWTO (R_RBR,			/* type */
 	 0,			/* rightshift */
-	 1,			/* size (0 = byte, 1 = short, 2 = long) */
+	 2,			/* size (0 = byte, 1 = short, 2 = long) */
 	 16,			/* bitsize */
-	 FALSE,			/* pc_relative */
+	 TRUE,			/* pc_relative */
 	 0,			/* bitpos */
 	 complain_overflow_signed, /* complain_on_overflow */
 	 0,			/* special_function */
@@ -1829,6 +1829,8 @@ xcoff64_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
     case BFD_RELOC_16:
       /* Note that this relocation is only internally used by gas.  */
       return &xcoff64_howto_table[0xc];
+    case BFD_RELOC_PPC_B16:
+      return &xcoff64_howto_table[0x1e];
     case BFD_RELOC_32:
     case BFD_RELOC_CTOR:
       return &xcoff64_howto_table[0x1c];
diff --git a/gas/testsuite/gas/ppc/ppc.exp b/gas/testsuite/gas/ppc/ppc.exp
index fec714c..ba29261 100644
--- a/gas/testsuite/gas/ppc/ppc.exp
+++ b/gas/testsuite/gas/ppc/ppc.exp
@@ -31,6 +31,7 @@ if { [istarget powerpc64*-*-*] || [istarget *-*-elf64*]} then {
     run_list_test "range64" "-a64"
 } elseif { [istarget powerpc*-*aix*] } then {
     run_dump_test "test1xcoff32"
+    run_dump_test "test2xcoff32"
 } elseif { [istarget powerpc*-*-*bsd*] \
      || [istarget powerpc*-*-elf*] \
      || [istarget powerpc*-*-eabi*] \
diff --git a/gas/testsuite/gas/ppc/test2xcoff32.d b/gas/testsuite/gas/ppc/test2xcoff32.d
new file mode 100644
index 0000000..125d34a
--- /dev/null
+++ b/gas/testsuite/gas/ppc/test2xcoff32.d
@@ -0,0 +1,40 @@
+#objdump: -dr
+#as:
+#name: PowerPC Test 2, 32 bit XCOFF
+
+.*: +file format aixcoff-rs6000
+
+
+Disassembly of section .text:
+
+00000000 <.main>:
+   0:	7c 08 02 a6 	mflr    r0
+   4:	90 01 00 08 	st      r0,8\(r1\)
+   8:	93 c1 ff f8 	st      r30,-8\(r1\)
+   c:	93 e1 ff fc 	st      r31,-4\(r1\)
+  10:	94 21 ff c0 	stu     r1,-64\(r1\)
+  14:	3b e0 00 00 	lil     r31,0
+  18:	83 c2 00 00 	l       r30,0\(r2\)
+			1a: R_TOC	LC\.\.0-0x70
+  1c:	7f c3 f3 78 	mr      r3,r30
+  20:	7f e4 fb 78 	mr      r4,r31
+  24:	4b ff ff dd 	bl      0 <.main>
+			24: R_BR	.printf
+  28:	60 00 00 00 	oril    r0,r0,0
+  2c:	2f 9f 00 09 	cmpi    7,r31,9
+  30:	3b ff 00 01 	cal     r31,1\(r31\)
+  34:	40 9e ff e8 	bne     7,1c <\.main\+0x1c>
+  38:	38 60 00 00 	lil     r3,0
+  3c:	38 21 00 40 	cal     r1,64\(r1\)
+  40:	80 01 00 08 	l       r0,8\(r1\)
+  44:	7c 08 03 a6 	mtlr    r0
+  48:	83 c1 ff f8 	l       r30,-8\(r1\)
+  4c:	83 e1 ff fc 	l       r31,-4\(r1\)
+  50:	4e 80 00 20 	br
+  54:	60 00 00 00 	oril    r0,r0,0
+  58:	60 00 00 00 	oril    r0,r0,0
+  5c:	60 00 00 00 	oril    r0,r0,0
+
+00000060 <_t\.rw_>:
+  60:	25 64 0a 00 	dozi    r11,r4,2560
+	...
diff --git a/gas/testsuite/gas/ppc/test2xcoff32.s b/gas/testsuite/gas/ppc/test2xcoff32.s
new file mode 100644
index 0000000..d4d9ac3
--- /dev/null
+++ b/gas/testsuite/gas/ppc/test2xcoff32.s
@@ -0,0 +1,41 @@
+	.csect .text[PR]
+	.toc
+LC..1:
+	.tc LC..0[TC],LC..0
+	.csect .text[PR]
+	.align 2
+	.globl main
+	.globl .main
+	.csect main[DS]
+main:
+	.long .main, TOC[tc0], 0
+	.csect .text[PR]
+.main:
+	mflr 0
+	stw 0,8(1)
+	stw 30,-8(1)
+	stw 31,-4(1)
+	stwu 1,-64(1)
+	li 31,0
+	lwz 30,LC..1(2)
+L..2:
+	mr 3,30
+	mr 4,31
+	bl .printf
+	nop
+	cmpwi 7,31,9
+	addi 31,31,1
+	bne 7,L..2
+	li 3,0
+	addi 1,1,64
+	lwz 0,8(1)
+	mtlr 0
+	lwz 30,-8(1)
+	lwz 31,-4(1)
+	blr
+	
+	.csect _t.rw_[RO],4
+	.align 2
+LC..0:
+	.byte "%d"
+	.byte 10, 0


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