msys2 / MINGW-packages

Package scripts for MinGW-w64 targets to build under MSYS2.
https://packages.msys2.org
BSD 3-Clause "New" or "Revised" License
2.22k stars 1.19k forks source link

librsvg problem in clang #21017

Open revelator opened 1 month ago

revelator commented 1 month ago

Description / Steps to reproduce the issue

building librsvg with clang produces this error ->

ld.lld: error: librsvg_c_api.a(bcryptprimitives.dll): .idata$4 should not refer to special section 0
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Expected behavior

should produce the librsvg build like with gcc

Actual behavior

bugs out with the above error

Verification

Windows Version

MSYS_NT-10.0-26100

MINGW environments affected

Are you willing to submit a PR?

No response

Biswa96 commented 1 month ago

I can reproduce the issue with clang64.

revelator commented 1 month ago

yeah not really sure whats going on there ???

revelator commented 1 month ago

looks like an invalid section in the bcryptprimitives export though it is not even part of the mingw-w64-abi only bcrypt. seems it links directly to the dll but fails and it is not clear if it is a problem with the compiler or something else.

revelator commented 1 month ago

ah i smell a mingw specific linker script sec investigating.

mati865 commented 1 month ago

There are no linker/version scripts involved since LLD doesn't support them at all and would just error out. The library is linked by Rust since https://github.com/rust-lang/rust/pull/121337 by creating own import library through LLVM backend.

revelator commented 1 month ago

exactly what i was after but yeah librsvg does not use a linker script so it seems to be something else going on.

revelator commented 1 month ago

ok it is rust it seems, tried reverting to a previous version and now it builds...

mati865 commented 1 month ago

How to reproduce this problem? For me clean checkout of librsvg from git (commit b4d6f2071342ef5be36f25253a9bf1bf9277f8ec) and running with Rust from CLANG64 works:

$ cargo b
...
Finished `dev` profile [unoptimized + debuginfo] target(s) in 44.55s

$ cargo clean

$ cargo b -r
...
Finished `release` profile [optimized] target(s) in 51.56s

$ rustc -vV
rustc 1.78.0 (9b00956e5 2024-04-29) (Rev1, Built by MSYS2 project)
binary: rustc
commit-hash: 9b00956e56009bab2aa15d7bff10916599e3d6d6
commit-date: 2024-04-29
host: x86_64-pc-windows-gnu
release: 1.78.0
LLVM version: 18.1.4

and so does current nightly:

$ PKG_CONFIG_SYSROOT_DIR=/h/msys64/clang64/share/pkgconfig PKG_CONFIG_PATH=/h/msys64/clang64/bin/pkgconf.exe cargo b --target x86_64-pc-windows-gnullvm
...
Finished `dev` profile [unoptimized + debuginfo] target(s) in 55.57s

$ cargo clean

$ PKG_CONFIG_SYSROOT_DIR=/h/msys64/clang64/share/pkgconfig PKG_CONFIG_PATH=/h/msys64/clang64/bin/pkgconf.exe cargo b --target x86_64-pc-windows-gnullvm -r
...
Finished `release` profile [optimized] target(s) in 49.13s

$ rustc -vV
rustc 1.80.0-nightly (da159eb33 2024-05-28)
binary: rustc
commit-hash: da159eb331b27df528185c616b394bb0e1d2a4bd
commit-date: 2024-05-28
host: x86_64-pc-windows-gnu
release: 1.80.0-nightly
LLVM version: 18.1.6
revelator commented 1 month ago

so some incompatibility between our version of rust/llvm and librsvg-2.58.0 ?

revelator commented 1 month ago

wait you are using the nightly version of rust ? im on 1.78 O_o

EDIT: nvm i see now

mati865 commented 1 month ago

It does reproduce when building MSYS2 package (and with upstream code not newer than 2.58 using some special steps).

As I said previous on Discord something must be wrong with generated import libraries:

$ objdump -t /h/projects/MINGW-packages/mingw-w64-librsvg/src/build-CLANG64/.libs/librsvg_c_api.a | rg idata [ 1](sec 1)(fl 0x00)(ty 0)(scl 68) (nx 0) 0x00000000 .idata$2 [ 2](sec 2)(fl 0x00)(ty 0)(scl 3) (nx 0) 0x00000000 .idata$6 [ 3](sec 0)(fl 0x00)(ty 0)(scl 68) (nx 0) 0x00000000 .idata$4 [ 4](sec 0)(fl 0x00)(ty 0)(scl 68) (nx 0) 0x00000000 .idata$5 [ 1](sec 1)(fl 0x00)(ty 0)(scl 68) (nx 0) 0x00000000 .idata$2 [ 2](sec 2)(fl 0x00)(ty 0)(scl 3) (nx 0) 0x00000000 .idata$6 [ 3](sec 0)(fl 0x00)(ty 0)(scl 68) (nx 0) 0x00000000 .idata$4 [ 4](sec 0)(fl 0x00)(ty 0)(scl 68) (nx 0) 0x00000000 .idata$5

- x86_64-pc-windows-gnu target:

