diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp index 1b94f10acf80e5..38a507cb9752ff 100644 --- a/lld/COFF/Driver.cpp +++ b/lld/COFF/Driver.cpp @@ -2601,7 +2601,10 @@ void LinkerDriver::linkerMain(ArrayRef argsArr) { createECExportThunks(); // Resolve remaining undefined symbols and warn about imported locals. - ctx.symtab.resolveRemainingUndefines(); + if (ctx.symtab.resolveRemainingUndefines()) { + run(); + ctx.symtab.resolveRemainingUndefines(); + } if (errorCount()) return; diff --git a/lld/COFF/SymbolTable.cpp b/lld/COFF/SymbolTable.cpp index efea16ccbbfea0..8d69a3966e638f 100644 --- a/lld/COFF/SymbolTable.cpp +++ b/lld/COFF/SymbolTable.cpp @@ -479,10 +479,11 @@ void SymbolTable::reportUnresolvable() { /* localImports */ nullptr, true); } -void SymbolTable::resolveRemainingUndefines() { +bool SymbolTable::resolveRemainingUndefines() { llvm::TimeTraceScope timeScope("Resolve remaining undefined symbols"); SmallPtrSet undefs; DenseMap localImports; + bool foundLazy = false; for (auto &i : symMap) { Symbol *sym = i.second; @@ -502,6 +503,11 @@ void SymbolTable::resolveRemainingUndefines() { // This odd rule is for compatibility with MSVC linker. if (name.starts_with("__imp_")) { Symbol *imp = find(name.substr(strlen("__imp_"))); + if (imp && imp->isLazy()) { + forceLazy(imp); + foundLazy = true; + continue; + } if (imp && isa(imp)) { auto *d = cast(imp); replaceSymbol(sym, ctx, name, d); @@ -529,6 +535,7 @@ void SymbolTable::resolveRemainingUndefines() { reportProblemSymbols( ctx, undefs, ctx.config.warnLocallyDefinedImported ? &localImports : nullptr, false); + return foundLazy; } std::pair SymbolTable::insert(StringRef name) { diff --git a/lld/COFF/SymbolTable.h b/lld/COFF/SymbolTable.h index bf97cf442039e0..1ab35a87cb9fad 100644 --- a/lld/COFF/SymbolTable.h +++ b/lld/COFF/SymbolTable.h @@ -57,7 +57,10 @@ class SymbolTable { // 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.