diff --git a/.cirrus.yml b/.cirrus.yml index efbb7701..b934e82b 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -12,11 +12,11 @@ env: RUSTFLAGS: -D warnings RUSTUP_MAX_RETRIES: '10' -aarch64_linux_test_task: +aarch64_linux_gnu_test_task: + env: + TARGET: aarch64-unknown-linux-gnu matrix: - name: test ($TARGET) - env: - TARGET: aarch64-unknown-linux-gnu arm_container: image: rust:latest setup_script: @@ -24,8 +24,6 @@ aarch64_linux_test_task: - lscpu - rustup toolchain add nightly --no-self-update --component rust-src && rustup default nightly - name: test ($TARGET, glibc 2.17) - env: - TARGET: aarch64-unknown-linux-gnu arm_container: # glibc 2.17 is the minimum glibc version that aarch64 support is available: https://sourceware.org/legacy-ml/libc-announce/2012/msg00001.html image: centos:7 @@ -34,16 +32,6 @@ aarch64_linux_test_task: - lscpu - yum install -y gcc git - curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal --default-toolchain nightly --component rust-src - - name: test ($TARGET) - env: - TARGET: aarch64-unknown-linux-musl - arm_container: - image: rust:alpine - setup_script: - - set -ex - - apk --no-cache add bash git musl-dev util-linux - - lscpu - - rustup toolchain add nightly --no-self-update --component rust-src && rustup default nightly test_script: - | [ ! -f $HOME/.cargo/env ] || . $HOME/.cargo/env @@ -54,6 +42,27 @@ aarch64_linux_test_task: # FEAT_LSE2 is tested on aarch64 macOS VM. - RUSTFLAGS="$RUSTFLAGS -C target-feature=+lse" RUSTDOCFLAGS="$RUSTDOCFLAGS -C target-feature=+lse" ./tools/test.sh -vv +aarch64_linux_musl_test_task: + name: test ($TARGET) + env: + TARGET: aarch64-unknown-linux-musl + arm_container: + image: rust:alpine + setup_script: + - set -ex + - apk --no-cache add bash git musl-dev util-linux + - lscpu + - rustup toolchain add nightly --no-self-update --component rust-src && rustup default nightly + test_script: + - set -ex + - ./tools/test.sh -vv + # -crt-static + - RUSTFLAGS="$RUSTFLAGS -C target-feature=-crt-static" RUSTDOCFLAGS="$RUSTDOCFLAGS -C target-feature=-crt-static" ./tools/test.sh -vv + # +lse + # Graviton2 (Neoverse N1) is ARMv8.2-a and doesn't support FEAT_LSE2. + # FEAT_LSE2 is tested on aarch64 macOS VM. + - RUSTFLAGS="$RUSTFLAGS -C target-feature=+lse" RUSTDOCFLAGS="$RUSTDOCFLAGS -C target-feature=+lse" ./tools/test.sh -vv + armel_linux_test_task: name: test ($TARGET) env: diff --git a/.github/.cspell/organization-dictionary.txt b/.github/.cspell/organization-dictionary.txt index b9ff7bda..b7e0b1c6 100644 --- a/.github/.cspell/organization-dictionary.txt +++ b/.github/.cspell/organization-dictionary.txt @@ -61,6 +61,7 @@ musleabi musleabihf newlibeabihf nvptx +ohos openwrt riscv softfloat diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 57d954b7..db93e0eb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -166,6 +166,12 @@ jobs: if: startsWith(matrix.rust, 'nightly') && !startsWith(matrix.os, 'windows') - run: tools/test.sh -vv $TARGET $DOCTEST_XCOMPILE $BUILD_STD + # -crt-static + - run: tools/test.sh -vv $TARGET $DOCTEST_XCOMPILE $BUILD_STD + env: + RUSTDOCFLAGS: ${{ env.RUSTDOCFLAGS }} -C target-feature=-crt-static + RUSTFLAGS: ${{ env.RUSTFLAGS }} -C target-feature=-crt-static + if: contains(matrix.target, '-musl') # +cmpxchg16b # macOS is skipped because it is +cmpxchg16b by default - run: tools/test.sh -vv $TARGET $DOCTEST_XCOMPILE $BUILD_STD diff --git a/src/imp/atomic128/README.md b/src/imp/atomic128/README.md index fb8578f5..de084c5d 100644 --- a/src/imp/atomic128/README.md +++ b/src/imp/atomic128/README.md @@ -26,11 +26,12 @@ Here is the table of targets that support run-time feature detection and the ins | target_arch | target_os/target_env | instruction/API | | ----------- | -------------------- | --------------- | | x86_64 | all (except for sgx) | cpuid | -| aarch64 | linux-gnu/android | getauxval | -| aarch64 | other linux | dlsym(getauxval) (via is_aarch64_feature_detected) | +| aarch64 | linux/android | getauxval | | aarch64 | freebsd | elf_aux_info | | aarch64 | macos/openbsd | sysctl | | aarch64 | windows | IsProcessorFeaturePresent | | aarch64 | fuchsia | zx_system_get_features | For targets not included in the above table, run-time detections are disabled and work the same as when `--cfg portable_atomic_no_outline_atomics` is set. + +See [detect/aarch64_auxv.rs](detect/aarch64_auxv.rs) module-level comments for more details on Linux/Android/FreeBSD. diff --git a/src/imp/atomic128/aarch64.rs b/src/imp/atomic128/aarch64.rs index 1be068c0..0df81e20 100644 --- a/src/imp/atomic128/aarch64.rs +++ b/src/imp/atomic128/aarch64.rs @@ -52,9 +52,17 @@ include!("macros.rs"); +// On musl with static linking, it seems that getauxval is not always available. +// See detect/aarch64_auxv.rs for more. #[cfg(not(portable_atomic_no_outline_atomics))] #[cfg(any( - all(target_os = "linux", target_env = "gnu"), + all( + target_os = "linux", + any( + target_env = "gnu", + all(any(target_env = "musl", target_env = "ohos"), not(target_feature = "crt-static")), + ), + ), target_os = "android", target_os = "freebsd", ))] @@ -72,10 +80,6 @@ mod detect; #[cfg(target_os = "windows")] #[path = "detect/aarch64_windows.rs"] mod detect; -#[cfg(not(portable_atomic_no_outline_atomics))] -#[cfg(all(target_os = "linux", not(target_env = "gnu")))] -#[path = "detect/aarch64_std.rs"] -mod detect; // test only #[cfg(test)] @@ -310,7 +314,16 @@ unsafe fn atomic_compare_exchange( not(portable_atomic_no_aarch64_target_feature), not(portable_atomic_no_outline_atomics), any( - target_os = "linux", + all( + target_os = "linux", + any( + target_env = "gnu", + all( + any(target_env = "musl", target_env = "ohos"), + not(target_feature = "crt-static"), + ), + ), + ), target_os = "android", target_os = "freebsd", target_os = "openbsd", @@ -325,7 +338,16 @@ unsafe fn atomic_compare_exchange( not(portable_atomic_no_aarch64_target_feature), not(portable_atomic_no_outline_atomics), any( - target_os = "linux", + all( + target_os = "linux", + any( + target_env = "gnu", + all( + any(target_env = "musl", target_env = "ohos"), + not(target_feature = "crt-static"), + ), + ), + ), target_os = "android", target_os = "freebsd", target_os = "openbsd", diff --git a/src/imp/atomic128/detect/aarch64_auxv.rs b/src/imp/atomic128/detect/aarch64_auxv.rs index c2fbca63..d80fb18c 100644 --- a/src/imp/atomic128/detect/aarch64_auxv.rs +++ b/src/imp/atomic128/detect/aarch64_auxv.rs @@ -8,20 +8,23 @@ // // - On glibc (*-linux-gnu*), [aarch64 support is available on glibc 2.17+](https://sourceware.org/legacy-ml/libc-announce/2012/msg00001.html) // and is newer than [glibc 2.16 that added getauxval](https://sourceware.org/legacy-ml/libc-announce/2012/msg00000.html). +// - On musl (*-linux-musl*, *-linux-ohos*), [aarch64 support is available on musl 1.1.7+](https://git.musl-libc.org/cgit/musl/tree/WHATSNEW?h=v1.1.7#n1422) +// and is newer than [musl 1.1.0 that added getauxval](https://git.musl-libc.org/cgit/musl/tree/WHATSNEW?h=v1.1.0#n1197). +// https://github.com/rust-lang/rust/commit/9a04ae4997493e9260352064163285cddc43de3c // - On bionic (*-android*), [64-bit architecture support is available on Android 5.0+ (API level 21+)](https://android-developers.googleblog.com/2014/10/whats-new-in-android-50-lollipop.html) // and is newer 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). // -// On other Linux targets, we cannot assume that getauxval is always available, -// so we use is_aarch64_feature_detected which uses dlsym (+io fallback) instead -// of this module. +// However, on musl with static linking, it seems that getauxval is not always available, independent of version requirements: https://github.com/rust-lang/rust/issues/89626 +// (That problem may have been fixed in https://github.com/rust-lang/rust/commit/9a04ae4997493e9260352064163285cddc43de3c, +// but even in the version containing that patch, [there is report](https://github.com/rust-lang/rust/issues/89626#issuecomment-1242636038) +// of the same error.) // -// - On musl (*-linux-musl*), [aarch64 support is available on musl 1.1.7+](https://git.musl-libc.org/cgit/musl/tree/WHATSNEW?h=v1.1.7#n1422) -// and is newer than [musl 1.1.0 that added getauxval](https://git.musl-libc.org/cgit/musl/tree/WHATSNEW?h=v1.1.0#n1197). -// However, it seems that getauxval is not always available, independent of version requirements: https://github.com/rust-lang/rust/issues/89626 -// (That problem may have been fixed in https://github.com/rust-lang/rust/commit/9a04ae4997493e9260352064163285cddc43de3c, -// but even in the version containing that patch, [there is report](https://github.com/rust-lang/rust/issues/89626#issuecomment-1242636038) -// of the same error.) -// - On uClibc-ng (*-linux-uclibc*), they [recently added getauxval](https://repo.or.cz/uclibc-ng.git/commitdiff/d869bb1600942c01a77539128f9ba5b5b55ad647) +// On other Linux targets, we cannot assume that getauxval is always available, so we don't support +// outline-atomics for now. +// +// - On musl with static linking. See the above for more. +// Also, in this case, dlsym(getauxval) always returns null. +// - On uClibc-ng (*-linux-uclibc*, *-l4re-uclibc*), they [recently added getauxval](https://repo.or.cz/uclibc-ng.git/commitdiff/d869bb1600942c01a77539128f9ba5b5b55ad647) // but have not released it yet (as of 2023-02-09). // - On Picolibc, [Picolibc 1.4.6 added getauxval stub](https://github.com/picolibc/picolibc#picolibc-version-146). // diff --git a/src/imp/atomic128/detect/aarch64_std.rs b/src/imp/atomic128/detect/aarch64_std.rs deleted file mode 100644 index 98df8f55..00000000 --- a/src/imp/atomic128/detect/aarch64_std.rs +++ /dev/null @@ -1,38 +0,0 @@ -#![cfg_attr( - any( - portable_atomic_no_aarch64_target_feature, - any(target_feature = "lse", portable_atomic_target_feature = "lse"), - ), - allow(dead_code) -)] - -#[inline] -pub(crate) fn has_lse() -> bool { - #[cfg(any(target_feature = "lse", portable_atomic_target_feature = "lse"))] - { - // FEAT_LSE is statically available. - true - } - #[cfg(not(any(target_feature = "lse", portable_atomic_target_feature = "lse")))] - #[allow(unreachable_code)] - { - #[cfg(all( - not(any( - portable_atomic_no_aarch64_target_feature, - portable_atomic_unstable_aarch64_target_feature, - )), - // https://github.com/rust-lang/stdarch/blob/a0c30f3e3c75adcd6ee7efc94014ebcead61c507/crates/std_detect/src/detect/mod.rs - // It is fine to use std for targets that we know can be linked to std. - // Note: std may not be available on tier 3 such as aarch64 FreeBSD/OpenBSD. - any( - feature = "std", - all(target_os = "linux", any(target_env = "gnu", target_env = "musl")), - ), - ))] - { - extern crate std; - return std::arch::is_aarch64_feature_detected!("lse"); - } - false - } -} diff --git a/tests/helper/src/gen/sys/aarch64_linux_musl/arch_arm64_include_uapi_asm_hwcap.rs b/tests/helper/src/gen/sys/aarch64_linux_musl/arch_arm64_include_uapi_asm_hwcap.rs new file mode 100644 index 00000000..e35cc62c --- /dev/null +++ b/tests/helper/src/gen/sys/aarch64_linux_musl/arch_arm64_include_uapi_asm_hwcap.rs @@ -0,0 +1,79 @@ +// This file is @generated by portable-atomic-internal-codegen +// (gen function at tools/codegen/src/ffi.rs). +// It is not intended for manual editing. + +pub const HWCAP_FP: u32 = 1; +pub const HWCAP_ASIMD: u32 = 2; +pub const HWCAP_EVTSTRM: u32 = 4; +pub const HWCAP_AES: u32 = 8; +pub const HWCAP_PMULL: u32 = 16; +pub const HWCAP_SHA1: u32 = 32; +pub const HWCAP_SHA2: u32 = 64; +pub const HWCAP_CRC32: u32 = 128; +pub const HWCAP_ATOMICS: u32 = 256; +pub const HWCAP_FPHP: u32 = 512; +pub const HWCAP_ASIMDHP: u32 = 1024; +pub const HWCAP_CPUID: u32 = 2048; +pub const HWCAP_ASIMDRDM: u32 = 4096; +pub const HWCAP_JSCVT: u32 = 8192; +pub const HWCAP_FCMA: u32 = 16384; +pub const HWCAP_LRCPC: u32 = 32768; +pub const HWCAP_DCPOP: u32 = 65536; +pub const HWCAP_SHA3: u32 = 131072; +pub const HWCAP_SM3: u32 = 262144; +pub const HWCAP_SM4: u32 = 524288; +pub const HWCAP_ASIMDDP: u32 = 1048576; +pub const HWCAP_SHA512: u32 = 2097152; +pub const HWCAP_SVE: u32 = 4194304; +pub const HWCAP_ASIMDFHM: u32 = 8388608; +pub const HWCAP_DIT: u32 = 16777216; +pub const HWCAP_USCAT: u32 = 33554432; +pub const HWCAP_ILRCPC: u32 = 67108864; +pub const HWCAP_FLAGM: u32 = 134217728; +pub const HWCAP_SSBS: u32 = 268435456; +pub const HWCAP_SB: u32 = 536870912; +pub const HWCAP_PACA: u32 = 1073741824; +pub const HWCAP_PACG: u32 = 2147483648; +pub const HWCAP2_DCPODP: u32 = 1; +pub const HWCAP2_SVE2: u32 = 2; +pub const HWCAP2_SVEAES: u32 = 4; +pub const HWCAP2_SVEPMULL: u32 = 8; +pub const HWCAP2_SVEBITPERM: u32 = 16; +pub const HWCAP2_SVESHA3: u32 = 32; +pub const HWCAP2_SVESM4: u32 = 64; +pub const HWCAP2_FLAGM2: u32 = 128; +pub const HWCAP2_FRINT: u32 = 256; +pub const HWCAP2_SVEI8MM: u32 = 512; +pub const HWCAP2_SVEF32MM: u32 = 1024; +pub const HWCAP2_SVEF64MM: u32 = 2048; +pub const HWCAP2_SVEBF16: u32 = 4096; +pub const HWCAP2_I8MM: u32 = 8192; +pub const HWCAP2_BF16: u32 = 16384; +pub const HWCAP2_DGH: u32 = 32768; +pub const HWCAP2_RNG: u32 = 65536; +pub const HWCAP2_BTI: u32 = 131072; +pub const HWCAP2_MTE: u32 = 262144; +pub const HWCAP2_ECV: u32 = 524288; +pub const HWCAP2_AFP: u32 = 1048576; +pub const HWCAP2_RPRES: u32 = 2097152; +pub const HWCAP2_MTE3: u32 = 4194304; +pub const HWCAP2_SME: u32 = 8388608; +pub const HWCAP2_SME_I16I64: u32 = 16777216; +pub const HWCAP2_SME_F64F64: u32 = 33554432; +pub const HWCAP2_SME_I8I32: u32 = 67108864; +pub const HWCAP2_SME_F16F32: u32 = 134217728; +pub const HWCAP2_SME_B16F32: u32 = 268435456; +pub const HWCAP2_SME_F32F32: u32 = 536870912; +pub const HWCAP2_SME_FA64: u32 = 1073741824; +pub const HWCAP2_WFXT: u32 = 2147483648; +pub const HWCAP2_EBF16: u64 = 4294967296; +pub const HWCAP2_SVE_EBF16: u64 = 8589934592; +pub const HWCAP2_CSSC: u64 = 17179869184; +pub const HWCAP2_RPRFM: u64 = 34359738368; +pub const HWCAP2_SVE2P1: u64 = 68719476736; +pub const HWCAP2_SME2: u64 = 137438953472; +pub const HWCAP2_SME2P1: u64 = 274877906944; +pub const HWCAP2_SME_I16I32: u64 = 549755813888; +pub const HWCAP2_SME_BI32I32: u64 = 1099511627776; +pub const HWCAP2_SME_B16B16: u64 = 2199023255552; +pub const HWCAP2_SME_F16F16: u64 = 4398046511104; diff --git a/tests/helper/src/gen/sys/aarch64_linux_musl/include_uapi_linux_auxvec.rs b/tests/helper/src/gen/sys/aarch64_linux_musl/include_uapi_linux_auxvec.rs new file mode 100644 index 00000000..2acda4c7 --- /dev/null +++ b/tests/helper/src/gen/sys/aarch64_linux_musl/include_uapi_linux_auxvec.rs @@ -0,0 +1,6 @@ +// This file is @generated by portable-atomic-internal-codegen +// (gen function at tools/codegen/src/ffi.rs). +// It is not intended for manual editing. + +pub const AT_HWCAP: u32 = 16; +pub const AT_HWCAP2: u32 = 26; diff --git a/tests/helper/src/gen/sys/aarch64_linux_musl/mod.rs b/tests/helper/src/gen/sys/aarch64_linux_musl/mod.rs new file mode 100644 index 00000000..bc00abf1 --- /dev/null +++ b/tests/helper/src/gen/sys/aarch64_linux_musl/mod.rs @@ -0,0 +1,24 @@ +// This file is @generated by portable-atomic-internal-codegen +// (gen function at tools/codegen/src/ffi.rs). +// It is not intended for manual editing. + +#![cfg_attr(rustfmt, rustfmt::skip)] +mod include_uapi_linux_auxvec; +pub use include_uapi_linux_auxvec::{AT_HWCAP, AT_HWCAP2}; +mod arch_arm64_include_uapi_asm_hwcap; +pub use arch_arm64_include_uapi_asm_hwcap::{ + HWCAP2_AFP, HWCAP2_BF16, HWCAP2_BTI, HWCAP2_CSSC, HWCAP2_DCPODP, HWCAP2_DGH, + HWCAP2_EBF16, HWCAP2_ECV, HWCAP2_FLAGM2, HWCAP2_FRINT, HWCAP2_I8MM, HWCAP2_MTE, + HWCAP2_MTE3, HWCAP2_RNG, HWCAP2_RPRES, HWCAP2_RPRFM, HWCAP2_SME, HWCAP2_SME2, + HWCAP2_SME2P1, HWCAP2_SME_B16B16, HWCAP2_SME_B16F32, HWCAP2_SME_BI32I32, + HWCAP2_SME_F16F16, HWCAP2_SME_F16F32, HWCAP2_SME_F32F32, HWCAP2_SME_F64F64, + HWCAP2_SME_FA64, HWCAP2_SME_I16I32, HWCAP2_SME_I16I64, HWCAP2_SME_I8I32, HWCAP2_SVE2, + HWCAP2_SVE2P1, HWCAP2_SVEAES, HWCAP2_SVEBF16, HWCAP2_SVEBITPERM, HWCAP2_SVEF32MM, + HWCAP2_SVEF64MM, HWCAP2_SVEI8MM, HWCAP2_SVEPMULL, HWCAP2_SVESHA3, HWCAP2_SVESM4, + HWCAP2_SVE_EBF16, HWCAP2_WFXT, HWCAP_AES, HWCAP_ASIMD, HWCAP_ASIMDDP, HWCAP_ASIMDFHM, + HWCAP_ASIMDHP, HWCAP_ASIMDRDM, HWCAP_ATOMICS, HWCAP_CPUID, HWCAP_CRC32, HWCAP_DCPOP, + HWCAP_DIT, HWCAP_EVTSTRM, HWCAP_FCMA, HWCAP_FLAGM, HWCAP_FP, HWCAP_FPHP, + HWCAP_ILRCPC, HWCAP_JSCVT, HWCAP_LRCPC, HWCAP_PACA, HWCAP_PACG, HWCAP_PMULL, + HWCAP_SB, HWCAP_SHA1, HWCAP_SHA2, HWCAP_SHA3, HWCAP_SHA512, HWCAP_SM3, HWCAP_SM4, + HWCAP_SSBS, HWCAP_SVE, HWCAP_USCAT, +}; diff --git a/tests/helper/src/gen/sys/mod.rs b/tests/helper/src/gen/sys/mod.rs index 69eec625..9a2f0e5b 100644 --- a/tests/helper/src/gen/sys/mod.rs +++ b/tests/helper/src/gen/sys/mod.rs @@ -46,6 +46,24 @@ mod aarch64_linux_gnu_ilp32; ) )] pub use aarch64_linux_gnu_ilp32::*; +#[cfg( + all( + target_arch = "aarch64", + target_os = "linux", + target_env = "musl", + target_pointer_width = "64" + ) +)] +mod aarch64_linux_musl; +#[cfg( + all( + target_arch = "aarch64", + target_os = "linux", + target_env = "musl", + target_pointer_width = "64" + ) +)] +pub use aarch64_linux_musl::*; #[cfg(all(target_arch = "aarch64", target_os = "android"))] mod aarch64_linux_android; #[cfg(all(target_arch = "aarch64", target_os = "android"))] diff --git a/tools/build.sh b/tools/build.sh index 3e245625..3bac9614 100755 --- a/tools/build.sh +++ b/tools/build.sh @@ -383,6 +383,14 @@ build() { x_cargo "${args[@]}" "$@" ;; esac + case "${target}" in + mips*-linux-musl*) ;; # -crt-static by default + *-linux-musl*) + CARGO_TARGET_DIR="${target_dir}/no-crt-static" \ + RUSTFLAGS="${target_rustflags} -C target_feature=-crt-static" \ + x_cargo "${args[@]}" "$@" + ;; + esac case "${target}" in x86_64*) # macOS is skipped because it is +cmpxchg16b by default diff --git a/tools/codegen/src/ffi.rs b/tools/codegen/src/ffi.rs index 5095dda7..a70eab05 100644 --- a/tools/codegen/src/ffi.rs +++ b/tools/codegen/src/ffi.rs @@ -28,6 +28,7 @@ static TARGETS: &[Target] = &[ triples: &[ "aarch64-unknown-linux-gnu", "aarch64-unknown-linux-gnu_ilp32", + "aarch64-unknown-linux-musl", "aarch64-linux-android", ], headers: &[