https://github.com/jrtc27 updated https://github.com/llvm/llvm-project/pull/173285
>From b65b9570750b44e565a078fd92adca971515679a Mon Sep 17 00:00:00 2001 From: Jessica Clarke <[email protected]> Date: Mon, 22 Dec 2025 17:08:05 +0000 Subject: [PATCH 1/2] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20in?= =?UTF-8?q?itial=20version?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Created using spr 1.3.5 --- lld/ELF/SyntheticSections.h | 7 ++++++- lld/test/ELF/aarch64-pauth-rela-iplt-end.s | 20 ++++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 lld/test/ELF/aarch64-pauth-rela-iplt-end.s diff --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h index 16bdda8ef75bb..47d87e76357f3 100644 --- a/lld/ELF/SyntheticSections.h +++ b/lld/ELF/SyntheticSections.h @@ -528,7 +528,12 @@ class RelocationBaseSection : public SyntheticSection { return !relocs.empty() || llvm::any_of(relocsVec, [](auto &v) { return !v.empty(); }); } - size_t getSize() const override { return relocs.size() * this->entsize; } + size_t getSize() const override { + size_t count = relocs.size(); + for (const auto &v : relocsVec) + count += v.size(); + return count * this->entsize; + } size_t getRelativeRelocCount() const { return numRelativeRelocs; } void mergeRels(); void partitionRels(); diff --git a/lld/test/ELF/aarch64-pauth-rela-iplt-end.s b/lld/test/ELF/aarch64-pauth-rela-iplt-end.s new file mode 100644 index 0000000000000..b2c7fe0c61c99 --- /dev/null +++ b/lld/test/ELF/aarch64-pauth-rela-iplt-end.s @@ -0,0 +1,20 @@ +# REQUIRES: aarch64 +# RUN: llvm-mc -filetype=obj -triple=aarch64 %s -o %t.o +# RUN: ld.lld --static %t.o -o %t +# RUN: llvm-readelf -S -s -d %t | FileCheck %s + +## Verify that R_AARCH64_AUTH_RELATIVE relocations are included within the +## bounds of __rela_iplt_start/end, as relative relocations still emitted for +## static PDEs due to needing run-time signing. Historically this would not be +## the case if added to .rela.dyn with sharding. + +# CHECK: .rela.dyn RELA 0000000000200158 000158 000018 18 A 0 0 8 +# CHECK: 0000000000200158 0 NOTYPE LOCAL HIDDEN 1 __rela_iplt_start +# CHECK: 0000000000200170 0 NOTYPE LOCAL HIDDEN 1 __rela_iplt_end + +adrp x0, __rela_iplt_start +adrp x0, __rela_iplt_end + +.data +foo: +.quad foo@AUTH(da,42) >From 53daf0e1f0be9ee5a218ea8b39f7ee6268b2e2ab Mon Sep 17 00:00:00 2001 From: Jessica Clarke <[email protected]> Date: Wed, 24 Dec 2025 10:54:41 +0000 Subject: [PATCH 2/2] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20ch?= =?UTF-8?q?anges=20introduced=20through=20rebase?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Created using spr 1.3.5 [skip ci] --- lld/ELF/Relocations.cpp | 47 ++++++++++++++++------------------- lld/ELF/SyntheticSections.cpp | 6 ++++- lld/ELF/SyntheticSections.h | 32 +++++++++++++++++++++--- lld/ELF/Writer.cpp | 17 +++---------- 4 files changed, 58 insertions(+), 44 deletions(-) diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp index 5c23c76c80f9e..d60216da2b03f 100644 --- a/lld/ELF/Relocations.cpp +++ b/lld/ELF/Relocations.cpp @@ -705,39 +705,36 @@ static void addRelativeReloc(Ctx &ctx, InputSectionBase &isec, RelExpr expr, RelType type) { Partition &part = isec.getPartition(ctx); - if (sym.isTagged()) { - part.relaDyn->addRelativeReloc<shard>(ctx.target->relativeRel, isec, - offsetInSec, sym, addend, type, expr); - // With MTE globals, we always want to derive the address tag by `ldg`-ing - // the symbol. When we have a RELATIVE relocation though, we no longer have - // a reference to the symbol. Because of this, when we have an addend that - // puts the result of the RELATIVE relocation out-of-bounds of the symbol - // (e.g. the addend is outside of [0, sym.getSize()]), the AArch64 MemtagABI - // says we should store the offset to the start of the symbol in the target - // field. This is described in further detail in: - // https://github.com/ARM-software/abi-aa/blob/main/memtagabielf64/memtagabielf64.rst#841extended-semantics-of-r_aarch64_relative - if (addend < 0 || static_cast<uint64_t>(addend) >= sym.getSize()) - isec.relocations.push_back({R_ADDEND_NEG, type, offsetInSec, addend, &sym}); - return; - } - // Add a relative relocation. If relrDyn section is enabled, and the // relocation offset is guaranteed to be even, add the relocation to // the relrDyn section, otherwise add it to the relaDyn section. // relrDyn sections don't support odd offsets. Also, relrDyn sections // don't store the addend values, so we must write it to the relocated // address. - if (part.relrDyn && isec.addralign >= 2 && offsetInSec % 2 == 0) { - isec.addReloc({expr, type, offsetInSec, addend, &sym}); - if (shard) - part.relrDyn->relocsVec[parallel::getThreadIndex()].push_back( - {&isec, isec.relocs().size() - 1}); - else - part.relrDyn->relocs.push_back({&isec, isec.relocs().size() - 1}); + // + // MTE globals may need to store the original addend as well so cannot use + // relrDyn. TODO: It should be unambiguous when not using R_ADDEND_NEG below? + RelrBaseSection *relrDyn = part.relrDyn.get(); + if (sym.isTagged()) + relrDyn = nullptr; + if (relrDyn && isec.addralign >= 2 && offsetInSec % 2 == 0) { + relrDyn->addRelativeReloc<shard>(isec, offsetInSec, sym, addend, type, + expr); return; } part.relaDyn->addRelativeReloc<shard>(ctx.target->relativeRel, isec, offsetInSec, sym, addend, type, expr); + // With MTE globals, we always want to derive the address tag by `ldg`-ing + // the symbol. When we have a RELATIVE relocation though, we no longer have + // a reference to the symbol. Because of this, when we have an addend that + // puts the result of the RELATIVE relocation out-of-bounds of the symbol + // (e.g. the addend is outside of [0, sym.getSize()]), the AArch64 MemtagABI + // says we should store the offset to the start of the symbol in the target + // field. This is described in further detail in: + // https://github.com/ARM-software/abi-aa/blob/main/memtagabielf64/memtagabielf64.rst#841extended-semantics-of-r_aarch64_relative + if (sym.isTagged() && + (addend < 0 || static_cast<uint64_t>(addend) >= sym.getSize())) + isec.addReloc({R_ADDEND_NEG, type, offsetInSec, addend, &sym}); } template <class PltSection, class GotPltSection> @@ -1014,8 +1011,8 @@ void RelocScan::process(RelExpr expr, RelType type, uint64_t offset, // When symbol values are determined in // finalizeAddressDependentContent, some .relr.auth.dyn relocations // may be moved to .rela.dyn. - sec->addReloc({expr, type, offset, addend, &sym}); - part.relrAuthDyn->relocs.push_back({sec, sec->relocs().size() - 1}); + part.relrAuthDyn->addRelativeReloc(*sec, offset, sym, addend, type, + expr); } else { part.relaDyn->addReloc({R_AARCH64_AUTH_RELATIVE, sec, offset, false, sym, addend, R_ABS}); diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index 1e9d44fa37bea..c81f649861a73 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -674,7 +674,6 @@ GotSection::GotSection(Ctx &ctx) numEntries = ctx.target->gotHeaderEntriesNum; } -void GotSection::addConstant(const Relocation &r) { relocations.push_back(r); } void GotSection::addEntry(const Symbol &sym) { assert(sym.auxIdx == ctx.symAux.size() - 1); ctx.symAux.back().gotIdx = numEntries++; @@ -1708,6 +1707,9 @@ void RelocationBaseSection::partitionRels() { } void RelocationBaseSection::finalizeContents() { + mergeRels(); + // Compute DT_RELACOUNT to be used by part.dynamic. + partitionRels(); SymbolTableBaseSection *symTab = getPartition(ctx).dynSymTab.get(); // When linking glibc statically, .rel{,a}.plt contains R_*_IRELATIVE @@ -1797,6 +1799,8 @@ void RelrBaseSection::mergeRels() { relocsVec.clear(); } +void RelrBaseSection::finalizeContents() { mergeRels(); } + template <class ELFT> AndroidPackedRelocationSection<ELFT>::AndroidPackedRelocationSection( Ctx &ctx, StringRef name, unsigned concurrency) diff --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h index 16bdda8ef75bb..8971d5f6c2349 100644 --- a/lld/ELF/SyntheticSections.h +++ b/lld/ELF/SyntheticSections.h @@ -113,7 +113,7 @@ class GotSection final : public SyntheticSection { bool isNeeded() const override; void writeTo(uint8_t *buf) override; - void addConstant(const Relocation &r); + void addConstant(const Relocation &r) { addReloc(r); } void addEntry(const Symbol &sym); void addAuthEntry(const Symbol &sym); bool addTlsDescEntry(const Symbol &sym); @@ -530,14 +530,14 @@ class RelocationBaseSection : public SyntheticSection { } size_t getSize() const override { return relocs.size() * this->entsize; } size_t getRelativeRelocCount() const { return numRelativeRelocs; } - void mergeRels(); - void partitionRels(); void finalizeContents() override; int32_t dynamicTag, sizeDynamicTag; SmallVector<DynamicReloc, 0> relocs; protected: + void mergeRels(); + void partitionRels(); void computeRels(); // Used when parallel relocation scanning adds relocations. The elements // will be moved into relocs by mergeRel(). @@ -592,15 +592,39 @@ struct RelativeReloc { class RelrBaseSection : public SyntheticSection { public: RelrBaseSection(Ctx &, unsigned concurrency, bool isAArch64Auth = false); - void mergeRels(); + /// Add a dynamic relocation without writing an addend to the output section. + /// This overload can be used if the addends are written directly instead of + /// using relocations on the input section. + template <bool shard = false> void addReloc(const RelativeReloc &reloc) { + relocs.push_back(reloc); + } + /// Add a relative dynamic relocation that uses the target address of \p sym + /// (i.e. InputSection::getRelocTargetVA()) + \p addend as the addend. + template <bool shard = false> + void addRelativeReloc(InputSectionBase &isec, uint64_t offsetInSec, + Symbol &sym, int64_t addend, RelType addendRelType, + RelExpr expr) { + assert(expr != R_ADDEND && "expected non-addend relocation expression"); + isec.addReloc({expr, addendRelType, offsetInSec, addend, &sym}); + addReloc<shard>({&isec, isec.relocs().size() - 1}); + } bool isNeeded() const override { return !relocs.empty() || llvm::any_of(relocsVec, [](auto &v) { return !v.empty(); }); } + void finalizeContents() override; SmallVector<RelativeReloc, 0> relocs; + +protected: + void mergeRels(); SmallVector<SmallVector<RelativeReloc, 0>, 0> relocsVec; }; +template <> +inline void RelrBaseSection::addReloc<true>(const RelativeReloc &reloc) { + relocsVec[llvm::parallel::getThreadIndex()].push_back(reloc); +} + // RelrSection is used to encode offsets for relative relocations. // Proposal for adding SHT_RELR sections to generic-abi is here: // https://groups.google.com/forum/#!topic/generic-abi/bX460iggiKg diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index db5626e701ad6..57202f42cce5b 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -2111,20 +2111,9 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() { // Dynamic section must be the last one in this list and dynamic // symbol table section (dynSymTab) must be the first one. for (Partition &part : ctx.partitions) { - if (part.relaDyn) { - part.relaDyn->mergeRels(); - // Compute DT_RELACOUNT to be used by part.dynamic. - part.relaDyn->partitionRels(); - finalizeSynthetic(ctx, part.relaDyn.get()); - } - if (part.relrDyn) { - part.relrDyn->mergeRels(); - finalizeSynthetic(ctx, part.relrDyn.get()); - } - if (part.relrAuthDyn) { - part.relrAuthDyn->mergeRels(); - finalizeSynthetic(ctx, part.relrAuthDyn.get()); - } + finalizeSynthetic(ctx, part.relaDyn.get()); + finalizeSynthetic(ctx, part.relrDyn.get()); + finalizeSynthetic(ctx, part.relrAuthDyn.get()); finalizeSynthetic(ctx, part.dynSymTab.get()); finalizeSynthetic(ctx, part.gnuHashTab.get()); _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
