rust-lang/rust

Wrong symbols are referenced for raw-dylib on i686-pc-windows-gnu

glandium opened this issue · 0 comments

The following code:

#[no_mangle]
pub extern "C" fn foo() {
    unsafe {
        windows_sys::Win32::System::Com::CoInitializeEx(std::ptr::null(), 0);
    }
}

With the following dependency:

windows-sys = { version = "0.59", features=["Win32_System_Com"] }

Also add the following to Cargo.toml:

[lib]
crate-type = ["staticlib"]

Building with RUSTFLAGS=--cfg=windows_raw_dylib cargo build --target i686-pc-windows-gnu (enabling raw-dylibs) produces a .a file that contains an ole32.dll import with the following references (as per llvm-readobj --symbols):

  Symbol {
    Name: CoInitializeEx
    Value: 0
    Section: .text (1)
    BaseType: Null (0x0)
    ComplexType: Null (0x0)
    StorageClass: External (0x2)
    AuxSymbolCount: 0
  }
  Symbol {
    Name: __imp_CoInitializeEx
    Value: 0
    Section: .idata$5 (5)
    BaseType: Null (0x0)
    ComplexType: Null (0x0)
    StorageClass: External (0x2)
    AuxSymbolCount: 0
  }

The real libole32.a from mingw contains:

  Symbol {
    Name: _CoInitializeEx@8
    Value: 0
    Section: .text (1)
    BaseType: Null (0x0)
    ComplexType: Null (0x0)
    StorageClass: External (0x2)
    AuxSymbolCount: 0
  }
  Symbol {
    Name: __imp__CoInitializeEx@8
    Value: 0
    Section: .idata$5 (5)
    BaseType: Null (0x0)
    ComplexType: Null (0x0)
    StorageClass: External (0x2)
    AuxSymbolCount: 0
  }

IOW, the symbol is decorated in the real library, but is not in the raw-dylib. This can cause problems downstream e.g. when linking with delayload.

See #130586 for a similar problem on i686-pc-windows-msvc that was fixed in 1.84.0.

Cc: @dpaoliello @kennykerr