From e9f27333008ab6c22781720d1227e356e2dcdc26 Mon Sep 17 00:00:00 2001 From: Dmitry Nechitaev Date: Thu, 5 Jun 2025 10:54:06 +0300 Subject: [PATCH 1/3] 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 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 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@PLT + callq undef2@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 Date: Thu, 5 Jun 2025 11:00:02 +0300 Subject: [PATCH 2/3] 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 `_) +* Added ``--unresolved-symbols=@`` 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 From 2e52861e717179f4891e5faec03de5e649c40d66 Mon Sep 17 00:00:00 2001 From: Dmitry Nechitaev Date: Thu, 5 Jun 2025 11:15:48 +0300 Subject: [PATCH 3/3] Fix style --- lld/ELF/Relocations.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp index 6e87f78caf426..66222a85fdbd2 100644 --- a/lld/ELF/Relocations.cpp +++ b/lld/ELF/Relocations.cpp @@ -805,9 +805,9 @@ static bool maybeReportUndefined(Ctx &ctx, Undefined &sym, return false; // Skip undefined symbols from list - for (const auto& ignoredUndef : ctx.arg.unresolvedSymbolsList) { + for (const auto &ignoredUndef : ctx.arg.unresolvedSymbolsList) { if (ignoredUndef == sym.getName()) { - return false; + return false; } }