[lld] [lld/coff] Fix assert on /start-lib foo.obj /end-lib during eager loads (PR #120292)

via llvm-commits llvm-commits at lists.llvm.org
Tue Dec 17 11:48:00 PST 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-platform-windows

Author: Nico Weber (nico)

<details>
<summary>Changes</summary>

If foo.obj is eagerly loaded (due to a prior undef referencing one if its symbols) and has more than one symbol, we used to assert: SymbolTable::addLazyObject() for the first symbol would set `lazy` to false and load all symbols from the file, but the outer ObjFile::parseLazy() loop would continue to run and call addLazyObject() for the second symbol, which would assert.

Instead, just stop adding lazy symbols if the file got loaded for real while adding a symbol.

(The ELF port has a similar early exit in `ObjFile<ELFT>::parseLazy()`.)

---
Full diff: https://github.com/llvm/llvm-project/pull/120292.diff


2 Files Affected:

- (modified) lld/COFF/InputFiles.cpp (+6-1) 
- (modified) lld/test/COFF/start-lib.ll (+24-6) 


``````````diff
diff --git a/lld/COFF/InputFiles.cpp b/lld/COFF/InputFiles.cpp
index 6ce075be798e4a..12e3c8db753b48 100644
--- a/lld/COFF/InputFiles.cpp
+++ b/lld/COFF/InputFiles.cpp
@@ -192,6 +192,8 @@ void ObjFile::parseLazy() {
     if (coffSym.isAbsolute() && ignoredSymbolName(name))
       continue;
     symtab.addLazyObject(this, name);
+    if (!lazy)
+      return;
     i += coffSym.getNumberOfAuxSymbols();
   }
 }
@@ -1291,8 +1293,11 @@ void BitcodeFile::parse() {
 
 void BitcodeFile::parseLazy() {
   for (const lto::InputFile::Symbol &sym : obj->symbols())
-    if (!sym.isUndefined())
+    if (!sym.isUndefined()) {
       symtab.addLazyObject(this, sym.getName());
+      if (!lazy)
+        return;
+    }
 }
 
 MachineTypes BitcodeFile::getMachineType() const {
diff --git a/lld/test/COFF/start-lib.ll b/lld/test/COFF/start-lib.ll
index f4f49ed4e4f6e6..c151e3cdcec555 100644
--- a/lld/test/COFF/start-lib.ll
+++ b/lld/test/COFF/start-lib.ll
@@ -6,24 +6,26 @@
 ; RUN: llc -filetype=obj %t.dir/main.ll -o %t.obj
 ; RUN: llc -filetype=obj %t.dir/start-lib1.ll -o %t1.obj
 ; RUN: llc -filetype=obj %t.dir/start-lib2.ll -o %t2.obj
+; RUN: llc -filetype=obj %t.dir/eager.ll -o %t-eager.obj
 ; RUN: opt -thinlto-bc %t.dir/main.ll -o %t.bc
 ; RUN: opt -thinlto-bc %t.dir/start-lib1.ll -o %t1.bc
 ; RUN: opt -thinlto-bc %t.dir/start-lib2.ll -o %t2.bc
+; RUN: opt -thinlto-bc %t.dir/eager.ll -o %t-eager.bc
 ;
 ; RUN: lld-link -out:%t1.exe -entry:main -opt:noref -lldmap:%t1.map \
-; RUN:     %t.obj %t1.obj %t2.obj
+; RUN:     %t.obj %t1.obj %t2.obj %t-eager.obj
 ; RUN: FileCheck --check-prefix=TEST1 %s < %t1.map
 ; RUN: lld-link -out:%t1.exe -entry:main -opt:noref -lldmap:%t1.thinlto.map \
-; RUN:     %t.bc %t1.bc %t2.bc
+; RUN:     %t.bc %t1.bc %t2.bc %t-eager.bc
 ; RUN: FileCheck --check-prefix=TEST1 %s < %t1.thinlto.map
 ; TEST1: foo
 ; TEST1: bar
 ;
 ; RUN: lld-link -out:%t2.exe -entry:main -opt:noref -lldmap:%t2.map \
-; RUN:     %t.obj -start-lib %t1.obj -end-lib %t2.obj
+; RUN:     %t.obj -start-lib %t1.obj %t-eager.obj -end-lib %t2.obj
 ; RUN: FileCheck --check-prefix=TEST2 %s < %t2.map
 ; RUN: lld-link -out:%t2.exe -entry:main -opt:noref -lldmap:%t2.thinlto.map \
-; RUN:     %t.bc -start-lib %t1.bc -end-lib %t2.bc
+; RUN:     %t.bc -start-lib %t1.bc %t-eager.bc -end-lib %t2.bc
 ; RUN: FileCheck --check-prefix=TEST2 %s < %t2.thinlto.map
 ; TEST2:     Address Size Align Out In Symbol
 ; TEST2-NOT:                           {{ }}foo{{$}}
@@ -31,10 +33,10 @@
 ; TEST2-NOT:                           {{ }}foo{{$}}
 ;
 ; RUN: lld-link -out:%t3.exe -entry:main -opt:noref -lldmap:%t3.map \
-; RUN:     %t.obj -start-lib %t1.obj %t2.obj
+; RUN:     %t.obj -start-lib %t1.obj %t2.obj %t-eager.obj
 ; RUN: FileCheck --check-prefix=TEST3 %s < %t3.map
 ; RUN: lld-link -out:%t3.exe -entry:main -opt:noref -lldmap:%t3.thinlto.map \
-; RUN:     %t.bc -start-lib %t1.bc %t2.bc
+; RUN:     %t.bc -start-lib %t1.bc %t2.bc %t-eager.bc
 ; RUN: FileCheck --check-prefix=TEST3 %s < %t3.thinlto.map
 ; TEST3:     Address Size Align Out In Symbol
 ; TEST3-NOT: {{ }}foo{{$}}
@@ -46,7 +48,10 @@
 target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
 target triple = "x86_64-pc-windows-msvc"
 
+declare void @eager()
+
 define void @main() {
+  %1 = call i32 () @eager()
   ret void
 }
 
@@ -79,3 +84,16 @@ define i32 @bar() {
 
 !llvm.linker.options = !{!0}
 !0 = !{!"/INCLUDE:bar"}
+
+#--- eager.ll
+
+target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-pc-windows-msvc"
+
+define void @eager() {
+  ret void
+}
+
+define i32 @ogre() {
+  ret i32 1
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/120292


More information about the llvm-commits mailing list