$ nm target/release/liblibrsvg_c.a | grep idata 00000000 i .idata$4 00000000 i .idata$5 00000000 i .idata$4 00000000 i .idata$5 00000000 i .idata$6 00000000 i .idata$7 00000000 i .idata$4 00000000 i .idata$5 00000000 i .idata$4 00000000 i .idata$5 00000000 i .idata$6 00000000 i .idata$7 00000000 i .idata$4 00000000 i .idata$5 00000000 i .idata$6 00000000 i .idata$7 00000000 i .idata$4 00000000 i .idata$5 00000000 i .idata$6 00000000 i .idata$7

$ objdump -t target/release/liblibrsvg_c.a | grep idata [ 8](sec 4)(fl 0x00)(ty 0)(scl 3) (nx 1) 0x00000000 .idata$4 [10](sec 5)(fl 0x00)(ty 0)(scl 3) (nx 1) 0x00000000 .idata$5 [12](sec 6)(fl 0x00)(ty 0)(scl 3) (nx 1) 0x00000000 .idata$7 [10](sec 4)(fl 0x00)(ty 0)(scl 3) (nx 1) 0x00000000 .idata$2 [12](sec 6)(fl 0x00)(ty 0)(scl 3) (nx 0) 0x00000000 .idata$4 [13](sec 5)(fl 0x00)(ty 0)(scl 3) (nx 0) 0x00000000 .idata$5 [ 3](sec 4)(fl 0x00)(ty 0)(scl 3) (nx 0) 0x00000000 .idata$7 [ 4](sec 5)(fl 0x00)(ty 0)(scl 3) (nx 0) 0x00000000 .idata$5 [ 5](sec 6)(fl 0x00)(ty 0)(scl 3) (nx 0) 0x00000000 .idata$4 [ 6](sec 7)(fl 0x00)(ty 0)(scl 3) (nx 0) 0x00000000 .idata$6 [ 8](sec 4)(fl 0x00)(ty 0)(scl 3) (nx 1) 0x00000000 .idata$4 [10](sec 5)(fl 0x00)(ty 0)(scl 3) (nx 1) 0x00000000 .idata$5 [12](sec 6)(fl 0x00)(ty 0)(scl 3) (nx 1) 0x00000000 .idata$7 [10](sec 4)(fl 0x00)(ty 0)(scl 3) (nx 1) 0x00000000 .idata$2 [12](sec 6)(fl 0x00)(ty 0)(scl 3) (nx 0) 0x00000000 .idata$4 [13](sec 5)(fl 0x00)(ty 0)(scl 3) (nx 0) 0x00000000 .idata$5 [ 3](sec 4)(fl 0x00)(ty 0)(scl 3) (nx 0) 0x00000000 .idata$7 [ 4](sec 5)(fl 0x00)(ty 0)(scl 3) (nx 0) 0x00000000 .idata$5 [ 5](sec 6)(fl 0x00)(ty 0)(scl 3) (nx 0) 0x00000000 .idata$4 [ 6](sec 7)(fl 0x00)(ty 0)(scl 3) (nx 0) 0x00000000 .idata$6 [ 3](sec 4)(fl 0x00)(ty 0)(scl 3) (nx 0) 0x00000000 .idata$7 [ 4](sec 5)(fl 0x00)(ty 0)(scl 3) (nx 0) 0x00000000 .idata$5 [ 5](sec 6)(fl 0x00)(ty 0)(scl 3) (nx 0) 0x00000000 .idata$4 [ 6](sec 7)(fl 0x00)(ty 0)(scl 3) (nx 0) 0x00000000 .idata$6 [ 3](sec 4)(fl 0x00)(ty 0)(scl 3) (nx 0) 0x00000000 .idata$7 [ 4](sec 5)(fl 0x00)(ty 0)(scl 3) (nx 0) 0x00000000 .idata$5 [ 5](sec 6)(fl 0x00)(ty 0)(scl 3) (nx 0) 0x00000000 .idata$4 [ 6](sec 7)(fl 0x00)(ty 0)(scl 3) (nx 0) 0x00000000 .idata$6


EDIT: Naturally those symbols are present in prebuilt std library as they originate from there:

$ nm ~/.rustup/toolchains/nightly-x86_64-pc-windows-gnu/lib/rustlib/x86_64-pc-windows-gnullvm/lib/libstd-d31db6c27cb2af27.rlib | rg idata 00000000 i .idata$2 00000000 ? .idata$4 00000000 ? .idata$5 00000000 i .idata$6 00000000 i .idata$2 00000000 ? .idata$4 00000000 ? .idata$5 00000000 i .idata$6

$ objdump -t ~/.rustup/toolchains/nightly-x86_64-pc-windows-gnu/lib/rustlib/x86_64-pc-windows-gnullvm/lib/libstd-d31db6c27cb2af27.rlib | rg idata [ 1](sec 1)(fl 0x00)(ty 0)(scl 68) (nx 0) 0x00000000 .idata$2 [ 2](sec 2)(fl 0x00)(ty 0)(scl 3) (nx 0) 0x00000000 .idata$6 [ 3](sec 0)(fl 0x00)(ty 0)(scl 68) (nx 0) 0x00000000 .idata$4 [ 4](sec 0)(fl 0x00)(ty 0)(scl 68) (nx 0) 0x00000000 .idata$5 [ 1](sec 1)(fl 0x00)(ty 0)(scl 68) (nx 0) 0x00000000 .idata$2 [ 2](sec 2)(fl 0x00)(ty 0)(scl 3) (nx 0) 0x00000000 .idata$6 [ 3](sec 0)(fl 0x00)(ty 0)(scl 68) (nx 0) 0x00000000 .idata$4 [ 4](sec 0)(fl 0x00)(ty 0)(scl 68) (nx 0) 0x00000000 .idata$5

