"corrupt .drectve" warning on x86_64-pc-windows-gnu target with Rust 1.70

(Update: I reported this to Rust's repo. GNU linker warns “corrupt .drectve” on staticlib binary generated with Rust 1.70 on Windows · Issue #112368 · rust-lang/rust · GitHub)

Recently, I updated the Rust toolchain to 1.70, and started to see a lot of warning like the following ones. It seems a staticlib for GNU target compiled with Rust 1.70 seems to generate incompatible binary with GNU. Before reporting to Rust's repository, I'd like to make sure I don't make some silly mistake since I'm not very familiar with the compiler things.

Warning: .drectve `-exclude-symbols:_ZN7testpkg11hello_world17ha68eef8a416aa303E ' unrecognized
Warning: corrupt .drectve at end of def file

The context is that, an OSS project, extendr, which I'm a member of, uses Rust to generate a staticlib for R programming language. Since R is GNU, the target needs to be GNU. This is what the minimal steps to reproduce the warning looks like. I also created a repository to reproduce the warning: GitHub - yutannihilation/rust170_gnu_warning (You can check the GHA results)

The warning happens on the last step, so it should be that the generated staticlib is incompatible with GCC, the GNU toolchain.

# compile Rust code to create a staticlib
cargo build --target=x86_64-pc-windows-gnu --lib --release

# compile the C code
gcc -c main.c -o main.o

# create DLL from the object and staticlib
gcc -o testpkgrust170_gnu_warning.dll main.o -L./target/x86_64-pc-windows-gnu/release -lrust170_gnu_warning -lws2_32 -ladvapi32 -luserenv -lbcrypt -lntdll 

I couldn't find a reliable reference, but, reading several SO answers (e.g. https://stackoverflow.com/a/37676997), it seems this warning ("corrupt .drectve") indicates the incompatibility between compilers. Rust 1.70 upgrades LLVM to version 16, so I suspect there's some unexpected change in LLVM 16. Among the items described in the release note, this one feels related, since this is the only one that is related to linker directives.

Any suggestions would be greatly appreciated.

I don't know exact the reason, my guess is that GNU linker doesn't support the .drective entries emitted by LLVM. though I think it should be safe to ignore the warnings, as those symbols are mangled rust symbols, they shouldn't conflict with C/C++ symbols. the only possible downside I can think of is the final linked artifact might be bloated with extra useless exports.

you can try to use lld instead of the GNU ld for the final linking step. or you might check if there's newer version of GNU toolchain that does support the directive entries.

1 Like

Thanks!

GNU linker doesn't support the .drective entries emitted by LLVM

Yes. The question is, why the directives unsupported by GNU are emitted for GNU target? I feel this is not what the things are supposed to be. So I'm about to report to Rust's repository.

it should be safe to ignore the warnings

Yes and no. I agree we can ignore the warnings, but it seems the concern described in the LLVM's commit can be a real problem:

as all symbols are exported, it can easily overflow the max number of exported symbols in a DLL (65536).

Anyway, as the directive is not supported, I think there's no way to avoid this possible overflow.

you can try to use lld instead of the GNU ld for the final linking step.

Thanks for the suggestion. But, unfortunately, this is not possible. As I described above, since this is for R, the project needs to stick with the toolchain that compiles R.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.