This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
RFA: Treat Thumb PLT branches as wide
- From: Richard Sandiford <richard dot sandiford at linaro dot org>
- To: binutils at sourceware dot org
- Date: Mon, 01 Nov 2010 13:33:54 +0000
- Subject: RFA: Treat Thumb PLT branches as wide
I tried adding Thumb 2 multilibs to an arm-linux-gnueabi GCC and then tried
to build using GOLD rather than the BFD linker. libgcc didn't build with
GOLD but it did with the BFD linker. The problem was that unwind-arm_s.o
had a branch to a locally-defined but not locally-binding symbol:
__gnu_Unwind_RaiseException:
...
b __gnu_Unwind_RaiseException(PLT)
which GAS assembled as a 16-bit rather than a 32-bit branch. The BFD
linker assumes that R_ARM_THM_JUMP11 relocations bind locally, so it
simply branched to the local symbol. GOLD still tried to use the PLT,
and raised a relocation overflow error.
I don't think what GAS is doing is the intended behaviour. PLT entries
are very likely to be outside the range of a 16-bit branch, and linkers
aren't required to insert a veneer. Both linkers seem to be behaving
in a reasonable way.
This is related to Nathan's fix for weak symbols:
http://sourceware.org/ml/binutils/2010-04/msg00446.html
although in the PLT case we can tell before relaxation that a 32-bit
branch is required.
Tested on arm-linux-gnueabi. OK to install?
Richard
gas/
* config/tc-arm.c (do_t_branch): Treat (PLT) branches as wide.
gas/testsuite/
* gas/arm/plt-1.s, gas/arm/plt-1.d: New test.
Index: gas/config/tc-arm.c
===================================================================
--- gas/config/tc-arm.c 2010-11-01 13:04:27.000000000 +0000
+++ gas/config/tc-arm.c 2010-11-01 13:12:49.000000000 +0000
@@ -9683,7 +9683,9 @@ do_t_branch (void)
else
opcode = inst.instruction;
- if (unified_syntax && inst.size_req == 4)
+ if (unified_syntax
+ && (inst.size_req == 4
+ || (inst.size_req != 2 && inst.operands[0].hasreloc)))
{
inst.instruction = THUMB_OP32(opcode);
if (cond == COND_ALWAYS)
Index: gas/testsuite/gas/arm/plt-1.s
===================================================================
--- /dev/null 2010-10-15 09:49:48.380060114 +0100
+++ gas/testsuite/gas/arm/plt-1.s 2010-11-01 13:09:25.000000000 +0000
@@ -0,0 +1,27 @@
+ .syntax unified
+ .text
+ .thumb
+
+ .globl Strong1
+ .thumb_func
+ .type Strong1, %function
+Strong1:
+ b Strong2(PLT)
+ b.w Strong2(PLT)
+ b.n Strong2(PLT)
+ b Strong2
+ b.w Strong2
+ b.n Strong2
+ .size Strong1,.-Strong1
+
+ .globl Strong2
+ .thumb_func
+ .type Strong2, %function
+Strong2:
+ b Strong1(PLT)
+ b.w Strong1(PLT)
+ b.n Strong1(PLT)
+ b Strong1
+ b.w Strong1
+ b.n Strong1
+ .size Strong2, .-Strong2
Index: gas/testsuite/gas/arm/plt-1.d
===================================================================
--- /dev/null 2010-10-15 09:49:48.380060114 +0100
+++ gas/testsuite/gas/arm/plt-1.d 2010-11-01 13:12:18.000000000 +0000
@@ -0,0 +1,38 @@
+# name: Thumb branch to PLT
+# as:
+# objdump: -dr
+# This test is only valid on ELF based ports.
+#not-target: *-*-*coff *-*-pe *-*-wince *-*-*aout* *-*-netbsd *-*-riscix*
+
+.*: +file format .*arm.*
+
+
+Disassembly of section \.text:
+
+0+000 <Strong1>:
+ 0: f7ff bffe b\.w 12 <Strong2>
+ 0: R_ARM_THM_JUMP24 Strong2
+ 4: f7ff bffe b\.w 12 <Strong2>
+ 4: R_ARM_THM_JUMP24 Strong2
+ 8: e7fe b\.n 12 <Strong2>
+ 8: R_ARM_THM_JUMP11 Strong2
+ a: e7fe b\.n 12 <Strong2>
+ a: R_ARM_THM_JUMP11 Strong2
+ c: f7ff bffe b\.w 12 <Strong2>
+ c: R_ARM_THM_JUMP24 Strong2
+ 10: e7fe b\.n 12 <Strong2>
+ 10: R_ARM_THM_JUMP11 Strong2
+
+0+012 <Strong2>:
+ 12: f7ff bffe b\.w 0 <Strong1>
+ 12: R_ARM_THM_JUMP24 Strong1
+ 16: f7ff bffe b\.w 0 <Strong1>
+ 16: R_ARM_THM_JUMP24 Strong1
+ 1a: e7fe b\.n 0 <Strong1>
+ 1a: R_ARM_THM_JUMP11 Strong1
+ 1c: e7fe b\.n 0 <Strong1>
+ 1c: R_ARM_THM_JUMP11 Strong1
+ 1e: f7ff bffe b\.w 0 <Strong1>
+ 1e: R_ARM_THM_JUMP24 Strong1
+ 22: e7fe b\.n 0 <Strong1>
+ 22: R_ARM_THM_JUMP11 Strong1