[lld] [LLD][COFF] Do another pass of resolveRemainingUndefines for undefined lazy symbols (PR #109082)

Mike Hommey via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 17 21:17:01 PDT 2024


https://github.com/glandium created https://github.com/llvm/llvm-project/pull/109082

Cc: @mstorsjo 

This addresses #107365 except for the strdup part.

>From c44939fc8d02065356f15cbb78b3674ae28f22f8 Mon Sep 17 00:00:00 2001
From: Mike Hommey <mh at glandium.org>
Date: Wed, 18 Sep 2024 13:11:40 +0900
Subject: [PATCH] [LLD][COFF] Do another pass of resolveRemainingUndefines for
 undefined lazy symbols

---
 lld/COFF/Driver.cpp      | 5 ++++-
 lld/COFF/SymbolTable.cpp | 9 ++++++++-
 lld/COFF/SymbolTable.h   | 5 ++++-
 3 files changed, 16 insertions(+), 3 deletions(-)

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<const char *> 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<Symbol *, 8> undefs;
   DenseMap<Symbol *, Symbol *> 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<Defined>(imp)) {
         auto *d = cast<Defined>(imp);
         replaceSymbol<DefinedLocalImport>(sym, ctx, name, d);
@@ -529,6 +535,7 @@ void SymbolTable::resolveRemainingUndefines() {
   reportProblemSymbols(
       ctx, undefs,
       ctx.config.warnLocallyDefinedImported ? &localImports : nullptr, false);
+  return foundLazy;
 }
 
 std::pair<Symbol *, bool> 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.



More information about the llvm-commits mailing list