revelator commented 1 month ago

not sure if refering to me but im not on discord so i did not know :) but its being looked at thats what matters.

mati865 commented 1 month ago

I'm afraid I'm not competent enough to understand what is going on here.

I've tried running objdump on those files but I don't even know what to look for (most of the differences are probably related to legacy vs short import lib format). llvm-objdump -x of relevant sections:

Details ``` C:/Users/mateusz/.rustup/toolchains/nightly-x86_64-pc-windows-gnu/lib/rustlib/x86_64-pc-windows-gnu/lib/libstd-8e1d66ff2e108c97.rlib(bcryptprimitives.dllt.o): file format coff-x86-64 rw-r--r-- 0/0 637 Thu Jan 1 01:00:00 1970 bcryptprimitives.dllt.o architecture: x86_64 start address: 0x0000000000000000 Characteristics 0x5 relocations stripped line numbers stripped Time/Date Thu Jan 1 01:00:00 1970 Sections: Idx Name Size VMA Type 0 .text 00000000 0000000000000000 TEXT 1 .data 00000000 0000000000000000 DATA 2 .bss 00000000 0000000000000000 BSS 3 .idata$4 00000008 0000000000000000 DATA 4 .idata$5 00000008 0000000000000000 DATA 5 .idata$7 00000018 0000000000000000 DATA SYMBOL TABLE: [ 0](sec -2)(fl 0x00)(ty 0)(scl 67) (nx 1) 0x00000000 .file AUX fake [ 2](sec 1)(fl 0x00)(ty 0)(scl 3) (nx 1) 0x00000000 .text AUX scnlen 0x0 nreloc 0 nlnno 0 checksum 0x0 assoc 0 comdat 0 [ 4](sec 2)(fl 0x00)(ty 0)(scl 3) (nx 1) 0x00000000 .data AUX scnlen 0x0 nreloc 0 nlnno 0 checksum 0x0 assoc 0 comdat 0 [ 6](sec 3)(fl 0x00)(ty 0)(scl 3) (nx 1) 0x00000000 .bss AUX scnlen 0x0 nreloc 0 nlnno 0 checksum 0x0 assoc 0 comdat 0 [ 8](sec 4)(fl 0x00)(ty 0)(scl 3) (nx 1) 0x00000000 .idata$4 AUX scnlen 0x8 nreloc 0 nlnno 0 checksum 0x0 assoc 0 comdat 0 [10](sec 5)(fl 0x00)(ty 0)(scl 3) (nx 1) 0x00000000 .idata$5 AUX scnlen 0x8 nreloc 0 nlnno 0 checksum 0x0 assoc 0 comdat 0 [12](sec 6)(fl 0x00)(ty 0)(scl 3) (nx 1) 0x00000000 .idata$7 AUX scnlen 0x15 nreloc 0 nlnno 0 checksum 0x0 assoc 0 comdat 0 [14](sec 6)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000000 __C__a__temp_msys64_tmp_rustc10hWNd_bcryptprimitives_lib_iname C:/Users/mateusz/.rustup/toolchains/nightly-x86_64-pc-windows-gnu/lib/rustlib/x86_64-pc-windows-gnu/lib/libstd-8e1d66ff2e108c97.rlib(bcryptprimitives.dllh.o): file format coff-x86-64 rw-r--r-- 0/0 726 Thu Jan 1 01:00:00 1970 bcryptprimitives.dllh.o architecture: x86_64 start address: 0x0000000000000000 Characteristics 0x4 line numbers stripped Time/Date Thu Jan 1 01:00:00 1970 Sections: Idx Name Size VMA Type 0 .text 00000000 0000000000000000 TEXT 1 .data 00000000 0000000000000000 DATA 2 .bss 00000000 0000000000000000 BSS 3 .idata$2 00000014 0000000000000000 DATA 4 .idata$5 00000000 0000000000000000 DATA 5 .idata$4 00000000 0000000000000000 DATA SYMBOL TABLE: [ 0](sec -2)(fl 0x00)(ty 0)(scl 67) (nx 1) 0x00000000 .file AUX fake [ 2](sec 6)(fl 0x00)(ty 0)(scl 3) (nx 0) 0x00000000 hname [ 3](sec 5)(fl 0x00)(ty 0)(scl 3) (nx 0) 0x00000000 fthunk [ 4](sec 1)(fl 0x00)(ty 0)(scl 3) (nx 1) 0x00000000 .text AUX scnlen 0x0 nreloc 0 nlnno 0 checksum 0x0 assoc 0 comdat 0 [ 6](sec 2)(fl 0x00)(ty 0)(scl 3) (nx 1) 0x00000000 .data AUX scnlen 0x0 nreloc 0 nlnno 0 checksum 0x0 assoc 0 comdat 0 [ 8](sec 3)(fl 0x00)(ty 0)(scl 3) (nx 1) 0x00000000 .bss AUX scnlen 0x0 nreloc 0 nlnno 0 checksum 0x0 assoc 0 comdat 0 [10](sec 4)(fl 0x00)(ty 0)(scl 3) (nx 1) 0x00000000 .idata$2 AUX scnlen 0x14 nreloc 3 nlnno 0 checksum 0x0 assoc 0 comdat 0 [12](sec 6)(fl 0x00)(ty 0)(scl 3) (nx 0) 0x00000000 .idata$4 [13](sec 5)(fl 0x00)(ty 0)(scl 3) (nx 0) 0x00000000 .idata$5 [14](sec 4)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000000 _head_C__a__temp_msys64_tmp_rustc10hWNd_bcryptprimitives_lib [15](sec 0)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000000 __C__a__temp_msys64_tmp_rustc10hWNd_bcryptprimitives_lib_iname RELOCATION RECORDS FOR [.idata$2]: OFFSET TYPE VALUE 0000000000000000 IMAGE_REL_AMD64_ADDR32NB .idata$4 000000000000000c IMAGE_REL_AMD64_ADDR32NB __C__a__temp_msys64_tmp_rustc10hWNd_bcryptprimitives_lib_iname 0000000000000010 IMAGE_REL_AMD64_ADDR32NB .idata$5 C:/Users/mateusz/.rustup/toolchains/nightly-x86_64-pc-windows-gnu/lib/rustlib/x86_64-pc-windows-gnu/lib/libstd-8e1d66ff2e108c97.rlib(bcryptprimitives.dlls00000.o): file format coff-x86-64 rw-r--r-- 0/0 659 Thu Jan 1 01:00:00 1970 bcryptprimitives.dlls00000.o architecture: x86_64 start address: 0x0000000000000000 Characteristics 0x4 line numbers stripped Time/Date Thu Jan 1 01:00:00 1970 Sections: Idx Name Size VMA Type 0 .text 00000008 0000000000000000 TEXT 1 .data 00000000 0000000000000000 DATA 2 .bss 00000000 0000000000000000 BSS 3 .idata$7 00000004 0000000000000000 4 .idata$5 00000008 0000000000000000 5 .idata$4 00000008 0000000000000000 6 .idata$6 0000000e 0000000000000000 SYMBOL TABLE: [ 0](sec 1)(fl 0x00)(ty 0)(scl 3) (nx 0) 0x00000000 .text [ 1](sec 2)(fl 0x00)(ty 0)(scl 3) (nx 0) 0x00000000 .data [ 2](sec 3)(fl 0x00)(ty 0)(scl 3) (nx 0) 0x00000000 .bss [ 3](sec 4)(fl 0x00)(ty 0)(scl 3) (nx 0) 0x00000000 .idata$7 [ 4](sec 5)(fl 0x00)(ty 0)(scl 3) (nx 0) 0x00000000 .idata$5 [ 5](sec 6)(fl 0x00)(ty 0)(scl 3) (nx 0) 0x00000000 .idata$4 [ 6](sec 7)(fl 0x00)(ty 0)(scl 3) (nx 0) 0x00000000 .idata$6 [ 7](sec 1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000000 ProcessPrng [ 8](sec 5)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000000 __imp_ProcessPrng [ 9](sec 0)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000000 _head_C__a__temp_msys64_tmp_rustc10hWNd_bcryptprimitives_lib RELOCATION RECORDS FOR [.text]: OFFSET TYPE VALUE 0000000000000002 IMAGE_REL_AMD64_REL32 __imp_ProcessPrng RELOCATION RECORDS FOR [.idata$7]: OFFSET TYPE VALUE 0000000000000000 IMAGE_REL_AMD64_ADDR32NB _head_C__a__temp_msys64_tmp_rustc10hWNd_bcryptprimitives_lib RELOCATION RECORDS FOR [.idata$5]: OFFSET TYPE VALUE 0000000000000000 IMAGE_REL_AMD64_ADDR32NB .idata$6 RELOCATION RECORDS FOR [.idata$4]: OFFSET TYPE VALUE 0000000000000000 IMAGE_REL_AMD64_ADDR32NB .idata$6 ```
Details ``` C:/Users/mateusz/.rustup/toolchains/nightly-x86_64-pc-windows-gnu/lib/rustlib/x86_64-pc-windows-gnullvm/lib/libstd-d31db6c27cb2af27.rlib(bcryptprimitives.dll): file format coff-x86-64 rw-r--r-- 0/0 397 Thu Jan 1 01:00:00 1970 bcryptprimitives.dll architecture: x86_64 start address: 0x0000000000000000 Characteristics 0x0 Time/Date Thu Jan 1 01:00:00 1970 Sections: Idx Name Size VMA Type 0 .idata$2 00000014 0000000000000000 DATA 1 .idata$6 00000015 0000000000000000 DATA SYMBOL TABLE: [ 0](sec 1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000000 __IMPORT_DESCRIPTOR_bcryptprimitives [ 1](sec 1)(fl 0x00)(ty 0)(scl 68) (nx 0) 0x00000000 .idata$2 [ 2](sec 2)(fl 0x00)(ty 0)(scl 3) (nx 0) 0x00000000 .idata$6 [ 3](sec 0)(fl 0x00)(ty 0)(scl 68) (nx 0) 0x00000000 .idata$4 [ 4](sec 0)(fl 0x00)(ty 0)(scl 68) (nx 0) 0x00000000 .idata$5 [ 5](sec 0)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000000 __NULL_IMPORT_DESCRIPTOR [ 6](sec 0)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000000 bcryptprimitives_NULL_THUNK_DATA RELOCATION RECORDS FOR [.idata$2]: OFFSET TYPE VALUE 000000000000000c IMAGE_REL_AMD64_ADDR32NB .idata$6 0000000000000000 IMAGE_REL_AMD64_ADDR32NB .idata$4 0000000000000010 IMAGE_REL_AMD64_ADDR32NB .idata$5 C:/Users/mateusz/.rustup/toolchains/nightly-x86_64-pc-windows-gnu/lib/rustlib/x86_64-pc-windows-gnullvm/lib/libstd-d31db6c27cb2af27.rlib(bcryptprimitives.dll): file format coff-x86-64 rw-r--r-- 0/0 127 Thu Jan 1 01:00:00 1970 bcryptprimitives.dll architecture: x86_64 start address: 0x0000000000000000 Characteristics 0x0 Time/Date Thu Jan 1 01:00:00 1970 Sections: Idx Name Size VMA Type 0 .idata$3 00000014 0000000000000000 DATA SYMBOL TABLE: [ 0](sec 1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000000 __NULL_IMPORT_DESCRIPTOR C:/Users/mateusz/.rustup/toolchains/nightly-x86_64-pc-windows-gnu/lib/rustlib/x86_64-pc-windows-gnullvm/lib/libstd-d31db6c27cb2af27.rlib(bcryptprimitives.dll): file format coff-x86-64 rw-r--r-- 0/0 172 Thu Jan 1 01:00:00 1970 bcryptprimitives.dll architecture: x86_64 start address: 0x0000000000000000 Characteristics 0x0 Time/Date Thu Jan 1 01:00:00 1970 Sections: Idx Name Size VMA Type 0 .idata$5 00000008 0000000000000000 DATA 1 .idata$4 00000008 0000000000000000 DATA SYMBOL TABLE: [ 0](sec 1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000000 bcryptprimitives_NULL_THUNK_DATA ```

llvm-objdump -s of relevant sections:

Details ``` C:/Users/mateusz/.rustup/toolchains/nightly-x86_64-pc-windows-gnu/lib/rustlib/x86_64-pc-windows-gnu/lib/libstd-8e1d66ff2e108c97.rlib(bcryptprimitives.dllt.o): file format coff-x86-64 Contents of section .idata$4: 0000 00000000 00000000 ........ Contents of section .idata$5: 0000 00000000 00000000 ........ Contents of section .idata$7: 0000 62637279 70747072 696d6974 69766573 bcryptprimitives 0010 2e646c6c 00000000 .dll.... C:/Users/mateusz/.rustup/toolchains/nightly-x86_64-pc-windows-gnu/lib/rustlib/x86_64-pc-windows-gnu/lib/libstd-8e1d66ff2e108c97.rlib(bcryptprimitives.dllh.o): file format coff-x86-64 Contents of section .idata$2: 0000 00000000 00000000 00000000 00000000 ................ 0010 00000000 .... C:/Users/mateusz/.rustup/toolchains/nightly-x86_64-pc-windows-gnu/lib/rustlib/x86_64-pc-windows-gnu/lib/libstd-8e1d66ff2e108c97.rlib(bcryptprimitives.dlls00000.o): file format coff-x86-64 Contents of section .text: 0000 ff250000 00009090 .%...... Contents of section .idata$7: 0000 00000000 .... Contents of section .idata$5: 0000 00000000 00000000 ........ Contents of section .idata$4: 0000 00000000 00000000 ........ Contents of section .idata$6: 0000 01005072 6f636573 7350726e 6700 ..ProcessPrng. ```
Details ``` C:/Users/mateusz/.rustup/toolchains/nightly-x86_64-pc-windows-gnu/lib/rustlib/x86_64-pc-windows-gnullvm/lib/libstd-d31db6c27cb2af27.rlib(bcryptprimitives.dll): file format coff-x86-64 Contents of section .idata$2: 0000 00000000 00000000 00000000 00000000 ................ 0010 00000000 .... Contents of section .idata$6: 0000 62637279 70747072 696d6974 69766573 bcryptprimitives 0010 2e646c6c 00 .dll. C:/Users/mateusz/.rustup/toolchains/nightly-x86_64-pc-windows-gnu/lib/rustlib/x86_64-pc-windows-gnullvm/lib/libstd-d31db6c27cb2af27.rlib(bcryptprimitives.dll): file format coff-x86-64 Contents of section .idata$3: 0000 00000000 00000000 00000000 00000000 ................ 0010 00000000 .... C:/Users/mateusz/.rustup/toolchains/nightly-x86_64-pc-windows-gnu/lib/rustlib/x86_64-pc-windows-gnullvm/lib/libstd-d31db6c27cb2af27.rlib(bcryptprimitives.dll): file format coff-x86-64 Contents of section .idata$5: 0000 00000000 00000000 ........ Contents of section .idata$4: 0000 00000000 00000000 ........ C:/Users/mateusz/.rustup/toolchains/nightly-x86_64-pc-windows-gnu/lib/rustlib/x86_64-pc-windows-gnullvm/lib/libstd-d31db6c27cb2af27.rlib(bcryptprimitives.dll): file format COFF-import-file ```

