This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: Fwd: [PATCH] arm: ensure symbol is a thumb symbol in new binutils
- From: Nick Clifton <nickc at redhat dot com>
- To: Christophe PRIOUZEAU <christophe dot priouzeau at st dot com>, Romain Naour <romain dot naour at gmail dot com>
- Cc: "binutils at sourceware dot org" <binutils at sourceware dot org>, buildroot <buildroot at buildroot dot org>
- Date: Mon, 4 Jun 2018 15:13:33 +0100
- Subject: Re: Fwd: [PATCH] arm: ensure symbol is a thumb symbol in new binutils
- References: <20171121172751.29545-1-Jason@zx2c4.com> <20171121173857.GJ31757@n2100.armlinux.org.uk> <CAHmME9quDFbdOR9hKRz-Px=Mh3FvYEyhVrs4V_+JT+GjDajMrA@mail.gmail.com> <20171121174942.GK31757@n2100.armlinux.org.uk> <CAHmME9oMTNJFnOwfhu26QSRSP92Axbc-+v9cCPsTKxekZvGvxg@mail.gmail.com> <20171123103518.GL31757@n2100.armlinux.org.uk> <CAHmME9qBxgDV-HGeqj75ohr=4Bf+TD73PcC0DUqTRh5PTOKyhQ@mail.gmail.com> <20171123140228.GP31757@n2100.armlinux.org.uk> <CAKv+Gu8TJi8qSWAkL231WhQkWxK+vSQm2tnQn_qN-2wdFaNaEA@mail.gmail.com> <765227b5-981d-0cea-c831-73cfe2f58721@redhat.com> <aaf57bb5-13e6-852c-0f67-f72aedef0e79@gmail.com> <254af731-459b-1f1d-2d93-27c5a91e7bfb@redhat.com> <1e9b8ffd-cc1d-2c39-e34a-d1e33f49a645@gmail.com> <aca33630-3c36-4ba9-0237-b971cb7ffee7@st.com>
Hi Christophe,
> I have made the test on buildroot 2018.05-rc3 with bintutils 2.29.1 and
> 2.30,
> for the two test my boot failed. The proposition of correction doesn't work.
Ho hum. OK, please could you try out this attached patch instead. It is part
of a larger patch to allow the behaviour of the assembler to be controlled by
a command line option, whose default is set at configure time. I just want to
be sure that the "ADR-does-NOT-set-interworking" default option actually does
work before I complete the rest of the patch.
Cheers
Nick
diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index dbaf1627bb..a72084fa3c 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -145,6 +145,32 @@ static int fix_v4bx = FALSE;
/* Warn on using deprecated features. */
static int warn_on_deprecated = TRUE;
+/* Customises the behaviour of the ADR and ADRL pseudo-ops when given a thumb
+ function pointer as an argument. If this option is TRUE then the bottom
+ bit of the address stored into the destination register will be set.
+ Otherwise it will be left alone (and presumably will be clear).
+
+ This option and customised default behaviour are necessary because there
+ is no clear specification for the behaviour of ADR and ADRL on thumb
+ symbols in the ARM Reference Manual. Versions of the binutils prior to
+ 2.29 did not set the bit at all. Versions 2.29 and 2.30 unconditionally
+ set the bit. Versions 2.31 onwards have this customisation option.
+
+ Setting the interworking bit breaks the ARM Linux kernel. But not setting
+ the bit breaks code like this:
+
+ ADR R0,__testFnPtr
+ BLX R0
+
+ if __testFnPtr is a thumb function pointer, but works if it is an ARM
+ function pointer. */
+#ifdef DEFAULT_THUMB_ADR_SETS_INTERWORKING
+static int thumb_adr_sets_interworking = TRUE;
+#else
+static int thumb_adr_sets_interworking = FALSE;
+#endif
+
+
/* Understand CodeComposer Studio assembly syntax. */
bfd_boolean codecomposer_syntax = FALSE;
@@ -8419,11 +8445,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 (thumb_adr_sets_interworking
+ && 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
@@ -8443,11 +8470,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 (thumb_adr_sets_interworking
+ && 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
@@ -25725,6 +25753,17 @@ struct arm_option_table arm_opts[] =
&warn_on_deprecated, 0, NULL},
{"mwarn-syms", N_("warn about symbols that match instruction names [default]"), (int *) (& flag_warn_syms), TRUE, NULL},
{"mno-warn-syms", N_("disable warnings about symobls that match instructions"), (int *) (& flag_warn_syms), FALSE, NULL},
+#ifdef DEFAULT_THUMB_ADR_SETS_INTERWORKING
+ {"mthumb-adr-sets-interworking", N_("ADR sets interworking bit [default]"),
+ (int *) (& thumb_adr_sets_interworking), TRUE, NULL},
+ {"mno-thumb-adr-sets-interworking", N_("ADR does not set interworking bit"),
+ (int *) (& thumb_adr_sets_interworking), FALSE, NULL},
+#else
+ {"mthumb-adr-sets-interworking", N_("adr sets interworking bit"),
+ (int *) (& thumb_adr_sets_interworking), TRUE, NULL},
+ {"mno-thumb-adr-sets-interworking", N_("adr does not set interworking bit [default]"),
+ (int *) (& thumb_adr_sets_interworking), FALSE, NULL},
+#endif
{NULL, NULL, NULL, 0, NULL}
};