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] PR gas/19744: Thumb-1 pcrop relocations don't work on Thumb-2 targets


 Hi All,

 This patch fixes code to allow Thumb-2 targets to use Thumb-1 pcrop
relocations. Indeed even if Thumb-2 targets have access to better solutions
to synthetize constants (using movt/movw pair), it should be able to cleanly
compile code targeted for Thumb-1 targets.
 It also adds checks to detect invalid usage (arm code, high registers).

 No regressions have been observed for arm-linux-gnueabi, arm-linux-gnueabihf,
arm-none-eabi, arm-none-nacl, armeb-linux-gnueabihf, arm-netbsdelf and
arm-vxworks.

---
gas/ChangeLog:

2016-03-07 Mickael Guene <mickael.guene@st.com>

    * config/tc-arm.c (do_arit): Protect against bad relocations usage.
    (do_mov): Likewise.
    (do_t_add_sub): Allow pcrop relocations for Thumb-2 targets.
    (do_t_mov_cmp): Likewise.
    (do_t_add_sub): Protect against bad relocations usage.
    (do_t_mov_cmp): Likewise.

gas/testsuite/ChangeLog:

2016-03-07 Mickael Guene <mickael.guene@st.com>

    * gas/arm/adds-thumb1-reloc-local-armv7-m.s: New.
    * gas/arm/adds-thumb1-reloc-local-armv7-m.d: New.
    * gas/arm/movs-thumb1-reloc-local-armv7-m.s: New.
    * gas/arm/movs-thumb1-reloc-local-armv7-m.d: New.

ld/testsuite/ChangeLog:

2016-03-07 Mickael Guene <mickael.guene@st.com>

    * ld-arm/arm-elf.exp: New tests.
    * ld-arm/thumb1-adds-armv7-m.s: New.
    * ld-arm/thumb1-movs-armv7-m.s: New.
---
 gas/config/tc-arm.c                                | 33 +++++++++++++----
 .../gas/arm/adds-thumb1-reloc-local-armv7-m.d      | 16 ++++++++
 .../gas/arm/adds-thumb1-reloc-local-armv7-m.s      | 13 +++++++
 .../gas/arm/movs-thumb1-reloc-local-armv7-m.d      | 16 ++++++++
 .../gas/arm/movs-thumb1-reloc-local-armv7-m.s      | 13 +++++++
 ld/testsuite/ld-arm/arm-elf.exp                    |  6 +++
 ld/testsuite/ld-arm/thumb1-adds-armv7-m.s          | 43 ++++++++++++++++++++++
 ld/testsuite/ld-arm/thumb1-movs-armv7-m.s          | 43 ++++++++++++++++++++++
 8 files changed, 175 insertions(+), 8 deletions(-)
 create mode 100644 gas/testsuite/gas/arm/adds-thumb1-reloc-local-armv7-m.d
 create mode 100644 gas/testsuite/gas/arm/adds-thumb1-reloc-local-armv7-m.s
 create mode 100644 gas/testsuite/gas/arm/movs-thumb1-reloc-local-armv7-m.d
 create mode 100644 gas/testsuite/gas/arm/movs-thumb1-reloc-local-armv7-m.s
 create mode 100644 ld/testsuite/ld-arm/thumb1-adds-armv7-m.s
 create mode 100644 ld/testsuite/ld-arm/thumb1-movs-armv7-m.s

diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index 6930220..4a32311 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -787,6 +787,7 @@ struct asm_opcode
 #define BAD_RANGE	_("branch out of range")
 #define BAD_FP16	_("selected processor does not support fp16 instruction")
 #define UNPRED_REG(R)	_("using " R " results in unpredictable behaviour")
+#define THUMB1_RELOC_ONLY  _("relocation valid in thumb1 code only")
 
 static struct hash_control * arm_ops_hsh;
 static struct hash_control * arm_cond_hsh;
