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

compiler_builtins string.h functions are not available when using std targets with #![no_std] #137833

Open
byeongkeunahn opened this issue Mar 1, 2025 · 13 comments
Labels
A-linkage Area: linking into static, shared libraries and binaries C-bug Category: This is a bug. E-needs-investigation Call for partcipation: This issues needs some investigation to determine current status I-prioritize Issue: Indicates that prioritization has been requested for this issue. regression-untriaged Untriaged performance or correctness regression.

Comments

@byeongkeunahn
Copy link

byeongkeunahn commented Mar 1, 2025

Code

The basm-rs project which uses no-std with mem feature for compiler-builtins fails to build on recent nightly. It can be reproduced on nightly-2025-02-28 on Windows x64 and Linux x64 by the following:

git clone https://github.com/boj-rs/basm-rs.git
cd basm-rs
git reset --hard 2e3799d
cargo run

The following PR seems relevant: #135501 (Inject compiler_builtins during postprocessing and ensure it is made private)

Although not sure, I suspect this might be due to the internal changes by the above PR making the mem feature ignored on the compiler-builtins crate.

Adding/removing compiler-builtins with mem feature enabled (on Cargo.toml) doesn't alleviate the issue.

I expected to see this happen: build should succeed

Instead, this happened: build fails with linker error (unresolved external symbols, LNK2001 and LNK2019 on memcpy, memset, strlen, etc.)

