This is the mail archive of the
binutils-cvs@sourceware.org
mailing list for the binutils project.
[binutils-gdb] Fix use of ARM ADR and ADRl pseudo-instructions with thumb function symbols.
- From: Nick Clifton <nickc at sourceware dot org>
- To: bfd-cvs at sourceware dot org
- Date: 15 May 2017 14:29:43 -0000
- Subject: [binutils-gdb] Fix use of ARM ADR and ADRl pseudo-instructions with thumb function symbols.
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=52a86f843b6dee1de9977293da9786649b146b05
commit 52a86f843b6dee1de9977293da9786649b146b05
Author: Nick Clifton <nickc@redhat.com>
Date: Mon May 15 15:29:02 2017 +0100
Fix use of ARM ADR and ADRl pseudo-instructions with thumb function symbols.
PR gas/21458
* config/tc-arm.c (do_adr): If the ADR involves a thumb function
symbol, ensure that the T bit will be set.
(do_adrl): Likewise.
(do_t_adr): Likewise.
* testsuite/gas/arm/pr21458.s: New test.
* testsuite/gas/arm/pr21458.d: New test driver.
Diff:
---
gas/ChangeLog | 10 ++++++++++
gas/config/tc-arm.c | 19 ++++++++++++++++++-
gas/testsuite/gas/arm/pr21458.d | 27 +++++++++++++++++++++++++++
gas/testsuite/gas/arm/pr21458.s | 40 ++++++++++++++++++++++++++++++++++++++++
4 files changed, 95 insertions(+), 1 deletion(-)
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 293930b..9d0fa57 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,13 @@
+2017-05-15 Nick Clifton <nickc@redhat.com>
+
+ PR gas/21458
+ * config/tc-arm.c (do_adr): If the ADR involves a thumb function
+ symbol, ensure that the T bit will be set.
+ (do_adrl): Likewise.
+ (do_t_adr): Likewise.
+ * testsuite/gas/arm/pr21458.s: New test.
+ * testsuite/gas/arm/pr21458.d: New test driver.
+
2017-05-15 Maciej W. Rozycki <macro@imgtec.com>
* testsuite/gas/mips/mips16-pcrel-1.d: Remove `-mips3' from `as'
diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index 7e35c34..08824b4 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -8351,6 +8351,12 @@ do_adr (void)
inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
inst.reloc.pc_rel = 1;
inst.reloc.exp.X_add_number -= 8;
+
+ if (inst.reloc.exp.X_op == O_symbol
+ && inst.reloc.exp.X_add_symbol != NULL
+ && S_IS_DEFINED (inst.reloc.exp.X_add_symbol)
+ && THUMB_IS_FUNC (inst.reloc.exp.X_add_symbol))
+ inst.reloc.exp.X_add_number += 1;
}
/* This is a pseudo-op of the form "adrl rd, label" to be converted
@@ -8369,6 +8375,12 @@ do_adrl (void)
inst.reloc.pc_rel = 1;
inst.size = INSN_SIZE * 2;
inst.reloc.exp.X_add_number -= 8;
+
+ if (inst.reloc.exp.X_op == O_symbol
+ && inst.reloc.exp.X_add_symbol != NULL
+ && S_IS_DEFINED (inst.reloc.exp.X_add_symbol)
+ && THUMB_IS_FUNC (inst.reloc.exp.X_add_symbol))
+ inst.reloc.exp.X_add_number += 1;
}
static void
@@ -10734,9 +10746,14 @@ do_t_adr (void)
inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
inst.reloc.exp.X_add_number -= 4; /* PC relative adjust. */
inst.reloc.pc_rel = 1;
-
inst.instruction |= Rd << 4;
}
+
+ if (inst.reloc.exp.X_op == O_symbol
+ && inst.reloc.exp.X_add_symbol != NULL
+ && S_IS_DEFINED (inst.reloc.exp.X_add_symbol)
+ && THUMB_IS_FUNC (inst.reloc.exp.X_add_symbol))
+ inst.reloc.exp.X_add_number += 1;
}
/* Arithmetic instructions for which there is just one 16-bit
diff --git a/gas/testsuite/gas/arm/pr21458.d b/gas/testsuite/gas/arm/pr21458.d
new file mode 100644
index 0000000..c0b1d12
--- /dev/null
+++ b/gas/testsuite/gas/arm/pr21458.d
@@ -0,0 +1,27 @@
+#objdump: -d --prefix-addresses --show-raw-insn
+#name: ADR(L) for Thumb functions
+#skip: *-*-pe *-wince-* *-*-coff *-*-vxworks
+
+# Test that using ADR(L) on thumb function symbols sets the T bit.
+
+.*: +file format .*arm.*
+
+Disassembly of section .text:
+0+00000 <.*> 4770[ ]+bx[ ]+lr
+0+00002 <.*> 46c0[ ]+nop[ ]+; \(mov r8, r8\)
+0+00004 <.*> e12fff1e[ ]+bx[ ]+lr
+0+00008 <.*> f2af 000b[ ]+subw[ ]+r0, pc, #11
+0+0000c <.*> 4780[ ]+blx[ ]+r0
+0+0000e <.*> f2af 020c[ ]+subw[ ]+r2, pc, #12
+0+00012 <.*> 4790[ ]+blx[ ]+r2
+0+00014 <.*> e24f401b[ ]+sub[ ]+r4, pc, #27
+0+00018 <.*> e1a00000[ ]+nop[ ]+; \(mov r0, r0\)
+0+0001c <.*> e12fff34[ ]+blx[ ]+r4
+0+00020 <.*> e24f6024[ ]+sub[ ]+r6, pc, #36[ ]+; 0x24
+0+00024 <.*> e1a00000[ ]+nop[ ]+; \(mov r0, r0\)
+0+00028 <.*> e12fff36[ ]+blx[ ]+r6
+0+0002c <.*> e24f8033[ ]+sub[ ]+r8, pc, #51[ ]+; 0x33
+0+00030 <.*> e12fff38[ ]+blx[ ]+r8
+0+00034 <.*> e24fa038[ ]+sub[ ]+sl, pc, #56[ ]+; 0x38
+0+00038 <.*> e12fff3a[ ]+blx[ ]+sl
+0+0003c <.*> 324fc043[ ]+subcc[ ]+ip, pc, #67[ ]+; 0x43
diff --git a/gas/testsuite/gas/arm/pr21458.s b/gas/testsuite/gas/arm/pr21458.s
new file mode 100644
index 0000000..0d89b0c
--- /dev/null
+++ b/gas/testsuite/gas/arm/pr21458.s
@@ -0,0 +1,40 @@
+.syntax unified
+.thumb
+.text
+.align 2
+.global __thumbFn
+.type __testFn, %function
+.thumb_func
+__thumbFn:
+ bx lr
+ nop
+
+.arm
+.global __armFn
+.type __armFn, %function
+__armFn:
+ bx lr
+
+.thumb
+.global __test_thumb
+.type __test_thumb, %function
+.thumb_func
+__test_thumb:
+ ADR R0,__thumbFn
+ BLX R0
+ ADR R2,__armFn
+ BLX R2
+
+.arm
+.global __test_arm
+.type __test_arm, %function
+__test_arm:
+ ADRL R4,__thumbFn
+ BLX R4
+ ADRL R6,__armFn
+ BLX R6
+ ADR r8, __thumbFn
+ blx r8
+ ADR r10, __armFn
+ blx r10
+ adrlo r12, __thumbFn