[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