Skip to content

Commit 16899d3

Browse files
committed
[LLD][COFF] Do another pass of resolveRemainingUndefines for undefined lazy symbols
1 parent c29dfb3 commit 16899d3

File tree

4 files changed

+41
-3
lines changed

4 files changed

+41
-3
lines changed

lld/COFF/Driver.cpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -2601,7 +2601,9 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
26012601
createECExportThunks();
26022602

26032603
// Resolve remaining undefined symbols and warn about imported locals.
2604-
ctx.symtab.resolveRemainingUndefines();
2604+
while (ctx.symtab.resolveRemainingUndefines()) {
2605+
run();
2606+
}
26052607
if (errorCount())
26062608
return;
26072609

lld/COFF/SymbolTable.cpp

+8-1
Original file line numberDiff line numberDiff line change
@@ -479,10 +479,11 @@ void SymbolTable::reportUnresolvable() {
479479
/* localImports */ nullptr, true);
480480
}
481481

482-
void SymbolTable::resolveRemainingUndefines() {
482+
bool SymbolTable::resolveRemainingUndefines() {
483483
llvm::TimeTraceScope timeScope("Resolve remaining undefined symbols");
484484
SmallPtrSet<Symbol *, 8> undefs;
485485
DenseMap<Symbol *, Symbol *> localImports;
486+
bool foundLazy = false;
486487

487488
for (auto &i : symMap) {
488489
Symbol *sym = i.second;
@@ -510,6 +511,11 @@ void SymbolTable::resolveRemainingUndefines() {
510511
undef->resolveWeakAlias();
511512
}
512513
}
514+
if (imp && imp->isLazy()) {
515+
forceLazy(imp);
516+
foundLazy = true;
517+
continue;
518+
}
513519
if (imp && isa<Defined>(imp)) {
514520
auto *d = cast<Defined>(imp);
515521
replaceSymbol<DefinedLocalImport>(sym, ctx, name, d);
@@ -537,6 +543,7 @@ void SymbolTable::resolveRemainingUndefines() {
537543
reportProblemSymbols(
538544
ctx, undefs,
539545
ctx.config.warnLocallyDefinedImported ? &localImports : nullptr, false);
546+
return foundLazy;
540547
}
541548

542549
std::pair<Symbol *, bool> SymbolTable::insert(StringRef name) {

lld/COFF/SymbolTable.h

+4-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,10 @@ class SymbolTable {
5757
// Try to resolve any undefined symbols and update the symbol table
5858
// accordingly, then print an error message for any remaining undefined
5959
// symbols and warn about imported local symbols.
60-
void resolveRemainingUndefines();
60+
// Returns whether more files might need to be linked in to resolve lazy
61+
// symbols, in which case the caller is expected to call the function again
62+
// after linking those files.
63+
bool resolveRemainingUndefines();
6164

6265
// Load lazy objects that are needed for MinGW automatic import and for
6366
// doing stdcall fixups.

lld/test/COFF/undefined_lazy.test

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# REQUIRES: x86
2+
3+
# RUN: split-file %s %t.dir
4+
# RUN: llvm-mc --filetype=obj -triple=x86_64-windows-msvc %t.dir/foo.s -o %t.foo.obj
5+
# RUN: llvm-mc --filetype=obj -triple=x86_64-windows-msvc %t.dir/bar.s -o %t.bar.obj
6+
# RUN: llvm-mc --filetype=obj -triple=x86_64-windows-msvc %t.dir/qux.s -o %t.qux.obj
7+
# RUN: llvm-lib %t.foo.obj -out:%t.foo.lib
8+
# RUN: llvm-lib %t.bar.obj -out:%t.bar.lib
9+
# RUN: lld-link %t.foo.lib %t.bar.lib %t.qux.obj -out:%t.dll -dll
10+
#
11+
#--- foo.s
12+
.text
13+
.globl foo
14+
foo:
15+
call bar
16+
#--- bar.s
17+
.text
18+
.globl bar
19+
bar:
20+
ret
21+
#--- qux.s
22+
.text
23+
.global _DllMainCRTStartup
24+
_DllMainCRTStartup:
25+
call *__imp_foo(%rip)
26+
ret

0 commit comments

Comments
 (0)