From b1fea01f887da629bb662762d360f74e5a3b618b Mon Sep 17 00:00:00 2001 From: tobhe Date: Sun, 26 Nov 2023 22:18:45 +0000 Subject: [PATCH] Add arm64 bti pads for range extension thunks. Large arm64 binaries like chromium use range extension thunks for accessing plt entries. Add bti landing pads for the additional indirection. upstream commit: 60827df765156cee6cca3dc5049388dde9dac1c0 ok kettenis@ --- gnu/llvm/lld/ELF/Arch/AArch64.cpp | 3 ++- gnu/llvm/lld/ELF/Symbols.cpp | 2 +- gnu/llvm/lld/ELF/Symbols.h | 3 +++ gnu/llvm/lld/ELF/Thunks.cpp | 4 +++- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/gnu/llvm/lld/ELF/Arch/AArch64.cpp b/gnu/llvm/lld/ELF/Arch/AArch64.cpp index 1ed1227dce6..dcea062c514 100644 --- a/gnu/llvm/lld/ELF/Arch/AArch64.cpp +++ b/gnu/llvm/lld/ELF/Arch/AArch64.cpp @@ -916,7 +916,8 @@ void AArch64BtiPac::writePlt(uint8_t *buf, const Symbol &sym, // escape to shared objects. isInIplt indicates a non-preemptible ifunc. Its // address may escape if referenced by a direct relocation. The condition is // conservative. - bool hasBti = btiHeader && (sym.hasFlag(NEEDS_COPY) || sym.isInIplt); + bool hasBti = btiHeader && + (sym.hasFlag(NEEDS_COPY) || sym.isInIplt || sym.thunkAccessed); if (hasBti) { memcpy(buf, btiData, sizeof(btiData)); buf += sizeof(btiData); diff --git a/gnu/llvm/lld/ELF/Symbols.cpp b/gnu/llvm/lld/ELF/Symbols.cpp index 96ae7a509c9..5addbaf3d0e 100644 --- a/gnu/llvm/lld/ELF/Symbols.cpp +++ b/gnu/llvm/lld/ELF/Symbols.cpp @@ -25,7 +25,7 @@ using namespace llvm::ELF; using namespace lld; using namespace lld::elf; -static_assert(sizeof(SymbolUnion) <= 64, "SymbolUnion too large"); +static_assert(sizeof(SymbolUnion) <= 72, "SymbolUnion too large"); template struct AssertSymbol { static_assert(std::is_trivially_destructible(), diff --git a/gnu/llvm/lld/ELF/Symbols.h b/gnu/llvm/lld/ELF/Symbols.h index 19ffc8fa7b4..865fba390fa 100644 --- a/gnu/llvm/lld/ELF/Symbols.h +++ b/gnu/llvm/lld/ELF/Symbols.h @@ -295,6 +295,9 @@ public: // True if defined in a DSO as protected visibility. uint8_t dsoProtected : 1; + // True if targeted by a range extension thunk. + uint8_t thunkAccessed : 1; + // Temporary flags used to communicate which symbol entries need PLT and GOT // entries during postScanRelocations(); std::atomic flags; diff --git a/gnu/llvm/lld/ELF/Thunks.cpp b/gnu/llvm/lld/ELF/Thunks.cpp index 5964196a1ba..bed059bf979 100644 --- a/gnu/llvm/lld/ELF/Thunks.cpp +++ b/gnu/llvm/lld/ELF/Thunks.cpp @@ -1217,7 +1217,9 @@ bool PPC64LongBranchThunk::isCompatibleWith(const InputSection &isec, return rel.type == R_PPC64_REL24 || rel.type == R_PPC64_REL14; } -Thunk::Thunk(Symbol &d, int64_t a) : destination(d), addend(a), offset(0) {} +Thunk::Thunk(Symbol &d, int64_t a) : destination(d), addend(a), offset(0) { + destination.thunkAccessed = true; +} Thunk::~Thunk() = default; -- 2.20.1