[llvm-branch-commits] [lld] [NFC][ELF] Only create alias in handleNonPreemptibleIfunc if needed (PR #210613)

Jessica Clarke via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Sun Jul 19 09:33:45 PDT 2026


https://github.com/jrtc27 created https://github.com/llvm/llvm-project/pull/210613

In the no direct relocations case, the original IFUNC symbol keeps its
value, and so there's no need to create a separate alias; it's only
needed when the original symbol is being redirected to the IPLT as a
normal function symbol.

This change also shifts the isInIplt assignment to be explicit and
mirror the allocateAux/pltIdx uses, rather than relying on makeDefined
copying it, and to be clear that this is in fact deliberately and
consistently being copied like them.

---

<sub>Stack created with <a href="https://github.com/github/gh-stack">GitHub Stacks CLI</a> • <a href="https://gh.io/stacks-feedback">Give Feedback 💬</a></sub>

>From e7115f1d1b882bfaaca9f227c3075a2e3917a4b5 Mon Sep 17 00:00:00 2001
From: Jessica Clarke <jrtc27 at jrtc27.com>
Date: Sun, 19 Jul 2026 14:02:36 +0100
Subject: [PATCH] [NFC][ELF] Only create alias in handleNonPreemptibleIfunc if
 needed

In the no direct relocations case, the original IFUNC symbol keeps its
value, and so there's no need to create a separate alias; it's only
needed when the original symbol is being redirected to the IPLT as a
normal function symbol.

This change also shifts the isInIplt assignment to be explicit and
mirror the allocateAux/pltIdx uses, rather than relying on makeDefined
copying it, and to be clear that this is in fact deliberately and
consistently being copied like them.
---
 lld/ELF/Relocations.cpp | 41 +++++++++++++++++++++++------------------
 1 file changed, 23 insertions(+), 18 deletions(-)

diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp
index 9050d97dd4573..71daf6fb95a8f 100644
--- a/lld/ELF/Relocations.cpp
+++ b/lld/ELF/Relocations.cpp
@@ -1230,11 +1230,10 @@ static bool handleNonPreemptibleIfunc(Ctx &ctx, Symbol &sym, uint16_t flags) {
   // ("canonicalizing" it), so all references see the same address, and the
   // resolver is called exactly once. This may result in two GOT entries: one
   // in .got.plt for the IRELATIVE, and one in .got pointing to the canonical
-  // IPLT entry (for GOT-generating relocations).
-  //
-  // We clone the symbol to preserve the original resolver address for the
-  // IRELATIVE addend. The clone is tracked in ctx.irelativeSyms so that linker
-  // relaxation can adjust its value when the resolver address changes.
+  // IPLT entry (for GOT-generating relocations). We clone the symbol to
+  // preserve the original resolver address for the IRELATIVE addend. The clone
+  // is tracked in ctx.irelativeSyms so that linker relaxation can adjust its
+  // value when the resolver address changes.
   //
   // Note: IRELATIVE relocations are needed even in static executables; see
   // `addRelIpltSymbols`.
@@ -1244,20 +1243,23 @@ static bool handleNonPreemptibleIfunc(Ctx &ctx, Symbol &sym, uint16_t flags) {
   if (!(flags & (NEEDS_GOT | NEEDS_PLT | HAS_DIRECT_RELOC)))
     return true;
 
-  sym.isInIplt = true;
-
-  auto *irelativeSym = makeDefined(cast<Defined>(sym));
-  irelativeSym->allocateAux(ctx);
-  ctx.irelativeSyms.push_back(irelativeSym);
-  auto &dyn = getIRelativeSection(ctx);
-  addPltEntry(ctx, *ctx.in.iplt, *ctx.in.igotPlt, dyn, ctx.target->iRelativeRel,
-              *irelativeSym);
-  sym.allocateAux(ctx);
-  ctx.symAux.back().pltIdx = ctx.symAux[irelativeSym->auxIdx].pltIdx;
+  auto addIpltEntry = [&](Symbol &irelativeSym) {
+    irelativeSym.isInIplt = true;
+    irelativeSym.allocateAux(ctx);
+    auto &dyn = getIRelativeSection(ctx);
+    addPltEntry(ctx, *ctx.in.iplt, *ctx.in.igotPlt, dyn,
+                ctx.target->iRelativeRel, irelativeSym);
+  };
 
   if (flags & HAS_DIRECT_RELOC) {
     // Change the value to the IPLT and redirect all references to it.
     auto &d = cast<Defined>(sym);
+    auto *irelativeSym = makeDefined(d);
+    addIpltEntry(*irelativeSym);
+    ctx.irelativeSyms.push_back(irelativeSym);
+    sym.isInIplt = true;
+    sym.allocateAux(ctx);
+    ctx.symAux.back().pltIdx = ctx.symAux[irelativeSym->auxIdx].pltIdx;
     d.section = ctx.in.iplt.get();
     d.value = d.getPltIdx(ctx) * ctx.target->ipltEntrySize;
     d.size = 0;
@@ -1270,9 +1272,12 @@ static bool handleNonPreemptibleIfunc(Ctx &ctx, Symbol &sym, uint16_t flags) {
              "R_AARCH64_AUTH_IRELATIVE is not supported yet");
       addGotEntry(ctx, sym);
     }
-  } else if (flags & NEEDS_GOT) {
-    // Redirect GOT accesses to point to the Igot.
-    sym.gotInIgot = true;
+  } else {
+    addIpltEntry(sym);
+    if (flags & NEEDS_GOT) {
+      // Redirect GOT accesses to point to the Igot.
+      sym.gotInIgot = true;
+    }
   }
   return true;
 }



More information about the llvm-branch-commits mailing list