llvm-objdump -D of relevant sections:

Details ``` C:/Users/mateusz/.rustup/toolchains/nightly-x86_64-pc-windows-gnu/lib/rustlib/x86_64-pc-windows-gnu/lib/libstd-8e1d66ff2e108c97.rlib(bcryptprimitives.dllt.o): file format coff-x86-64 Disassembly of section .idata$4: 0000000000000000 <.idata$4>: ... Disassembly of section .idata$5: 0000000000000000 <.idata$5>: ... Disassembly of section .idata$7: 0000000000000000 <__C__a__temp_msys64_tmp_rustc10hWNd_bcryptprimitives_lib_iname>: 0: 62 63 72 79 70 5: 74 70 je 0x77 <__C__a__temp_msys64_tmp_rustc10hWNd_bcryptprimitives_lib_iname+0x77> 7: 72 69 jb 0x72 <__C__a__temp_msys64_tmp_rustc10hWNd_bcryptprimitives_lib_iname+0x72> 9: 6d insl %dx, %es:(%rdi) a: 69 74 69 76 65 73 2e 64 imull $0x642e7365, 0x76(%rcx,%rbp,2), %esi # imm = 0x642E7365 12: 6c insb %dx, %es:(%rdi) 13: 6c insb %dx, %es:(%rdi) 14: 00 00 addb %al, (%rax) 16: 00 00 addb %al, (%rax) C:/Users/mateusz/.rustup/toolchains/nightly-x86_64-pc-windows-gnu/lib/rustlib/x86_64-pc-windows-gnu/lib/libstd-8e1d66ff2e108c97.rlib(bcryptprimitives.dllh.o): file format coff-x86-64 Disassembly of section .idata$2: 0000000000000000 <_head_C__a__temp_msys64_tmp_rustc10hWNd_bcryptprimitives_lib>: ... C:/Users/mateusz/.rustup/toolchains/nightly-x86_64-pc-windows-gnu/lib/rustlib/x86_64-pc-windows-gnu/lib/libstd-8e1d66ff2e108c97.rlib(bcryptprimitives.dlls00000.o): file format coff-x86-64 Disassembly of section .text: 0000000000000000 : 0: ff 25 00 00 00 00 jmpq *(%rip) # 0x6 6: 90 nop 7: 90 nop Disassembly of section .idata$7: 0000000000000000 <.idata$7>: 0: 00 00 addb %al, (%rax) 2: 00 00 addb %al, (%rax) Disassembly of section .idata$5: 0000000000000000 <__imp_ProcessPrng>: ... Disassembly of section .idata$4: 0000000000000000 <.idata$4>: ... Disassembly of section .idata$6: 0000000000000000 <.idata$6>: 0: 01 00 addl %eax, (%rax) 2: 50 pushq %rax 3: 72 6f jb 0x74 <.idata$6+0x74> 5: 63 65 73 movslq 0x73(%rbp), %esp 8: 73 50 jae 0x5a <.idata$6+0x5a> a: 72 6e jb 0x7a <.idata$6+0x7a> c: 67 00 ```
Details ``` C:/Users/mateusz/.rustup/toolchains/nightly-x86_64-pc-windows-gnu/lib/rustlib/x86_64-pc-windows-gnullvm/lib/libstd-d31db6c27cb2af27.rlib(bcryptprimitives.dll): file format coff-x86-64 Disassembly of section .idata$2: 0000000000000000 <__IMPORT_DESCRIPTOR_bcryptprimitives>: ... Disassembly of section .idata$6: 0000000000000000 <.idata$6>: 0: 62 63 72 79 70 5: 74 70 je 0x77 <.idata$6+0x77> 7: 72 69 jb 0x72 <.idata$6+0x72> 9: 6d insl %dx, %es:(%rdi) a: 69 74 69 76 65 73 2e 64 imull $0x642e7365, 0x76(%rcx,%rbp,2), %esi # imm = 0x642E7365 12: 6c insb %dx, %es:(%rdi) 13: 6c insb %dx, %es:(%rdi) 14: 00 C:/Users/mateusz/.rustup/toolchains/nightly-x86_64-pc-windows-gnu/lib/rustlib/x86_64-pc-windows-gnullvm/lib/libstd-d31db6c27cb2af27.rlib(bcryptprimitives.dll): file format coff-x86-64 Disassembly of section .idata$3: 0000000000000000 <__NULL_IMPORT_DESCRIPTOR>: ... C:/Users/mateusz/.rustup/toolchains/nightly-x86_64-pc-windows-gnu/lib/rustlib/x86_64-pc-windows-gnullvm/lib/libstd-d31db6c27cb2af27.rlib(bcryptprimitives.dll): file format coff-x86-64 Disassembly of section .idata$5: 0000000000000000 <bcryptprimitives_NULL_THUNK_DATA>: ... Disassembly of section .idata$4: 0000000000000000 <.idata$4>: ... C:/Users/mateusz/.rustup/toolchains/nightly-x86_64-pc-windows-gnu/lib/rustlib/x86_64-pc-windows-gnullvm/lib/libstd-d31db6c27cb2af27.rlib(bcryptprimitives.dll): file format COFF-import-file ```

llvm-readobj with various flags also didn't help. The says about a symbol with section number: 0 but I couldn't find anything like that.

EDIT: Ah, I fixated on Number: from llvm-readobj -t:

  Section {
    Number: 2
    Name: .idata$4 (2E 69 64 61 74 61 24 34)
    VirtualSize: 0x0
    VirtualAddress: 0x0
    RawDataSize: 8
    PointerToRawData: 0x6C
    PointerToRelocations: 0x0
    PointerToLineNumbers: 0x0
    RelocationCount: 0
    LineNumberCount: 0
    Characteristics [ (0xC0400040)
      IMAGE_SCN_ALIGN_8BYTES (0x400000)
      IMAGE_SCN_CNT_INITIALIZED_DATA (0x40)
      IMAGE_SCN_MEM_READ (0x40000000)
      IMAGE_SCN_MEM_WRITE (0x80000000)
    ]
  }
]

but looks like llvm-readobj -s is the helpful one here:

  Symbol {
    Name: .idata$4
    Value: 0
    Section: IMAGE_SYM_UNDEFINED (0)
    BaseType: Null (0x0)
    ComplexType: Null (0x0)
    StorageClass: Section (0x68)
    AuxSymbolCount: 0
  }

Probably sec 0 from objdump means the same thing as IMAGE_SYM_UNDEFINED (0). Not sure how it helps though, at least I have something to report upstream.

