-
-
Notifications
You must be signed in to change notification settings - Fork 206
[LLD] Version script support #65
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
Comments
Continuation to discussion in #56 Seems like reusing Supporting LLD will have to wait until then. |
That's surprising - which aspect of them doesn't binutils ld support? As far as I know they handle them just fine; you pass the name of the def file as one of the input files, and it handles at least the normal list of exports that GNU ld, lld and msvc link.exe all handle the same. |
Passed to Clang with
Def file contents: https://gist.github.com/mati865/85265364bcaaacc101e33a77f059a896 |
Three things come to mind:
|
It's the same result ( |
Works fine for me in a minimal testcase: $ cat test.c
void a(void) {}
void b(void) {}
void c(void) {}
$ cat test.def
EXPORTS
a
b
$ x86_64-w64-mingw32-gcc -c test.c -o test.o
$ x86_64-w64-mingw32-ld --version
GNU ld (GNU Binutils) 2.25
Copyright (C) 2014 Free Software Foundation, Inc.
This program is free software; you may redistribute it under the terms of
the GNU General Public License version 3 or (at your option) a later version.
This program has absolutely no warranty.
$ x86_64-w64-mingw32-ld test.o test.def -o test.dll -shared
$ llvm-readobj --coff-exports test.dll
File: test.dll
Format: COFF-x86-64
Arch: x86_64
AddressSize: 64bit
Export {
Ordinal: 1
Name: a
RVA: 0x1000
}
Export {
Ordinal: 2
Name: b
RVA: 0x1007
}
|
Builds are taking quite some time but now I can confirm LD does work when |
Update on this topic:
`.def` file from above case:
`linker-script` from above case:
I don't full understand what is going on so Rust support for LLD with MinGW targets will wait for now. |
Was this with def files, with LLD? To narrow things down, if you have time, it could be useful to try applying that on a normal GCC/binutils based build, to see if that aspect is creating issues, or if it's just other aspects of LLD vs ld.bfd vs link.exe. |
Those results are the same with ld.bfd and LLD. Though I mostly test ld.bfd since import libs are not always generated yet so using LLD requires a lot manual work. |
Oh, ok, that's weird then. Maybe the def file generation scripts need to know about and handle some other mingw-ism... |
I tried adding I'll inspect ELF LLD code for |
I've looked at it a few times, and version script seems to be a subset of full linker script, and linker script is essentially a script that controls the whole linker, which in the ELF linker is very closely integrated with the whole linker. But maybe it's possible to extract out the bits necessary for version script without bringing all of it. Having support for version script would indeed be great. |
Oh, this part EDIT: Also those are isolated cases (from testsuite), def file works most of the time. |
I think the other problem is ld.bfd not support lto, because llvm gold plugin not support PE/COFF target. and if use ld.bfd need rebuild mingw-w64 crt with binutils, otherwise it will cause link failure. By the way. is there any way let llvm gold plugin support PE/COFF like gcc lto plugin? |
Extracting the parser properly (by not duplicating) the code is indeed very hard task. |
So I have solution for BFD:
That way whole testsuite passes with Clang + BFD. No idea if I had issue with my previous LLD config or upgrade to LLD 10 broke it but I'm unable to link Rust with it's std library when using LLD because of |
That's great! Needing to specify
Can you isolate one of the missing symbols in the LLD case - the thing to investigate then is, given the same input to both LLD and ld.bfd, why does ld.bfd export that symbol but LLD doesn't? |
LLD dll and import library (
LLD dll and import library (
I think it's related to whether compiler decides the functions can be inlined since all the missing functions I have randomly checked are either marked with Example of slightly bigger function:
Correction: amount of the symbols is the same, they are just imported differently. |
Note that nm (at least llvm-nm) doesn't list whether a function is exported, it just checks the symbol table of the dll - a stripped dll (or at least one built with I think the issue here could be the slightly unexpected chars in the symbol names ( |
IIRC dllimport was used in Rust years ago but most of it usage was removed. Well, it appears this was the missing bit: https://github.com/rust-lang/rust/blob/c1e05528696ca523055b0f7ce94b8033dcbaa39e/src/librustc_codegen_llvm/context.rs#L218-L261
Interesting. When looking at LLD import lib there is no single symbol which would match |
Ok, I see, so with MSVC like tools, it tried to use dllimport as needed, reluctantly. With MinGW like tools, it knows the linker will fix things up as needed, so no need to worry. But that "fixing things up as needed" relies on the import lib flagging functions vs data correctly, and what happens correctly when using a version script, but when using a def file, the def file needs to know what's data and what's a function, otherwise the attempts at reading "data" will actually read the
Ok, hopefully that's it. In the best case, this is a couple-lines fix somewhere in the def file parser (llvm/lib/Object/COFF* iirc), unless there's conflicting syntax elements. Using |
Ok so I've tried enabling dllimport and it doesn't look like
It's a static which I suppose should be marked with LLD fails even earlier than BFD because symbols with |
Ok, so that sounds like the dllimport gets applied correctly, but the dllexport doesn't take effect (maybe an incompatibility between dllexport attributes embedded in the object files vs how ld.bfd interprets them?). |
Probably the last straight, during building of
There is probably another missing bit somewhere else. Maybe I should build Rust with MSVC and disable incremental compilation to compare them? |
I'm not sure how to interpret this last error message. So there's an undefined reference against a symbol That sounds like a case where dllimport was used when compiling the code that refers to it, but it turns out to be linked statically instead of dynamically as expected. |
BFD always creates import libraries like that:
That symbol is actually present inside LLD still fails to link with errors like
|
OK it surely is .def parsing issue: .global _main
.global _foo$foo
.global _bar.bar
.text
_main:
ret
_foo$foo:
ret
_bar.bar:
ret
.section .drectve
.ascii "-export:foo$foo -export:bar.bar" Looks fine:
Now move
And we get:
So
Which kinda surprises me because folks were already using LLD to develop Rust. |
Well, where LLD already is used, they use the MSVC workflow of only using dllexport/dllimport, not def files? Thanks for the repro cases and for verifying. Especially as link.exe handles Also fwiw, |
Def files are always enabled for MSVC unless building executable. Apparently they use workaround forcing
I'll try to find it and eventually fix it unless you beat me to it 😉. |
I posted a fix for the LLD period in symbol names in def files issue at https://reviews.llvm.org/D79619, fwiw. |
I was looking at that code yesterday but postponed it till today. Thank you for the fix. |
Moving from #56
It's not top priority but would be nice to support it at some point.
The text was updated successfully, but these errors were encountered: