Skip to content
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

[Windows/Clang-cl] Linker errors while linking Rust-built static lib into a main project #115813

Closed
amitin opened this issue Sep 13, 2023 · 5 comments
Labels
C-bug Category: This is a bug.

Comments

@amitin
Copy link

amitin commented Sep 13, 2023

In our C/C++ project we use Rust-written components as a static lib which includes C interface to Rust code.
We use cmake to invoke cargo as an external command. The static lib builds successfully this way and we link it into our main project's target dll.
We use Clang-CL toolkit as a part of MSVS 2022 to compile and link our project.
Updating Rust to 1.70+ causes linker errors (see below).

Cargo build command is

cargo.exe build --target x86_64-pc-windows-msvc --release

I expected to see this happen: successful build

Instead, this happened: linker errors

lld-link : error : undefined symbol: __declspec(dllimport) NtCreateFile [C:\workspace\ourproj.vcxproj]
  >>> referenced by /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be/library\std\src\sys\windows\fs.rs:829
  >>>               esu_rust.lib(std-0f357f0f8e8eb48f.std.895242974ff7d01b-cgu.0.rcgu.o):(std::sys::windows::fs::open_l
  ink_no_reparse::h262f7b3e7853935c)

lld-link : error : undefined symbol: __declspec(dllimport) RtlNtStatusToDosError [C:\workspace\ourproj.vcxproj]
  >>> referenced by /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be/library\std\src\sys\windows\fs.rs:858
  >>>               esu_rust.lib(std-0f357f0f8e8eb48f.std.895242974ff7d01b-cgu.0.rcgu.o):(std::sys::windows::fs::open_l
  ink_no_reparse::h262f7b3e7853935c)
  >>> referenced by /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be/library\std\src\sys\windows\handle.rs:273
  >>>               esu_rust.lib(std-0f357f0f8e8eb48f.std.895242974ff7d01b-cgu.0.rcgu.o):(std::sys::windows::handle::Ha
  ndle::synchronous_read::h00067f19ba39bde9)
  >>> referenced by /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be/library\std\src\sys\windows\handle.rs:319
  >>>               esu_rust.lib(std-0f357f0f8e8eb48f.std.895242974ff7d01b-cgu.0.rcgu.o):(std::sys::windows::handle::Ha
  ndle::synchronous_write::h977c567d7f264f32)

lld-link : error : undefined symbol: __declspec(dllimport) NtReadFile [C:\workspace\ourproj.vcxproj]
  >>> referenced by /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be/library\std\src\sys\windows\handle.rs:242
  >>>               esu_rust.lib(std-0f357f0f8e8eb48f.std.895242974ff7d01b-cgu.0.rcgu.o):(std::sys::windows::handle::Ha
  ndle::synchronous_read::h00067f19ba39bde9)

lld-link : error : undefined symbol: __declspec(dllimport) NtWriteFile [C:\workspace\ourproj.vcxproj]
  >>> referenced by /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be/library\std\src\sys\windows\handle.rs:291
  >>>               esu_rust.lib(std-0f357f0f8e8eb48f.std.895242974ff7d01b-cgu.0.rcgu.o):(std::sys::windows::handle::Ha
  ndle::synchronous_write::h977c567d7f264f32)

Version it worked on

It most recently worked on:

rustc 1.69.0 (84c898d65 2023-04-16)
binary: rustc
commit-hash: 84c898d65adf2f39a5a98507f1fe0ce10a2b8dbc
commit-date: 2023-04-16
host: x86_64-pc-windows-msvc
release: 1.69.0
LLVM version: 15.0.7

Version with regression

rustc --version --verbose:

rustc 1.70.0 (90c541806 2023-05-31)
binary: rustc
commit-hash: 90c541806f23a127002de5b4038be731ba1458ca
commit-date: 2023-05-31
host: x86_64-pc-windows-msvc
release: 1.70.0
LLVM version: 16.0.2

Rust 1.72 also has this issue.

Workaround

Explicitly adding ntdll dependency fixes the issue, but this doesn't seem good to have an extra dependency.

@amitin amitin added C-bug Category: This is a bug. regression-untriaged Untriaged performance or correctness regression. labels Sep 13, 2023
@rustbot rustbot added needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. I-prioritize Issue: Indicates that prioritization has been requested for this issue. labels Sep 13, 2023
@ChrisDenton
Copy link
Member

You also need ntdll.lib. To see all required native libs you can use rustc with --print native-static-libs.

@amitin
Copy link
Author

amitin commented Sep 13, 2023

Well, why did it work with 1.69? What was a purpose of adding dependency to ntdll.dll into Rust?

@ChrisDenton
Copy link
Member

Well, why did it work with 1.69?

Because 1.69 used GetModuleHandle at runtime instead.

What was a purpose of adding dependency to ntdll.dll into Rust?

To save lazily loading the functions.

@amitin
Copy link
Author

amitin commented Sep 13, 2023

Thanks for your explanations.
Still not clear though why don't use kernel32.dll counterparts for these functions, but it's OK, closing the case.

@amitin amitin closed this as completed Sep 13, 2023
@ChrisDenton
Copy link
Member

ChrisDenton commented Sep 13, 2023

  • NtCreateFile is used to mitigate CVE-2022-21658.
  • NtReadFile and NtWriteFile are used to avoid a soundness issue when stdin, stdout or stderr are opened for async reads or writes (also other file handles). See File implementation on Windows has unsound methods #81357.
  • RtlNtStatusToDosError is simply used to convert the status codes from the above two functions into normal Win32 errors.

@apiraino apiraino removed I-prioritize Issue: Indicates that prioritization has been requested for this issue. needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. regression-untriaged Untriaged performance or correctness regression. labels Sep 13, 2023
btasker added a commit to influxdata/flux that referenced this issue Nov 26, 2024
Rust >1.69 appears to require explicit inclusion of ntdll dep
rust-lang/rust#115813
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.
Projects
None yet
Development

No branches or pull requests

4 participants