@@ -8315,6 +8316,9 @@ do_adrl (void)
 static void
 do_arit (void)
 {
+  constraint (inst.reloc.type >= BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
+	      && inst.reloc.type <= BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC ,
+	      THUMB1_RELOC_ONLY);
   if (!inst.operands[1].present)
     inst.operands[1].reg = inst.operands[0].reg;
   inst.instruction |= inst.operands[0].reg << 12;
@@ -8972,6 +8976,9 @@ do_mlas (void)
 static void
 do_mov (void)
 {
+  constraint (inst.reloc.type >= BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
+	      && inst.reloc.type <= BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC ,
+	      THUMB1_RELOC_ONLY);
   inst.instruction |= inst.operands[0].reg << 12;
   encode_arm_shifter_operand (1);
 }
@@ -10472,9 +10479,12 @@ do_t_add_sub (void)
 		  inst.instruction |= (Rd << 4) | Rs;
 		  if (inst.reloc.type < BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
 		      || inst.reloc.type > BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC)
-		    inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
-		  if (inst.size_req != 2)
-		    inst.relax = opcode;
+		  {
+		    if (inst.size_req == 2)
+		      inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
+		    else
+		      inst.relax = opcode;
+		  }
 		}
 	      else
 		constraint (inst.size_req == 2, BAD_HIREG);
