Skip to content

Commit 085cd72

Browse files
committed
[LLD] [COFF] Handle undefined weak symbols in LTO
When reading the bitcode input, undefined weak symbols will show up as undefined symbols - which fails the early pass of checking for missing symbols in symtab.reportUnresolvable(), before doing the actual LTO compilation. Mark such symbols as deferUndefined (added in 3785a41 / https://reviews.llvm.org/D89004 for the -wrap option), to let them pass through this LTO precheck. After the LTO compilation, the weak undefined symbols will point towards an absolute null symbol as default. Such weak undefined symbols are used for the TLS init function in the Itanium C++ ABI, for TLS variables that potentially need to run a constructor, when accessed across translation units. This fixes #64513.
1 parent f4bc189 commit 085cd72

File tree

2 files changed

+42
-0
lines changed

2 files changed

+42
-0
lines changed

lld/COFF/InputFiles.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1040,6 +1040,8 @@ void BitcodeFile::parse() {
10401040
fakeSC = &ctx.ltoDataSectionChunk.chunk;
10411041
if (objSym.isUndefined()) {
10421042
sym = ctx.symtab.addUndefined(symName, this, false);
1043+
if (objSym.isWeak())
1044+
sym->deferUndefined = true;
10431045
} else if (objSym.isCommon()) {
10441046
sym = ctx.symtab.addCommon(this, symName, objSym.getCommonSize());
10451047
} else if (objSym.isWeak() && objSym.isIndirect()) {

lld/test/COFF/lto-weak-undefined.ll

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
; REQUIRES: x86
2+
3+
;; Test linking of weak symbols with LTO. The weak symbol may be defined
4+
;; by another object file, or may be left undefined. When compiling the
5+
;; IR with an undefined weak symbol, the emitted object file will contain
6+
;; a weak alias pointing at an absolute symbol for the address null.
7+
;; Make sure both cases can be linked correctly.
8+
9+
; RUN: split-file %s %t.dir
10+
; RUN: llvm-as %t.dir/main.ll -o %t.main.obj
11+
; RUN: llvm-as %t.dir/optional.ll -o %t.optional.obj
12+
13+
; RUN: lld-link /entry:main %t.main.obj /out:%t-undef.exe
14+
; RUN: lld-link /entry:main %t.main.obj %t.optional.obj /out:%t-def.exe
15+
16+
;--- main.ll
17+
target datalayout = "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
18+
target triple = "x86_64-pc-windows-msvc"
19+
20+
define dso_local i32 @main() {
21+
entry:
22+
br i1 icmp ne (ptr @optionalFunc, ptr null), label %if.then, label %if.end
23+
24+
if.then:
25+
tail call void @optionalFunc()
26+
br label %if.end
27+
28+
if.end:
29+
ret i32 0
30+
}
31+
32+
declare extern_weak void @optionalFunc()
33+
34+
;--- optional.ll
35+
target datalayout = "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
36+
target triple = "x86_64-pc-windows-msvc"
37+
38+
define void @optionalFunc() {
39+
ret void
40+
}

0 commit comments

Comments
 (0)