https://github.com/llvmbot created https://github.com/llvm/llvm-project/pull/224946
Backport 5565740f2367093b89481ba7371adf820971977d Requested by: @nikic >From 016aefac95b77405ba74c37d2fd78a8a272f5854 Mon Sep 17 00:00:00 2001 From: Arthur Eubanks <[email protected]> Date: Mon, 27 Jul 2026 10:39:23 -0700 Subject: [PATCH] [lld] Don't drop RELR relocations for late-added GOT entries (#211911) In #208959 we started dropping RELR relocations for late-added GOT entries when reverting x86-64 GOTPCRELX relaxations in X86_64::relaxOnce. There is a separate unrelaxation bug where if the object files didn't have any relocations of a certain type, we'd prune .relr.dyn (or even .rela.dyn). Will be addressed separately. Assisted-by: Gemini (cherry picked from commit 5565740f2367093b89481ba7371adf820971977d) --- lld/ELF/Relocations.cpp | 4 +-- lld/ELF/SyntheticSections.h | 8 ++++-- .../ELF/x86-64-gotpc-relax-too-far-relr.s | 26 +++++++++++++++++++ 3 files changed, 34 insertions(+), 4 deletions(-) create mode 100644 lld/test/ELF/x86-64-gotpc-relax-too-far-relr.s diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp index 4702d941d28ca..a1d3c5c2ea005 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 523f6587899fe..1079275439bc7 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 0000000000000..6c5e5f4368a41 --- /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@GOTPCREL(%rip), %rax + +.section .data,"aw",@progbits +.align 8 +.globl foo +foo: + .quad foo _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