revelator commented 1 month ago

yeah it also baffled me to no end... tried searching every freaking library or object file for a reference to where this might be comming from, took me all night and im still baffled (x_x). seems to work if i use an older version of llvm/clang together with an older rust build so it seems to be something recent.

i even tried making an import library for bcryptprimitives.dll to look at the section data for that spurious 0 but sadly found nothing so it does not seem to be from any imports. since it only started happening with recent rust id wager some upstream change might have caused this unintentionally but as mati points out it works in the nightly rust build so the confusion is even worse.

mati865 commented 1 month ago

Not really minimal but at least self contained. Can be reproduced by unpacking one of ZIPs (libstd is the smaller one) and running clang -shared -Wl,--whole-archive ./libstd-d31db6c27cb2af27.rlib or clang -shared -Wl,--whole-archive ./librsvg_c_api.a.

libstd-d31db6c27cb2af27.zip librsvg_c_api.zip

mstorsjo commented 4 weeks ago

Thanks - I've reproduced the issue and given it an initial look.

It's possible to reproduce this issue with something as simple as this:

$ cat test.def
LIBRARY foo.dll
EXPORTS
MyFunc
$ llvm-dlltool -m i386:x86-64 -d test.def -l test.lib
$  lld-link -wholearchive:test.lib
lld-link: error: test.lib(foo.dll): .idata$4 should not refer to special section 0

The reason for this, is that import libraries are usually treated somewhat specially. MSVC style import libraries ("short import library") have a couple regular object files, and a number of synthetic files that just tells the linker about what should exist in the DLL. (This contrary to the old style import libraries, "long import library", which GNU tools produce, where all object files are regular object files, which together build the import tables.)

Normally, when linking MSVC style import libraries, LLD doesn't really look at the files that are regular object file, and instead completely synthesize these tables instead. Now when linking with -wholearchive:, it forces the linker to actually process these object files which it usually ignores, and we hit this error.

So lesson 1: Don't force including import libraries with --whole-archive.

However, if generating a similar import library with MSVC tools instead, lib -def:test.def -out:msvc.lib, then the symbols look somewhat different, so LLD doesn't error out in the same way.

(I note that looking at the object files from that import library with obj2yaml triggers failed asserts, we should fix that.)

Even then, if I force linking the import library from MSVC with -wholearchive, it also misbehaves:

$ lld-link -wholearchive:msvc.lib -out:test.dll -subsystem:console -noentry -dll
lld-link: warning: ignoring section .debug$S with unrecognized magic 0x2
lld-link: warning: ignoring section .debug$S with unrecognized magic 0x2
lld-link: warning: ignoring section .debug$S with unrecognized magic 0x2
lld-link: error: section larger than 4 GiB: .data

So even if we fix the LLVM import library generation to output things in the same form as MSVC does, we practically can't link against them with -wholearchive with LLD. I guess that can be considered a limitation in LLD...

So, takeaways:

mati865 commented 4 weeks ago

Thank you so much for this. So the problem might lie within the librsvg build system because IIUC it's not Rust who added that --whole-archive.

Question to anyone who knows autotools better: Is this --whole-archive added by libtool?

