[lld] Support --unresolved-symbols=@<file> option in LLD for ELF (PR #142917)

Dmitry Nechitaev via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 5 01:06:50 PDT 2025


https://github.com/Nechda created https://github.com/llvm/llvm-project/pull/142917

This pull request implements one more feature of the `--unresolved-symbols=@<file>` flag in LLD.

Original issue: https://github.com/llvm/llvm-project/issues/142798

>From e9f27333008ab6c22781720d1227e356e2dcdc26 Mon Sep 17 00:00:00 2001
From: Dmitry Nechitaev <nechda6 at gmail.com>
Date: Thu, 5 Jun 2025 10:54:06 +0300
Subject: [PATCH 1/2] Support --unresolved-symbols=@/path/to/file

---
 lld/ELF/Config.h                         | 1 +
 lld/ELF/Driver.cpp                       | 8 ++++++++
 lld/ELF/Relocations.cpp                  | 7 +++++++
 lld/test/ELF/Inputs/unresolved-symbols.s | 1 +
 lld/test/ELF/Inputs/unresolved.ignore    | 1 +
 lld/test/ELF/unresolved-symbols.s        | 6 ++++++
 6 files changed, 24 insertions(+)
 create mode 100644 lld/test/ELF/Inputs/unresolved.ignore

diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h
index f0e9592d85dd6..65624685398e8 100644
--- a/lld/ELF/Config.h
+++ b/lld/ELF/Config.h
@@ -397,6 +397,7 @@ struct Config {
   SortSectionPolicy sortSection;
   StripPolicy strip;
   UnresolvedPolicy unresolvedSymbols;
+  llvm::SmallVector<std::string> unresolvedSymbolsList;
   UnresolvedPolicy unresolvedSymbolsInShlib;
   Target2Policy target2;
   GcsPolicy zGcs;
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index 6150fe072156f..64cc035c6e8e4 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -714,6 +714,14 @@ static void setUnresolvedSymbolPolicy(Ctx &ctx, opt::InputArgList &args) {
       } else if (s == "report-all") {
         diagRegular = true;
         diagShlib = true;
+      } else if (s.starts_with("@")) {
+        // Read file with set of unresolved symbols
+        StringRef filename(s.substr(1ULL));
+        std::optional<MemoryBufferRef> buffer = readFile(ctx, filename);
+        if (!buffer)
+          continue;
+        for (auto [_, line] : llvm::enumerate(args::getLines(*buffer)))
+          ctx.arg.unresolvedSymbolsList.emplace_back(line);
       } else {
         ErrAlways(ctx) << "unknown --unresolved-symbols value: " << s;
       }
diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp
index 8413d8bb2437c..6e87f78caf426 100644
--- a/lld/ELF/Relocations.cpp
+++ b/lld/ELF/Relocations.cpp
@@ -804,6 +804,13 @@ static bool maybeReportUndefined(Ctx &ctx, Undefined &sym,
   if (ctx.arg.unresolvedSymbols == UnresolvedPolicy::Ignore && canBeExternal)
     return false;
 
+  // Skip undefined symbols from list
+  for (const auto& ignoredUndef : ctx.arg.unresolvedSymbolsList) {
+    if (ignoredUndef == sym.getName()) {
+        return false;
+    }
+  }
+
   // clang (as of 2019-06-12) / gcc (as of 8.2.1) PPC64 may emit a .rela.toc
   // which references a switch table in a discarded .rodata/.text section. The
   // .toc and the .rela.toc are incorrectly not placed in the comdat. The ELF
diff --git a/lld/test/ELF/Inputs/unresolved-symbols.s b/lld/test/ELF/Inputs/unresolved-symbols.s
index b504708e43dab..86fb468d0b65f 100644
--- a/lld/test/ELF/Inputs/unresolved-symbols.s
+++ b/lld/test/ELF/Inputs/unresolved-symbols.s
@@ -1,3 +1,4 @@
 .globl _shared
 _shared:
   callq undef at PLT
+  callq undef2 at PLT
diff --git a/lld/test/ELF/Inputs/unresolved.ignore b/lld/test/ELF/Inputs/unresolved.ignore
new file mode 100644
index 0000000000000..141921671b8f8
--- /dev/null
+++ b/lld/test/ELF/Inputs/unresolved.ignore
@@ -0,0 +1 @@
+undef
diff --git a/lld/test/ELF/unresolved-symbols.s b/lld/test/ELF/unresolved-symbols.s
index 91194d376ca88..fbc7bea1bdcb6 100644
--- a/lld/test/ELF/unresolved-symbols.s
+++ b/lld/test/ELF/unresolved-symbols.s
@@ -63,5 +63,11 @@
 # RUN:   FileCheck -check-prefix=ERRUND %s
 # RUN: not ld.lld %t2.o -o /dev/null 2>&1 | FileCheck -check-prefix=ERRUND %s
 
+## Ignoring undefines in objects should not produce error for symbol from object.
+# RUN: not ld.lld %t2.o -o /dev/null --unresolved-symbols=@%p/Inputs/unresolved.ignore 2>&1 | \
+# RUN:   FileCheck %s --check-prefix=IGNLST
+
+# IGNLST: error: undefined symbol: undef2
+
 .globl _start
 _start:

>From 25422547ef8d9d2d959fea0875aa223c3086da1a Mon Sep 17 00:00:00 2001
From: Dmitry Nechitaev <nechda6 at gmail.com>
Date: Thu, 5 Jun 2025 11:00:02 +0300
Subject: [PATCH 2/2] Add item to release notes

---
 lld/docs/ReleaseNotes.rst | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/lld/docs/ReleaseNotes.rst b/lld/docs/ReleaseNotes.rst
index 5c180fd8fbeeb..26ce07156d181 100644
--- a/lld/docs/ReleaseNotes.rst
+++ b/lld/docs/ReleaseNotes.rst
@@ -58,6 +58,9 @@ ELF Improvements
   on executable sections.
   (`#128883 <https://github.com/llvm/llvm-project/pull/128883>`_)
 
+* Added ``--unresolved-symbols=@<file>`` flag to specify path to a file with the
+  list of unresolved symbols that will not trigger an error during lininking.
+
 Breaking changes
 ----------------
 * Executable-only and readable-executable sections are now allowed to be placed



More information about the llvm-commits mailing list