Skip to content

Support --unresolved-symbols=@<file> option in LLD for ELF #142917

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions lld/ELF/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,7 @@ struct Config {
SortSectionPolicy sortSection;
StripPolicy strip;
UnresolvedPolicy unresolvedSymbols;
llvm::SmallVector<std::string> unresolvedSymbolsList;
UnresolvedPolicy unresolvedSymbolsInShlib;
Target2Policy target2;
GcsPolicy zGcs;
Expand Down
8 changes: 8 additions & 0 deletions lld/ELF/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
7 changes: 7 additions & 0 deletions lld/ELF/Relocations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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()) {
Copy link
Member

@MaskRay MaskRay Jun 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

omit braces in this case.

ctx.arg.unresolvedSymbolsList can be a DenseSet to improve performance when the list is long.

This should only apply to canBeExternal symbols.
Peter has a comment that you might be able to use --defsym=bar=0 instead.

I'd file a binutils feature request before rushing to add an option

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
Expand Down
3 changes: 3 additions & 0 deletions lld/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo lininking -> linking

You may also want to find a more permanent place to document this. Right now it is not in the help or man-page. LLD is piggybacking on top of GNU ld's docs at https://sourceware.org/binutils/docs/ld/Options.html and that won't mention it.


Breaking changes
----------------
* Executable-only and readable-executable sections are now allowed to be placed
Expand Down
1 change: 1 addition & 0 deletions lld/test/ELF/Inputs/unresolved-symbols.s
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
.globl _shared
_shared:
callq undef@PLT
callq undef2@PLT
1 change: 1 addition & 0 deletions lld/test/ELF/Inputs/unresolved.ignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
undef
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New lld tests tend to favour using split-file to put all the inputs for a test in the same file.

I'd also recommend having more test cases. For example an empty file, multiple symbols on separate lines.

6 changes: 6 additions & 0 deletions lld/test/ELF/unresolved-symbols.s
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Loading