Linker error on Windows x64
error: linking with `link.exe` failed: exit code: 1120
  |
  = note: \"C:\\Program Files\\Microsoft Visual Studio\\2022\\Enterprise\\VC\\Tools\\MSVC\\14.43.34808\\bin\\HostX64\\x64\\link.exe\" \"/DEF:C:\\Users\\UNNER~1\\AppData\\Local\\Temp\\ustcw0AdYp\\lib.def\" \"/NOLOGO\" \"C:\\Users\\UNNER~1\\AppData\\Local\\Temp\\ustcw0AdYp\\symbols.o\" \"<20 object files omitted>\" \"D:\\a\\basm-rs\\basm-rs\\target\\x86_64-pc-windows-msvc\\debug\\deps/{libbasm_std-e50feab6cac5330a.rlib,libryu-2d7a27dd94711b38.rlib,liblibm-fe7c82a0dfd00cea.rlib}.rlib\" \"<sysroot>\\lib\\ustlib\\x86_64-pc-windows-msvc\\lib/{liballoc-*,librustc_std_workspace_core-*,libcore-*,libcompiler_builtins-*}.rlib\" \"kernel32.lib\" \"/defaultlib:msvcrt\" \"/NXCOMPAT\" \"/OUT:D:\\a\\basm-rs\\basm-rs\\target\\x86_64-pc-windows-msvc\\debug\\deps\\basm.exe\" \"/OPT:NOREF,NOICF\" \"/DEBUG\" \"/PDBALTPATH:%_PDB%\" \"/NATVIS:<sysroot>\\lib\\ustlib\\etc\\intrinsic.natvis\" \"/NATVIS:<sysroot>\\lib\\ustlib\\etc\\liballoc.natvis\" \"/NATVIS:<sysroot>\\lib\\ustlib\\etc\\libcore.natvis\" \"/NATVIS:<sysroot>\\lib\\ustlib\\etc\\libstd.natvis\" \"/SUBSYSTEM:CONSOLE\" \"/NODEFAULTLIB\" \"/DYNAMICBASE\" \"/ENTRY:_basm_start\" \"/NXCOMPAT:NO\" \"/STACK:268435456\" \"/EMITTOOLVERSIONINFO:NO\" \"/EMITPOGOPHASEINFO\"
  = note: some arguments are omitted. use `--verbose` to show all linker arguments
  = note: LINK : warning LNK4216: Exported entry point _basm_start
             Creating library D:\a\basm-rs\basm-rs\target\x86_64-pc-windows-msvc\debug\deps\basm.lib and object D:\a\basm-rs\basm-rs\target\x86_64-pc-windows-msvc\debug\deps\basm.exp
          libbasm_std-e50feab6cac5330a.rlib(basm_std-e50feab6cac5330a.2d78w7yq39aio618eu29n502q.rcgu.o) : error LNK2001: unresolved external symbol memset
          libbasm_std-e50feab6cac5330a.rlib(basm_std-e50feab6cac5330a.8mxgkpuy6eljjccapmv5glh9y.rcgu.o) : error LNK2001: unresolved external symbol memset
          libbasm_std-e50feab6cac5330a.rlib(basm_std-e50feab6cac5330a.2e9hbj5zjzej5yoo4fu21vxtv.rcgu.o) : error LNK2001: unresolved external symbol memset
          libcore-b522dd968c06714e.rlib(core-b522dd968c06714e.core.edc02a3bf6895602-cgu.0.rcgu.o) : error LNK2001: unresolved external symbol memset
          basm.9g5xzwdjyxd5pguzsqqvp1u28.rcgu.o : error LNK2001: unresolved external symbol memset
          basm.ej25b0acf8kdeqne13ab4e3tg.rcgu.o : error LNK2001: unresolved external symbol memset
          libbasm_std-e50feab6cac5330a.rlib(basm_std-e50feab6cac5330a.21coi540lkxfaa98dxwpief3l.rcgu.o) : error LNK2001: unresolved external symbol memset
          libbasm_std-e50feab6cac5330a.rlib(basm_std-e50feab6cac5330a.6hgz425wf1ayywi5fv5zoeppv.rcgu.o) : error LNK2001: unresolved external symbol memset
          liballoc-e4bc1996f9879934.rlib(alloc-e4bc1996f9879934.alloc.e6877761d14c58d1-cgu.0.rcgu.o) : error LNK2001: unresolved external symbol memcpy
          libcore-b522dd968c06714e.rlib(core-b522dd968c06714e.core.edc02a3bf6895602-cgu.0.rcgu.o) : error LNK2001: unresolved external symbol memcpy
          libbasm_std-e50feab6cac5330a.rlib(basm_std-e50feab6cac5330a.5zm4u3b7fw5pph8duhnwpp6sy.rcgu.o) : error LNK2001: unresolved external symbol memcpy
          libbasm_std-e50feab6cac5330a.rlib(basm_std-e50feab6cac5330a.2e9hbj5zjzej5yoo4fu21vxtv.rcgu.o) : error LNK2001: unresolved external symbol memcpy
          libbasm_std-e50feab6cac5330a.rlib(basm_std-e50feab6cac5330a.clqiejq8kje9m36l2phy1w3p7.rcgu.o) : error LNK2001: unresolved external symbol memcpy
          libbasm_std-e50feab6cac5330a.rlib(basm_std-e50feab6cac5330a.3vz9srzewsp7rhgzgwnlscjyp.rcgu.o) : error LNK2001: unresolved external symbol memcpy
          libbasm_std-e50feab6cac5330a.rlib(basm_std-e50feab6cac5330a.4a4k385dn4e64jekc5mql1bvs.rcgu.o) : error LNK2001: unresolved external symbol memcpy
          libbasm_std-e50feab6cac5330a.rlib(basm_std-e50feab6cac5330a.1bhgywgafx4gek4bizurc869q.rcgu.o) : error LNK2001: unresolved external symbol memcpy
          libbasm_std-e50feab6cac5330a.rlib(basm_std-e50feab6cac5330a.8mxgkpuy6eljjccapmv5glh9y.rcgu.o) : error LNK2001: unresolved external symbol memcpy
          libbasm_std-e50feab6cac5330a.rlib(basm_std-e50feab6cac5330a.4mpf37xghynf3g95v9jum0jua.rcgu.o) : error LNK2001: unresolved external symbol memcpy
          libbasm_std-e50feab6cac5330a.rlib(basm_std-e50feab6cac5330a.2d78w7yq39aio618eu29n502q.rcgu.o) : error LNK2001: unresolved external symbol memcpy
          libbasm_std-e50feab6cac5330a.rlib(basm_std-e50feab6cac5330a.bxi98gwkuewj2h7gu80p7ilhj.rcgu.o) : error LNK2001: unresolved external symbol memcpy
          libbasm_std-e50feab6cac5330a.rlib(basm_std-e50feab6cac5330a.13w32kxokxkxyhh2n5kpvrakm.rcgu.o) : error LNK2001: unresolved external symbol memcpy
          libbasm_std-e50feab6cac5330a.rlib(basm_std-e50feab6cac5330a.1jxwkrjvpwz2q2r6atshltkax.rcgu.o) : error LNK2001: unresolved external symbol memcpy
          libbasm_std-e50feab6cac5330a.rlib(basm_std-e50feab6cac5330a.21coi540lkxfaa98dxwpief3l.rcgu.o) : error LNK2001: unresolved external symbol memcpy
          libbasm_std-e50feab6cac5330a.rlib(basm_std-e50feab6cac5330a.7w49ql5si9b0bo5czy3vd3fp6.rcgu.o) : error LNK2001: unresolved external symbol memcpy
          libbasm_std-e50feab6cac5330a.rlib(basm_std-e50feab6cac5330a.05gcffme57m7trw63ywnai9vp.rcgu.o) : error LNK2001: unresolved external symbol memcpy
          libbasm_std-e50feab6cac5330a.rlib(basm_std-e50feab6cac5330a.6hgz425wf1ayywi5fv5zoeppv.rcgu.o) : error LNK2001: unresolved external symbol memcpy
          basm.9g5xzwdjyxd5pguzsqqvp1u28.rcgu.o : error LNK2001: unresolved external symbol memcpy
          basm.cmnxgaonqn55yzn8blh7dmqx0.rcgu.o : error LNK2001: unresolved external symbol memcpy
          basm.ej25b0acf8kdeqne13ab4e3tg.rcgu.o : error LNK2001: unresolved external symbol memcpy
          libbasm_std-e50feab6cac5330a.rlib(basm_std-e50feab6cac5330a.d039nxxqg81e8ll6x542f66xx.rcgu.o) : error LNK2001: unresolved external symbol memcpy
          libbasm_std-e50feab6cac5330a.rlib(basm_std-e50feab6cac5330a.4a4k385dn4e64jekc5mql1bvs.rcgu.o) : error LNK2019: unresolved external symbol memmove referenced in function _ZN5alloc11collections9vec_deque21VecDeque$LT$T$C$A$GT$24handle_capacity_increase17h8b4f648ad63441e0E
          liballoc-e4bc1996f9879934.rlib(alloc-e4bc1996f9879934.alloc.e6877761d14c58d1-cgu.0.rcgu.o) : error LNK2001: unresolved external symbol memmove
          liballoc-e4bc1996f9879934.rlib(alloc-e4bc1996f9879934.alloc.e6877761d14c58d1-cgu.0.rcgu.o) : error LNK2019: unresolved external symbol strlen referenced in function _ZN5alloc3ffi5c_str7CString8from_raw17h6b22e763d8c0a09cE
          libcore-b522dd968c06714e.rlib(core-b522dd968c06714e.core.edc02a3bf6895602-cgu.0.rcgu.o) : error LNK2019: unresolved external symbol memcmp referenced in function _ZN4core3str7pattern11StrSearcher3new17h9aededd987e99d14E
          D:\a\basm-rs\basm-rs\target\x86_64-pc-windows-msvc\debug\deps\basm.exe : fatal error LNK1120: 5 unresolved externals
Linker error on Linux x64
error: linking with `cc` failed: exit status: 1
  |
  = note:  \"cc\" \"-Wl,--version-script=/tmp/rustclFz4Fk/list\" \"-Wl,--no-undefined-version\" \"-m64\" \"/tmp/rustclFz4Fk/symbols.o\" \"<20 object files omitted>\" \"-Wl,--as-needed\" \"-Wl,-Bstatic\" \"/home/runner/work/basm-rs/basm-rs/target/x86_64-unknown-linux-gnu/debug/deps/{libbasm_std-1acb57257a97f135.rlib,libryu-bd5489fc747e1497.rlib,liblibm-5e8cfbe847b175e2.rlib}.rlib\" \"<sysroot>/lib/rustlib/x86_64-unknown-linux-gnu/lib/{liballoc-*,librustc_std_workspace_core-*,libcore-*,libcompiler_builtins-*}.rlib\" \"-Wl,-Bdynamic\" \"-B<sysroot>/lib/rustlib/x86_64-unknown-linux-gnu/bin/gcc-ld\" \"-fuse-ld=lld\" \"-Wl,--eh-frame-hdr\" \"-Wl,-z,noexecstack\" \"-L\" \"<sysroot>/lib/rustlib/x86_64-unknown-linux-gnu/lib\" \"-o\" \"/home/runner/work/basm-rs/basm-rs/target/x86_64-unknown-linux-gnu/debug/deps/basm-65a3de73172c3759\" \"-Wl,--no-gc-sections\" \"-pie\" \"-Wl,-z,relro,-z,now\" \"-nodefaultlibs\" \"-nostartfiles\" \"-nostdlib\" \"-static-pie\" \"-fno-exceptions\" \"-fno-asynchronous-unwind-tables\" \"-fno-unwind-tables\" \"-fno-stack-protector\" \"-fno-plt\" \"-Wl,--entry=_basm_start,--build-id=none,--gc-sections,--export-dynamic,--no-eh-frame-hdr,-z,norelro\"
  = note: some arguments are omitted. use `--verbose` to show all linker arguments
  = note: rust-lld: error: undefined symbol: memset
          >>> referenced by writer.rs:116 (basm-std/src/platform/io/writer.rs:116)
          >>>               /home/runner/work/basm-rs/basm-rs/target/x86_64-unknown-linux-gnu/debug/deps/basm-65a3de73172c3759.6h36ab66ebuo091kns7g1lspd.rcgu.o:(basm_std::platform::io::writer::Writer$LT$_$GT$::new::h5e1d045719356f57)
          >>> referenced by writer.rs:302 (basm-std/src/platform/io/writer.rs:302)
          >>>               /home/runner/work/basm-rs/basm-rs/target/x86_64-unknown-linux-gnu/debug/deps/basm-65a3de73172c3759.6h36ab66ebuo091kns7g1lspd.rcgu.o:(basm_std::platform::io::writer::Writer$LT$_$GT$::u64::h40db478c2d0af0ea)
          >>> referenced by writer.rs:303 (basm-std/src/platform/io/writer.rs:303)
          >>>               /home/runner/work/basm-rs/basm-rs/target/x86_64-unknown-linux-gnu/debug/deps/basm-65a3de73172c3759.6h36ab66ebuo091kns7g1lspd.rcgu.o:(basm_std::platform::io::writer::Writer$LT$_$GT$::u64::h40db478c2d0af0ea)
          >>> referenced 5 more times
          
          rust-lld: error: undefined symbol: memcpy
          >>> referenced by writer.rs:115 (basm-std/src/platform/io/writer.rs:115)
          >>>               /home/runner/work/basm-rs/basm-rs/target/x86_64-unknown-linux-gnu/debug/deps/basm-65a3de73172c3759.6h36ab66ebuo091kns7g1lspd.rcgu.o:(basm_std::platform::io::writer::Writer$LT$_$GT$::new::h5e1d045719356f57)
          >>> referenced by mod.rs:3594 (/home/runner/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/intrinsics/mod.rs:3594)
          >>>               basm_std-1acb57257a97f135.5gkonddl664c9rz6m85dkzhrb.rcgu.o:(alloc::vec::Vec$LT$T$C$A$GT$::append_elements::h074461469b673f76) in archive /home/runner/work/basm-rs/basm-rs/target/x86_64-unknown-linux-gnu/debug/deps/libbasm_std-1acb57257a97f135.rlib
          >>> referenced by mod.rs:3594 (/home/runner/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/intrinsics/mod.rs:3594)
          >>>               basm_std-1acb57257a97f135.8ju6k4gh4r2sxl5p2ta3jlwdn.rcgu.o:(alloc::alloc::Global::grow_impl::h17fbfe5bd8679995) in archive /home/runner/work/basm-rs/basm-rs/target/x86_64-unknown-linux-gnu/debug/deps/libbasm_std-1acb57257a97f135.rlib
          >>> referenced 13 more times
          collect2: error: ld returned 1 exit status

