Rollup merge of #141993 - tgross35:use-in-tree-builtins, r=bjorn3

Use the in-tree `compiler-builtins` for the sysroot

Many of `std`'s dependency have a dependency on the crates.io `compiler-builtins` when used with the feature `rustc-std-workspace-core`. Use a Cargo patch to select the in-tree version instead.

`compiler-builtins` is also added as a dependency of `rustc-std-workspace-core` so these crates can remove their crates.io dependency in the future.

Zulip discussion: [#t-compiler > Using in-tree compiler-builtins](https://rust-lang.zulipchat.com/#narrow/channel/131828-t-compiler/topic/Using.20in-tree.20compiler-builtins/with/522445336)

Once this merges, the following PRs will need to make it to a release for the relevant crates:

- https://github.com/rust-lang/getopts/pull/119 (can merge at any time)
- https://github.com/rust-lang/hashbrown/pull/625 (can merge at any time)
- https://github.com/rust-lang/stdarch/pull/1825
- https://github.com/rust-lang/rustc-demangle/pull/80
- https://github.com/rust-lang/cfg-if/pull/84
- https://github.com/unicode-rs/unicode-width/pull/77

The above should cover all tier 1 targets with no `std` features enabled. The remaining cover the rest:

- https://github.com/alexcrichton/dlmalloc-rs/pull/50 (wasm, xous, sgx)
- https://github.com/gimli-rs/gimli/pull/769
- https://github.com/r-efi/r-efi/pull/89 (efi)
- https://github.com/r-efi/r-efi-alloc/pull/9 (efi)
- https://github.com/fortanix/rust-sgx/pull/770 (sgx)
- https://github.com/hermit-os/hermit-rs/pull/718 (hermit)
- https://github.com/bytecodealliance/wasi-rs/pull/108 (wasi)
- https://github.com/gimli-rs/addr2line/pull/345
- https://github.com/oyvindln/adler2/pull/2
- https://github.com/BurntSushi/memchr/pull/180
- https://github.com/Frommi/miniz_oxide/pull/173
- https://github.com/gimli-rs/object/pull/777

try-job: x86_64-gnu
try-job: test-various
This commit is contained in:
Trevor Gross 2025-06-09 12:17:53 -05:00 committed by GitHub
commit ab87ed150b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
19 changed files with 99 additions and 35 deletions

View file

@ -3130,11 +3130,12 @@ dependencies = [
[[package]]
name = "rustc-build-sysroot"
version = "0.5.7"
version = "0.5.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "10edc2e4393515193bd766e2f6c050b0536a68e56f2b6d56c07ababfdc114ff0"
checksum = "16d115ad7e26e0d1337f64ae6598f758194696afc2e9f34c8a6f24582529c3dc"
dependencies = [
"anyhow",
"regex",
"rustc_version",
"tempfile",
"walkdir",

View file

@ -6,7 +6,6 @@ resolver = "2"
[dependencies]
core = { path = "./sysroot_src/library/core" }
compiler_builtins = "0.1"
alloc = { path = "./sysroot_src/library/alloc" }
std = { path = "./sysroot_src/library/std", features = ["panic_unwind", "backtrace"] }
test = { path = "./sysroot_src/library/test" }
@ -16,6 +15,7 @@ proc_macro = { path = "./sysroot_src/library/proc_macro" }
rustc-std-workspace-core = { path = "./sysroot_src/library/rustc-std-workspace-core" }
rustc-std-workspace-alloc = { path = "./sysroot_src/library/rustc-std-workspace-alloc" }
rustc-std-workspace-std = { path = "./sysroot_src/library/rustc-std-workspace-std" }
compiler_builtins = { path = "./sysroot_src/library/compiler-builtins/compiler-builtins" }
# For compiler-builtins we always use a high number of codegen units.
# The goal here is to place every single intrinsic into its own object

View file

@ -62,11 +62,9 @@ dependencies = [
[[package]]
name = "compiler_builtins"
version = "0.1.160"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6376049cfa92c0aa8b9ac95fae22184b981c658208d4ed8a1dc553cd83612895"
dependencies = [
"cc",
"rustc-std-workspace-core",
"core",
]
[[package]]
@ -304,6 +302,7 @@ dependencies = [
name = "rustc-std-workspace-core"
version = "1.99.0"
dependencies = [
"compiler_builtins",
"core",
]

View file

@ -50,3 +50,4 @@ rustc-demangle.opt-level = "s"
rustc-std-workspace-core = { path = 'rustc-std-workspace-core' }
rustc-std-workspace-alloc = { path = 'rustc-std-workspace-alloc' }
rustc-std-workspace-std = { path = 'rustc-std-workspace-std' }
compiler_builtins = { path = "compiler-builtins/compiler-builtins" }

View file

@ -16,7 +16,7 @@ bench = false
[dependencies]
core = { path = "../core", public = true }
compiler_builtins = { version = "=0.1.160", features = ['rustc-dep-of-std'] }
compiler_builtins = { path = "../compiler-builtins/compiler-builtins", features = ["rustc-dep-of-std"] }
[features]
compiler-builtins-mem = ['compiler_builtins/mem']

View file

@ -17,9 +17,7 @@ doctest = false
test = false
[dependencies]
# For more information on this dependency see
# https://github.com/rust-lang/rust/tree/master/library/rustc-std-workspace-core
core = { version = "1.0.1", optional = true, package = "rustc-std-workspace-core" }
core = { path = "../../core", optional = true }
[build-dependencies]
cc = { optional = true, version = "1.2" }

View file

@ -22,6 +22,9 @@ fn main() {
println!("cargo:compiler-rt={}", cwd.join("compiler-rt").display());
println!("cargo::rustc-check-cfg=cfg(kernel_user_helpers)");
println!("cargo::rustc-check-cfg=cfg(feature, values(\"mem-unaligned\"))");
// Emscripten's runtime includes all the builtins
if target.os == "emscripten" {
return;
@ -47,7 +50,6 @@ fn main() {
}
// These targets have hardware unaligned access support.
println!("cargo::rustc-check-cfg=cfg(feature, values(\"mem-unaligned\"))");
if target.arch.contains("x86_64")
|| target.arch.contains("x86")
|| target.arch.contains("aarch64")
@ -78,7 +80,6 @@ fn main() {
// Only emit the ARM Linux atomic emulation on pre-ARMv6 architectures. This
// includes the old androideabi. It is deprecated but it is available as a
// rustc target (arm-linux-androideabi).
println!("cargo::rustc-check-cfg=cfg(kernel_user_helpers)");
if llvm_target[0] == "armv4t"
|| llvm_target[0] == "armv5te"
|| target.triple == "arm-linux-androideabi"

View file

@ -4,7 +4,7 @@
//! To avoid breaking backwards compat, C toolchains introduced a concept of "outlined atomics",
//! where atomic operations call into the compiler runtime to dispatch between two depending on
//! which is supported on the current CPU.
//! See https://community.arm.com/arm-community-blogs/b/tools-software-ides-blog/posts/making-the-most-of-the-arm-architecture-in-gcc-10#:~:text=out%20of%20line%20atomics for more discussion.
//! See <https://community.arm.com/arm-community-blogs/b/tools-software-ides-blog/posts/making-the-most-of-the-arm-architecture-in-gcc-10#:~:text=out%20of%20line%20atomics> for more discussion.
//!
//! Currently we only support LL/SC, because LSE requires `getauxval` from libc in order to do runtime detection.
//! Use the `compiler-rt` intrinsics if you want LSE support.

View file

@ -4,12 +4,17 @@ use core::{arch, mem};
// Kernel-provided user-mode helper functions:
// https://www.kernel.org/doc/Documentation/arm/kernel_user_helpers.txt
unsafe fn __kuser_cmpxchg(oldval: u32, newval: u32, ptr: *mut u32) -> bool {
let f: extern "C" fn(u32, u32, *mut u32) -> u32 = mem::transmute(0xffff0fc0usize as *const ());
// FIXME(volatile): the third parameter is a volatile pointer
// SAFETY: kernel docs specify a known address with the given signature
let f = unsafe {
mem::transmute::<_, extern "C" fn(u32, u32, *mut u32) -> u32>(0xffff0fc0usize as *const ())
};
f(oldval, newval, ptr) == 0
}
unsafe fn __kuser_memory_barrier() {
let f: extern "C" fn() = mem::transmute(0xffff0fa0usize as *const ());
// SAFETY: kernel docs specify a known address with the given signature
let f = unsafe { mem::transmute::<_, extern "C" fn()>(0xffff0fa0usize as *const ()) };
f();
}
@ -67,8 +72,10 @@ fn insert_aligned(aligned: u32, val: u32, shift: u32, mask: u32) -> u32 {
/// - if `size_of::<T>() == 2`, `ptr` or `ptr` offset by 2 bytes must be valid for a relaxed atomic
/// read of 2 bytes.
/// - if `size_of::<T>() == 4`, `ptr` must be valid for a relaxed atomic read of 4 bytes.
// FIXME: assert some of the preconditions in debug mode
unsafe fn atomic_load_aligned<T>(ptr: *mut u32) -> u32 {
if mem::size_of::<T>() == 4 {
const { assert!(size_of::<T>() <= 4) };
if size_of::<T>() == 4 {
// SAFETY: As `T` has a size of 4, the caller garantees this is sound.
unsafe { AtomicU32::from_ptr(ptr).load(Ordering::Relaxed) }
} else {
@ -100,11 +107,13 @@ unsafe fn atomic_rmw<T, F: Fn(u32) -> u32, G: Fn(u32, u32) -> u32>(ptr: *mut T,
let (shift, mask) = get_shift_mask(ptr);
loop {
let curval_aligned = atomic_load_aligned::<T>(aligned_ptr);
// FIXME(safety): preconditions review needed
let curval_aligned = unsafe { atomic_load_aligned::<T>(aligned_ptr) };
let curval = extract_aligned(curval_aligned, shift, mask);
let newval = f(curval);
let newval_aligned = insert_aligned(curval_aligned, newval, shift, mask);
if __kuser_cmpxchg(curval_aligned, newval_aligned, aligned_ptr) {
// FIXME(safety): preconditions review needed
if unsafe { __kuser_cmpxchg(curval_aligned, newval_aligned, aligned_ptr) } {
return g(curval, newval);
}
}
@ -116,13 +125,15 @@ unsafe fn atomic_cmpxchg<T>(ptr: *mut T, oldval: u32, newval: u32) -> u32 {
let (shift, mask) = get_shift_mask(ptr);
loop {
let curval_aligned = atomic_load_aligned::<T>(aligned_ptr);
// FIXME(safety): preconditions review needed
let curval_aligned = unsafe { atomic_load_aligned::<T>(aligned_ptr) };
let curval = extract_aligned(curval_aligned, shift, mask);
if curval != oldval {
return curval;
}
let newval_aligned = insert_aligned(curval_aligned, newval, shift, mask);
if __kuser_cmpxchg(curval_aligned, newval_aligned, aligned_ptr) {
// FIXME(safety): preconditions review needed
if unsafe { __kuser_cmpxchg(curval_aligned, newval_aligned, aligned_ptr) } {
return oldval;
}
}
@ -132,7 +143,14 @@ macro_rules! atomic_rmw {
($name:ident, $ty:ty, $op:expr, $fetch:expr) => {
intrinsics! {
pub unsafe extern "C" fn $name(ptr: *mut $ty, val: $ty) -> $ty {
atomic_rmw(ptr, |x| $op(x as $ty, val) as u32, |old, new| $fetch(old, new)) as $ty
// FIXME(safety): preconditions review needed
unsafe {
atomic_rmw(
ptr,
|x| $op(x as $ty, val) as u32,
|old, new| $fetch(old, new)
) as $ty
}
}
}
};
@ -149,7 +167,8 @@ macro_rules! atomic_cmpxchg {
($name:ident, $ty:ty) => {
intrinsics! {
pub unsafe extern "C" fn $name(ptr: *mut $ty, oldval: $ty, newval: $ty) -> $ty {
atomic_cmpxchg(ptr, oldval as u32, newval as u32) as $ty
// FIXME(safety): preconditions review needed
unsafe { atomic_cmpxchg(ptr, oldval as u32, newval as u32) as $ty }
}
}
};
@ -285,6 +304,7 @@ atomic_cmpxchg!(__sync_val_compare_and_swap_4, u32);
intrinsics! {
pub unsafe extern "C" fn __sync_synchronize() {
__kuser_memory_barrier();
// SAFETY: preconditions are the same as the calling function.
unsafe { __kuser_memory_barrier() };
}
}

View file

@ -69,7 +69,7 @@ pub unsafe fn copy_backward(dest: *mut u8, src: *const u8, count: usize) {
"rep movsb",
"sub $7, %rsi",
"sub $7, %rdi",
"mov {qword_count}, %rcx",
"mov {qword_count:r}, %rcx",
"rep movsq",
"test {pre_byte_count:e}, {pre_byte_count:e}",
"add $7, %rsi",
@ -212,7 +212,7 @@ pub unsafe fn c_string_length(mut s: *const core::ffi::c_char) -> usize {
let x = {
let r;
asm!(
"movdqa ({addr}), {dest}",
"movdqa ({addr:r}), {dest}",
addr = in(reg) s,
dest = out(xmm_reg) r,
options(att_syntax, nostack),
@ -232,7 +232,7 @@ pub unsafe fn c_string_length(mut s: *const core::ffi::c_char) -> usize {
let x = {
let r;
asm!(
"movdqa ({addr}), {dest}",
"movdqa ({addr:r}), {dest}",
addr = in(reg) s,
dest = out(xmm_reg) r,
options(att_syntax, nostack),

View file

@ -13,7 +13,7 @@ doc = false
[dependencies]
core = { path = "../core" }
compiler_builtins = "0.1.0"
compiler_builtins = { path = "../compiler-builtins/compiler-builtins" }
[target.'cfg(target_os = "android")'.dependencies]
libc = { version = "0.2", default-features = false }

View file

@ -15,7 +15,7 @@ doc = false
alloc = { path = "../alloc" }
core = { path = "../core" }
unwind = { path = "../unwind" }
compiler_builtins = "0.1.0"
compiler_builtins = { path = "../compiler-builtins/compiler-builtins" }
cfg-if = { version = "1.0", features = ['rustc-dep-of-std'] }
[target.'cfg(not(all(windows, target_env = "msvc")))'.dependencies]

View file

@ -12,3 +12,4 @@ path = "lib.rs"
[dependencies]
core = { path = "../core" }
compiler_builtins = { path = "../compiler-builtins/compiler-builtins", features = ["compiler-builtins"] }

View file

@ -2,3 +2,7 @@
#![no_core]
pub use core::*;
// Crate must be brought into scope so it appears in the crate graph for anything that
// depends on `rustc-std-workspace-core`.
use compiler_builtins as _;

View file

@ -18,7 +18,7 @@ cfg-if = { version = "1.0", features = ['rustc-dep-of-std'] }
panic_unwind = { path = "../panic_unwind", optional = true }
panic_abort = { path = "../panic_abort" }
core = { path = "../core", public = true }
compiler_builtins = { version = "=0.1.160" }
compiler_builtins = { path = "../compiler-builtins/compiler-builtins" }
unwind = { path = "../unwind" }
hashbrown = { version = "0.15", default-features = false, features = [
'rustc-dep-of-std',

View file

@ -15,7 +15,7 @@ doc = false
[dependencies]
core = { path = "../core" }
compiler_builtins = "0.1.0"
compiler_builtins = { path = "../compiler-builtins/compiler-builtins" }
cfg-if = "1.0"
[target.'cfg(not(all(windows, target_env = "msvc")))'.dependencies]

View file

@ -2,6 +2,15 @@
# It is not intended for manual editing.
version = 4
[[package]]
name = "aho-corasick"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
dependencies = [
"memchr",
]
[[package]]
name = "anyhow"
version = "1.0.97"
@ -207,12 +216,42 @@ dependencies = [
]
[[package]]
name = "rustc-build-sysroot"
version = "0.5.7"
name = "regex"
version = "1.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "10edc2e4393515193bd766e2f6c050b0536a68e56f2b6d56c07ababfdc114ff0"
checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191"
dependencies = [
"aho-corasick",
"memchr",
"regex-automata",
"regex-syntax",
]
[[package]]
name = "regex-automata"
version = "0.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
[[package]]
name = "rustc-build-sysroot"
version = "0.5.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "16d115ad7e26e0d1337f64ae6598f758194696afc2e9f34c8a6f24582529c3dc"
dependencies = [
"anyhow",
"regex",
"rustc_version",
"tempfile",
"walkdir",

View file

@ -18,7 +18,7 @@ directories = "6"
rustc_version = "0.4"
serde_json = "1.0.40"
cargo_metadata = "0.19"
rustc-build-sysroot = "0.5.7"
rustc-build-sysroot = "0.5.8"
# Enable some feature flags that dev-dependencies need but dependencies
# do not. This makes `./miri install` after `./miri build` faster.

View file

@ -1,6 +1,6 @@
error: linking with `./fake-linker` failed: exit status: 1
|
= note: "./fake-linker" "-m64" "/symbols.o" "<2 object files omitted>" "-Wl,--as-needed" "-Wl,-Bstatic" "<sysroot>/lib/rustlib/x86_64-unknown-linux-gnu/lib/{libstd-*,libpanic_unwind-*,libobject-*,libmemchr-*,libaddr2line-*,libgimli-*,librustc_demangle-*,libstd_detect-*,libhashbrown-*,librustc_std_workspace_alloc-*,libminiz_oxide-*,libadler2-*,libunwind-*,libcfg_if-*,liblibc-*,liballoc-*,librustc_std_workspace_core-*,libcore-*,libcompiler_builtins-*}.rlib" "-Wl,-Bdynamic" "-lgcc_s" "-lutil" "-lrt" "-lpthread" "-lm" "-ldl" "-lc" "-L" "/raw-dylibs" "-Wl,--eh-frame-hdr" "-Wl,-z,noexecstack" "-L" "/build-root/test/run-make/linker-warning/rmake_out" "-L" "<sysroot>/lib/rustlib/x86_64-unknown-linux-gnu/lib" "-o" "main" "-Wl,--gc-sections" "-pie" "-Wl,-z,relro,-z,now" "-nodefaultlibs" "run_make_error"
= note: "./fake-linker" "-m64" "/symbols.o" "<2 object files omitted>" "-Wl,--as-needed" "-Wl,-Bstatic" "<sysroot>/lib/rustlib/x86_64-unknown-linux-gnu/lib/{libstd-*,libpanic_unwind-*,libobject-*,libmemchr-*,libaddr2line-*,libgimli-*,librustc_demangle-*,libstd_detect-*,libhashbrown-*,librustc_std_workspace_alloc-*,libminiz_oxide-*,libadler2-*,libunwind-*,libcfg_if-*,liblibc-*,librustc_std_workspace_core-*,liballoc-*,libcore-*,libcompiler_builtins-*}.rlib" "-Wl,-Bdynamic" "-lgcc_s" "-lutil" "-lrt" "-lpthread" "-lm" "-ldl" "-lc" "-L" "/raw-dylibs" "-Wl,--eh-frame-hdr" "-Wl,-z,noexecstack" "-L" "/build-root/test/run-make/linker-warning/rmake_out" "-L" "<sysroot>/lib/rustlib/x86_64-unknown-linux-gnu/lib" "-o" "main" "-Wl,--gc-sections" "-pie" "-Wl,-z,relro,-z,now" "-nodefaultlibs" "run_make_error"
= note: some arguments are omitted. use `--verbose` to show all linker arguments
= note: error: baz