This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[Patch]: xcoff: fix 16 bit relative branches
- From: Tristan Gingold <gingold at adacore dot com>
- To: "binutils at sourceware dot org Development" <binutils at sourceware dot org>
- Cc: Richard Sandiford <rsandifo at linux dot vnet dot ibm dot com>
- Date: Wed, 10 Jul 2013 16:50:16 +0200
- Subject: [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