-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
raw-dylib feature does not support all cases for stdcall functions on i686-pc-windows-* #96534
Labels
C-bug
Category: This is a bug.
F-raw_dylib
`#![feature(raw_dylib)]`
O-windows
Operating system: Windows
T-compiler
Relevant to the compiler team, which will review and decide on the PR/issue.
Comments
15 tasks
bjorn3
added
C-bug
Category: This is a bug.
F-raw_dylib
`#![feature(raw_dylib)]`
O-windows
Operating system: Windows
T-compiler
Relevant to the compiler team, which will review and decide on the PR/issue.
labels
Apr 28, 2022
@rustbot claim |
FYI, I've managed to get an implementation of the |
Dylan-DPC
added a commit
to Dylan-DPC/rust
that referenced
this issue
Aug 25, 2022
…leywiser Implementation of import_name_type Fixes rust-lang#96534 by implementing rust-lang/compiler-team#525 Symbols that are exported or imported from a binary on 32bit x86 Windows can be named in four separate ways, corresponding to the [import name types](https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#import-name-type) from the PE-COFF spec. The exporting and importing binaries must use the same name encoding, otherwise mismatches can lead to link failures due to "missing symbols" or to 0xc0000139 (`STATUS_ENTRYPOINT_NOT_FOUND`) errors when the executable/library is loaded. For details, see the comments on the raw-dylib feature's rust-lang#58713. To generate the correct import libraries for these DLLs, therefore, rustc must know the import name type for each `extern` function, and there is currently no way for users to provide this information. This change adds a new `MetaNameValueStr` key to the `#[link]` attribute called `import_name_type`, and which accepts one of three values: `decorated`, `noprefix`, and `undecorated`. A single DLL is likely to export all its functions using the same import type name, hence `import_name_type` is a parameter of `#[link]` rather than being its own attribute that is applied per-function. It is possible to have a single DLL that exports different functions using different import name types, but users could express such cases by providing multiple export blocks for the same DLL, each with a different import name type. Note: there is a fourth import name type defined in the PE-COFF spec, `IMPORT_ORDINAL`. This case is already handled by the `#[link_ordinal]` attribute. While it could be merged into `import_type_name`, that would not make sense as `#[link_ordinal]` provides per-function information (namely the ordinal itself). Design decisions (these match the MCP linked above): * For GNU, `decorated` matches the PE Spec and MSVC rather than the default behavior of `dlltool` (i.e., there will be a leading `_` for `stdcall`). * If `import_name_type` is not present, we will keep our current behavior of matching the environment (MSVC vs GNU) default for decorating. * Using `import_name_type` on architectures other than 32bit x86 will result in an error. * Using `import_name_type` with link kinds other than `"raw-dylib"` will result in an error.
I got the following error:
Which seems to be from |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Labels
C-bug
Category: This is a bug.
F-raw_dylib
`#![feature(raw_dylib)]`
O-windows
Operating system: Windows
T-compiler
Relevant to the compiler team, which will review and decide on the PR/issue.
Contrary to our original expectations, when an i686 DLL exports a stdcall function, the function's name can appear in the library's export table in one of several different ways. I don't know if this list is exhaustive, but I've seen the following variations:
_exported_function@8
(i.e., with leading underscore and trailing argument-list size)exported_function@8
(trailing size only)exported_function
(exactly as it appears in the defining source file)Which form the symbols take appears to depend on how the DLL is linked. This is another facet of the problem that I don't fully understand, but one variable appears to be whether the function is defined with
__declspec(dllexport)
or the function is marked for export in a .DEF file provided to the linker invocation that creates the .DLL file.To successfully link against such a DLL, the import library has to match not only the name of the symbol as it appears in the exporting DLL, but also the reference to the name (usually of the form
__imp_exported_function@8
, at least with rustc/LLVM) by which the importing library/image refers to it.In an earlier attempt to solve this problem, we did notice that the three variants of the symbol name in the list above correspond to 3 of the 4 possible values of the IMPORT_NAME_TYPE enum defined in the PE-COFF spec, and I created an earlier proposal for adding a new attribute to specify the IMPORT_NAME_TYPE, but this turns out not to work. In particular, an earlier attempt on my part to have rustc supply the function names to LLVM with the decoration specified by the user doesn't work: specifying
NAME_TYPE_UNDECORATE
(intended to be the 3rd case above) resulted in an error when attempting to link the .rlib: the symbol__imp__exported_function@8
was not found. To reproduce, run src/test/run-make/raw-dylib-import-name type from the import-name-time branch of my fork of rustc.The text was updated successfully, but these errors were encountered: