-
Notifications
You must be signed in to change notification settings - Fork 12.5k
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
[lld][coff] spurious duplicate symbols with delayload on x86 #107371
Comments
@llvm/issue-subscribers-lld-coff Author: Mike Hommey (glandium)
STR:
- Download https://drive.google.com/file/d/1AESRw2pf8lbMwfKl4S238UlOBqf1YHCR/view?usp=sharing
- Unpack the archive and enter the `repro` directory.
- Run `lld-link @response.txt`
Expected result: success Actual result:
Removing What's peculiar in this link is that there are COFF import files in gkrust.lib that repeats symbols from other Cc: @mstorsjo |
Thanks, reproed. Regarding rust and embedded import libraries, there are also other known issues around that, when some build systems want to link such a library with |
So it turns out there's something fishy in the windows-targets crate, which makes rust generate symbols that are different from the symbols in the real import library, and that confuses lld because both symbols have the same external name, leading the the duplicate symbol error, which is, in fact, confusing in itself considering what's going on. So, for instance, the real ole32.lib has This is 32-bits only because on 64-bits windows, both ole32.lib and gkrust.lib have If I remove the I'm not sure whether what lld does to name the synthetic symbol should be considered a bug or not, but at the very least, the error could be less confusing. |
If you'd manage to produce a minimal, lld testcase sized reproduction of the issue, it'd be interesting to study where the duplicate symbol name comes from. (It's been a few years since I touched delayloading last time, so I'm not entirely up to date with what symbols are created there.)
Hmm, I don't think removing the import name type Let's have a closer look at the import library entry in the original WinSDK ole32.lib for this function:
So on the object file level, the import library has the symbols Now if we do the same on the rust provided import library, we see this:
So this doesn't really do the right thing at all. Other object file references to this symbol would be referring to So I think the import name type |
Well, removing the Here's how a C++ file refers to CoInitializeEx:
Here's how gkrust.lib refers to CoInitializeEx:
Here's how gkrust.lib refers to it with
(I'm not sure what's up with the non- |
Oh, they come from a crate that uses winapi, so which doesn't use raw-dylib. |
For link time behaviour, possibly yes, but I doubt that your executable will start at runtime. What does |
There isn't an |
I guess the most important part is this: it's indeed not the same as when not using raw-dylibs at all:
|
I presume this is for the linked binary? Yeah this won't load at runtime, but as this is a delayed import, you won't notice until you actually try to call the function. There's no exported
I meant to just run |
Yeah I don't really know about the rust/raw-dylibs aspects, but if the import lib entry in |
At this point, I think the only thing I'd consider a bug on the LLVM side is lld-link's duplicate symbol message is lacking an indication of origin of the duplicate symbol in this specific corner case. |
STR:
repro
directory.lld-link @response.txt
Expected result: success
Actual result:
Removing
-DELAYLOAD:ole32.dll
,-DELAYLOAD:user32.dll
, and-DELAYLOAD:winmm.dll
from the response file makes the issue go away.What's peculiar in this link is that there are COFF import files in gkrust.lib that repeats symbols from other
.lib
s. Those come from rust's raw-dylib feature. It somehow makes the linker trip with the delayload, but only on x86, not x86_64 or aarch64.Cc: @mstorsjo
The text was updated successfully, but these errors were encountered: