diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index 43caf7734fdbd..5c9ae52d9e6c0 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -128,10 +128,6 @@ debug_refcell = ["core/debug_refcell"] llvm_enzyme = ["core/llvm_enzyme"] -# Enable std_detect features: -std_detect_file_io = ["std_detect/std_detect_file_io"] -std_detect_dlsym_getauxval = ["std_detect/std_detect_dlsym_getauxval"] - # Enable using raw-dylib for Windows imports. # This will eventually be the default. windows_raw_dylib = ["windows-targets/windows_raw_dylib"] diff --git a/library/std_detect/Cargo.toml b/library/std_detect/Cargo.toml index 2739bb5923009..a6785bb20555d 100644 --- a/library/std_detect/Cargo.toml +++ b/library/std_detect/Cargo.toml @@ -7,11 +7,6 @@ authors = [ "Gonzalo Brito Gadeschi ", ] description = "`std::detect` - Rust's standard library run-time CPU feature detection." -homepage = "https://github.com/rust-lang/stdarch" -repository = "https://github.com/rust-lang/stdarch" -readme = "README.md" -keywords = ["std", "run-time", "feature", "detection"] -categories = ["hardware-support"] license = "MIT OR Apache-2.0" edition = "2024" @@ -25,10 +20,7 @@ core = { version = "1.0.0", package = 'rustc-std-workspace-core' } alloc = { version = "1.0.0", package = 'rustc-std-workspace-alloc' } [target.'cfg(not(windows))'.dependencies] -libc = { version = "0.2.0", optional = true, default-features = false } +libc = { version = "0.2.0", default-features = false } [features] -default = [] -std_detect_file_io = [ "libc" ] -std_detect_dlsym_getauxval = [ "libc" ] -std_detect_env_override = [ "libc" ] +std_detect_env_override = [] diff --git a/library/std_detect/README.md b/library/std_detect/README.md index 177848dec1044..895f3426d0495 100644 --- a/library/std_detect/README.md +++ b/library/std_detect/README.md @@ -21,32 +21,6 @@ run-time feature detection support than the one offered by Rust's standard library. We intend to make `std_detect` more flexible and configurable in this regard to better serve the needs of `#[no_std]` targets. -# Features - -* `std_detect_dlsym_getauxval` (enabled by default, requires `libc`): Enable to -use `libc::dlsym` to query whether [`getauxval`] is linked into the binary. When -this is not the case, this feature allows other fallback methods to perform -run-time feature detection. When this feature is disabled, `std_detect` assumes -that [`getauxval`] is linked to the binary. If that is not the case the behavior -is undefined. - - Note: This feature is ignored on `*-linux-{gnu,musl,ohos}*` and `*-android*` targets - because we can safely assume `getauxval` is linked to the binary. - * `*-linux-gnu*` targets ([since Rust 1.64](https://blog.rust-lang.org/2022/08/01/Increasing-glibc-kernel-requirements.html)) - have glibc requirements higher than [glibc 2.16 that added `getauxval`](https://sourceware.org/legacy-ml/libc-announce/2012/msg00000.html). - * `*-linux-musl*` targets ([at least since Rust 1.15](https://github.com/rust-lang/rust/blob/1.15.0/src/ci/docker/x86_64-musl/build-musl.sh#L15)) - use musl newer than [musl 1.1.0 that added `getauxval`](https://git.musl-libc.org/cgit/musl/tree/WHATSNEW?h=v1.1.0#n1197) - * `*-linux-ohos*` targets use a [fork of musl 1.2](https://gitee.com/openharmony/docs/blob/master/en/application-dev/reference/native-lib/musl.md) - * `*-android*` targets ([since Rust 1.68](https://blog.rust-lang.org/2023/01/09/android-ndk-update-r25.html)) - have the minimum supported API level higher than [Android 4.3 (API level 18) that added `getauxval`](https://github.com/aosp-mirror/platform_bionic/blob/d3ebc2f7c49a9893b114124d4a6b315f3a328764/libc/include/sys/auxv.h#L49). - -* `std_detect_file_io` (enabled by default, requires `std`): Enable to perform run-time feature -detection using file APIs (e.g. `/proc/self/auxv`, etc.) if other more performant -methods fail. This feature requires `libstd` as a dependency, preventing the -crate from working on applications in which `std` is not available. - -[`getauxval`]: https://man7.org/linux/man-pages/man3/getauxval.3.html - # Platform support * All `x86`/`x86_64` targets are supported on all platforms by querying the diff --git a/library/std_detect/src/detect/mod.rs b/library/std_detect/src/detect/mod.rs index ae6fb2ab37279..c888dd34d9db5 100644 --- a/library/std_detect/src/detect/mod.rs +++ b/library/std_detect/src/detect/mod.rs @@ -47,21 +47,21 @@ cfg_select! { #[path = "os/x86.rs"] mod os; } - all(any(target_os = "linux", target_os = "android"), feature = "libc") => { + any(target_os = "linux", target_os = "android") => { #[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))] #[path = "os/riscv.rs"] mod riscv; #[path = "os/linux/mod.rs"] mod os; } - all(target_os = "freebsd", feature = "libc") => { + target_os = "freebsd" => { #[cfg(target_arch = "aarch64")] #[path = "os/aarch64.rs"] mod aarch64; #[path = "os/freebsd/mod.rs"] mod os; } - all(target_os = "openbsd", feature = "libc") => { + target_os = "openbsd" => { #[allow(dead_code)] // we don't use code that calls the mrs instruction. #[cfg(target_arch = "aarch64")] #[path = "os/aarch64.rs"] @@ -73,7 +73,7 @@ cfg_select! { #[path = "os/windows/aarch64.rs"] mod os; } - all(target_vendor = "apple", target_arch = "aarch64", feature = "libc") => { + all(target_vendor = "apple", target_arch = "aarch64") => { #[path = "os/darwin/aarch64.rs"] mod os; } diff --git a/library/std_detect/src/detect/os/linux/aarch64/tests.rs b/library/std_detect/src/detect/os/linux/aarch64/tests.rs index a3562f2fd9362..4d7c9a419d386 100644 --- a/library/std_detect/src/detect/os/linux/aarch64/tests.rs +++ b/library/std_detect/src/detect/os/linux/aarch64/tests.rs @@ -1,77 +1,70 @@ +use super::auxvec::auxv_from_file; use super::*; +// The baseline hwcaps used in the (artificial) auxv test files. +fn baseline_hwcaps() -> AtHwcap { + AtHwcap { + fp: true, + asimd: true, + aes: true, + pmull: true, + sha1: true, + sha2: true, + crc32: true, + atomics: true, + fphp: true, + asimdhp: true, + asimdrdm: true, + lrcpc: true, + dcpop: true, + asimddp: true, + ssbs: true, + ..AtHwcap::default() + } +} -#[cfg(feature = "std_detect_file_io")] -mod auxv_from_file { - use super::auxvec::auxv_from_file; - use super::*; - // The baseline hwcaps used in the (artificial) auxv test files. - fn baseline_hwcaps() -> AtHwcap { +#[test] +fn linux_empty_hwcap2_aarch64() { + let file = concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/detect/test_data/linux-empty-hwcap2-aarch64.auxv" + ); + println!("file: {file}"); + let v = auxv_from_file(file).unwrap(); + println!("HWCAP : 0x{:0x}", v.hwcap); + println!("HWCAP2: 0x{:0x}", v.hwcap2); + assert_eq!(AtHwcap::from(v), baseline_hwcaps()); +} +#[test] +fn linux_no_hwcap2_aarch64() { + let file = + concat!(env!("CARGO_MANIFEST_DIR"), "/src/detect/test_data/linux-no-hwcap2-aarch64.auxv"); + println!("file: {file}"); + let v = auxv_from_file(file).unwrap(); + println!("HWCAP : 0x{:0x}", v.hwcap); + println!("HWCAP2: 0x{:0x}", v.hwcap2); + assert_eq!(AtHwcap::from(v), baseline_hwcaps()); +} +#[test] +fn linux_hwcap2_aarch64() { + let file = + concat!(env!("CARGO_MANIFEST_DIR"), "/src/detect/test_data/linux-hwcap2-aarch64.auxv"); + println!("file: {file}"); + let v = auxv_from_file(file).unwrap(); + println!("HWCAP : 0x{:0x}", v.hwcap); + println!("HWCAP2: 0x{:0x}", v.hwcap2); + assert_eq!( + AtHwcap::from(v), AtHwcap { - fp: true, - asimd: true, - aes: true, - pmull: true, - sha1: true, - sha2: true, - crc32: true, - atomics: true, - fphp: true, - asimdhp: true, - asimdrdm: true, - lrcpc: true, - dcpop: true, - asimddp: true, - ssbs: true, - ..AtHwcap::default() + // Some other HWCAP bits. + paca: true, + pacg: true, + // HWCAP2-only bits. + dcpodp: true, + frint: true, + rng: true, + bti: true, + mte: true, + ..baseline_hwcaps() } - } - - #[test] - fn linux_empty_hwcap2_aarch64() { - let file = concat!( - env!("CARGO_MANIFEST_DIR"), - "/src/detect/test_data/linux-empty-hwcap2-aarch64.auxv" - ); - println!("file: {file}"); - let v = auxv_from_file(file).unwrap(); - println!("HWCAP : 0x{:0x}", v.hwcap); - println!("HWCAP2: 0x{:0x}", v.hwcap2); - assert_eq!(AtHwcap::from(v), baseline_hwcaps()); - } - #[test] - fn linux_no_hwcap2_aarch64() { - let file = concat!( - env!("CARGO_MANIFEST_DIR"), - "/src/detect/test_data/linux-no-hwcap2-aarch64.auxv" - ); - println!("file: {file}"); - let v = auxv_from_file(file).unwrap(); - println!("HWCAP : 0x{:0x}", v.hwcap); - println!("HWCAP2: 0x{:0x}", v.hwcap2); - assert_eq!(AtHwcap::from(v), baseline_hwcaps()); - } - #[test] - fn linux_hwcap2_aarch64() { - let file = - concat!(env!("CARGO_MANIFEST_DIR"), "/src/detect/test_data/linux-hwcap2-aarch64.auxv"); - println!("file: {file}"); - let v = auxv_from_file(file).unwrap(); - println!("HWCAP : 0x{:0x}", v.hwcap); - println!("HWCAP2: 0x{:0x}", v.hwcap2); - assert_eq!( - AtHwcap::from(v), - AtHwcap { - // Some other HWCAP bits. - paca: true, - pacg: true, - // HWCAP2-only bits. - dcpodp: true, - frint: true, - rng: true, - bti: true, - mte: true, - ..baseline_hwcaps() - } - ); - } + ); } diff --git a/library/std_detect/src/detect/os/linux/auxvec.rs b/library/std_detect/src/detect/os/linux/auxvec.rs index 75e01bdc4499d..c0bbc7d4efa88 100644 --- a/library/std_detect/src/detect/os/linux/auxvec.rs +++ b/library/std_detect/src/detect/os/linux/auxvec.rs @@ -44,20 +44,16 @@ pub(crate) struct AuxVec { /// /// There is no perfect way of reading the auxiliary vector. /// -/// - If the `std_detect_dlsym_getauxval` cargo feature is enabled, this will use -/// `getauxval` if its linked to the binary, and otherwise proceed to a fallback implementation. -/// When `std_detect_dlsym_getauxval` is disabled, this will assume that `getauxval` is -/// linked to the binary - if that is not the case the behavior is undefined. -/// - Otherwise, if the `std_detect_file_io` cargo feature is enabled, it will +/// - If [`getauxval`] is linked to the binary we use it, and otherwise it will /// try to read `/proc/self/auxv`. /// - If that fails, this function returns an error. /// /// Note that run-time feature detection is not invoked for features that can /// be detected at compile-time. /// -/// Note: The `std_detect_dlsym_getauxval` cargo feature is ignored on -/// `*-linux-{gnu,musl,ohos}*` and `*-android*` targets because we can safely assume `getauxval` -/// is linked to the binary. +/// Note: We always directly use `getauxval` on `*-linux-{gnu,musl,ohos}*` and +/// `*-android*` targets rather than `dlsym` it because we can safely assume +/// `getauxval` is linked to the binary. /// - `*-linux-gnu*` targets ([since Rust 1.64](https://blog.rust-lang.org/2022/08/01/Increasing-glibc-kernel-requirements.html)) /// have glibc requirements higher than [glibc 2.16 that added `getauxval`](https://sourceware.org/legacy-ml/libc-announce/2012/msg00000.html). /// - `*-linux-musl*` targets ([at least since Rust 1.15](https://github.com/rust-lang/rust/blob/1.15.0/src/ci/docker/x86_64-musl/build-musl.sh#L15)) @@ -71,6 +67,7 @@ pub(crate) struct AuxVec { /// /// [auxvec_h]: https://github.com/torvalds/linux/blob/master/include/uapi/linux/auxvec.h /// [auxv_docs]: https://docs.rs/auxv/0.3.3/auxv/ +/// [`getauxval`]: https://man7.org/linux/man-pages/man3/getauxval.3.html pub(crate) fn auxv() -> Result { // Try to call a getauxval function. if let Ok(hwcap) = getauxval(AT_HWCAP) { @@ -115,16 +112,9 @@ pub(crate) fn auxv() -> Result { let _ = hwcap; } - #[cfg(feature = "std_detect_file_io")] - { - // If calling getauxval fails, try to read the auxiliary vector from - // its file: - auxv_from_file("/proc/self/auxv").map_err(|_| ()) - } - #[cfg(not(feature = "std_detect_file_io"))] - { - Err(()) - } + // If calling getauxval fails, try to read the auxiliary vector from + // its file: + auxv_from_file("/proc/self/auxv").map_err(|_| ()) } /// Tries to read the `key` from the auxiliary vector by calling the @@ -132,14 +122,16 @@ pub(crate) fn auxv() -> Result { fn getauxval(key: usize) -> Result { type F = unsafe extern "C" fn(libc::c_ulong) -> libc::c_ulong; cfg_select! { - all( - feature = "std_detect_dlsym_getauxval", - not(all( + any( + all( target_os = "linux", any(target_env = "gnu", target_env = "musl", target_env = "ohos"), - )), - not(target_os = "android"), + ), + target_os = "android", ) => { + let ffi_getauxval: F = libc::getauxval; + } + _ => { let ffi_getauxval: F = unsafe { let ptr = libc::dlsym(libc::RTLD_DEFAULT, c"getauxval".as_ptr()); if ptr.is_null() { @@ -148,23 +140,18 @@ fn getauxval(key: usize) -> Result { core::mem::transmute(ptr) }; } - _ => { - let ffi_getauxval: F = libc::getauxval; - } } Ok(unsafe { ffi_getauxval(key as libc::c_ulong) as usize }) } /// Tries to read the auxiliary vector from the `file`. If this fails, this /// function returns `Err`. -#[cfg(feature = "std_detect_file_io")] pub(super) fn auxv_from_file(file: &str) -> Result { let file = super::read_file(file)?; auxv_from_file_bytes(&file) } /// Read auxiliary vector from a slice of bytes. -#[cfg(feature = "std_detect_file_io")] pub(super) fn auxv_from_file_bytes(bytes: &[u8]) -> Result { // See . // @@ -181,7 +168,6 @@ pub(super) fn auxv_from_file_bytes(bytes: &[u8]) -> Result Result { // Targets with only AT_HWCAP: #[cfg(any( diff --git a/library/std_detect/src/detect/os/linux/auxvec/tests.rs b/library/std_detect/src/detect/os/linux/auxvec/tests.rs index 631a3e5e9ef17..88f0d6d493376 100644 --- a/library/std_detect/src/detect/os/linux/auxvec/tests.rs +++ b/library/std_detect/src/detect/os/linux/auxvec/tests.rs @@ -41,7 +41,6 @@ fn auxv_dump() { } } -#[cfg(feature = "std_detect_file_io")] cfg_select! { target_arch = "arm" => { // The tests below can be executed under qemu, where we do not have access to the test @@ -86,7 +85,6 @@ cfg_select! { } #[test] -#[cfg(feature = "std_detect_file_io")] fn auxv_dump_procfs() { if let Ok(auxvec) = auxv_from_file("/proc/self/auxv") { println!("{:?}", auxvec); @@ -103,7 +101,6 @@ fn auxv_dump_procfs() { target_arch = "s390x", ))] #[test] -#[cfg(feature = "std_detect_file_io")] fn auxv_crate_procfs() { if let Ok(procfs_auxv) = auxv_from_file("/proc/self/auxv") { assert_eq!(auxv().unwrap(), procfs_auxv); diff --git a/library/std_detect/src/detect/os/linux/mod.rs b/library/std_detect/src/detect/os/linux/mod.rs index 5273c16c0893c..aec94f963f5c1 100644 --- a/library/std_detect/src/detect/os/linux/mod.rs +++ b/library/std_detect/src/detect/os/linux/mod.rs @@ -1,11 +1,9 @@ //! Run-time feature detection on Linux -//! -#[cfg(feature = "std_detect_file_io")] + use alloc::vec::Vec; mod auxvec; -#[cfg(feature = "std_detect_file_io")] fn read_file(orig_path: &str) -> Result, alloc::string::String> { use alloc::format; diff --git a/library/std_detect/src/lib.rs b/library/std_detect/src/lib.rs index 73e2f5dd96442..5e1d21bbfd17d 100644 --- a/library/std_detect/src/lib.rs +++ b/library/std_detect/src/lib.rs @@ -27,8 +27,7 @@ extern crate std; // rust-lang/rust#83888: removing `extern crate` gives an error that `vec_spare> -#[cfg_attr(feature = "std_detect_file_io", allow(unused_extern_crates))] -#[cfg(feature = "std_detect_file_io")] +#[allow(unused_extern_crates)] extern crate alloc; #[doc(hidden)] diff --git a/library/sysroot/Cargo.toml b/library/sysroot/Cargo.toml index eec8c461b6db4..a188680829166 100644 --- a/library/sysroot/Cargo.toml +++ b/library/sysroot/Cargo.toml @@ -20,7 +20,7 @@ test = { path = "../test", public = true } # Forward features to the `std` crate as necessary [features] -default = ["std_detect_file_io", "std_detect_dlsym_getauxval", "panic-unwind"] +default = ["panic-unwind"] backtrace = ["std/backtrace"] backtrace-trace-only = ["std/backtrace-trace-only"] compiler-builtins-c = ["std/compiler-builtins-c"] @@ -32,7 +32,5 @@ system-llvm-libunwind = ["std/system-llvm-libunwind"] optimize_for_size = ["std/optimize_for_size"] panic-unwind = ["std/panic-unwind"] profiler = ["dep:profiler_builtins"] -std_detect_file_io = ["std/std_detect_file_io"] -std_detect_dlsym_getauxval = ["std/std_detect_dlsym_getauxval"] windows_raw_dylib = ["std/windows_raw_dylib"] llvm_enzyme = ["std/llvm_enzyme"]