@@ -10482,6 +10492,9 @@ do_t_add_sub (void)
 	  if (inst.size_req == 4
 	      || (inst.size_req != 2 && !opcode))
 	    {
+	      constraint (inst.reloc.type >= BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
+			  && inst.reloc.type <= BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC ,
+			  THUMB1_RELOC_ONLY);
 	      if (Rd == REG_PC)
 		{
 		  constraint (add, BAD_PC);
@@ -11826,17 +11839,21 @@ do_t_mov_cmp (void)
 	    {
 	      inst.instruction = THUMB_OP16 (opcode);
 	      inst.instruction |= Rn << 8;
-	      if (inst.size_req == 2)
+	      if (inst.reloc.type < BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
+		  || inst.reloc.type > BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC)
 		{
-		  if (inst.reloc.type < BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
-		      || inst.reloc.type > BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC)
+		  if (inst.size_req == 2)
 		    inst.reloc.type = BFD_RELOC_ARM_THUMB_IMM;
+		  else
+		    inst.relax = opcode;
 		}
-	      else
-		  inst.relax = opcode;
 	    }
 	  else
 	    {
+	      constraint (inst.reloc.type >= BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
+			  && inst.reloc.type <= BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC ,
+			  THUMB1_RELOC_ONLY);
+
 	      inst.instruction = THUMB_OP32 (inst.instruction);
 	      inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
 	      inst.instruction |= Rn << r0off;
diff --git a/gas/testsuite/gas/arm/adds-thumb1-reloc-local-armv7-m.d b/gas/testsuite/gas/arm/adds-thumb1-reloc-local-armv7-m.d
new file mode 100644
index 0000000..1bab56d
--- /dev/null
+++ b/gas/testsuite/gas/arm/adds-thumb1-reloc-local-armv7-m.d
@@ -0,0 +1,16 @@
+#objdump: -dr --prefix-addresses --show-raw-insn
+#skip: *-*-*coff *-*-pe *-*-wince *-*-*aout* *-*-netbsd *-*-riscix*
+#name: ADDS relocations against local symbols for armv7-m
+
+.*: +file format .*arm.*
+
+Disassembly of section .text:
+0[0-9a-f]+ <[^>]+> 3000      	adds	r0, #0
+			0: R_ARM_THM_ALU_ABS_G3_NC	bar
+0[0-9a-f]+ <[^>]+> 3000      	adds	r0, #0
+			2: R_ARM_THM_ALU_ABS_G2_NC	bar
+0[0-9a-f]+ <[^>]+> 3000      	adds	r0, #0
+			4: R_ARM_THM_ALU_ABS_G1_NC	bar
+0[0-9a-f]+ <[^>]+> 3000      	adds	r0, #0
+			6: R_ARM_THM_ALU_ABS_G0_NC	bar
+#...
diff --git a/gas/testsuite/gas/arm/adds-thumb1-reloc-local-armv7-m.s b/gas/testsuite/gas/arm/adds-thumb1-reloc-local-armv7-m.s
new file mode 100644
index 0000000..c5d95fc
--- /dev/null
+++ b/gas/testsuite/gas/arm/adds-thumb1-reloc-local-armv7-m.s
@@ -0,0 +1,13 @@
+.arch armv7-m
+.text
+.syntax unified
+.thumb
+foo:
+adds r0, #:upper8_15:#bar
+adds r0, #:upper0_7:#bar
+adds r0, #:lower8_15:#bar
+adds r0, #:lower0_7:#bar
+
+.space 0x10000
+
+bar:
diff --git a/gas/testsuite/gas/arm/movs-thumb1-reloc-local-armv7-m.d b/gas/testsuite/gas/arm/movs-thumb1-reloc-local-armv7-m.d
new file mode 100644
index 0000000..1e94394
--- /dev/null
+++ b/gas/testsuite/gas/arm/movs-thumb1-reloc-local-armv7-m.d
@@ -0,0 +1,16 @@
+#objdump: -dr --prefix-addresses --show-raw-insn
+#skip: *-*-*coff *-*-pe *-*-wince *-*-*aout* *-*-netbsd *-*-riscix*
+#name: MOVS relocations against local symbols for armv7-m
+
+.*: +file format .*arm.*
+
+Disassembly of section .text:
+0[0-9a-f]+ <[^>]+> 2000      	movs	r0, #0
+			0: R_ARM_THM_ALU_ABS_G3_NC	bar
+0[0-9a-f]+ <[^>]+> 2000      	movs	r0, #0
+			2: R_ARM_THM_ALU_ABS_G2_NC	bar
+0[0-9a-f]+ <[^>]+> 2000      	movs	r0, #0
+			4: R_ARM_THM_ALU_ABS_G1_NC	bar
+0[0-9a-f]+ <[^>]+> 2000      	movs	r0, #0
+			6: R_ARM_THM_ALU_ABS_G0_NC	bar
+#...
diff --git a/gas/testsuite/gas/arm/movs-thumb1-reloc-local-armv7-m.s b/gas/testsuite/gas/arm/movs-thumb1-reloc-local-armv7-m.s
new file mode 100644
index 0000000..6699fc7
--- /dev/null
+++ b/gas/testsuite/gas/arm/movs-thumb1-reloc-local-armv7-m.s
@@ -0,0 +1,13 @@
+.arch armv7-m
+.text
+.syntax unified
+.thumb
+foo:
+movs r0, #:upper8_15:#bar
+movs r0, #:upper0_7:#bar
+movs r0, #:lower8_15:#bar
+movs r0, #:lower0_7:#bar
+
+.space 0x10000
+
+bar:
diff --git a/ld/testsuite/ld-arm/arm-elf.exp b/ld/testsuite/ld-arm/arm-elf.exp
index a2082a8..0af32c0 100644
--- a/ld/testsuite/ld-arm/arm-elf.exp
+++ b/ld/testsuite/ld-arm/arm-elf.exp
@@ -235,6 +235,12 @@ set armelftests_common_3 {
     {"ADDS thumb1 relocations" "-static -T arm.ld" "" "" {thumb1-adds.s}
      {{objdump -dw thumb1-adds.d}}
      "thumb1-adds"}
+    {"MOVS thumb1 relocations for armv7-m target" "-static -T arm.ld" "" "" {thumb1-movs-armv7-m.s}
+     {{objdump -dw thumb1-movs.d}}
+     "thumb1-movs"}
+    {"ADDS thumb1 relocations for armv7-m target" "-static -T arm.ld" "" "" {thumb1-adds-armv7-m.s}
+     {{objdump -dw thumb1-adds.d}}
+     "thumb1-adds"}
 }
 
 run_ld_link_tests $armelftests_common_1
diff --git a/ld/testsuite/ld-arm/thumb1-adds-armv7-m.s b/ld/testsuite/ld-arm/thumb1-adds-armv7-m.s
new file mode 100644
index 0000000..9640072
--- /dev/null
+++ b/ld/testsuite/ld-arm/thumb1-adds-armv7-m.s
@@ -0,0 +1,43 @@
+	.text
+	.arch armv7-m
+	.syntax unified
+	.global	_start
+	.thumb_func
+	.type	_start, %function
+_start:
+	.thumb_func
+	.type	thumb1, %function
+thumb1:
+	adds r0, #:upper8_15:#thumb3
+	adds r1, #:upper0_7:#thumb3
+	adds r2, #:lower8_15:#thumb1
+	adds r3, #:lower0_7:#thumb1
+	adds r4, #:lower0_7:#thumb3
+	adds r5, #:lower8_15:#thumb3
+	adds r6, #:upper0_7:#thumb1
+	adds r7, #:upper8_15:#thumb1
+	.thumb_func
+	.type	thumb2, %function
+thumb2:
+	adds r0, #:upper8_15:#thumb3
+	adds r1, #:upper0_7:#(var2 + 1)
+	adds r2, #:lower8_15:#(thumb3 + 255)
+	adds r3, #:lower0_7:#(var1 + 0xaa)
+	adds r7, #:upper8_15:#var1 + 4
+	adds r6, #:upper0_7:#thumb3
+	adds r5, #:lower8_15:#var2 + 0xff
+	adds r4, #:lower0_7:#var2 - (-2)
+var1:
+	.byte 1
+var2:
+	.byte 2
+
+	.section .far, "ax", %progbits
+	.thumb_func
+	.type	thumb3, %function
+thumb3:
+	adds r0, #:upper8_15:#thumb1
+	adds r1, #:upper0_7:#thumb2
+	adds r2, #:lower8_15:#thumb3
+	adds r3, #:lower0_7:#thumb1
+
diff --git a/ld/testsuite/ld-arm/thumb1-movs-armv7-m.s b/ld/testsuite/ld-arm/thumb1-movs-armv7-m.s
new file mode 100644
index 0000000..ffb8273
--- /dev/null
+++ b/ld/testsuite/ld-arm/thumb1-movs-armv7-m.s
@@ -0,0 +1,43 @@
+	.text
+	.arch armv7-m
+	.syntax unified
+	.global	_start
+	.thumb_func
+	.type	_start, %function
+_start:
+	.thumb_func
+	.type	thumb1, %function
+thumb1:
+	movs r0, #:upper8_15:#thumb3
+	movs r1, #:upper0_7:#thumb3
+	movs r2, #:lower8_15:#thumb1
+	movs r3, #:lower0_7:#thumb1
+	movs r4, #:lower0_7:#thumb3
+	movs r5, #:lower8_15:#thumb3
+	movs r6, #:upper0_7:#thumb1
+	movs r7, #:upper8_15:#thumb1
+	.thumb_func
+	.type	thumb2, %function
+thumb2:
+	movs r0, #:upper8_15:#(thumb3 + 0)
+	movs r1, #:upper0_7:#(thumb2 + 1)
+	movs r2, #:lower8_15:#(var1 + 255)
+	movs r3, #:lower0_7:#var1
+	movs r7, #:upper8_15:#var1 + 4
+	movs r6, #:upper0_7:#var2
+	movs r5, #:lower8_15:#var2 + 0xff
+	movs r4, #:lower0_7:#var2 - (-1)
+var1:
+	.byte 1
+var2:
+	.byte 2
+
+	.section .far, "ax", %progbits
+	.thumb_func
+	.type	thumb3, %function
+thumb3:
+	movs r0, #:upper8_15:#thumb1
+	movs r1, #:upper0_7:#thumb2
+	movs r2, #:lower8_15:#thumb3
+	movs r3, #:lower0_7:#thumb1
+
-- 
2.7.0


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