diff --git a/.github/.cspell/project-dictionary.txt b/.github/.cspell/project-dictionary.txt index f5c0a7f28..0ccca448b 100644 --- a/.github/.cspell/project-dictionary.txt +++ b/.github/.cspell/project-dictionary.txt @@ -37,6 +37,7 @@ csrrci csrsi cxchg cxchgweak +dlfcn dlsym DWCAS ecall @@ -128,6 +129,7 @@ revidr rsbegin rsend rsil +RTLD sbcs selgr seqlock diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e1bfb627c..115789578 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -324,12 +324,15 @@ jobs: - run: tools/test.sh -vv ${TARGET:-} ${DOCTEST_XCOMPILE:-} ${BUILD_STD:-} ${RELEASE:-} # We test doctest only once with the default build conditions because doctest is slow. Both api-test # and src/tests have extended copies of doctest, so this will not reduce test coverage. + # portable_atomic_no_outline_atomics only affects x86_64, AArch64, Arm, powerpc64, and RISC-V Linux. + # outline-atomics is disabled by default on AArch64/powerpc64 musl with static linking + # powerpc64le- (little-endian) is skipped because it is pwr8 by default + # RISC-V Linux is skipped because outline-atomics is currently disabled by default on riscv. - run: tools/test.sh -vv --tests ${TARGET:-} ${BUILD_STD:-} ${RELEASE:-} env: RUSTDOCFLAGS: ${{ env.RUSTDOCFLAGS }} --cfg portable_atomic_no_outline_atomics RUSTFLAGS: ${{ env.RUSTFLAGS }} --cfg portable_atomic_no_outline_atomics - # outline-atomics is disabled by default on AArch64 musl with static linking - if: (matrix.target == '' && !contains(matrix.rust, 'i686') || startsWith(matrix.target, 'x86_64')) || startsWith(matrix.target, 'aarch64') && !(contains(matrix.target, '-musl') && matrix.flags == '') || startsWith(matrix.target, 'armv5te') || matrix.target == 'arm-linux-androideabi' + if: (matrix.target == '' && !contains(matrix.rust, 'i686') || startsWith(matrix.target, 'x86_64')) || (startsWith(matrix.target, 'aarch64') || startsWith(matrix.target, 'powerpc64-')) && !(contains(matrix.target, '-musl') && matrix.flags == '') || startsWith(matrix.target, 'armv5te') || matrix.target == 'arm-linux-androideabi' - run: tools/test.sh -vv --tests ${TARGET:-} ${BUILD_STD:-} ${RELEASE:-} env: # Note: detect_false cfg is intended to make it easy for portable-atomic developers to @@ -337,9 +340,13 @@ jobs: # __kuser_helper_version < 5, etc., and is not a public API. RUSTDOCFLAGS: ${{ env.RUSTDOCFLAGS }} --cfg portable_atomic_test_outline_atomics_detect_false RUSTFLAGS: ${{ env.RUSTFLAGS }} --cfg portable_atomic_test_outline_atomics_detect_false - # outline-atomics is disabled by default on AArch64 musl with static linking + # powerpc64 is skipped because tested below. if: (matrix.target == '' && !contains(matrix.rust, 'i686') || startsWith(matrix.target, 'x86_64')) || startsWith(matrix.target, 'aarch64') && !(contains(matrix.target, '-musl') && matrix.flags == '') || startsWith(matrix.target, 'armv5te') || matrix.target == 'arm-linux-androideabi' - # outline-atomics is disabled by default on AArch64 musl with static linking, powerpc64, and RISC-V + - run: tools/test.sh -vv --tests ${TARGET:-} ${BUILD_STD:-} ${RELEASE:-} + env: + QEMU_CPU: power7 # no quadword-atomics + if: startsWith(matrix.target, 'powerpc64-') + # portable_atomic_outline_atomics only affects AArch64 non-glibc-Linux/illumos, powerpc64, and RISC-V Linux. # powerpc64le- (little-endian) is skipped because it is pwr8 by default - run: tools/test.sh -vv --tests ${TARGET:-} ${BUILD_STD:-} ${RELEASE:-} --exclude api-test env: @@ -353,7 +360,8 @@ jobs: # __kuser_helper_version < 5, etc., and is not a public API. RUSTDOCFLAGS: ${{ env.RUSTDOCFLAGS }} --cfg portable_atomic_outline_atomics --cfg portable_atomic_test_outline_atomics_detect_false RUSTFLAGS: ${{ env.RUSTFLAGS }} --cfg portable_atomic_outline_atomics --cfg portable_atomic_test_outline_atomics_detect_false - if: startsWith(matrix.target, 'aarch64') && contains(matrix.target, '-musl') && matrix.flags == '' || startsWith(matrix.target, 'powerpc64-') || startsWith(matrix.target, 'riscv') + # powerpc64 and RISC-V are skipped because tested below. + if: startsWith(matrix.target, 'aarch64') && contains(matrix.target, '-musl') && matrix.flags == '' - run: tools/test.sh -vv --tests ${TARGET:-} ${BUILD_STD:-} ${RELEASE:-} --exclude api-test env: RUSTDOCFLAGS: ${{ env.RUSTDOCFLAGS }} --cfg portable_atomic_outline_atomics @@ -483,6 +491,7 @@ jobs: sync_files: runner-to-vm run: | set -CeEuxo pipefail + export CI=true export RUSTFLAGS="${RUSTFLAGS} --cfg qemu" # AArch64 FreeBSD/NetBSD/OpenBSD are tier 3 targets, so install Rust from package manager instead of rustup. case "$(uname -s)" in diff --git a/README.md b/README.md index 81b44c728..d051a61b9 100644 --- a/README.md +++ b/README.md @@ -170,10 +170,10 @@ RUSTFLAGS="--cfg portable_atomic_no_outline_atomics" cargo ... If dynamic dispatching by run-time CPU feature detection is enabled, it allows maintaining support for older CPUs while using features that are not supported on older CPUs, such as CMPXCHG16B (x86_64) and FEAT_LSE/FEAT_LSE2 (AArch64). Note: - - Dynamic detection is currently only enabled in Rust 1.59+ for x86_64 and AArch64, Rust 1.82+ for RISC-V (disabled by default), nightly only for powerpc64 (disabled by default) and Arm64EC, otherwise it works the same as when this cfg is set. + - Dynamic detection is currently only enabled in Rust 1.59+ for x86_64 and AArch64, Rust 1.82+ for RISC-V (disabled by default), nightly only for powerpc64 and Arm64EC, otherwise it works the same as when this cfg is set. - If the required target features are enabled at compile-time, the atomic operations are inlined. - This is compatible with no-std (as with all features except `std`). - - On some targets, run-time detection is disabled by default mainly for compatibility with older versions of operating systems or incomplete build environments, and can be enabled by `--cfg portable_atomic_outline_atomics`. (When both cfg are enabled, `*_no_*` cfg is preferred.) + - On some targets, run-time detection is disabled by default mainly for incomplete build environments, and can be enabled by `--cfg portable_atomic_outline_atomics`. (When both cfg are enabled, `*_no_*` cfg is preferred.) - Some AArch64 targets enable LLVM's `outline-atomics` target feature by default, so if you set this cfg, you may want to disable that as well. (portable-atomic's outline-atomics does not depend on the compiler-rt symbols, so even if you need to disable LLVM's outline-atomics, you may not need to disable portable-atomic's outline-atomics.) See also the [`atomic128` module's readme](https://github.com/taiki-e/portable-atomic/blob/HEAD/src/imp/atomic128/README.md). diff --git a/src/cfgs.rs b/src/cfgs.rs index 7145ab5e1..e78d2c4ac 100644 --- a/src/cfgs.rs +++ b/src/cfgs.rs @@ -299,14 +299,13 @@ mod atomic_64_macros { all( feature = "fallback", not(portable_atomic_no_outline_atomics), - portable_atomic_outline_atomics, // TODO(powerpc64): currently disabled by default any( all( target_os = "linux", any( target_env = "gnu", all( - any(target_env = "musl", target_env = "ohos"), + any(target_env = "musl", target_env = "ohos", target_env = "uclibc"), not(target_feature = "crt-static"), ), portable_atomic_outline_atomics, @@ -314,7 +313,7 @@ mod atomic_64_macros { ), target_os = "android", target_os = "freebsd", - all(target_os = "openbsd", portable_atomic_outline_atomics), + all(target_os = "openbsd", not(target_feature = "crt-static")), ), not(any(miri, portable_atomic_sanitize_thread)), ), @@ -406,14 +405,13 @@ mod atomic_128_macros { all( feature = "fallback", not(portable_atomic_no_outline_atomics), - portable_atomic_outline_atomics, // TODO(powerpc64): currently disabled by default any( all( target_os = "linux", any( target_env = "gnu", all( - any(target_env = "musl", target_env = "ohos"), + any(target_env = "musl", target_env = "ohos", target_env = "uclibc"), not(target_feature = "crt-static"), ), portable_atomic_outline_atomics, @@ -421,7 +419,7 @@ mod atomic_128_macros { ), target_os = "android", target_os = "freebsd", - all(target_os = "openbsd", portable_atomic_outline_atomics), + all(target_os = "openbsd", not(target_feature = "crt-static")), ), not(any(miri, portable_atomic_sanitize_thread)), ), diff --git a/src/imp/atomic128/README.md b/src/imp/atomic128/README.md index b10abe834..e951ef4e3 100644 --- a/src/imp/atomic128/README.md +++ b/src/imp/atomic128/README.md @@ -11,7 +11,7 @@ Here is the table of targets that support 128-bit atomics and the instructions u | x86_64 | cmpxchg16b or vmovdqa | cmpxchg16b or vmovdqa | cmpxchg16b | cmpxchg16b | cmpxchg16b target feature required. vmovdqa requires Intel, AMD, or Zhaoxin CPU with AVX.
Both compile-time and run-time detection are supported for cmpxchg16b. vmovdqa is currently run-time detection only.
Requires rustc 1.59+ | | aarch64/arm64ec | ldxp/stxp or casp or ldp/ldiapp | ldxp/stxp or casp or stp/stilp/swpp | ldxp/stxp or casp | ldxp/stxp or casp/swpp/ldclrp/ldsetp | casp requires lse target feature, ldp/stp requires lse2 target feature, ldiapp/stilp requires lse2 and rcpc3 target features, swpp/ldclrp/ldsetp requires lse128 target feature.
Both compile-time and run-time detection are supported.
Requires rustc 1.59+ (aarch64) / nightly (arm64ec) | | riscv64 | amocas.q | amocas.q | amocas.q | amocas.q | Experimental because LLVM marking the corresponding target feature as experimental. Requires experimental-zacas target feature. Both compile-time and run-time detection are supported (run-time detection is currently disabled by default).
Requires rustc 1.82+ (LLVM 19+) | -| powerpc64 | lq | stq | lqarx/stqcx. | lqarx/stqcx. | Requires target-cpu pwr8+ (powerpc64le is pwr8 by default). Both compile-time and run-time detection are supported (run-time detection is currently disabled by default).
Requires nightly | +| powerpc64 | lq | stq | lqarx/stqcx. | lqarx/stqcx. | Requires target-cpu pwr8+ (powerpc64le is pwr8 by default). Both compile-time and run-time detection are supported.
Requires nightly | | s390x | lpq | stpq | cdsg | cdsg | Requires nightly | On compiler versions or platforms where these are not supported, the fallback implementation is used. diff --git a/src/imp/atomic128/aarch64.rs b/src/imp/atomic128/aarch64.rs index 14d30aab7..acb1a087f 100644 --- a/src/imp/atomic128/aarch64.rs +++ b/src/imp/atomic128/aarch64.rs @@ -94,7 +94,10 @@ include!("macros.rs"); target_os = "linux", any( target_env = "gnu", - all(any(target_env = "musl", target_env = "ohos"), not(target_feature = "crt-static")), + all( + any(target_env = "musl", target_env = "ohos", target_env = "uclibc"), + not(target_feature = "crt-static"), + ), portable_atomic_outline_atomics, ), ), @@ -177,7 +180,7 @@ macro_rules! debug_assert_lse { any( target_env = "gnu", all( - any(target_env = "musl", target_env = "ohos"), + any(target_env = "musl", target_env = "ohos", target_env = "uclibc"), not(target_feature = "crt-static"), ), portable_atomic_outline_atomics, @@ -214,7 +217,7 @@ macro_rules! debug_assert_lse2 { any( target_env = "gnu", all( - any(target_env = "musl", target_env = "ohos"), + any(target_env = "musl", target_env = "ohos", target_env = "uclibc"), not(target_feature = "crt-static"), ), portable_atomic_outline_atomics, @@ -255,7 +258,7 @@ macro_rules! debug_assert_lse128 { any( target_env = "gnu", all( - any(target_env = "musl", target_env = "ohos"), + any(target_env = "musl", target_env = "ohos", target_env = "uclibc"), not(target_feature = "crt-static"), ), portable_atomic_outline_atomics, @@ -296,7 +299,7 @@ macro_rules! debug_assert_rcpc3 { any( target_env = "gnu", all( - any(target_env = "musl", target_env = "ohos"), + any(target_env = "musl", target_env = "ohos", target_env = "uclibc"), not(target_feature = "crt-static"), ), portable_atomic_outline_atomics, @@ -509,7 +512,7 @@ unsafe fn atomic_load(src: *mut u128, order: Ordering) -> u128 { any( target_env = "gnu", all( - any(target_env = "musl", target_env = "ohos"), + any(target_env = "musl", target_env = "ohos", target_env = "uclibc"), not(target_feature = "crt-static"), ), portable_atomic_outline_atomics, @@ -606,7 +609,7 @@ unsafe fn atomic_load(src: *mut u128, order: Ordering) -> u128 { any( target_env = "gnu", all( - any(target_env = "musl", target_env = "ohos"), + any(target_env = "musl", target_env = "ohos", target_env = "uclibc"), not(target_feature = "crt-static"), ), portable_atomic_outline_atomics, @@ -932,7 +935,7 @@ unsafe fn atomic_store(dst: *mut u128, val: u128, order: Ordering) { any( target_env = "gnu", all( - any(target_env = "musl", target_env = "ohos"), + any(target_env = "musl", target_env = "ohos", target_env = "uclibc"), not(target_feature = "crt-static"), ), portable_atomic_outline_atomics, @@ -1037,7 +1040,7 @@ unsafe fn atomic_store(dst: *mut u128, val: u128, order: Ordering) { any( target_env = "gnu", all( - any(target_env = "musl", target_env = "ohos"), + any(target_env = "musl", target_env = "ohos", target_env = "uclibc"), not(target_feature = "crt-static"), ), portable_atomic_outline_atomics, @@ -1263,7 +1266,7 @@ unsafe fn atomic_compare_exchange( any( target_env = "gnu", all( - any(target_env = "musl", target_env = "ohos"), + any(target_env = "musl", target_env = "ohos", target_env = "uclibc"), not(target_feature = "crt-static"), ), portable_atomic_outline_atomics, @@ -1402,7 +1405,7 @@ unsafe fn atomic_compare_exchange( any( target_env = "gnu", all( - any(target_env = "musl", target_env = "ohos"), + any(target_env = "musl", target_env = "ohos", target_env = "uclibc"), not(target_feature = "crt-static"), ), portable_atomic_outline_atomics, diff --git a/src/imp/atomic128/mod.rs b/src/imp/atomic128/mod.rs index 6c98be2f8..b2b15d01d 100644 --- a/src/imp/atomic128/mod.rs +++ b/src/imp/atomic128/mod.rs @@ -28,14 +28,13 @@ pub(super) mod aarch64; all( feature = "fallback", not(portable_atomic_no_outline_atomics), - any(test, portable_atomic_outline_atomics), // TODO(powerpc64): currently disabled by default any( all( target_os = "linux", any( target_env = "gnu", all( - any(target_env = "musl", target_env = "ohos"), + any(target_env = "musl", target_env = "ohos", target_env = "uclibc"), not(target_feature = "crt-static"), ), portable_atomic_outline_atomics, @@ -43,7 +42,7 @@ pub(super) mod aarch64; ), target_os = "android", target_os = "freebsd", - all(target_os = "openbsd", portable_atomic_outline_atomics), + all(target_os = "openbsd", not(target_feature = "crt-static")), ), not(any(miri, portable_atomic_sanitize_thread)), ), diff --git a/src/imp/atomic128/powerpc64.rs b/src/imp/atomic128/powerpc64.rs index dfca71aec..b96dc340d 100644 --- a/src/imp/atomic128/powerpc64.rs +++ b/src/imp/atomic128/powerpc64.rs @@ -41,7 +41,6 @@ mod fallback; // On musl with static linking, it seems that getauxval 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(powerpc64): currently disabled by default #[cfg(any( test, not(any( @@ -54,13 +53,16 @@ mod fallback; target_os = "linux", any( target_env = "gnu", - all(any(target_env = "musl", target_env = "ohos"), not(target_feature = "crt-static")), + all( + any(target_env = "musl", target_env = "ohos", target_env = "uclibc"), + not(target_feature = "crt-static"), + ), portable_atomic_outline_atomics, ), ), target_os = "android", target_os = "freebsd", - all(target_os = "openbsd", portable_atomic_outline_atomics), + all(target_os = "openbsd", not(target_feature = "crt-static")), ))] #[path = "../detect/auxv.rs"] mod detect; diff --git a/src/imp/detect/README.md b/src/imp/detect/README.md index 77f0e6cf7..998981393 100644 --- a/src/imp/detect/README.md +++ b/src/imp/detect/README.md @@ -7,23 +7,23 @@ Here is the table of targets that support run-time CPU feature detection and the | target_arch | target_os/target_env | instruction/API | features | note | | ----------- | -------------------- | --------------- | -------- | ---- | | x86_64 | all (except for sgx) | cpuid | all | Enabled by default | -| aarch64 | linux | getauxval | all | Only enabled by default on `*-linux-gnu*`, and `*-linux-musl*"` (default is static linking)/`*-linux-ohos*` (default is dynamic linking) with dynamic linking enabled. | +| aarch64 | linux | getauxval | all | Only enabled by default on `*-linux-gnu*` and `*-linux-{musl,ohos,uclibc}*` with dynamic linking enabled (musl is static linking by default). (dlsym is used by default if needed for compatibility with older versions) | | aarch64 | android | getauxval | all | Enabled by default | | aarch64 | freebsd | elf_aux_info | lse, lse2 | Enabled by default | | aarch64 | netbsd | sysctlbyname | all | Enabled by default | | aarch64 | openbsd | sysctl | all | Enabled by default | -| aarch64 | macos/ios/tvos/watchos/visionos | sysctlbyname | all | Currently only used in tests (see [aarch64_apple.rs](aarch64_apple.rs)). | +| aarch64 | macos/ios/tvos/watchos/visionos | sysctlbyname | all | Currently only used in tests (see [aarch64_apple.rs](aarch64_apple.rs)). | | aarch64 | illumos | getisax | lse, lse2 | Disabled by default | -| aarch64/arm64ec | windows | IsProcessorFeaturePresent | lse | Enabled by default | +| aarch64/arm64ec | windows | IsProcessorFeaturePresent | lse | Enabled by default | | aarch64 | fuchsia | zx_system_get_features | lse | Enabled by default | | riscv32/riscv64 | linux/android | riscv_hwprobe | all | Disabled by default | -| powerpc64 | linux | getauxval | all | Disabled by default | -| powerpc64 | freebsd | elf_aux_info | all | Disabled by default | -| powerpc64 | openbsd | elf_aux_info | all | Disabled by default | +| powerpc64 | linux | getauxval | all | Only enabled by default on `*-linux-gnu*` and `*-linux-{musl,ohos,uclibc}*` with dynamic linking enabled (musl is static linking by default). (dlsym is used by default if needed for compatibility with older versions) | +| powerpc64 | freebsd | elf_aux_info | all | Enabled by default (dlsym is used by default for compatibility with older versions) | +| powerpc64 | openbsd | elf_aux_info | all | Enabled by default (dlsym is used by default for compatibility with older versions) | Run-time detection is enabled by default on most targets and can be disabled with `--cfg portable_atomic_no_outline_atomics`. -On some targets, run-time detection is disabled by default mainly for compatibility with older versions of operating systems or incomplete build environments, and can be enabled by `--cfg portable_atomic_outline_atomics`. (When both cfg are enabled, `*_no_*` cfg is preferred.) +On some targets, run-time detection is disabled by default mainly for incomplete build environments, and can be enabled by `--cfg portable_atomic_outline_atomics`. (When both cfg are enabled, `*_no_*` cfg is preferred.) For targets not included in the above table, run-time detection is always disabled and works the same as when `--cfg portable_atomic_no_outline_atomics` is set. diff --git a/src/imp/detect/auxv.rs b/src/imp/detect/auxv.rs index 680aaa05f..2f18ec354 100644 --- a/src/imp/detect/auxv.rs +++ b/src/imp/detect/auxv.rs @@ -26,11 +26,15 @@ Supported platforms: Since Rust 1.71, std requires musl 1.2.3+ https://blog.rust-lang.org/2023/05/09/Updating-musl-targets.html - uClibc-ng 1.0.43+ (through getauxval) https://github.com/wbx-github/uclibc-ng/commit/d869bb1600942c01a77539128f9ba5b5b55ad647 + Not always available on: + - aarch64 (uClibc-ng 1.0.22+ https://github.com/wbx-github/uclibc-ng/commit/dba942c80dc2cfa5768a856fff98e22a755fdd27) + ([powerpc64 is not supported](https://github.com/wbx-github/uclibc-ng/commit/d4d4f37fda7fa57e57132ff2f0d735ce7cc2178e)) - Picolibc 1.4.6+ (through getauxval) https://github.com/picolibc/picolibc/commit/19bfe51d62ad7e32533c7f664b5bca8e26286e31 - Android 4.3+ (API level 18+) (through getauxval) https://github.com/aosp-mirror/platform_bionic/blob/d3ebc2f7c49a9893b114124d4a6b315f3a328764/libc/include/sys/auxv.h#L49 - Always available on 64-bit architectures, which is supported on Android 5.0+ (API level 21+) https://android-developers.googleblog.com/2014/10/whats-new-in-android-50-lollipop.html + Always available on: + - 64-bit architectures (Android 5.0+ (API level 21+) https://android-developers.googleblog.com/2014/10/whats-new-in-android-50-lollipop.html) - FreeBSD 12.0+ and 11.4+ (through elf_aux_info) https://github.com/freebsd/freebsd-src/commit/0b08ae2120cdd08c20a2b806e2fcef4d0a36c470 https://github.com/freebsd/freebsd-src/blob/release/11.4.0/sys/sys/auxv.h @@ -40,33 +44,33 @@ Supported platforms: Since Rust 1.75, std requires FreeBSD 12+ https://github.com/rust-lang/rust/pull/114521 - OpenBSD 7.6+ (through elf_aux_info) https://github.com/openbsd/src/commit/ef873df06dac50249b2dd380dc6100eee3b0d23d + Not always available on: + - aarch64 (OpenBSD 6.1+ https://www.openbsd.org/61.html) + - powerpc64 (OpenBSD 6.8+ https://www.openbsd.org/68.html) -# Linux/Android - -As of Rust 1.69, is_aarch64_feature_detected always uses dlsym by default -on AArch64 Linux/Android, but on the following platforms, we can safely assume -getauxval is linked to the binary. - -- On glibc (*-linux-gnu*), [AArch64 support is available on glibc 2.17+](https://github.com/bminor/glibc/blob/glibc-2.17/NEWS#L35) -- On musl (*-linux-musl*, *-linux-ohos*), [AArch64 support is available on musl 1.1.7+](https://github.com/bminor/musl/blob/v1.1.7/WHATSNEW#L1422) -- 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) +On platforms that we can assume that getauxval/elf_aux_info is always available, we directly call +them on except for musl with static linking. (At this time, we also retain compatibility with +versions that reached EoL or no longer supported by `std`, with the exception of AArch64 FreeBSD described below.) -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 +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 other Linux targets, we cannot assume that getauxval is always available, so we don't enable -run-time detection by default (can be enabled by `--cfg portable_atomic_outline_atomics`). +On platforms that we cannot assume that getauxval/elf_aux_info is always available, so we use dlsym +instead of directly calling getauxval/elf_aux_info. (You can force getauxval/elf_aux_info to be +called directly instead of using dlsym by `--cfg portable_atomic_outline_atomics`). -- musl with static linking. See the above for more. - Also, dlsym(getauxval) always returns null when statically linked. -- uClibc-ng (*-linux-uclibc*, *-l4re-uclibc*). getauxval was recently added (See the above list). -- Picolibc. getauxval was recently added (See the above list). +# Linux/Android + +As of Rust 1.69, is_aarch64_feature_detected always uses dlsym by default +on AArch64 Linux/Android, but on some platforms, we can safely assume +getauxval is linked to the binary (see the above). See also https://github.com/rust-lang/stdarch/pull/1375 -See tests::test_linux_like and aarch64_aa64reg.rs for (test-only) alternative implementations. +See tests::test_alternative and aarch64_aa64reg.rs for (test-only) alternative implementations. # FreeBSD @@ -85,7 +89,7 @@ but FreeBSD 11 (11.4) was EoL on 2021-09-30, and FreeBSD 11.3 was EoL on 2020-09 https://www.freebsd.org/security/unsupported See also https://github.com/rust-lang/stdarch/pull/611#issuecomment-445464613 -See tests::test_freebsd and aarch64_aa64reg.rs for (test-only) alternative implementations. +See tests::test_alternative and aarch64_aa64reg.rs for (test-only) alternative implementations. # OpenBSD @@ -95,17 +99,6 @@ https://github.com/openbsd/src/commit/ef873df06dac50249b2dd380dc6100eee3b0d23d On AArch64, there is an alternative that available on older version, so we use it (see aarch64_aa64reg.rs). -# PowerPC64 - -On PowerPC64, run-time detection is currently disabled by default mainly for -compatibility with older versions of operating systems -(can be enabled by `--cfg portable_atomic_outline_atomics`). - -- On glibc, [powerpc64 support is available on glibc 2.3+](https://github.com/bminor/glibc/blob/glibc-2.3/NEWS#L55) -- On musl, [powerpc64 support is available on musl 1.1.15+](https://github.com/bminor/musl/blob/v1.1.15/WHATSNEW#L1702) -- On FreeBSD, [powerpc64 support is available on FreeBSD 9.0+](https://www.freebsd.org/releases/9.0R/announce) - -(On uClibc-ng, [powerpc64 is not supported](https://github.com/wbx-github/uclibc-ng/commit/d4d4f37fda7fa57e57132ff2f0d735ce7cc2178e)) */ include!("common.rs"); @@ -116,9 +109,42 @@ mod os { // core::ffi::c_* (except c_void) requires Rust 1.64, libc 1.0 plans to require Rust 1.63 #[cfg_attr(test, allow(dead_code))] pub(super) mod ffi { - pub(crate) use super::super::c_types::c_ulong; + #[cfg(any( + test, + all(target_arch = "aarch64", target_os = "android"), + not(any( + all( + target_os = "linux", + any( + all(target_env = "gnu", target_arch = "aarch64"), + target_env = "musl", + target_env = "ohos", + ), + ), + all(target_os = "android", target_pointer_width = "64"), + portable_atomic_outline_atomics, + )), + ))] + pub(crate) use super::super::c_types::c_char; #[cfg(all(target_arch = "aarch64", target_os = "android"))] - pub(crate) use super::super::c_types::{c_char, c_int}; + pub(crate) use super::super::c_types::c_int; + pub(crate) use super::super::c_types::c_ulong; + #[cfg(any( + test, + not(any( + all( + target_os = "linux", + any( + all(target_env = "gnu", target_arch = "aarch64"), + target_env = "musl", + target_env = "ohos", + ), + ), + all(target_os = "android", target_pointer_width = "64"), + portable_atomic_outline_atomics, + )), + ))] + pub(crate) use super::super::c_types::c_void; sys_const!({ // https://github.com/torvalds/linux/blob/v6.11/include/uapi/linux/auxvec.h @@ -131,6 +157,28 @@ mod os { ))] pub(crate) const AT_HWCAP2: c_ulong = 26; + // Defined in dlfcn.h. + // https://github.com/bminor/glibc/blob/glibc-2.40/dlfcn/dlfcn.h + // https://github.com/bminor/musl/blob/v1.2.5/include/dlfcn.h + // https://github.com/wbx-github/uclibc-ng/blob/v1.0.47/include/dlfcn.h + // https://github.com/aosp-mirror/platform_bionic/blob/d3ebc2f7c49a9893b114124d4a6b315f3a328764/libc/include/dlfcn.h + #[cfg(any( + test, + not(any( + all( + target_os = "linux", + any( + all(target_env = "gnu", target_arch = "aarch64"), + target_env = "musl", + target_env = "ohos", + ), + ), + all(target_os = "android", target_pointer_width = "64"), + portable_atomic_outline_atomics, + )), + ))] + pub(crate) const RTLD_DEFAULT: *mut c_void = core::ptr::null_mut(); + // Defined in sys/system_properties.h. // https://github.com/aosp-mirror/platform_bionic/blob/d3ebc2f7c49a9893b114124d4a6b315f3a328764/libc/include/sys/system_properties.h #[cfg(all(target_arch = "aarch64", target_os = "android"))] @@ -146,8 +194,44 @@ mod os { // https://github.com/wbx-github/uclibc-ng/blob/v1.0.47/include/sys/auxv.h // https://github.com/aosp-mirror/platform_bionic/blob/d3ebc2f7c49a9893b114124d4a6b315f3a328764/libc/include/sys/auxv.h // https://github.com/picolibc/picolibc/blob/1.8.6/newlib/libc/include/sys/auxv.h + #[cfg(any( + test, + all( + target_os = "linux", + any( + all(target_env = "gnu", target_arch = "aarch64"), + target_env = "musl", + target_env = "ohos", + ), + ), + all(target_os = "android", target_pointer_width = "64"), + portable_atomic_outline_atomics, + ))] pub(crate) fn getauxval(type_: c_ulong) -> c_ulong; + // Defined in dlfcn.h. + // https://man7.org/linux/man-pages/man3/dlsym.3.html + // https://github.com/bminor/glibc/blob/glibc-2.40/dlfcn/dlfcn.h + // https://github.com/bminor/musl/blob/v1.2.5/include/dlfcn.h + // https://github.com/wbx-github/uclibc-ng/blob/v1.0.47/include/dlfcn.h + // https://github.com/aosp-mirror/platform_bionic/blob/d3ebc2f7c49a9893b114124d4a6b315f3a328764/libc/include/dlfcn.h + #[cfg(any( + test, + not(any( + all( + target_os = "linux", + any( + all(target_env = "gnu", target_arch = "aarch64"), + target_env = "musl", + target_env = "ohos", + ), + ), + all(target_os = "android", target_pointer_width = "64"), + portable_atomic_outline_atomics, + )), + ))] + pub(crate) fn dlsym(handle: *mut c_void, symbol: *const c_char) -> *mut c_void; + // Defined in sys/system_properties.h. // https://github.com/aosp-mirror/platform_bionic/blob/d3ebc2f7c49a9893b114124d4a6b315f3a328764/libc/include/sys/system_properties.h #[cfg(all(target_arch = "aarch64", target_os = "android"))] @@ -159,6 +243,7 @@ mod os { }); } + pub(super) type GetauxvalTy = unsafe extern "C" fn(ffi::c_ulong) -> ffi::c_ulong; pub(super) fn getauxval(type_: ffi::c_ulong) -> ffi::c_ulong { #[cfg(all(target_arch = "aarch64", target_os = "android"))] { @@ -181,8 +266,43 @@ mod os { } } - // SAFETY: `getauxval` is thread-safe. See also the module level docs. - unsafe { ffi::getauxval(type_) } + #[cfg(any( + all( + target_os = "linux", + any( + all(target_env = "gnu", target_arch = "aarch64"), + target_env = "musl", + target_env = "ohos", + ), + ), + all(target_os = "android", target_pointer_width = "64"), + portable_atomic_outline_atomics, + ))] + let getauxval: GetauxvalTy = ffi::getauxval; + #[cfg(not(any( + all( + target_os = "linux", + any( + all(target_env = "gnu", target_arch = "aarch64"), + target_env = "musl", + target_env = "ohos", + ), + ), + all(target_os = "android", target_pointer_width = "64"), + portable_atomic_outline_atomics, + )))] + // SAFETY: we passed a valid C string to dlsym, and a pointer returned by dlsym + // is a valid pointer to the function if it is non-null. + let getauxval: GetauxvalTy = unsafe { + let ptr = ffi::dlsym(ffi::RTLD_DEFAULT, "getauxval\0".as_ptr().cast::()); + if ptr.is_null() { + return 0; + } + core::mem::transmute::<*mut ffi::c_void, GetauxvalTy>(ptr) + }; + + // SAFETY: `getauxval` is thread-safe. + unsafe { getauxval(type_) } } } #[cfg(any(target_os = "freebsd", target_os = "openbsd"))] @@ -192,6 +312,14 @@ mod os { // core::ffi::c_* (except c_void) requires Rust 1.64, libc 1.0 plans to require Rust 1.63 #[cfg_attr(test, allow(dead_code))] pub(super) mod ffi { + #[cfg(any( + test, + not(any( + all(target_os = "freebsd", target_arch = "aarch64"), + portable_atomic_outline_atomics, + )), + ))] + pub(crate) use super::super::c_types::c_char; pub(crate) use super::super::c_types::{c_int, c_ulong, c_void}; sys_const!({ @@ -205,6 +333,24 @@ mod os { pub(crate) const AT_HWCAP: c_int = 25; #[cfg(any(test, target_arch = "powerpc64"))] pub(crate) const AT_HWCAP2: c_int = 26; + + // FreeBSD + // Defined in dlfcn.h. + // https://man.freebsd.org/dlsym(3) + // https://github.com/freebsd/freebsd-src/blob/release/14.1.0/include/dlfcn.h + // OpenBSD + // Defined in dlfcn.h. + // https://man.openbsd.org/dlsym.3 + // https://github.com/openbsd/src/blob/ed8f5e8d82ace15e4cefca2c82941b15cb1a7830/include/dlfcn.h + #[cfg(any( + test, + not(any( + all(target_os = "freebsd", target_arch = "aarch64"), + portable_atomic_outline_atomics, + )), + ))] + #[allow(clippy::cast_sign_loss)] + pub(crate) const RTLD_DEFAULT: *mut c_void = -2_isize as usize as *mut c_void; }); sys_fn!({ @@ -217,28 +363,71 @@ mod os { // Defined in sys/auxv.h. // https://man.openbsd.org/elf_aux_info.3 // https://github.com/openbsd/src/blob/ed8f5e8d82ace15e4cefca2c82941b15cb1a7830/sys/sys/auxv.h + #[cfg(any( + test, + any( + all(target_os = "freebsd", target_arch = "aarch64"), + portable_atomic_outline_atomics, + ), + ))] pub(crate) fn elf_aux_info(aux: c_int, buf: *mut c_void, buf_len: c_int) -> c_int; + + // FreeBSD + // Defined in dlfcn.h. + // https://man.freebsd.org/dlsym(3) + // https://github.com/freebsd/freebsd-src/blob/release/14.1.0/include/dlfcn.h + // OpenBSD + // Defined in dlfcn.h. + // https://man.openbsd.org/dlsym.3 + // https://github.com/openbsd/src/blob/ed8f5e8d82ace15e4cefca2c82941b15cb1a7830/include/dlfcn.h + #[cfg(any( + test, + not(any( + all(target_os = "freebsd", target_arch = "aarch64"), + portable_atomic_outline_atomics, + )), + ))] + pub(crate) fn dlsym(handle: *mut c_void, symbol: *const c_char) -> *mut c_void; } }); } + pub(super) type ElfAuxInfoTy = + unsafe extern "C" fn(ffi::c_int, *mut ffi::c_void, ffi::c_int) -> ffi::c_int; pub(super) fn getauxval(aux: ffi::c_int) -> ffi::c_ulong { #[allow(clippy::cast_possible_wrap, clippy::cast_possible_truncation)] const OUT_LEN: ffi::c_int = mem::size_of::() as ffi::c_int; + + #[cfg(any( + all(target_os = "freebsd", target_arch = "aarch64"), + portable_atomic_outline_atomics, + ))] + let elf_aux_info: ElfAuxInfoTy = ffi::elf_aux_info; + #[cfg(not(any( + all(target_os = "freebsd", target_arch = "aarch64"), + portable_atomic_outline_atomics, + )))] + // SAFETY: we passed a valid C string to dlsym, and a pointer returned by dlsym + // is a valid pointer to the function if it is non-null. + let elf_aux_info: ElfAuxInfoTy = unsafe { + let ptr = + ffi::dlsym(ffi::RTLD_DEFAULT, "elf_aux_info\0".as_ptr().cast::()); + if ptr.is_null() { + return 0; + } + mem::transmute::<*mut ffi::c_void, ElfAuxInfoTy>(ptr) + }; + let mut out: ffi::c_ulong = 0; // SAFETY: // - the pointer is valid because we got it from a reference. // - `OUT_LEN` is the same as the size of `out`. // - `elf_aux_info` is thread-safe. - unsafe { - let res = ffi::elf_aux_info( - aux, - (&mut out as *mut ffi::c_ulong).cast::(), - OUT_LEN, - ); - // If elf_aux_info fails, `out` will be left at zero (which is the proper default value). - debug_assert!(res == 0 || out == 0); - } + let res = unsafe { + elf_aux_info(aux, (&mut out as *mut ffi::c_ulong).cast::(), OUT_LEN) + }; + // If elf_aux_info fails, `out` will be left at zero (which is the proper default value). + debug_assert!(res == 0 || out == 0); out } } @@ -377,12 +566,8 @@ mod arch { )] #[cfg(test)] mod tests { - #[cfg(not(target_os = "openbsd"))] - #[cfg(not(all( - target_os = "linux", - target_arch = "aarch64", - target_pointer_width = "32", - )))] + use std::mem; + use super::*; #[allow(clippy::cast_sign_loss)] @@ -406,6 +591,84 @@ mod tests { } } + #[cfg(any(target_os = "linux", target_os = "android"))] + #[test] + fn test_dlsym_getauxval() { + unsafe { + let ptr = ffi::dlsym(ffi::RTLD_DEFAULT, "getauxval\0".as_ptr().cast::()); + if cfg!(any( + all( + target_os = "linux", + any( + target_env = "gnu", + all( + any(target_env = "musl", target_env = "ohos"), + not(target_feature = "crt-static"), + ), + ), + ), + target_os = "android", + )) { + assert!(!ptr.is_null()); + } else if option_env!("CI").is_some() { + assert!(ptr.is_null()); + } + if ptr.is_null() { + return; + } + let dlsym_getauxval = mem::transmute::<*mut ffi::c_void, os::GetauxvalTy>(ptr); + assert_eq!(dlsym_getauxval(ffi::AT_HWCAP), ffi::getauxval(ffi::AT_HWCAP)); + assert_eq!(dlsym_getauxval(ffi::AT_HWCAP2), ffi::getauxval(ffi::AT_HWCAP2)); + } + } + #[cfg(any(target_os = "freebsd", target_os = "openbsd"))] + #[test] + fn test_dlsym_elf_aux_info() { + unsafe { + let ptr = + ffi::dlsym(ffi::RTLD_DEFAULT, "elf_aux_info\0".as_ptr().cast::()); + if cfg!(target_os = "freebsd") || option_env!("CI").is_some() { + assert!(!ptr.is_null()); + } + if ptr.is_null() { + return; + } + let dlsym_elf_aux_info = mem::transmute::<*mut ffi::c_void, os::ElfAuxInfoTy>(ptr); + let mut out: ffi::c_ulong = 0; + let mut dlsym_out: ffi::c_ulong = 0; + #[allow(clippy::cast_possible_wrap, clippy::cast_possible_truncation)] + let out_len = mem::size_of::() as ffi::c_int; + assert_eq!( + ffi::elf_aux_info( + ffi::AT_HWCAP, + (&mut out as *mut ffi::c_ulong).cast::(), + out_len, + ), + dlsym_elf_aux_info( + ffi::AT_HWCAP, + (&mut dlsym_out as *mut ffi::c_ulong).cast::(), + out_len, + ), + ); + assert_eq!(out, dlsym_out); + out = 0; + dlsym_out = 0; + assert_eq!( + ffi::elf_aux_info( + ffi::AT_HWCAP2, + (&mut out as *mut ffi::c_ulong).cast::(), + out_len, + ), + dlsym_elf_aux_info( + ffi::AT_HWCAP2, + (&mut dlsym_out as *mut ffi::c_ulong).cast::(), + out_len, + ), + ); + assert_eq!(out, dlsym_out); + } + } + #[cfg(any(target_os = "linux", target_os = "android"))] #[cfg(not(all(target_arch = "aarch64", target_pointer_width = "32")))] #[test] @@ -413,7 +676,7 @@ mod tests { use c_types::*; #[cfg(not(portable_atomic_no_asm))] use std::arch::asm; - use std::{mem, str, vec}; + use std::{str, vec}; #[cfg(target_pointer_width = "32")] use sys::Elf32_auxv_t as Elf_auxv_t; #[cfg(target_pointer_width = "64")] @@ -582,7 +845,7 @@ mod tests { use c_types::*; #[cfg(not(portable_atomic_no_asm))] use std::arch::asm; - use std::{mem, ptr}; + use std::ptr; use test_helper::sys; // This is almost equivalent to what elf_aux_info does. diff --git a/src/imp/detect/common.rs b/src/imp/detect/common.rs index 028471a4a..600cac00b 100644 --- a/src/imp/detect/common.rs +++ b/src/imp/detect/common.rs @@ -149,6 +149,7 @@ mod c_types { // See also https://github.com/taiki-e/test-helper/blob/HEAD/tools/codegen/src/ffi.rs. #[cfg(test)] #[allow( + unused_attributes, // for #[allow(..)] in $(#[$attr])* clippy::cast_possible_wrap, clippy::cast_sign_loss, clippy::cast_possible_truncation, @@ -156,11 +157,29 @@ mod c_types { const _: fn() = || { $( $(#[$attr])* - static_assert!($name == test_helper::sys::$name as $ty); + sys_const_cmp!($name, $ty); )* }; }; } + #[cfg(test)] + macro_rules! sys_const_cmp { + (RTLD_DEFAULT, $ty:ty) => { + // ptr comparison and ptr-to-int cast are not stable on const context, so use ptr-to-int + // transmute and compare its result. + static_assert!( + // SAFETY: Pointer-to-integer transmutes are valid (since we are okay with losing the + // provenance here). (Same as ::addr().) + unsafe { + core::mem::transmute::<$ty, usize>(RTLD_DEFAULT) + == core::mem::transmute::<$ty, usize>(test_helper::sys::RTLD_DEFAULT) + } + ); + }; + ($name:ident, $ty:ty) => { + static_assert!($name == test_helper::sys::$name as $ty); + }; + } /// Defines functions with #[cfg(test)] static assertions which checks /// signatures are the same as the platform's latest header files' ones. // Note: This macro is sys_fn!({ }), not sys_fn! { }. diff --git a/src/imp/fallback/mod.rs b/src/imp/fallback/mod.rs index d7314f8b1..913bf293a 100644 --- a/src/imp/fallback/mod.rs +++ b/src/imp/fallback/mod.rs @@ -24,14 +24,13 @@ type and the value type must be the same. target_arch = "powerpc64", feature = "fallback", not(portable_atomic_no_outline_atomics), - portable_atomic_outline_atomics, // TODO(powerpc64): currently disabled by default any( all( target_os = "linux", any( target_env = "gnu", all( - any(target_env = "musl", target_env = "ohos"), + any(target_env = "musl", target_env = "ohos", target_env = "uclibc"), not(target_feature = "crt-static"), ), portable_atomic_outline_atomics, @@ -39,7 +38,7 @@ type and the value type must be the same. ), target_os = "android", target_os = "freebsd", - all(target_os = "openbsd", portable_atomic_outline_atomics), + all(target_os = "openbsd", not(target_feature = "crt-static")), ), not(any(miri, portable_atomic_sanitize_thread)), ), diff --git a/src/imp/mod.rs b/src/imp/mod.rs index 0bc3208be..0761a3fbf 100644 --- a/src/imp/mod.rs +++ b/src/imp/mod.rs @@ -342,14 +342,13 @@ items! { all( feature = "fallback", not(portable_atomic_no_outline_atomics), - portable_atomic_outline_atomics, // TODO(powerpc64): currently disabled by default any( all( target_os = "linux", any( target_env = "gnu", all( - any(target_env = "musl", target_env = "ohos"), + any(target_env = "musl", target_env = "ohos", target_env = "uclibc"), not(target_feature = "crt-static"), ), portable_atomic_outline_atomics, @@ -357,7 +356,7 @@ items! { ), target_os = "android", target_os = "freebsd", - all(target_os = "openbsd", portable_atomic_outline_atomics), + all(target_os = "openbsd", not(target_feature = "crt-static")), ), not(any(miri, portable_atomic_sanitize_thread)), ), @@ -452,14 +451,13 @@ pub(crate) use self::atomic128::riscv64::{AtomicI128, AtomicU128}; all( feature = "fallback", not(portable_atomic_no_outline_atomics), - portable_atomic_outline_atomics, // TODO(powerpc64): currently disabled by default any( all( target_os = "linux", any( target_env = "gnu", all( - any(target_env = "musl", target_env = "ohos"), + any(target_env = "musl", target_env = "ohos", target_env = "uclibc"), not(target_feature = "crt-static"), ), portable_atomic_outline_atomics, @@ -467,7 +465,7 @@ pub(crate) use self::atomic128::riscv64::{AtomicI128, AtomicU128}; ), target_os = "android", target_os = "freebsd", - all(target_os = "openbsd", portable_atomic_outline_atomics), + all(target_os = "openbsd", not(target_feature = "crt-static")), ), not(any(miri, portable_atomic_sanitize_thread)), ), diff --git a/src/lib.rs b/src/lib.rs index 08e78bc50..7fc10538b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -164,10 +164,10 @@ RUSTFLAGS="--cfg portable_atomic_no_outline_atomics" cargo ... If dynamic dispatching by run-time CPU feature detection is enabled, it allows maintaining support for older CPUs while using features that are not supported on older CPUs, such as CMPXCHG16B (x86_64) and FEAT_LSE/FEAT_LSE2 (AArch64). Note: - - Dynamic detection is currently only enabled in Rust 1.59+ for x86_64 and AArch64, Rust 1.82+ for RISC-V (disabled by default), nightly only for powerpc64 (disabled by default) and Arm64EC, otherwise it works the same as when this cfg is set. + - Dynamic detection is currently only enabled in Rust 1.59+ for x86_64 and AArch64, Rust 1.82+ for RISC-V (disabled by default), nightly only for powerpc64 and Arm64EC, otherwise it works the same as when this cfg is set. - If the required target features are enabled at compile-time, the atomic operations are inlined. - This is compatible with no-std (as with all features except `std`). - - On some targets, run-time detection is disabled by default mainly for compatibility with older versions of operating systems or incomplete build environments, and can be enabled by `--cfg portable_atomic_outline_atomics`. (When both cfg are enabled, `*_no_*` cfg is preferred.) + - On some targets, run-time detection is disabled by default mainly for incomplete build environments, and can be enabled by `--cfg portable_atomic_outline_atomics`. (When both cfg are enabled, `*_no_*` cfg is preferred.) - Some AArch64 targets enable LLVM's `outline-atomics` target feature by default, so if you set this cfg, you may want to disable that as well. (portable-atomic's outline-atomics does not depend on the compiler-rt symbols, so even if you need to disable LLVM's outline-atomics, you may not need to disable portable-atomic's outline-atomics.) See also the [`atomic128` module's readme](https://github.com/taiki-e/portable-atomic/blob/HEAD/src/imp/atomic128/README.md). diff --git a/tools/build.sh b/tools/build.sh index 2654549b4..2e7f5bb44 100755 --- a/tools/build.sh +++ b/tools/build.sh @@ -386,7 +386,7 @@ build() { --tests --features "${test_features}" --ignore-unknown-features - --workspace --exclude bench --exclude portable-atomic-internal-codegen + --workspace --exclude bench ) elif [[ -n "${TARGET_GROUP:-}" ]]; then case "${target}" in @@ -528,18 +528,22 @@ build() { x_cargo "${args[@]}" "$@" # Check {,no-}outline-atomics case "${target}" in - # portable_atomic_no_outline_atomics only affects x86_64, aarch64, arm, and powerpc64. - # powerpc64 is skipped because outline-atomics is currently disabled by default on powerpc64. - x86_64* | aarch64* | arm*) + # portable_atomic_no_outline_atomics only affects x86_64, AArch64, Arm, powerpc64, and RISC-V Linux. + # outline-atomics is disabled by default on AArch64/powerpc64 musl with static linking + # powerpc64le- (little-endian) is skipped because it is pwr8 by default + # RISC-V Linux is skipped because outline-atomics is currently disabled by default on riscv. + aarch64*-linux-musl* | powerpc64-*-linux-musl*) ;; + x86_64* | aarch64* | arm* | powerpc64-*) CARGO_TARGET_DIR="${target_dir}/no-outline-atomics" \ RUSTFLAGS="${target_rustflags} --cfg portable_atomic_no_outline_atomics" \ x_cargo "${args[@]}" "$@" ;; esac case "${target}" in - # portable_atomic_outline_atomics only affects aarch64 Linux/illumos and powerpc64. + # portable_atomic_outline_atomics only affects AArch64 non-glibc-Linux/illumos, powerpc64, and RISC-V Linux. # powerpc64le- (little-endian) is skipped because it is pwr8 by default - aarch64*-linux-* | aarch64*-illumos* | powerpc64-*) + aarch64*-linux-gnu*) ;; + aarch64*-linux-* | aarch64*-illumos* | powerpc64-* | riscv*-linux-*) CARGO_TARGET_DIR="${target_dir}/outline-atomics" \ RUSTFLAGS="${target_rustflags} --cfg portable_atomic_outline_atomics" \ x_cargo "${args[@]}" "$@" @@ -556,9 +560,10 @@ build() { RUSTFLAGS="${target_rustflags} -C target_feature=-crt-static" \ x_cargo "${args[@]}" "$@" case "${target}" in - # portable_atomic_no_outline_atomics only affects x86_64, aarch64, arm, and powerpc64. - # powerpc64 is skipped because outline-atomics is currently disabled by default on powerpc64. - x86_64* | aarch64* | arm*) + # portable_atomic_no_outline_atomics only affects x86_64, AArch64, Arm, powerpc64, and RISC-V Linux. + # powerpc64le- (little-endian) is skipped because it is pwr8 by default + # RISC-V Linux is skipped because its implementation does not change depending on whether or not crt-static is enabled. + x86_64* | aarch64* | arm* | powerpc64-*) CARGO_TARGET_DIR="${target_dir}/no-crt-static-no-outline-atomics" \ RUSTFLAGS="${target_rustflags} -C target_feature=-crt-static --cfg portable_atomic_no_outline_atomics" \ x_cargo "${args[@]}" "$@" diff --git a/tools/test.sh b/tools/test.sh index 2a5da70ca..69e883448 100755 --- a/tools/test.sh +++ b/tools/test.sh @@ -194,7 +194,7 @@ else fi case "${cmd}" in build) ;; - *) args+=(--workspace --exclude bench --exclude portable-atomic-internal-codegen) ;; + *) args+=(--workspace --exclude bench) ;; esac target="${target:-"${host}"}" target_lower="${target//-/_}"