Skip to content

Commit 513e0af

Browse files
authored
[LLD][COFF] Detect weak reference cycles. (#104463)
Instead of entering an infinite loop.
1 parent f5f0055 commit 513e0af

File tree

2 files changed

+46
-1
lines changed

2 files changed

+46
-1
lines changed

lld/COFF/Symbols.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,9 +126,13 @@ DefinedImportThunk::DefinedImportThunk(COFFLinkerContext &ctx, StringRef name,
126126

127127
Defined *Undefined::getWeakAlias() {
128128
// A weak alias may be a weak alias to another symbol, so check recursively.
129-
for (Symbol *a = weakAlias; a; a = cast<Undefined>(a)->weakAlias)
129+
DenseSet<Symbol *> weakChain;
130+
for (Symbol *a = weakAlias; a; a = cast<Undefined>(a)->weakAlias) {
130131
if (auto *d = dyn_cast<Defined>(a))
131132
return d;
133+
if (!weakChain.insert(a).second)
134+
break; // We have a cycle.
135+
}
132136
return nullptr;
133137
}
134138

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
REQUIRES: x86
2+
RUN: split-file %s %t.dir && cd %t.dir
3+
4+
RUN: llvm-mc -filetype=obj -triple=x86_64-windows test.s -o test.obj
5+
RUN: llvm-mc -filetype=obj -triple=x86_64-windows sym2.s -o sym2.obj
6+
RUN: llvm-mc -filetype=obj -triple=x86_64-windows def.s -o def.obj
7+
8+
RUN: not lld-link -machine:amd64 -dll -noentry -out:test.dll test.obj sym2.obj 2>&1 | FileCheck -check-prefix=ERR %s
9+
10+
ERR: error: undefined symbol: testsym
11+
ERR-NEXT: >>> referenced by test.obj
12+
ERR-EMPTY:
13+
ERR-NEXT: error: undefined symbol: sym1
14+
ERR-NEXT: >>> referenced by test.obj
15+
ERR-NEXT: >>> referenced by sym2.obj
16+
ERR-EMPTY:
17+
ERR-NEXT: error: undefined symbol: sym2
18+
ERR-NEXT: >>> referenced by test.obj
19+
ERR-NEXT: >>> referenced by sym2.obj
20+
21+
Depending on symbol processing order, we may have temporary weak reference cycles:
22+
23+
RUN: lld-link -machine:amd64 -dll -noentry -out:test.dll test.obj sym2.obj def.obj
24+
RUN: lld-link -machine:amd64 -dll -noentry -out:test.dll test.obj def.obj sym2.obj
25+
RUN: lld-link -machine:amd64 -dll -noentry -out:test.dll def.obj test.obj sym2.obj
26+
27+
#--- test.s
28+
.weak testsym
29+
.set testsym, sym1
30+
.weak sym1
31+
.set sym1, sym2
32+
33+
#--- sym2.s
34+
.weak sym2
35+
.set sym2, sym1
36+
37+
#--- def.s
38+
.globl sym1
39+
.data
40+
sym1:
41+
.word 0

0 commit comments

Comments
 (0)