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]

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


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