[llvm-branch-commits] [lld] release/23.x: [lld] Don't drop RELR relocations for late-added GOT entries (#211911) (PR #224946)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Sun Sep 20 10:48:21 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-lld-elf
Author: llvmbot
<details>
<summary>Changes</summary>
Backport 5565740f2367093b89481ba7371adf820971977d
Requested by: @<!-- -->nikic
---
Full diff: https://github.com/llvm/llvm-project/pull/224946.diff
3 Files Affected:
- (modified) lld/ELF/Relocations.cpp (+2-2)
- (modified) lld/ELF/SyntheticSections.h (+6-2)
- (added) lld/test/ELF/x86-64-gotpc-relax-too-far-relr.s (+26)
``````````diff
diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp
index 4702d941d28ca4..a1d3c5c2ea005f 100644
--- a/lld/ELF/Relocations.cpp
+++ b/lld/ELF/Relocations.cpp
@@ -724,8 +724,8 @@ static void addRelativeReloc(Ctx &ctx, InputSectionBase &isec,
if (sym.isTagged())
relrDyn = nullptr;
if (relrDyn && isec.addralign >= 2 && offsetInSec % 2 == 0) {
- relrDyn->addRelativeReloc(isec, offsetInSec, sym, addend, type, expr,
- shard);
+ relrDyn->addRelativeReloc<concurrent>(isec, offsetInSec, sym, addend, type,
+ expr, shard);
return;
}
RelType relativeType = ctx.target->relativeRel;
diff --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h
index 523f6587899fe1..1079275439bc7f 100644
--- a/lld/ELF/SyntheticSections.h
+++ b/lld/ELF/SyntheticSections.h
@@ -609,12 +609,16 @@ class RelrBaseSection : public SyntheticSection {
RelrBaseSection(Ctx &, unsigned concurrency, bool isAArch64Auth = false);
/// Add a relative dynamic relocation that uses the target address of \p sym
/// (i.e. InputSection::getRelocTargetVA()) + \p addend as the addend.
+ template <bool concurrent = false>
void addRelativeReloc(InputSectionBase &isec, uint64_t offsetInSec,
Symbol &sym, int64_t addend, RelType addendRelType,
- RelExpr expr, unsigned shard) {
+ RelExpr expr, unsigned shard = 0) {
assert(expr != R_ADDEND && "expected non-addend relocation expression");
isec.addReloc({expr, addendRelType, offsetInSec, addend, &sym});
- relocsVec[shard].push_back({&isec, isec.relocs().size() - 1});
+ if constexpr (concurrent)
+ relocsVec[shard].push_back({&isec, isec.relocs().size() - 1});
+ else
+ relocs.push_back({&isec, isec.relocs().size() - 1});
}
bool isNeeded() const override {
return !relocs.empty() ||
diff --git a/lld/test/ELF/x86-64-gotpc-relax-too-far-relr.s b/lld/test/ELF/x86-64-gotpc-relax-too-far-relr.s
new file mode 100644
index 00000000000000..6c5e5f4368a410
--- /dev/null
+++ b/lld/test/ELF/x86-64-gotpc-relax-too-far-relr.s
@@ -0,0 +1,26 @@
+# REQUIRES: x86
+## Test that RELR relocations added when unrelaxing GOTPCREL relocations
+## during layout optimization (relaxOnce) are included in .relr.dyn.
+## .quad foo ensures .relr.dyn is not removed before unrelaxing.
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t.o
+# RUN: ld.lld -pie --pack-dyn-relocs=relr --section-start=.text=0x10000 --section-start=.got=0x20000 --section-start=.data=0x100000000 %t.o -o %t
+# RUN: llvm-readobj -r %t | FileCheck %s
+
+# CHECK: Relocations [
+# CHECK-NEXT: Section ({{.*}}) .relr.dyn {
+# CHECK-NEXT: 0x20000 R_X86_64_RELATIVE -
+# CHECK-NEXT: 0x100000000 R_X86_64_RELATIVE -
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+
+.text
+.globl _start
+_start:
+ movq foo at GOTPCREL(%rip), %rax
+
+.section .data,"aw", at progbits
+.align 8
+.globl foo
+foo:
+ .quad foo
``````````
</details>
https://github.com/llvm/llvm-project/pull/224946
More information about the llvm-branch-commits
mailing list