[lld] 6a1bdd9 - [LLD][COFF] Do as many passes of resolveRemainingUndefines as necessary for undefined lazy symbols (#109082)

via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 3 12:53:31 PDT 2024


Author: Mike Hommey
Date: 2024-10-03T22:53:26+03:00
New Revision: 6a1bdd9a2e2a089c85d24dd5d934681fa22cf9ed

URL: https://github.com/llvm/llvm-project/commit/6a1bdd9a2e2a089c85d24dd5d934681fa22cf9ed
DIFF: https://github.com/llvm/llvm-project/commit/6a1bdd9a2e2a089c85d24dd5d934681fa22cf9ed.diff

LOG: [LLD][COFF] Do as many passes of resolveRemainingUndefines as necessary for undefined lazy symbols (#109082)

Added: 
    lld/test/COFF/undefined_lazy.test

Modified: 
    lld/COFF/Driver.cpp
    lld/COFF/SymbolTable.cpp
    lld/COFF/SymbolTable.h

Removed: 
    


################################################################################
diff  --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp
index dc757bf7dd1e7a..85a58a3677181a 100644
--- a/lld/COFF/Driver.cpp
+++ b/lld/COFF/Driver.cpp
@@ -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;
 

diff  --git a/lld/COFF/SymbolTable.cpp b/lld/COFF/SymbolTable.cpp
index 0ef58910151cf0..3bd471389daa1f 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;
@@ -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) {

diff  --git a/lld/COFF/SymbolTable.h b/lld/COFF/SymbolTable.h
index e3f674b8098f8b..dab03afde3f987 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.

diff  --git a/lld/test/COFF/undefined_lazy.test b/lld/test/COFF/undefined_lazy.test
new file mode 100644
index 00000000000000..ed5cd358b5cd93
--- /dev/null
+++ b/lld/test/COFF/undefined_lazy.test
@@ -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


        


More information about the llvm-commits mailing list