-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[LLD] [COFF] Handle undefined weak symbols in LTO #70430
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-lto @llvm/pr-subscribers-lld-coff Author: Martin Storsjö (mstorsjo) ChangesWhen 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, 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. Full diff: https://github.com/llvm/llvm-project/pull/70430.diff 2 Files Affected:
diff --git a/lld/COFF/InputFiles.cpp b/lld/COFF/InputFiles.cpp
index 38ce29e6ab68c04..b5db6d2e1613d75 100644
--- a/lld/COFF/InputFiles.cpp
+++ b/lld/COFF/InputFiles.cpp
@@ -1040,6 +1040,8 @@ void BitcodeFile::parse() {
fakeSC = &ctx.ltoDataSectionChunk.chunk;
if (objSym.isUndefined()) {
sym = ctx.symtab.addUndefined(symName, this, false);
+ if (objSym.isWeak())
+ sym->deferUndefined = true;
} else if (objSym.isCommon()) {
sym = ctx.symtab.addCommon(this, symName, objSym.getCommonSize());
} else if (objSym.isWeak() && objSym.isIndirect()) {
diff --git a/lld/test/COFF/lto-weak-undefined.ll b/lld/test/COFF/lto-weak-undefined.ll
new file mode 100644
index 000000000000000..408d4342431baa7
--- /dev/null
+++ b/lld/test/COFF/lto-weak-undefined.ll
@@ -0,0 +1,34 @@
+; REQUIRES: x86
+
+; RUN: split-file %s %t.dir
+; RUN: llvm-as %t.dir/main.ll -o %t.main.obj
+; RUN: llvm-as %t.dir/optional.ll -o %t.optional.obj
+
+; RUN: lld-link /entry:main %t.main.obj /out:%t-undef.exe
+; RUN: lld-link /entry:main %t.main.obj %t.optional.obj /out:%t-def.exe
+
+#--- main.ll
+target datalayout = "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-pc-windows-msvc"
+
+define dso_local i32 @main() {
+entry:
+ br i1 icmp ne (ptr @optionalFunc, ptr null), label %if.then, label %if.end
+
+if.then:
+ tail call void @optionalFunc()
+ br label %if.end
+
+if.end:
+ ret i32 0
+}
+
+declare extern_weak void @optionalFunc()
+
+#--- optional.ll
+target datalayout = "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-pc-windows-msvc"
+
+define void @optionalFunc() {
+ ret void
+}
|
Ping |
I'm not familiar with that. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is correct.
Perhaps augment the description to say that deferUndefined
from https://reviews.llvm.org/D89004 for -wrap
is reused.
@@ -0,0 +1,34 @@ | |||
; REQUIRES: x86 | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add a file-level comment about the purpose as this may be less intuitive.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, I added this now.
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 llvm#64513.
50a1248
to
085cd72
Compare
Sure, will do that when landing it, thanks! |
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.