[LLD][COFF] Do as many passes of resolveRemainingUndefines as necessary for undefined lazy symbols (#109082)
This commit is contained in:
@@ -2628,7 +2628,9 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
|
||||
createECExportThunks();
|
||||
|
||||
// Resolve remaining undefined symbols and warn about imported locals.
|
||||
ctx.symtab.resolveRemainingUndefines();
|
||||
while (ctx.symtab.resolveRemainingUndefines())
|
||||
run();
|
||||
|
||||
if (errorCount())
|
||||
return;
|
||||
|
||||
|
||||
@@ -479,10 +479,11 @@ void SymbolTable::reportUnresolvable() {
|
||||
/* localImports */ nullptr, true);
|
||||
}
|
||||
|
||||
void SymbolTable::resolveRemainingUndefines() {
|
||||
bool SymbolTable::resolveRemainingUndefines() {
|
||||
llvm::TimeTraceScope timeScope("Resolve remaining undefined symbols");
|
||||
SmallPtrSet<Symbol *, 8> undefs;
|
||||
DenseMap<Symbol *, Symbol *> localImports;
|
||||
bool foundLazy = false;
|
||||
|
||||
for (auto &i : symMap) {
|
||||
Symbol *sym = i.second;
|
||||
@@ -510,6 +511,11 @@ void SymbolTable::resolveRemainingUndefines() {
|
||||
undef->resolveWeakAlias();
|
||||
}
|
||||
}
|
||||
if (imp && imp->isLazy()) {
|
||||
forceLazy(imp);
|
||||
foundLazy = true;
|
||||
continue;
|
||||
}
|
||||
if (imp && isa<Defined>(imp)) {
|
||||
auto *d = cast<Defined>(imp);
|
||||
replaceSymbol<DefinedLocalImport>(sym, ctx, name, d);
|
||||
@@ -537,6 +543,7 @@ void SymbolTable::resolveRemainingUndefines() {
|
||||
reportProblemSymbols(
|
||||
ctx, undefs,
|
||||
ctx.config.warnLocallyDefinedImported ? &localImports : nullptr, false);
|
||||
return foundLazy;
|
||||
}
|
||||
|
||||
std::pair<Symbol *, bool> SymbolTable::insert(StringRef name) {
|
||||
|
||||
@@ -57,7 +57,10 @@ public:
|
||||
// Try to resolve any undefined symbols and update the symbol table
|
||||
// accordingly, then print an error message for any remaining undefined
|
||||
// symbols and warn about imported local symbols.
|
||||
void resolveRemainingUndefines();
|
||||
// Returns whether more files might need to be linked in to resolve lazy
|
||||
// symbols, in which case the caller is expected to call the function again
|
||||
// after linking those files.
|
||||
bool resolveRemainingUndefines();
|
||||
|
||||
// Load lazy objects that are needed for MinGW automatic import and for
|
||||
// doing stdcall fixups.
|
||||
|
||||
26
lld/test/COFF/undefined_lazy.test
Normal file
26
lld/test/COFF/undefined_lazy.test
Normal file
@@ -0,0 +1,26 @@
|
||||
# REQUIRES: x86
|
||||
|
||||
# RUN: split-file %s %t.dir
|
||||
# RUN: llvm-mc --filetype=obj -triple=x86_64-windows-msvc %t.dir/foo.s -o %t.foo.obj
|
||||
# RUN: llvm-mc --filetype=obj -triple=x86_64-windows-msvc %t.dir/bar.s -o %t.bar.obj
|
||||
# RUN: llvm-mc --filetype=obj -triple=x86_64-windows-msvc %t.dir/qux.s -o %t.qux.obj
|
||||
# RUN: llvm-lib %t.foo.obj -out:%t.foo.lib
|
||||
# RUN: llvm-lib %t.bar.obj -out:%t.bar.lib
|
||||
# RUN: lld-link %t.foo.lib %t.bar.lib %t.qux.obj -out:%t.dll -dll
|
||||
#
|
||||
#--- foo.s
|
||||
.text
|
||||
.globl foo
|
||||
foo:
|
||||
call bar
|
||||
#--- bar.s
|
||||
.text
|
||||
.globl bar
|
||||
bar:
|
||||
ret
|
||||
#--- qux.s
|
||||
.text
|
||||
.global _DllMainCRTStartup
|
||||
_DllMainCRTStartup:
|
||||
call *__imp_foo(%rip)
|
||||
ret
|
||||
Reference in New Issue
Block a user