Version it worked on

It most recently worked on: nightly-2025-02-23

Version with regression

rustc --version --verbose:

rustc 1.87.0-nightly (287487624 2025-02-28)
binary: rustc
commit-hash: 287487624357c19b22d27aa3ed584b8ccd080b4d
commit-date: 2025-02-28
host: x86_64-pc-windows-msvc
release: 1.87.0-nightly
LLVM version: 20.1.0

Output of cargo-bisect-rustc

searched nightlies: from nightly-2025-02-20 to nightly-2025-02-28
regressed nightly: nightly-2025-02-24
searched commit range: 46420c9...f8a913b
regressed commit: bca5f37

bisected with cargo-bisect-rustc v0.6.7

Host triple: x86_64-pc-windows-msvc
Reproduce with:

cargo bisect-rustc --end=2025-02-28
@byeongkeunahn byeongkeunahn added C-bug Category: This is a bug. regression-untriaged Untriaged performance or correctness regression. labels Mar 1, 2025
@rustbot rustbot added 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. labels Mar 1, 2025
@tgross35
Copy link
Contributor

tgross35 commented Mar 1, 2025

Thanks for bisecting already. I don't think the compiler changes in #135501 should have affected Cargo features at all since that only affects when the already-built compiler-builtins crate gets injected; however, I am wondering whether the changes from public to private in Cargo.toml may have changed the way features get are getting enabled. Cc @rust-lang/cargo in case anybody knows of some behavior differences here.

