Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

raw-dylib compilation fails targeting nightly-i686-pc-windows-gnu when function name begins with 'L' #104453

Closed
kennykerr opened this issue Nov 15, 2022 · 3 comments
Assignees
Labels
C-bug Category: This is a bug.

Comments

@kennykerr
Copy link
Contributor

kennykerr commented Nov 15, 2022

While testing raw-dylib support against nightly-i686-pc-windows-gnu I noticed that it would fail with a cryptic error.

Here's a minimal repro: https://github.com/kennykerr/repro-raw-dylib

#![feature(raw_dylib)]
#![feature(native_link_modifiers_verbatim)]

#[link(name = "kernel32.dll", kind = "raw-dylib", modifiers = "+verbatim", import_name_type = "undecorated")]
extern "stdcall" {
    fn LoadLibraryA(name: *const u8) -> isize;
}

#[test]
fn test() {
    assert_ne!(0, unsafe { LoadLibraryA("kernel32.dll\0".as_ptr()) });
}

This compiles and runs cleanly i686-pc-windows-msvc but fails on i686-pc-windows-gnu with the following error:

error: assembler label 'LoadLibraryA' can not be undefined
rust version 1.67.0-nightly (e631891f7 2022-11-13)

@dpaoliello pointed out that it seems that if we have an undecorated symbol that begins with 'L' (yep) then LLVM assumes that it is an assembler label, hence the error.

@kennykerr kennykerr added the C-bug Category: This is a bug. label Nov 15, 2022
@dpaoliello
Copy link
Contributor

@rustbot claim

matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Nov 21, 2022
…, r=michaelwoerister

Mark functions created for `raw-dylib` on x86 with DllImport storage class

Fix for rust-lang#104453

## Issue Details
On x86 Windows, LLVM uses 'L' as the prefix for any private global symbols (`PrivateGlobalPrefix`), so when the `raw-dylib` feature creates an undecorated function symbol that begins with an 'L' LLVM misinterprets that as a private global symbol that it created and so fails the compilation at a later stage since such a symbol must have a definition.

## Fix Details
Mark the function we are creating for `raw-dylib` with `DllImport` storage class (this was already being done for MSVC at a later point for `callee::get_fn` but not for GNU (due to "backwards compatibility")): this will cause LLVM to prefix the name with `__imp_` and so it won't mistake it for a private global symbol.
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Nov 21, 2022
…, r=michaelwoerister

Mark functions created for `raw-dylib` on x86 with DllImport storage class

Fix for rust-lang#104453

## Issue Details
On x86 Windows, LLVM uses 'L' as the prefix for any private global symbols (`PrivateGlobalPrefix`), so when the `raw-dylib` feature creates an undecorated function symbol that begins with an 'L' LLVM misinterprets that as a private global symbol that it created and so fails the compilation at a later stage since such a symbol must have a definition.

## Fix Details
Mark the function we are creating for `raw-dylib` with `DllImport` storage class (this was already being done for MSVC at a later point for `callee::get_fn` but not for GNU (due to "backwards compatibility")): this will cause LLVM to prefix the name with `__imp_` and so it won't mistake it for a private global symbol.
@goffrie
Copy link
Contributor

goffrie commented Jan 25, 2023

This was fixed by #104511, right?

@dpaoliello
Copy link
Contributor

This was fixed by #104511, right?

Correct

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
C-bug Category: This is a bug.
Projects
None yet
Development

No branches or pull requests

4 participants