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] Fix Thumb-2 BLX misassembly


Hi,

This patch fixes disassembly of Thumb-2 BLX instructions (to ARM-mode
code). At present, the low bit is sometimes erroneously set (depending
on the offsets involved), which creates an undefined instruction.

Tested with cross to arm-linux-gnueabi, with a new test case.

OK to apply?

Thanks,

Julian

ChangeLog

    gas/
    * config/tc-arm.c (do_t_blx): Always use BFD_RELOC_THUMB_PCREL_BLX.
    (md_pcrel_from_section): Align address for BLX.
    (tc_gen_reloc): Change BFD_RELOC_THUMB_PCREL_BLX relocations to
    BFD_RELOC_THUMB_PCREL_BRANCH23 for EABI v4+.

    ld/testsuite/
    * ld-arm/arm-elf.exp (armeabitests): Add thumb2-bl-blx-interwork
    test.
    * ld-arm/thumb2-bl-blx-interwork.s: New.
    * ld-arm/thumb2-bl-blx-interwork.d: New.
--- .pc/blx-fix/gas/config/tc-arm.c	2009-05-01 03:21:51.000000000 -0700
+++ gas/config/tc-arm.c	2009-05-01 03:21:56.000000000 -0700
@@ -9002,12 +9002,7 @@ do_t_blx (void)
     {
       /* No register.  This must be BLX(1).  */
       inst.instruction = 0xf000e800;
-#ifdef OBJ_ELF
-      if (EF_ARM_EABI_VERSION (meabi_flags) >= EF_ARM_EABI_VER4)
-	inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH23;
-      else
-#endif
-	inst.reloc.type = BFD_RELOC_THUMB_PCREL_BLX;
+      inst.reloc.type = BFD_RELOC_THUMB_PCREL_BLX;
       inst.reloc.pc_rel = 1;
     }
 }
@@ -18213,9 +18208,13 @@ md_pcrel_from_section (fixS * fixP, segT
     case BFD_RELOC_THUMB_PCREL_BRANCH20:
     case BFD_RELOC_THUMB_PCREL_BRANCH23:
     case BFD_RELOC_THUMB_PCREL_BRANCH25:
-    case BFD_RELOC_THUMB_PCREL_BLX:
       return base + 4;
 
+      /* BLX is like branches above, but forces the low two bits of PC to
+	 zero.  */
+    case BFD_RELOC_THUMB_PCREL_BLX:
+      return (base + 4) & ~3;
+
       /* ARM mode branches are offset by +8.  However, the Windows CE
 	 loader expects the relocation not to take this into account.  */
     case BFD_RELOC_ARM_PCREL_BRANCH:
@@ -19737,7 +19736,6 @@ tc_gen_reloc (asection *section, fixS *f
     case BFD_RELOC_THUMB_PCREL_BRANCH20:
     case BFD_RELOC_THUMB_PCREL_BRANCH23:
     case BFD_RELOC_THUMB_PCREL_BRANCH25:
-    case BFD_RELOC_THUMB_PCREL_BLX:
     case BFD_RELOC_VTABLE_ENTRY:
     case BFD_RELOC_VTABLE_INHERIT:
 #ifdef TE_PE
@@ -19746,6 +19744,15 @@ tc_gen_reloc (asection *section, fixS *f
       code = fixp->fx_r_type;
       break;
 
+    case BFD_RELOC_THUMB_PCREL_BLX:
+#ifdef OBJ_ELF
+      if (EF_ARM_EABI_VERSION (meabi_flags) >= EF_ARM_EABI_VER4)
+	code = BFD_RELOC_THUMB_PCREL_BRANCH23;
+      else
+#endif
+	code = BFD_RELOC_THUMB_PCREL_BLX;
+      break;
+
     case BFD_RELOC_ARM_LITERAL:
     case BFD_RELOC_ARM_HWLITERAL:
       /* If this is called then the a literal has
--- .pc/blx-fix/ld/testsuite/ld-arm/arm-elf.exp	2009-05-01 03:21:51.000000000 -0700
+++ ld/testsuite/ld-arm/arm-elf.exp	2009-05-01 03:22:19.000000000 -0700
@@ -243,6 +243,9 @@ set armeabitests {
      {"Thumb-2 Interworked branch" "-T arm.ld" "" {thumb2-b-interwork.s}
       {{objdump -dr thumb2-b-interwork.d}}
       "thumb2-b-interwork"}
+    {"BL/BLX interworking" "-T arm.ld" "" {thumb2-bl-blx-interwork.s}
+     {{objdump -dr thumb2-bl-blx-interwork.d}}
+     "thumb2-bl-blx-interwork"}
     {"ARMv4 interworking" "-static -T arm.ld --fix-v4bx-interworking" "--fix-v4bx -meabi=4" {armv4-bx.s}
      {{objdump -d armv4-bx.d}}
      "armv4-bx"}
--- /dev/null	2007-05-10 18:31:20.000000000 -0700
+++ ld/testsuite/ld-arm/thumb2-bl-blx-interwork.d	2009-05-01 03:21:56.000000000 -0700
@@ -0,0 +1,71 @@
+
+.*:     file format .*
+
+
+Disassembly of section \.text:
+
+00008000 <_start>:
+    8000:	f000 e81a 	blx	8038 <arm0>
+    8004:	f000 e81e 	blx	8044 <arm4>
+    8008:	bf00      	nop
+    800a:	f000 e816 	blx	8038 <arm0>
+    800e:	f000 e81a 	blx	8044 <arm4>
+    8012:	bf00      	nop
+    8014:	f000 f818 	bl	8048 <thumb0>
+    8018:	f000 f81b 	bl	8052 <thumb2>
+    801c:	f000 f81e 	bl	805c <thumb4>
+    8020:	f000 f821 	bl	8066 <thumb6>
+    8024:	bf00      	nop
+    8026:	f000 f80f 	bl	8048 <thumb0>
+    802a:	f000 f812 	bl	8052 <thumb2>
+    802e:	f000 f815 	bl	805c <thumb4>
+    8032:	f000 f818 	bl	8066 <thumb6>
+    8036:	bf00      	nop
+
+00008038 <arm0>:
+    8038:	e12fff1e 	bx	lr
+    803c:	e320f000 	nop	\{0\}
+    8040:	e320f000 	nop	\{0\}
+
+00008044 <arm4>:
+    8044:	e12fff1e 	bx	lr
+
+00008048 <thumb0>:
+    8048:	4770      	bx	lr
+    804a:	bf00      	nop
+    804c:	f3af 8000 	nop\.w
+    8050:	bf00      	nop
+
+00008052 <thumb2>:
+    8052:	4770      	bx	lr
+    8054:	f3af 8000 	nop\.w
+    8058:	bf00      	nop
+    805a:	bf00      	nop
+
+0000805c <thumb4>:
+    805c:	4770      	bx	lr
+    805e:	bf00      	nop
+    8060:	bf00      	nop
+    8062:	bf00      	nop
+    8064:	bf00      	nop
+
+00008066 <thumb6>:
+    8066:	4770      	bx	lr
+
+00008068 <backwards>:
+    8068:	f7ff efe6 	blx	8038 <arm0>
+    806c:	f7ff efea 	blx	8044 <arm4>
+    8070:	bf00      	nop
+    8072:	f7ff efe2 	blx	8038 <arm0>
+    8076:	f7ff efe6 	blx	8044 <arm4>
+    807a:	bf00      	nop
+    807c:	f7ff ffe4 	bl	8048 <thumb0>
+    8080:	f7ff ffe7 	bl	8052 <thumb2>
+    8084:	f7ff ffea 	bl	805c <thumb4>
+    8088:	f7ff ffed 	bl	8066 <thumb6>
+    808c:	bf00      	nop
+    808e:	f7ff ffdb 	bl	8048 <thumb0>
+    8092:	f7ff ffde 	bl	8052 <thumb2>
+    8096:	f7ff ffe1 	bl	805c <thumb4>
+    809a:	f7ff ffe4 	bl	8066 <thumb6>
+    809e:	bf00      	nop
--- /dev/null	2007-05-10 18:31:20.000000000 -0700
+++ ld/testsuite/ld-arm/thumb2-bl-blx-interwork.s	2009-05-01 03:21:56.000000000 -0700
@@ -0,0 +1,87 @@
+	.arch armv7-a
+	.global _start
+	.syntax unified
+	.text
+	.thumb
+
+	.macro do_calls
+	@ The following four instructions are accepted by gas, but generate
+	@ meaningless code.
+	@bl.w arm0
+	@bl.w arm4
+	@nop
+	@bl.w arm0
+	@bl.w arm4
+	@nop
+	blx.w arm0
+	blx.w arm4
+	nop
+	blx.w arm0
+	blx.w arm4
+	nop
+	bl.w thumb0
+	bl.w thumb2
+	bl.w thumb4
+	bl.w thumb6
+	nop
+	bl.w thumb0
+	bl.w thumb2
+	bl.w thumb4
+	bl.w thumb6
+	nop
+	@ These eight are all accepted by gas, but generate bad code.
+	@blx.w thumb0
+	@blx.w thumb2
+	@blx.w thumb4
+	@blx.w thumb6
+	@nop
+	@blx.w thumb0
+	@blx.w thumb2
+	@blx.w thumb4
+	@blx.w thumb6
+	.endm
+
+	.thumb_func
+	.align 3
+_start:
+	do_calls
+
+	.arm
+	.align 3
+arm0:
+	bx lr
+
+	.align 3
+	nop
+arm4:
+	bx lr
+
+	.thumb
+	.thumb_func
+	.align 3
+thumb0:
+	bx lr
+
+	.thumb_func
+	.align 3
+	nop
+thumb2:
+	bx lr
+
+	.thumb_func
+	.align 3
+	nop
+	nop
+thumb4:
+	bx lr
+
+	.thumb_func
+	.align 3
+	nop
+	nop
+	nop
+thumb6:
+	bx lr
+
+backwards:
+	do_calls

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