Are you able to build rustc? That theory can probably be tested by reverting 8c1b49d (Use public-dependencies in all sysroot crates) which shouldn't affect anything else.

Separately, it may be useful if you can post the output of nm -gC libcompiler_builtins-hash.rlib for that target (just search for libcompiler_builtins in the rustc sysroot to get the right file) to see what exactly the story is for available symbols. nevermind, that part is reasonably straightforward.

@saethlin
Copy link
Member

saethlin commented Mar 1, 2025

Are you able to build rustc?

Why is this relevant? Maybe you know something about basm that I don't know, but AFAIK the problem is this:
https://github.com/boj-rs/basm-rs/blob/2e3799d684b6fc3f9db672b8f077966c5ee04541/basm/Cargo.toml#L32-L45

I was previously advised by t-libs that adding a Cargo dependency on the published compiler-builtins is not a use of the library that is supported, and indeed I ran into many strange linkage and crate resolution issues when I was trying to do that.

@byeongkeunahn
Copy link
Author

Are you able to build rustc?

I'm not familiar with building rustc, I'll give it a try when I have time. Thanks for the suggestion :)

I was previously advised by t-libs that adding a Cargo dependency on the published compiler-builtins is not a use of the library that is supported, and indeed I ran into many strange linkage and crate resolution issues when I was trying to do that.

I appreciate that this is not an intended use case. However, in that case, the issue is that the linking error persists when the compiler-builtins dependency is removed from Cargo.toml. If I recall correctly, the compiler-builtins dependency was added a few years ago to resolve the same linker error regarding undefined external symbols (memcpy/memset/strlen).

@tgross35
Copy link
Contributor

tgross35 commented Mar 1, 2025

I know nothing about basm but the original post says:

Adding/removing compiler-builtins with mem feature enabled (on Cargo.toml) doesn't alleviate the issue.

