[llvm-branch-commits] [lld] [ELF] Emit synthetic local in symbol table for non-preemptible IFUNC (PR #210616)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Sun Jul 19 09:34:56 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-lld-elf
Author: Jessica Clarke (jrtc27)
<details>
<summary>Changes</summary>
Currently we create an internal alias of the original symbol and then
rewrite the latter to point to the IPLT entry, which means we lose
symbol table information for the actual resolver. In practice compilers
also emit a normal function symbol for the resolver due to how IFUNCs
are represented in GNU C so that at least shows up, but we shouldn't be
relying on it. By emitting a synthetic local we can keep having a symbol
for the resolver whilst still redirecting references to the IPLT entry.
---
<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>
---
Full diff: https://github.com/llvm/llvm-project/pull/210616.diff
6 Files Affected:
- (modified) lld/ELF/Relocations.cpp (+2-3)
- (modified) lld/ELF/SyntheticSections.cpp (+1-1)
- (modified) lld/ELF/SyntheticSections.h (+1-1)
- (modified) lld/test/ELF/gnu-ifunc-i386.s (+18)
- (modified) lld/test/ELF/ppc32-ifunc-nonpreemptible-nopic.s (+1-1)
- (modified) lld/test/ELF/ppc32-ifunc-nonpreemptible-pic.s (+1-1)
``````````diff
diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp
index 88657709b5e8b..a11920e904120 100644
--- a/lld/ELF/Relocations.cpp
+++ b/lld/ELF/Relocations.cpp
@@ -1254,9 +1254,8 @@ static bool handleNonPreemptibleIfunc(Ctx &ctx, Symbol &sym, uint16_t flags) {
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(
- ctx, d.file, d.getName(), std::as_const(d).binding, d.stOther,
- std::as_const(d).type, d.value, d.size, d.section);
+ auto *irelativeSym = addSyntheticLocal(ctx, d.getName(), d.type, d.value,
+ d.size, *d.section);
addIpltEntry(*irelativeSym);
ctx.irelativeSyms.push_back(irelativeSym);
sym.isInIplt = true;
diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp
index fda7a835827ce..27a6cc17e9516 100644
--- a/lld/ELF/SyntheticSections.cpp
+++ b/lld/ELF/SyntheticSections.cpp
@@ -102,7 +102,7 @@ InputSection *elf::createInterpSection(Ctx &ctx) {
Defined *elf::addSyntheticLocal(Ctx &ctx, StringRef name, uint8_t type,
uint64_t value, uint64_t size,
- InputSectionBase §ion) {
+ SectionBase §ion) {
Defined *s = makeDefined(ctx, section.file, name, STB_LOCAL, STV_DEFAULT,
type, value, size, §ion);
if (ctx.in.symTab)
diff --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h
index 6e7df2461ba35..3cceb86b97ffe 100644
--- a/lld/ELF/SyntheticSections.h
+++ b/lld/ELF/SyntheticSections.h
@@ -1326,7 +1326,7 @@ template <typename ELFT> void writePhdrs(Ctx &, uint8_t *buf);
Defined *addSyntheticLocal(Ctx &ctx, StringRef name, uint8_t type,
uint64_t value, uint64_t size,
- InputSectionBase §ion);
+ SectionBase §ion);
void addVerneed(Ctx &, Symbol &ss);
diff --git a/lld/test/ELF/gnu-ifunc-i386.s b/lld/test/ELF/gnu-ifunc-i386.s
index 43b19b27ea4ec..f88a01cc4fb7c 100644
--- a/lld/test/ELF/gnu-ifunc-i386.s
+++ b/lld/test/ELF/gnu-ifunc-i386.s
@@ -38,6 +38,24 @@
// CHECK-NEXT: Section: Undefined
// CHECK-NEXT: }
// CHECK-NEXT: Symbol {
+// CHECK-NEXT: Name: bar
+// CHECK-NEXT: Value: 0x4010E4
+// CHECK-NEXT: Size: 0
+// CHECK-NEXT: Binding: Local
+// CHECK-NEXT: Type: GNU_IFunc
+// CHECK-NEXT: Other: 0
+// CHECK-NEXT: Section: .text
+// CHECK-NEXT: }
+// CHECK-NEXT: Symbol {
+// CHECK-NEXT: Name: foo
+// CHECK-NEXT: Value: 0x4010E5
+// CHECK-NEXT: Size: 0
+// CHECK-NEXT: Binding: Local
+// CHECK-NEXT: Type: GNU_IFunc
+// CHECK-NEXT: Other: 0
+// CHECK-NEXT: Section: .text
+// CHECK-NEXT: }
+// CHECK-NEXT: Symbol {
// CHECK-NEXT: Name: __rel_iplt_start
// CHECK-NEXT: Value: [[RELA]]
// CHECK-NEXT: Size: 0
diff --git a/lld/test/ELF/ppc32-ifunc-nonpreemptible-nopic.s b/lld/test/ELF/ppc32-ifunc-nonpreemptible-nopic.s
index fca98cd7011de..f37c3294442cb 100644
--- a/lld/test/ELF/ppc32-ifunc-nonpreemptible-nopic.s
+++ b/lld/test/ELF/ppc32-ifunc-nonpreemptible-nopic.s
@@ -16,7 +16,7 @@
# HEX-NEXT: 0x10020110 00000000 ....
# CHECK: Disassembly of section .text:
-# CHECK: <.text>:
+# CHECK: <func>:
# CHECK-NEXT: 100100e0: blr
# CHECK: <_start>:
# CHECK-NEXT: bl 0x100100f0
diff --git a/lld/test/ELF/ppc32-ifunc-nonpreemptible-pic.s b/lld/test/ELF/ppc32-ifunc-nonpreemptible-pic.s
index 328bb9caa3534..a58bf551cfae9 100644
--- a/lld/test/ELF/ppc32-ifunc-nonpreemptible-pic.s
+++ b/lld/test/ELF/ppc32-ifunc-nonpreemptible-pic.s
@@ -30,7 +30,7 @@
.long func
# CHECK: Disassembly of section .text:
-# CHECK: <.text>:
+# CHECK: <func>:
# CHECK-NEXT: 10188: blr
# CHECK: <_start>:
# CHECK-NEXT: bl 0x10190
``````````
</details>
https://github.com/llvm/llvm-project/pull/210616
More information about the llvm-branch-commits
mailing list