From fc6141f097056f830a412afebed8d81a9d72b696 Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Wed, 20 Jun 2018 12:38:10 +0100 Subject: [PATCH] Change the ARM assembler's ADR and ADRl pseudo-ops so that they will only set the bottom bit of imported thumb function symbols if the -mthumb-interwork option is active. For more information see the email thread starting here: https://www.sourceware.org/ml/binutils/2018-05/msg00348.html PR 21458 * tc-arm.c (do_adr): Only set the bottom bit of an imported thumb function symbol address if -mthumb-interwork is active. (do_adrl): Likewise. * doc/c-arm.texi: Update descriptions of the -mthumb-interwork option and the ADR and ADRL pseudo-ops. * NEWS: Mention the new behaviour of the ADR and ADRL pseudo-ops. * testsuite/gas/arm/pr21458.d: Add -mthumb-interwork option to assembler command line. * testsuite/gas/arm/adr.d: Likewise. * testsuite/gas/arm/adrl.d: Likewise. --- gas/ChangeLog | 14 ++++++++++++++ gas/NEWS | 4 ++++ gas/config/tc-arm.c | 10 ++++++---- gas/doc/c-arm.texi | 17 ++++++++++++++++- gas/testsuite/gas/arm/adr.d | 1 + gas/testsuite/gas/arm/adrl.d | 1 + gas/testsuite/gas/arm/pr21458.d | 3 ++- 7 files changed, 44 insertions(+), 6 deletions(-) Index: git/gas/config/tc-arm.c =================================================================== --- git.orig/gas/config/tc-arm.c +++ git/gas/config/tc-arm.c @@ -8410,11 +8410,12 @@ do_adr (void) inst.reloc.pc_rel = 1; inst.reloc.exp.X_add_number -= 8; - if (inst.reloc.exp.X_op == O_symbol + if (support_interwork + && 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; + inst.reloc.exp.X_add_number |= 1; } /* This is a pseudo-op of the form "adrl rd, label" to be converted @@ -8434,11 +8435,12 @@ do_adrl (void) inst.size = INSN_SIZE * 2; inst.reloc.exp.X_add_number -= 8; - if (inst.reloc.exp.X_op == O_symbol + if (support_interwork + && 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; + inst.reloc.exp.X_add_number |= 1; } static void Index: git/gas/doc/c-arm.texi =================================================================== --- git.orig/gas/doc/c-arm.texi +++ git/gas/doc/c-arm.texi @@ -317,7 +317,8 @@ instructions; that is, it should behave @cindex @code{-mthumb-interwork} command line option, ARM @item -mthumb-interwork This option specifies that the output generated by the assembler should -be marked as supporting interworking. +be marked as supporting interworking. It also affects the behaviour +of the @code{ADR} and @code{ADRL} pseudo opcodes. @cindex @code{-mimplicit-it} command line option, ARM @item -mimplicit-it=never @@ -1060,6 +1061,16 @@ out of range, or if it is not defined in the ADR instruction, then an error will be generated. This instruction will not make use of the literal pool. +If @var{label} is a thumb function symbol, and thumb interworking has +been enabled via the @option{-mthumb-interwork} option then the bottom +bit of the value stored into @var{register} will be set. This allows +the following sequence to work as expected: + +@smallexample + adr r0, thumb_function + blx r0 +@end smallexample + @cindex @code{ADRL reg,