I assumed this meant they were still seeing a regression across the versions even if they removed the compiler_builtins dependency. Why that project has the dependency in the first place, I have no idea.

(But yeah, we need to do something about compiler-builtins on crates.io once we understand whether there are any remaining legitimate usecases, syncs have me very pretty of that not being a submodule/tree anyway. On my eventual todo list...)

@tgross35
Copy link
Contributor

tgross35 commented Mar 1, 2025

I'm not familiar with building rustc, I'll give it a try when I have time. Thanks for the suggestion :)

It's reasonably easy, ./x build --stage 1, then run the commands from https://rustc-dev-guide.rust-lang.org/building/how-to-build-and-run.html#creating-a-rustup-toolchain so you can cargo +stage1 build .... The rest of page has more details.

If you can reproduce this with a smaller crate, I'll also try to take a closer look over the weekend.

@byeongkeunahn
Copy link
Author

byeongkeunahn commented Mar 1, 2025

If you can reproduce this with a smaller crate, I'll also try to take a closer look over the weekend.

I've constructed a minimized version which runs on x64 Windows only. It is set to use nightly-2025-02-23. Any of the following changes will make cargo run fail with linker errors:

  • When the compiler-builtins dependency is commented out
  • When the nightly version is changed to nightly-2025-02-24
  • When rustflags = ["-C", "target-cpu=haswell"] in .cargo/config.toml is removed

Furthermore, while the minimized version does not have issues with cargo run --release, the original (full) repo still fails with linker errors.

Please find the minimal example below.

basm-rs-minimal-example.zip

It is possible that I might be using the no-std feature incorrectly. Please let me know if that is the case.

@bjorn3
Copy link
Member

bjorn3 commented Mar 1, 2025

Does it work if you keep the compiler-builtins dependency with the mem feature enabled but add extern crate compiler_builtins; to your source code?

@byeongkeunahn
Copy link
Author

byeongkeunahn commented Mar 1, 2025

Oh yes, that seems to work on nightly-2025-02-24 and afterwards. More precisely, the following works:

extern crate compiler_builtins;
extern crate alloc;

However, when the order is reversed, linking error persists:

extern crate alloc;
extern crate compiler_builtins;

I've observed the same tendency in both the minimal example and the original repo.

Unfortunately, cargo fmt (which we check for on CI) prefers the latter ordering.

@Noratrieb Noratrieb added A-linkage Area: linking into static, shared libraries and binaries and removed needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. labels Mar 1, 2025
@tgross35
Copy link
Contributor

tgross35 commented Mar 1, 2025

Oh yes, that seems to work on nightly-2025-02-24 and afterwards. More precisely, the following works:

extern crate compiler_builtins;
extern crate alloc;

However, when the order is reversed, linking error persists:

extern crate alloc;
extern crate compiler_builtins;

I'm guessing the difference is that with the first version and before #135501, the crates.io version built with mem gets picked up and I think you wind up with both in the graph. But with the second version it's getting compiler_builtins from alloc's graph first (which is the sysroot version without mem) and so it doesn't add compiler_builtins again due to the check at

// If a `#![compiler_builtins]` crate already exists, avoid injecting it twice. This is
// the common case since usually it appears as a dependency of `std` or `alloc`.
for (cnum, cmeta) in self.cstore.iter_crate_data() {
if cmeta.is_compiler_builtins() {
info!("`compiler_builtins` already exists (cnum = {cnum}); skipping injection");
return;
}
}
. This could probably be verified by running with RUSTC_LOG=rustc_metadata::creader=info and comparing the output between the two.

Removing target-cpu=haswell and running with or without --release probably just changes codegen such that the missing symbols are sometimes needed at all. This could also be looking at your crate's .rlib before link with the different flag combinations and seeing whether or not there is an undefined symbol memcpy (I think the Windows equivalent of nm to check this is dumpbin?).

Why are you passing /NODEFAULTLIB in build.rs? I'm assuming this is why it isn't just using the system's library. We don't distribute compiler_builtins with the mem feature on Windows to avoid conflicting with the system libs.

