This is the mail archive of the
binutils-cvs@sourceware.org
mailing list for the binutils project.
[binutils-gdb] [GOLD] Don't install branch-to-stub for TLS relaxed ERRATUM 843419 sequences on AArch64
- From: Jiong Wang <jiwang at sourceware dot org>
- To: bfd-cvs at sourceware dot org
- Date: 15 Jun 2017 10:25:40 -0000
- Subject: [binutils-gdb] [GOLD] Don't install branch-to-stub for TLS relaxed ERRATUM 843419 sequences on AArch64
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=37de058ab2e9619fbb6dea52ec2773a5d65619c4
commit 37de058ab2e9619fbb6dea52ec2773a5d65619c4
Author: Jiong Wang <jiong.wang@arm.com>
Date: Thu Jun 15 10:35:28 2017 +0100
[GOLD] Don't install branch-to-stub for TLS relaxed ERRATUM 843419 sequences on AArch64
TLS relaxation may change erratum 843419 sequences that those offending ADRP
instructions actually transformed into other instructions in which case there
is erratum 843419 risk anymore that we should avoid installing unnecessary
branch-to-stub.
gold/
* aarch64.cc (Insn_utilities::is_mrs_tpidr_el0): New method.
(AArch64_relobj<size, big_endian>::try_fix_erratum_843419_optimized):
Return ture for some TLS relaxed sequences.
Diff:
---
gold/ChangeLog | 6 ++++++
gold/aarch64.cc | 31 +++++++++++++++++++++++++++++--
2 files changed, 35 insertions(+), 2 deletions(-)
diff --git a/gold/ChangeLog b/gold/ChangeLog
index e3c4472..a0aefdd 100644
--- a/gold/ChangeLog
+++ b/gold/ChangeLog
@@ -1,3 +1,9 @@
+2017-06-15 Jiong Wang <jiong.wang@arm.com>
+
+ * aarch64.cc (Insn_utilities::is_mrs_tpidr_el0): New method.
+ (AArch64_relobj<size, big_endian>::try_fix_erratum_843419_optimized):
+ Return ture for some TLS relaxed sequences.
+
2017-06-07 Eric Christopher <echristo@gmail.com>
* aarch64.cc (maybe_apply_stub): Add debug logging for looking
diff --git a/gold/aarch64.cc b/gold/aarch64.cc
index 2470986..7309ded 100644
--- a/gold/aarch64.cc
+++ b/gold/aarch64.cc
@@ -110,6 +110,10 @@ public:
is_adrp(const Insntype insn)
{ return (insn & 0x9F000000) == 0x90000000; }
+ static bool
+ is_mrs_tpidr_el0(const Insntype insn)
+ { return (insn & 0xFFFFFFE0) == 0xd53bd040; }
+
static unsigned int
aarch64_rm(const Insntype insn)
{ return aarch64_bits(insn, 16, 5); }
@@ -2010,9 +2014,32 @@ AArch64_relobj<size, big_endian>::try_fix_erratum_843419_optimized(
E843419_stub<size, big_endian>* e843419_stub =
reinterpret_cast<E843419_stub<size, big_endian>*>(stub);
AArch64_address pc = pview.address + e843419_stub->adrp_sh_offset();
- Insntype* adrp_view = reinterpret_cast<Insntype*>(
- pview.view + e843419_stub->adrp_sh_offset());
+ unsigned int adrp_offset = e843419_stub->adrp_sh_offset ();
+ Insntype* adrp_view = reinterpret_cast<Insntype*>(pview.view + adrp_offset);
Insntype adrp_insn = adrp_view[0];
+
+ // If the instruction at adrp_sh_offset is "mrs R, tpidr_el0", it may come
+ // from IE -> LE relaxation etc. This is a side-effect of TLS relaxation that
+ // ADRP has been turned into MRS, there is no erratum risk anymore.
+ // Therefore, we return true to avoid doing unnecessary branch-to-stub.
+ if (Insn_utilities::is_mrs_tpidr_el0(adrp_insn))
+ return true;
+
+ // If the instruction at adrp_sh_offset is not ADRP and the instruction before
+ // it is "mrs R, tpidr_el0", it may come from LD -> LE relaxation etc.
+ // Like the above case, there is no erratum risk any more, we can safely
+ // return true.
+ if (!Insn_utilities::is_adrp(adrp_insn) && adrp_offset)
+ {
+ Insntype* prev_view
+ = reinterpret_cast<Insntype*>(pview.view + adrp_offset - 4);
+ Insntype prev_insn = prev_view[0];
+
+ if (Insn_utilities::is_mrs_tpidr_el0(prev_insn))
+ return true;
+ }
+
+ /* If we reach here, the first instruction must be ADRP. */
gold_assert(Insn_utilities::is_adrp(adrp_insn));
// Get adrp 33-bit signed imm value.
int64_t adrp_imm = Insn_utilities::