diff --git a/.github/.cspell/project-dictionary.txt b/.github/.cspell/project-dictionary.txt index 185182c7..c8144aed 100644 --- a/.github/.cspell/project-dictionary.txt +++ b/.github/.cspell/project-dictionary.txt @@ -43,6 +43,7 @@ cxchgweak DESTDIR dlsym DWCAS +ecall elems espup exynos diff --git a/src/cfgs.rs b/src/cfgs.rs index 31271b9b..5fddb071 100644 --- a/src/cfgs.rs +++ b/src/cfgs.rs @@ -166,20 +166,7 @@ mod atomic_32_macros { feature = "fallback", not(portable_atomic_no_outline_atomics), any(test, portable_atomic_outline_atomics), // TODO(riscv): currently disabled by default - any( - all( - target_os = "linux", - any( - target_env = "gnu", - all( - any(target_env = "musl", target_env = "ohos"), - not(target_feature = "crt-static"), - ), - portable_atomic_outline_atomics, - ), - ), - target_os = "android", - ), + any(target_os = "linux", target_os = "android"), ), ), ), @@ -242,20 +229,7 @@ mod atomic_64_macros { feature = "fallback", not(portable_atomic_no_outline_atomics), any(test, portable_atomic_outline_atomics), // TODO(riscv): currently disabled by default - any( - all( - target_os = "linux", - any( - target_env = "gnu", - all( - any(target_env = "musl", target_env = "ohos"), - not(target_feature = "crt-static"), - ), - portable_atomic_outline_atomics, - ), - ), - target_os = "android", - ), + any(target_os = "linux", target_os = "android"), ), ), ), @@ -310,20 +284,7 @@ mod atomic_64_macros { feature = "fallback", not(portable_atomic_no_outline_atomics), any(test, portable_atomic_outline_atomics), // TODO(riscv): currently disabled by default - any( - all( - target_os = "linux", - any( - target_env = "gnu", - all( - any(target_env = "musl", target_env = "ohos"), - not(target_feature = "crt-static"), - ), - portable_atomic_outline_atomics, - ), - ), - target_os = "android", - ), + any(target_os = "linux", target_os = "android"), not(any(miri, portable_atomic_sanitize_thread)), ), ), @@ -429,20 +390,7 @@ mod atomic_128_macros { feature = "fallback", not(portable_atomic_no_outline_atomics), any(test, portable_atomic_outline_atomics), // TODO(riscv): currently disabled by default - any( - all( - target_os = "linux", - any( - target_env = "gnu", - all( - any(target_env = "musl", target_env = "ohos"), - not(target_feature = "crt-static"), - ), - portable_atomic_outline_atomics, - ), - ), - target_os = "android", - ), + any(target_os = "linux", target_os = "android"), not(any(miri, portable_atomic_sanitize_thread)), ), ), diff --git a/src/imp/atomic128/mod.rs b/src/imp/atomic128/mod.rs index f4a1ebbb..abea2a86 100644 --- a/src/imp/atomic128/mod.rs +++ b/src/imp/atomic128/mod.rs @@ -68,20 +68,7 @@ pub(super) mod powerpc64; feature = "fallback", not(portable_atomic_no_outline_atomics), any(test, portable_atomic_outline_atomics), // TODO(riscv): currently disabled by default - any( - all( - target_os = "linux", - any( - target_env = "gnu", - all( - any(target_env = "musl", target_env = "ohos"), - not(target_feature = "crt-static"), - ), - portable_atomic_outline_atomics, - ), - ), - target_os = "android", - ), + any(target_os = "linux", target_os = "android"), not(any(miri, portable_atomic_sanitize_thread)), ), ), diff --git a/src/imp/atomic128/riscv64.rs b/src/imp/atomic128/riscv64.rs index 8da45af5..1f90f208 100644 --- a/src/imp/atomic128/riscv64.rs +++ b/src/imp/atomic128/riscv64.rs @@ -27,8 +27,6 @@ include!("macros.rs"); #[path = "../fallback/outline_atomics.rs"] mod fallback; -// On musl with static linking, it seems that libc is not always available. -// See detect/auxv.rs for more. #[cfg(not(portable_atomic_no_outline_atomics))] #[cfg(any(test, portable_atomic_outline_atomics))] // TODO(riscv): currently disabled by default #[cfg(any( @@ -38,17 +36,7 @@ mod fallback; portable_atomic_target_feature = "experimental-zacas", )), ))] -#[cfg(any( - all( - target_os = "linux", - any( - target_env = "gnu", - all(any(target_env = "musl", target_env = "ohos"), not(target_feature = "crt-static")), - portable_atomic_outline_atomics, - ), - ), - target_os = "android", -))] +#[cfg(any(target_os = "linux", target_os = "android"))] #[path = "../detect/riscv_linux.rs"] mod detect; diff --git a/src/imp/atomic64/mod.rs b/src/imp/atomic64/mod.rs index 4c2e6b1c..65b67bb8 100644 --- a/src/imp/atomic64/mod.rs +++ b/src/imp/atomic64/mod.rs @@ -35,20 +35,7 @@ pub(super) mod arm_linux; feature = "fallback", not(portable_atomic_no_outline_atomics), any(test, portable_atomic_outline_atomics), // TODO(riscv): currently disabled by default - any( - all( - target_os = "linux", - any( - target_env = "gnu", - all( - any(target_env = "musl", target_env = "ohos"), - not(target_feature = "crt-static"), - ), - portable_atomic_outline_atomics, - ), - ), - target_os = "android", - ), + any(target_os = "linux", target_os = "android"), ), ), ))] diff --git a/src/imp/atomic64/riscv32.rs b/src/imp/atomic64/riscv32.rs index 4bfab7b0..d6b2b8ef 100644 --- a/src/imp/atomic64/riscv32.rs +++ b/src/imp/atomic64/riscv32.rs @@ -29,8 +29,6 @@ include!("macros.rs"); #[path = "../fallback/outline_atomics.rs"] mod fallback; -// On musl with static linking, it seems that libc is not always available. -// See detect/auxv.rs for more. #[cfg(not(portable_atomic_no_outline_atomics))] #[cfg(any(test, portable_atomic_outline_atomics))] // TODO(riscv): currently disabled by default #[cfg(any( @@ -40,17 +38,7 @@ mod fallback; portable_atomic_target_feature = "experimental-zacas", )), ))] -#[cfg(any( - all( - target_os = "linux", - any( - target_env = "gnu", - all(any(target_env = "musl", target_env = "ohos"), not(target_feature = "crt-static")), - portable_atomic_outline_atomics, - ), - ), - target_os = "android", -))] +#[cfg(any(target_os = "linux", target_os = "android"))] #[path = "../detect/riscv_linux.rs"] mod detect; diff --git a/src/imp/detect/riscv_linux.rs b/src/imp/detect/riscv_linux.rs index f42c3d9c..7178fecc 100644 --- a/src/imp/detect/riscv_linux.rs +++ b/src/imp/detect/riscv_linux.rs @@ -20,6 +20,7 @@ mod ffi { // https://github.com/torvalds/linux/blob/v6.11/arch/riscv/include/uapi/asm/hwprobe.h #[derive(Copy, Clone)] + #[cfg_attr(test, derive(Debug, PartialEq))] #[repr(C)] pub(crate) struct riscv_hwprobe { pub(crate) key: i64, @@ -34,10 +35,49 @@ mod ffi { // https://github.com/torvalds/linux/commit/154a3706122978eeb34d8223d49285ed4f3c61fa pub(crate) const RISCV_HWPROBE_EXT_ZACAS: u64 = 1 << 34; + #[cfg(not(all( + target_os = "linux", + any(target_arch = "riscv32", all(target_arch = "riscv64", target_pointer_width = "64")), + )))] extern "C" { // https://man7.org/linux/man-pages/man2/syscall.2.html pub(crate) fn syscall(number: c_long, ...) -> c_long; } + // Use asm-based syscall for compatibility with non-libc targets if possible. + #[cfg(all( + target_os = "linux", // https://github.com/bytecodealliance/rustix/issues/1095 + any(target_arch = "riscv32", all(target_arch = "riscv64", target_pointer_width = "64")), + ))] + #[inline] + pub(crate) unsafe fn syscall( + number: c_long, + a0: *mut riscv_hwprobe, + a1: c_size_t, + a2: c_size_t, + a3: *mut c_ulong, + a4: c_uint, + ) -> c_long { + let r; + // registers must be extended to 64-bit for RV64 + let a4 = a4 as usize; + // SAFETY: the caller must uphold the safety contract. + // Refs: + // - https://github.com/bminor/musl/blob/v1.2.5/arch/riscv32/syscall_arch.h + // - https://github.com/bminor/musl/blob/v1.2.5/arch/riscv64/syscall_arch.h + unsafe { + core::arch::asm!( + "ecall", + in("a7") number, + inout("a0") a0 => r, + in("a1") a1, + in("a2") a2, + in("a3") a3, + in("a4") a4, + options(nostack, preserves_flags) + ); + } + r + } // https://github.com/torvalds/linux/blob/v6.11/Documentation/arch/riscv/hwprobe.rst pub(crate) unsafe fn __riscv_hwprobe( @@ -82,6 +122,32 @@ fn _detect(info: &mut CpuInfo) { mod tests { use super::*; + // We use asm-based syscall for compatibility with non-libc targets. + // This test tests that our ones and libc::syscall returns the same result. + #[test] + fn test_linux_like() { + use test_helper::libc; + unsafe fn __libc_riscv_hwprobe( + pairs: *mut ffi::riscv_hwprobe, + pair_count: ffi::c_size_t, + cpu_set_size: ffi::c_size_t, + cpus: *mut ffi::c_ulong, + flags: ffi::c_uint, + ) -> ffi::c_long { + // SAFETY: the caller must uphold the safety contract. + unsafe { + libc::syscall(ffi::__NR_riscv_hwprobe, pairs, pair_count, cpu_set_size, cpus, flags) + } + } + fn libc_riscv_hwprobe(out: &mut ffi::riscv_hwprobe) -> bool { + unsafe { __libc_riscv_hwprobe(out, 1, 0, ptr::null_mut(), 0) == 0 } + } + let mut out = ffi::riscv_hwprobe { key: ffi::RISCV_HWPROBE_KEY_IMA_EXT_0, value: 0 }; + let mut libc_out = ffi::riscv_hwprobe { key: ffi::RISCV_HWPROBE_KEY_IMA_EXT_0, value: 0 }; + assert_eq!(riscv_hwprobe(&mut out), libc_riscv_hwprobe(&mut libc_out)); + assert_eq!(out, libc_out); + } + // Static assertions for FFI bindings. // This checks that FFI bindings defined in this crate, FFI bindings defined // in libc, and FFI bindings generated for the platform's latest header file diff --git a/src/imp/fallback/mod.rs b/src/imp/fallback/mod.rs index adb9e109..21973330 100644 --- a/src/imp/fallback/mod.rs +++ b/src/imp/fallback/mod.rs @@ -55,20 +55,7 @@ type and the value type must be the same. feature = "fallback", not(portable_atomic_no_outline_atomics), any(test, portable_atomic_outline_atomics), // TODO(riscv): currently disabled by default - any( - all( - target_os = "linux", - any( - target_env = "gnu", - all( - any(target_env = "musl", target_env = "ohos"), - not(target_feature = "crt-static"), - ), - portable_atomic_outline_atomics, - ), - ), - target_os = "android", - ), + any(target_os = "linux", target_os = "android"), ), ), ), @@ -83,20 +70,7 @@ type and the value type must be the same. feature = "fallback", not(portable_atomic_no_outline_atomics), any(test, portable_atomic_outline_atomics), // TODO(riscv): currently disabled by default - any( - all( - target_os = "linux", - any( - target_env = "gnu", - all( - any(target_env = "musl", target_env = "ohos"), - not(target_feature = "crt-static"), - ), - portable_atomic_outline_atomics, - ), - ), - target_os = "android", - ), + any(target_os = "linux", target_os = "android"), not(any(miri, portable_atomic_sanitize_thread)), ), ), diff --git a/src/imp/mod.rs b/src/imp/mod.rs index c6587826..97739195 100644 --- a/src/imp/mod.rs +++ b/src/imp/mod.rs @@ -283,20 +283,7 @@ items! { feature = "fallback", not(portable_atomic_no_outline_atomics), any(test, portable_atomic_outline_atomics), // TODO(riscv): currently disabled by default - any( - all( - target_os = "linux", - any( - target_env = "gnu", - all( - any(target_env = "musl", target_env = "ohos"), - not(target_feature = "crt-static"), - ), - portable_atomic_outline_atomics, - ), - ), - target_os = "android", - ), + any(target_os = "linux", target_os = "android"), ), ), ), @@ -337,20 +324,7 @@ items! { feature = "fallback", not(portable_atomic_no_outline_atomics), any(test, portable_atomic_outline_atomics), // TODO(riscv): currently disabled by default - any( - all( - target_os = "linux", - any( - target_env = "gnu", - all( - any(target_env = "musl", target_env = "ohos"), - not(target_feature = "crt-static"), - ), - portable_atomic_outline_atomics, - ), - ), - target_os = "android", - ), + any(target_os = "linux", target_os = "android"), not(any(miri, portable_atomic_sanitize_thread)), ), ), @@ -416,20 +390,7 @@ pub(crate) use self::atomic64::arm_linux::{AtomicI64, AtomicU64}; feature = "fallback", not(portable_atomic_no_outline_atomics), any(test, portable_atomic_outline_atomics), // TODO(riscv): currently disabled by default - any( - all( - target_os = "linux", - any( - target_env = "gnu", - all( - any(target_env = "musl", target_env = "ohos"), - not(target_feature = "crt-static"), - ), - portable_atomic_outline_atomics, - ), - ), - target_os = "android", - ), + any(target_os = "linux", target_os = "android"), ), ), ))] @@ -470,20 +431,7 @@ pub(crate) use self::atomic128::x86_64::{AtomicI128, AtomicU128}; feature = "fallback", not(portable_atomic_no_outline_atomics), any(test, portable_atomic_outline_atomics), // TODO(riscv): currently disabled by default - any( - all( - target_os = "linux", - any( - target_env = "gnu", - all( - any(target_env = "musl", target_env = "ohos"), - not(target_feature = "crt-static"), - ), - portable_atomic_outline_atomics, - ), - ), - target_os = "android", - ), + any(target_os = "linux", target_os = "android"), not(any(miri, portable_atomic_sanitize_thread)), ), ),