@byeongkeunahn
Copy link
Author

Why are you passing /NODEFAULTLIB in build.rs? I'm assuming this is why it isn't just using the system's library. We don't distribute compiler_builtins with the mem feature on Windows to avoid conflicting with the system libs.

It was to reduce the binary size whenever possible. Nevertheless, the linker error pattern doesn't change even if /NODEFAULTLIB is removed.

basm-rs-minimal-example-v2.zip

@tgross35
Copy link
Contributor

tgross35 commented Mar 2, 2025

Reduced:

#![no_main]
#![no_std]

extern crate alloc;

struct Allocator;

unsafe impl core::alloc::GlobalAlloc for Allocator {
    unsafe fn alloc(&self, _: core::alloc::Layout) -> *mut u8 {
        unimplemented!()
    }
    unsafe fn alloc_zeroed(&self, _: core::alloc::Layout) -> *mut u8 {
        unimplemented!()
    }
    unsafe fn dealloc(&self, _: *mut u8, _: core::alloc::Layout) {}
    unsafe fn realloc(&self, _: *mut u8, _: core::alloc::Layout, _: usize) -> *mut u8 {
        unimplemented!()
    }
}

#[global_allocator]
static ALLOC: Allocator = Allocator;

#[unsafe(no_mangle)]
extern "win64" fn __CxxFrameHandler3() -> ! {
    unimplemented!()
}

#[panic_handler]
fn panic(_pi: &core::panic::PanicInfo) -> ! {
    unimplemented!()
}

#[unsafe(no_mangle)]
pub unsafe extern "win64" fn _basm_start() -> ! {
    unimplemented!()
}

With rustc src\lib.rs -Cpanic=abort -C link-arg=/SUBSYSTEM:CONSOLE -C link-arg=/ENTRY:_basm_start, the same symbols are missing (memcpy, memset, memmove etc).

Run with RUSTC_LOG=rustc_metadata::creader=info makes it pretty clear that after #135501, a non-sysroot compiler_builtins doesn't get into the crate graph unless added early with extern crate compiler_builtins, but for older versions it allowed duplicates. It is possible to adjust that part of resolution to allow >1 compiler_builtins crate (by deleting the block I linked above).

I am hesitant to do that though because the current behavior is generally preferable; we want to discourage direct use of compiler_builtins, and enabling multiple versions to be linked is an absolute disaster waiting to happen (E.g. we recently changed the function signatures on our i128 overflowing multiplication symbols).

I'm not sure what a better solution is, however. Maybe it's easiest to enable mem in the distributed version on Windows and make the symbols weak? We do this for other symbols, with a caveat that I think this doesn't work for windows-gnu.

Cc @ChrisDenton, do you have any ideas?

@byeongkeunahn
Copy link
Author

Thank you for the detailed analysis. One thing I'd like to note is that the linker error also occurs on Linux, not just Windows. The error message on Linux can be found at the beginning of this issue thread. The reason I limited the above example to Windows was simply to minimize the amount of code.

@tgross35
Copy link
Contributor

tgross35 commented Mar 2, 2025

Ah, I thought we were providing the symbols on Unix because weak linkage works well, but I guess bootstrap only sets this for no_std targets

features += " compiler-builtins-mem";
.

@tgross35 tgross35 changed the title no-std build fails on Windows/Linux x64 compiler_builtins string.h functions are not available when using std targets with #![no_std] Mar 2, 2025
@apiraino apiraino added the E-needs-investigation Call for partcipation: This issues needs some investigation to determine current status label Mar 6, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-linkage Area: linking into static, shared libraries and binaries C-bug Category: This is a bug. E-needs-investigation Call for partcipation: This issues needs some investigation to determine current status I-prioritize Issue: Indicates that prioritization has been requested for this issue. regression-untriaged Untriaged performance or correctness regression.
Projects
None yet
Development

No branches or pull requests

7 participants