Issue |
158248
|
Summary |
[lld-link] Crash on LTO pulling in objects with export attributes
|
Labels |
lld:COFF
|
Assignees |
|
Reporter |
mstorsjo
|
First off - this issue is very similar to https://github.com/llvm/llvm-project/issues/131807. During linking, a late stage ends up pulling in an object file, which contains an `-export:` attribute.
We handle `-export` entries here, https://github.com/llvm/llvm-project/blob/llvmorg-21.1.1/lld/COFF/Driver.cpp#L2536-L2558, resolving their symbols and attempting to pull in those symbols. But any late included object file with a new `-export:` attribute is missed, never executing something like `e.sym = symtab.addGCRoot(e.name, !e.data);`, which means that at the end, we have `e.sym == nullptr`.
This case is somewhat different in the mechanisms in how we end up late-including more object files, but the effect is the same - a late included object file with `-export` is fatal.
To reproduce the issue:
* `entry.c`:
```c
double pow(double, double);
double entry(double d) {
return pow(d, d);
}
```
* `pow.c`:
```c
double __declspec(dllexport) pow(double x, double y) {
return x;
}
```
* `_fltused.c`:
```c
int _fltused;
```
Build like this:
```console
clang -target x86_64-windows-msvc -c entry.c -flto=thin -fno-math-errno
clang -target x86_64-windows-msvc -c pow.c
clang -target x86_64-windows-msvc -c _fltused.c
llvm-ar rcs math.lib pow.o _fltused.o
lld-link entry.o -entry:entry -subsystem:console math.lib
```
The triggering factor here, is that the compiled IR object `entry.o` doesn't show any traces of the `pow` function:
```console
$ llvm-nm entry.o
---------------- T entry
```
This happens as long as building with `-fno-math-errno` and not using `-fno-builtin` - the math function is treated as the IR builtin `@llvm.pow.f64`. After the bitcode is compiled to a regular object file, we get an actual reference to the `pow` symbol, try to pull it in from `math.lib`, and find the `-export` directive.
For LTO, there is logic to try to pull in any potential function that can be referenced by generated code like this, here: https://github.com/llvm/llvm-project/blob/llvmorg-21.1.1/lld/COFF/Driver.cpp#L2561-L2571
This does include the `pow` function - however, this only pulls in potential bitcode object files. Regular objects are not pulled in here: https://github.com/llvm/llvm-project/blob/llvmorg-21.1.1/lld/COFF/SymbolTable.cpp#L951-L964
This is a reduced form of downstream issue https://github.com/mstorsjo/llvm-mingw/issues/516.
CC @aganea @rnk @cjacek @Andarwinux
What do you think about this case? The previous very similar issue, https://github.com/llvm/llvm-project/issues/131807, was handled by making that mechanism (pulling in a symbol `<foo>` for an undefined referece to `__imp_<foo>`) not pull in lazy objects from archives.
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs