From: Nick Clifton Date: Mon, 15 May 2017 14:29:02 +0000 (+0100) Subject: Fix use of ARM ADR and ADRl pseudo-instructions with thumb function symbols. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=52a86f843b6dee1de9977293da9786649b146b05;p=binutils-gdb.git 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 --git a/gas/ChangeLog b/gas/ChangeLog index 293930b280e..9d0fa57082e 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,13 @@ +2017-05-15 Nick Clifton + + 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 * 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 7e35c348d20..08824b4c9b2 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 00000000000..c0b1d126812 --- /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 00000000000..0d89b0cb58b --- /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