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//-/_}"