[lld] 513e0af - [LLD][COFF] Detect weak reference cycles. (#104463)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Aug 20 01:21:04 PDT 2024
Author: Jacek Caban
Date: 2024-08-20T10:21:00+02:00
New Revision: 513e0af0a940f3a823f8f0e83189cb33cb81496f
URL: https://github.com/llvm/llvm-project/commit/513e0af0a940f3a823f8f0e83189cb33cb81496f
DIFF: https://github.com/llvm/llvm-project/commit/513e0af0a940f3a823f8f0e83189cb33cb81496f.diff
LOG: [LLD][COFF] Detect weak reference cycles. (#104463)
Instead of entering an infinite loop.
Added:
lld/test/COFF/weak-external-cycle.test
Modified:
lld/COFF/Symbols.cpp
Removed:
################################################################################
diff --git a/lld/COFF/Symbols.cpp b/lld/COFF/Symbols.cpp
index f4efcf2266cd6b..ff8ad1e619116f 100644
--- a/lld/COFF/Symbols.cpp
+++ b/lld/COFF/Symbols.cpp
@@ -126,9 +126,13 @@ DefinedImportThunk::DefinedImportThunk(COFFLinkerContext &ctx, StringRef name,
Defined *Undefined::getWeakAlias() {
// A weak alias may be a weak alias to another symbol, so check recursively.
- for (Symbol *a = weakAlias; a; a = cast<Undefined>(a)->weakAlias)
+ DenseSet<Symbol *> weakChain;
+ for (Symbol *a = weakAlias; a; a = cast<Undefined>(a)->weakAlias) {
if (auto *d = dyn_cast<Defined>(a))
return d;
+ if (!weakChain.insert(a).second)
+ break; // We have a cycle.
+ }
return nullptr;
}
diff --git a/lld/test/COFF/weak-external-cycle.test b/lld/test/COFF/weak-external-cycle.test
new file mode 100644
index 00000000000000..65f483350790f7
--- /dev/null
+++ b/lld/test/COFF/weak-external-cycle.test
@@ -0,0 +1,41 @@
+REQUIRES: x86
+RUN: split-file %s %t.dir && cd %t.dir
+
+RUN: llvm-mc -filetype=obj -triple=x86_64-windows test.s -o test.obj
+RUN: llvm-mc -filetype=obj -triple=x86_64-windows sym2.s -o sym2.obj
+RUN: llvm-mc -filetype=obj -triple=x86_64-windows def.s -o def.obj
+
+RUN: not lld-link -machine:amd64 -dll -noentry -out:test.dll test.obj sym2.obj 2>&1 | FileCheck -check-prefix=ERR %s
+
+ERR: error: undefined symbol: testsym
+ERR-NEXT: >>> referenced by test.obj
+ERR-EMPTY:
+ERR-NEXT: error: undefined symbol: sym1
+ERR-NEXT: >>> referenced by test.obj
+ERR-NEXT: >>> referenced by sym2.obj
+ERR-EMPTY:
+ERR-NEXT: error: undefined symbol: sym2
+ERR-NEXT: >>> referenced by test.obj
+ERR-NEXT: >>> referenced by sym2.obj
+
+Depending on symbol processing order, we may have temporary weak reference cycles:
+
+RUN: lld-link -machine:amd64 -dll -noentry -out:test.dll test.obj sym2.obj def.obj
+RUN: lld-link -machine:amd64 -dll -noentry -out:test.dll test.obj def.obj sym2.obj
+RUN: lld-link -machine:amd64 -dll -noentry -out:test.dll def.obj test.obj sym2.obj
+
+#--- test.s
+ .weak testsym
+.set testsym, sym1
+ .weak sym1
+.set sym1, sym2
+
+#--- sym2.s
+ .weak sym2
+.set sym2, sym1
+
+#--- def.s
+ .globl sym1
+ .data
+sym1:
+ .word 0
More information about the llvm-commits
mailing list