$ LANG=C make -j32 V=1
make  all-recursive
make[1]: Entering directory '/h/projects/librsvg'
Making all in .
make[2]: Entering directory '/h/projects/librsvg'
/bin/sh ./libtool  --tag=CC   --mode=link cc  -g -O2  -version-info 52:0:50 -export-dynamic -no-undefined -export-symbols-regex "^rsvg_.*" "-Wl,--gc-sections"    -o librsvg-2.la -rpath /clang64/lib   librsvg_c_api.la -lpng16 -lcairo-gobject -lfreetype -lgdk_pixbuf-2.0 -lgio-2.0 -lxml2 -lpangocairo-1.0 -lpango-1.0 -lgobject-2.0 -lglib-2.0 -lintl -lharfbuzz -lcairo -lm  -lws2_32 -luserenv -lbcrypt -lntdll -v
libtool: link: rm -fr  .libs/librsvg-2.exp
libtool: link: /clang64/bin/nm -B   ./.libs/librsvg_c_api.a | /usr/bin/sed -n -e 's/^.*[         ]\([ABCDGIRSTW][ABCDGIRSTW]*\)[         ][      ]*\([_A-Za-z][_A-Za-z0-9]*\)\{0,1\}$/\1 \2 \2/p' | /usr/bin/sed '/ __gnu_lto/d' | /usr/bin/sed -e '/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //' | sort | uniq > .libs/librsvg-2.exp
libtool: link: /usr/bin/grep -E -e "^rsvg_.*" ".libs/librsvg-2.exp" > ".libs/librsvg-2.expT"
libtool: link: mv -f ".libs/librsvg-2.expT" ".libs/librsvg-2.exp"
libtool: link: if test DEF = "`/usr/bin/sed -n -e 's/^[  ]*//' -e '/^\(;.*\)*$/d' -e 's/^\(EXPORTS\|LIBRARY\)\([         ].*\)*$/DEF/p' -e q .libs/librsvg-2.exp`" ; then cp .libs/librsvg-2.exp .libs/librsvg-2-2.dll.def; else echo EXPORTS > .libs/librsvg-2-2.dll.def; cat .libs/librsvg-2.exp >> .libs/librsvg-2-2.dll.def; fi
libtool: link:  cc -shared .libs/librsvg-2-2.dll.def  -Wl,--whole-archive ./.libs/librsvg_c_api.a -Wl,--no-whole-archive  -lpng16 -lcairo-gobject -lfreetype -lgdk_pixbuf-2.0 -lgio-2.0 -lxml2 -lpangocairo-1.0 -lpango-1.0 -lgobject-2.0 -lglib-2.0 -lintl -lharfbuzz -lcairo -lws2_32 -luserenv -lbcrypt -lntdll  -g -O2 -Wl,--gc-sections   -o .libs/librsvg-2-2.dll -Wl,--enable-auto-image-base -Xlinker --out-implib -Xlinker .libs/librsvg-2.dll.a
ld.lld: error: librsvg_c_api.a(bcryptprimitives.dll): .idata$4 should not refer to special section 0
cc: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [Makefile:900: librsvg-2.la] Error 1
make[2]: Leaving directory '/h/projects/librsvg'
make[1]: *** [Makefile:1158: all-recursive] Error 1
make[1]: Leaving directory '/h/projects/librsvg'
make: *** [Makefile:793: all] Error 2

Talking about this line: libtool: link: cc -shared .libs/librsvg-2-2.dll.def -Wl,--whole-archive ./.libs/librsvg_c_api.a ...., I have added -v to line 900, as you can see in the log above, but it's not the failing command. Makefile.txt

mstorsjo commented 3 weeks ago

As a side note here - it has to be mentioned, that this probably isn't an issue with the "long import library" format produced by the GNU tools - there, all object files are relevant and work entirely as usual object files, so linking them with --whole-archive should be fine.

So the problem might lie within the librsvg build system because IIUC it's not Rust who added that --whole-archive.

Question to anyone who knows autotools better: Is this --whole-archive added by libtool?

Not very familiar with this case, but it's quite plausible.

Using --whole-archive is generally quite common and reasonable with static libraries, so it might be hard to get around.

I'm not famliar with Rust's libraries though, but why does it end up with import library members in the same library as other implementation files? Overall, import libraries are special enough that it feels odd to merge them in like that. Or is that done to make linking work, without needing to separately specify which import libraries to link against, making those libraries implicitly enabled?

For the record, I tried tweaking obj2yaml to not fail on these files, and while it works, I'm not sure how useful it is, I'll consider if I want to upstream it or not. I also tried tweaking llvm-dlltool to change the details to match what MSVC produces - that works, but then linking fails with the same errors as when linking the MSVC produced import libraries. So not sure if this is worthwhile doing anyway...

mati865 commented 3 weeks ago

I'm not famliar with Rust's libraries though, but why does it end up with import library members in the same library as other implementation files? Overall, import libraries are special enough that it feels odd to merge them in like that. Or is that done to make linking work, without needing to separately specify which import libraries to link against, making those libraries implicitly enabled?

I don't know the reasoning behind this, but when it comes to static libs, I suppose it's either by an accident or as an attempt to make things easier for the users. We've got the proof it makes things harder, so maybe it could be changed.

There are also .rlib files which are basically intermediate static libraries meant to be used only be the compiler, so they also contain metadata and IIRC some symbols not meant to exporting. The compiler will use them to create final outputs, so it needs to keep track of imported DLLs somehow. Probably combining import libraries with other objects was the easiest way to achieve that, but this is the compiler's own format, so I imagine it could be implemented in a different way. Maybe we don't need to care about it, though? It has worked like that for quite some time now and didn't cause issues, so rlibs are surely linked without --whole-archive.

revelator commented 3 weeks ago

damn seems i hit a hornets nest :) but im glad it got figured out.