Skip to content

Commit

Permalink
Merge #69
Browse files Browse the repository at this point in the history
69: detect: Avoid dlsym on aarch64 android r=taiki-e a=taiki-e

Follow-up #67 

On Android, [64-bit architecture support is available on Android 5.0+ (API level 21+)](https://android-developers.googleblog.com/2014/10/whats-new-in-android-50-lollipop.html) and is newer than [Android 4.3 (API level 18) that getauxval was added](https://android.googlesource.com/platform/bionic/+/refs/heads/master/libc/include/sys/auxv.h#49), so we can safely assume getauxval is linked to the binary.

Co-authored-by: Taiki Endo <[email protected]>
  • Loading branch information
bors[bot] and taiki-e authored Feb 4, 2023
2 parents 5c54cfb + 692283f commit 6e943cb
Show file tree
Hide file tree
Showing 10 changed files with 92 additions and 33 deletions.
61 changes: 40 additions & 21 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ jobs:
uses: taiki-e/workflows/.github/workflows/tidy.yml@main

test:
env:
cargo: cargo
strategy:
fail-fast: false
matrix:
Expand All @@ -67,6 +69,14 @@ jobs:
target: aarch64-unknown-linux-gnu
- rust: nightly
target: aarch64_be-unknown-linux-gnu
- rust: stable
target: aarch64-unknown-linux-musl
- rust: nightly
target: aarch64-unknown-linux-musl
- rust: stable
target: aarch64-linux-android
- rust: nightly
target: aarch64-linux-android
- rust: nightly
target: arm-unknown-linux-gnueabi
- rust: nightly
Expand Down Expand Up @@ -121,7 +131,14 @@ jobs:
- uses: taiki-e/setup-cross-toolchain-action@v1
with:
target: ${{ matrix.target }}
if: matrix.target != ''
if: matrix.target != '' && !(contains(matrix.target, '-musl') || contains(matrix.target, '-android'))
- uses: taiki-e/install-action@cross
if: contains(matrix.target, '-musl') || contains(matrix.target, '-android')
- run: echo "cargo=cross" >>"${GITHUB_ENV}"
if: contains(matrix.target, '-musl') || contains(matrix.target, '-android')
# Workaround https://github.com/cross-rs/cross/issues/1128 / https://github.com/rust-lang/rust/issues/103673
- run: echo "BUILD_STD=-Z build-std" >>"${GITHUB_ENV}"
if: startsWith(matrix.rust, 'nightly') && contains(matrix.target, '-android')
- run: echo "RUSTFLAGS=${RUSTFLAGS} --cfg qemu" >>"${GITHUB_ENV}"
if: matrix.target != '' && !startsWith(matrix.target, 'i686') && !startsWith(matrix.target, 'x86_64')
- run: echo "TARGET=--target=${{ matrix.target }}" >>"${GITHUB_ENV}"
Expand All @@ -130,33 +147,33 @@ jobs:
- run: echo "RANDOMIZE_LAYOUT=-Z randomize-layout" >>"${GITHUB_ENV}"
if: startsWith(matrix.rust, 'nightly') && !startsWith(matrix.os, 'windows')

- run: cargo test -vv --workspace --all-features $EXCLUDE $TARGET $DOCTEST_XCOMPILE $BUILD_STD
- run: cargo test -vv --workspace --all-features --release $EXCLUDE $TARGET $DOCTEST_XCOMPILE $BUILD_STD
- run: $cargo test -vv --workspace --all-features $EXCLUDE $TARGET $DOCTEST_XCOMPILE $BUILD_STD
- run: $cargo test -vv --workspace --all-features --release $EXCLUDE $TARGET $DOCTEST_XCOMPILE $BUILD_STD
# LTO + doctests is very slow on some platforms
- run: cargo test -vv --workspace --all-features --release --tests $EXCLUDE $TARGET $DOCTEST_XCOMPILE $BUILD_STD
- run: $cargo test -vv --workspace --all-features --release --tests $EXCLUDE $TARGET $DOCTEST_XCOMPILE $BUILD_STD
env:
CARGO_PROFILE_RELEASE_CODEGEN_UNITS: 1
CARGO_PROFILE_RELEASE_LTO: fat
- run: cargo careful test -vv --workspace --all-features $EXCLUDE $TARGET $DOCTEST_XCOMPILE
env:
RUSTDOCFLAGS: ${{ env.RUSTDOCFLAGS }} ${{ env.RANDOMIZE_LAYOUT }}
RUSTFLAGS: ${{ env.RUSTFLAGS }} ${{ env.RANDOMIZE_LAYOUT }}
if: startsWith(matrix.rust, 'nightly')
if: startsWith(matrix.rust, 'nightly') && !(contains(matrix.target, '-musl') || contains(matrix.target, '-android'))

# +cmpxchg16b
# macOS is skipped because it is +cmpxchg16b by default
- run: cargo test -vv --workspace --all-features $EXCLUDE $TARGET $DOCTEST_XCOMPILE $BUILD_STD
- run: $cargo test -vv --workspace --all-features $EXCLUDE $TARGET $DOCTEST_XCOMPILE $BUILD_STD
env:
RUSTDOCFLAGS: ${{ env.RUSTDOCFLAGS }} -C target-feature=+cmpxchg16b
RUSTFLAGS: ${{ env.RUSTFLAGS }} -C target-feature=+cmpxchg16b
if: (matrix.target == '' || startsWith(matrix.target, 'x86_64')) && !startsWith(matrix.os, 'macos')
- run: cargo test -vv --workspace --all-features --release $EXCLUDE $TARGET $DOCTEST_XCOMPILE $BUILD_STD
- run: $cargo test -vv --workspace --all-features --release $EXCLUDE $TARGET $DOCTEST_XCOMPILE $BUILD_STD
env:
RUSTDOCFLAGS: ${{ env.RUSTDOCFLAGS }} -C target-feature=+cmpxchg16b
RUSTFLAGS: ${{ env.RUSTFLAGS }} -C target-feature=+cmpxchg16b
if: (matrix.target == '' || startsWith(matrix.target, 'x86_64')) && !startsWith(matrix.os, 'macos')
# LTO + doctests is very slow on some platforms
- run: cargo test -vv --workspace --all-features --release --tests $EXCLUDE $TARGET $DOCTEST_XCOMPILE $BUILD_STD
- run: $cargo test -vv --workspace --all-features --release --tests $EXCLUDE $TARGET $DOCTEST_XCOMPILE $BUILD_STD
env:
CARGO_PROFILE_RELEASE_CODEGEN_UNITS: 1
CARGO_PROFILE_RELEASE_LTO: fat
Expand All @@ -167,21 +184,21 @@ jobs:
env:
RUSTDOCFLAGS: ${{ env.RUSTDOCFLAGS }} -C target-feature=+cmpxchg16b ${{ env.RANDOMIZE_LAYOUT }}
RUSTFLAGS: ${{ env.RUSTFLAGS }} -C target-feature=+cmpxchg16b ${{ env.RANDOMIZE_LAYOUT }}
if: (matrix.target == '' || startsWith(matrix.target, 'x86_64')) && !startsWith(matrix.os, 'macos') && startsWith(matrix.rust, 'nightly')
if: (matrix.target == '' || startsWith(matrix.target, 'x86_64')) && !startsWith(matrix.os, 'macos') && startsWith(matrix.rust, 'nightly') && !(contains(matrix.target, '-musl') || contains(matrix.target, '-android'))

# +lse
- run: cargo test -vv --workspace --all-features $EXCLUDE $TARGET $DOCTEST_XCOMPILE $BUILD_STD
- run: $cargo test -vv --workspace --all-features $EXCLUDE $TARGET $DOCTEST_XCOMPILE $BUILD_STD
env:
RUSTDOCFLAGS: ${{ env.RUSTDOCFLAGS }} -C target-feature=+lse
RUSTFLAGS: ${{ env.RUSTFLAGS }} -C target-feature=+lse
if: startsWith(matrix.target, 'aarch64')
- run: cargo test -vv --workspace --all-features --release $EXCLUDE $TARGET $DOCTEST_XCOMPILE $BUILD_STD
- run: $cargo test -vv --workspace --all-features --release $EXCLUDE $TARGET $DOCTEST_XCOMPILE $BUILD_STD
env:
RUSTDOCFLAGS: ${{ env.RUSTDOCFLAGS }} -C target-feature=+lse
RUSTFLAGS: ${{ env.RUSTFLAGS }} -C target-feature=+lse
if: startsWith(matrix.target, 'aarch64')
# LTO + doctests is very slow on some platforms
- run: cargo test -vv --workspace --all-features --release --tests $EXCLUDE $TARGET $DOCTEST_XCOMPILE $BUILD_STD
- run: $cargo test -vv --workspace --all-features --release --tests $EXCLUDE $TARGET $DOCTEST_XCOMPILE $BUILD_STD
env:
CARGO_PROFILE_RELEASE_CODEGEN_UNITS: 1
CARGO_PROFILE_RELEASE_LTO: fat
Expand All @@ -192,23 +209,23 @@ jobs:
env:
RUSTDOCFLAGS: ${{ env.RUSTDOCFLAGS }} -C target-feature=+lse ${{ env.RANDOMIZE_LAYOUT }}
RUSTFLAGS: ${{ env.RUSTFLAGS }} -C target-feature=+lse ${{ env.RANDOMIZE_LAYOUT }}
if: startsWith(matrix.target, 'aarch64') && startsWith(matrix.rust, 'nightly')
if: startsWith(matrix.target, 'aarch64') && startsWith(matrix.rust, 'nightly') && !(contains(matrix.target, '-musl') || contains(matrix.target, '-android'))
# TODO: it seems qemu-user has not yet properly implemented FEAT_LSE2: https://github.com/taiki-e/portable-atomic/pull/11#issuecomment-1114044327

# pwr7
# powerpc64- (big-endian) is skipped because it is pre-pwr8 by default
- run: cargo test -vv --workspace --all-features $EXCLUDE $TARGET $DOCTEST_XCOMPILE $BUILD_STD
- run: $cargo test -vv --workspace --all-features $EXCLUDE $TARGET $DOCTEST_XCOMPILE $BUILD_STD
env:
RUSTDOCFLAGS: ${{ env.RUSTDOCFLAGS }} -C target-cpu=pwr7
RUSTFLAGS: ${{ env.RUSTFLAGS }} -C target-cpu=pwr7
if: startsWith(matrix.target, 'powerpc64le-')
- run: cargo test -vv --workspace --all-features --release $EXCLUDE $TARGET $DOCTEST_XCOMPILE $BUILD_STD
- run: $cargo test -vv --workspace --all-features --release $EXCLUDE $TARGET $DOCTEST_XCOMPILE $BUILD_STD
env:
RUSTDOCFLAGS: ${{ env.RUSTDOCFLAGS }} -C target-cpu=pwr7
RUSTFLAGS: ${{ env.RUSTFLAGS }} -C target-cpu=pwr7
if: startsWith(matrix.target, 'powerpc64le-')
# LTO + doctests is very slow on some platforms
- run: cargo test -vv --workspace --all-features --release --tests $EXCLUDE $TARGET $DOCTEST_XCOMPILE $BUILD_STD
- run: $cargo test -vv --workspace --all-features --release --tests $EXCLUDE $TARGET $DOCTEST_XCOMPILE $BUILD_STD
env:
CARGO_PROFILE_RELEASE_CODEGEN_UNITS: 1
CARGO_PROFILE_RELEASE_LTO: fat
Expand All @@ -219,22 +236,22 @@ jobs:
env:
RUSTDOCFLAGS: ${{ env.RUSTDOCFLAGS }} -C target-cpu=pwr7 ${{ env.RANDOMIZE_LAYOUT }}
RUSTFLAGS: ${{ env.RUSTFLAGS }} -C target-cpu=pwr7 ${{ env.RANDOMIZE_LAYOUT }}
if: startsWith(matrix.target, 'powerpc64le-') && startsWith(matrix.rust, 'nightly')
if: startsWith(matrix.target, 'powerpc64le-') && startsWith(matrix.rust, 'nightly') && !(contains(matrix.target, '-musl') || contains(matrix.target, '-android'))

# pwr8
# powerpc64le- (little-endian) is skipped because it is pwr8 by default
- run: cargo test -vv --workspace --all-features $EXCLUDE $TARGET $DOCTEST_XCOMPILE $BUILD_STD
- run: $cargo test -vv --workspace --all-features $EXCLUDE $TARGET $DOCTEST_XCOMPILE $BUILD_STD
env:
RUSTDOCFLAGS: ${{ env.RUSTDOCFLAGS }} -C target-cpu=pwr8
RUSTFLAGS: ${{ env.RUSTFLAGS }} -C target-cpu=pwr8
if: startsWith(matrix.target, 'powerpc64-')
- run: cargo test -vv --workspace --all-features --release $EXCLUDE $TARGET $DOCTEST_XCOMPILE $BUILD_STD
- run: $cargo test -vv --workspace --all-features --release $EXCLUDE $TARGET $DOCTEST_XCOMPILE $BUILD_STD
env:
RUSTDOCFLAGS: ${{ env.RUSTDOCFLAGS }} -C target-cpu=pwr8
RUSTFLAGS: ${{ env.RUSTFLAGS }} -C target-cpu=pwr8
if: startsWith(matrix.target, 'powerpc64-')
# LTO + doctests is very slow on some platforms
- run: cargo test -vv --workspace --all-features --release --tests $EXCLUDE $TARGET $DOCTEST_XCOMPILE $BUILD_STD
- run: $cargo test -vv --workspace --all-features --release --tests $EXCLUDE $TARGET $DOCTEST_XCOMPILE $BUILD_STD
env:
CARGO_PROFILE_RELEASE_CODEGEN_UNITS: 1
CARGO_PROFILE_RELEASE_LTO: fat
Expand All @@ -245,9 +262,11 @@ jobs:
env:
RUSTDOCFLAGS: ${{ env.RUSTDOCFLAGS }} -C target-cpu=pwr8 ${{ env.RANDOMIZE_LAYOUT }}
RUSTFLAGS: ${{ env.RUSTFLAGS }} -C target-cpu=pwr8 ${{ env.RANDOMIZE_LAYOUT }}
if: startsWith(matrix.target, 'powerpc64-') && startsWith(matrix.rust, 'nightly')
if: startsWith(matrix.target, 'powerpc64-') && startsWith(matrix.rust, 'nightly') && !(contains(matrix.target, '-musl') || contains(matrix.target, '-android'))

- run: cargo minimal-versions build -vvv --workspace --all-features --ignore-private $TARGET $BUILD_STD
# We set BUILD_STD due to https://github.com/cross-rs/cross/issues/1128 / https://github.com/rust-lang/rust/issues/103673
if: "!(startsWith(matrix.rust, 'nightly') && contains(matrix.target, '-android'))"

build:
name: build (${{ matrix.rust }}${{ matrix.tests && ', --tests' }})
Expand Down
15 changes: 15 additions & 0 deletions Cross.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[build.env]
passthrough = [
"CARGO_INCREMENTAL",
"CARGO_NET_GIT_FETCH_WITH_CLI",
"CARGO_NET_RETRY",
"CARGO_PROFILE_RELEASE_CODEGEN_UNITS",
"CARGO_PROFILE_RELEASE_LTO",
"CARGO_TERM_COLOR",
"CI",
"RUST_BACKTRACE",
"RUST_TEST_THREADS",
"RUSTDOCFLAGS",
"RUSTFLAGS",
"RUSTUP_MAX_RETRIES",
]
3 changes: 2 additions & 1 deletion src/imp/atomic128/aarch64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,15 @@
include!("macros.rs");

#[cfg_attr(
all(target_os = "linux", target_env = "gnu"),
any(all(target_os = "linux", target_env = "gnu"), target_os = "android"),
path = "detect/aarch64_linux_getauxval.rs"
)]
#[cfg_attr(target_os = "windows", path = "detect/aarch64_windows.rs")]
#[cfg_attr(any(target_os = "freebsd", target_os = "openbsd"), path = "detect/aarch64_aa64reg.rs")]
#[cfg_attr(
not(any(
all(target_os = "linux", target_env = "gnu"),
target_os = "android",
target_os = "windows",
target_os = "freebsd",
target_os = "openbsd"
Expand Down
17 changes: 11 additions & 6 deletions src/imp/atomic128/detect/aarch64_linux_getauxval.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
// Run-time feature detection on aarch64 Linux by using getauxval.
// Run-time feature detection on aarch64 Linux/Android by using getauxval.
//
// As of nightly-2023-01-23, is_aarch64_feature_detected always uses dlsym by default
// on aarch64 linux, but on linux-gnu [aarch64 support is available on glibc 2.17+](https://sourceware.org/legacy-ml/libc-announce/2012/msg00001.html)
// and is newer than [glibc 2.16 that getauxval was added](https://sourceware.org/legacy-ml/libc-announce/2012/msg00000.html),
// so we can safely assume getauxval is linked to the binary.
// https://github.com/rust-lang/stdarch/pull/1375
// on aarch64 Linux/Android, but on the following platforms, so we can safely assume getauxval
// is linked to the binary.
//
// On other linux targets, we cannot assume that getauxval is always available yet
// - On linux-gnu, [aarch64 support is available on glibc 2.17+](https://sourceware.org/legacy-ml/libc-announce/2012/msg00001.html)
// and is newer than [glibc 2.16 that getauxval was added](https://sourceware.org/legacy-ml/libc-announce/2012/msg00000.html).
// - On Android, [64-bit architecture support is available on Android 5.0+ (API level 21+)](https://android-developers.googleblog.com/2014/10/whats-new-in-android-50-lollipop.html)
// and is newer than [Android 4.3 (API level 18) that getauxval was added](https://android.googlesource.com/platform/bionic/+/refs/heads/master/libc/include/sys/auxv.h#49).
//
// See also https://github.com/rust-lang/stdarch/pull/1375
//
// On other Linux targets, we cannot assume that getauxval is always available yet
// (see stdarch PR linked above for details), so we use is_aarch64_feature_detected
// which uses dlsym (+io fallback) instead of this module.

Expand Down
2 changes: 1 addition & 1 deletion src/imp/atomic128/detect/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ mod tests_aarch64_common {
}
impl ProcCpuinfo {
fn new() -> Option<Self> {
if cfg!(any(target_os = "linux", target_os = "netbsd")) {
if cfg!(any(target_os = "linux", target_os = "android", target_os = "netbsd")) {
let text = fs::read_to_string("/proc/cpuinfo").unwrap();
let features = text
.lines()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/* automatically generated by rust-bindgen 0.63.0 */

pub const HWCAP_ATOMICS: u32 = 256;
pub const HWCAP_CPUID: u32 = 2048;
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/* automatically generated by rust-bindgen 0.63.0 */

pub const AT_HWCAP: u32 = 16;
7 changes: 7 additions & 0 deletions src/tests/gen/sys/aarch64_linux_android/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// This file is @generated by portable-atomic-internal-codegen
// (gen function at tools/codegen/src/ffi.rs).
// It is not intended for manual editing.

#![cfg_attr(rustfmt, rustfmt::skip)]
pub(crate) mod include_uapi_linux_auxvec;
pub(crate) mod arch_arm64_include_uapi_asm_hwcap;
4 changes: 4 additions & 0 deletions src/tests/gen/sys/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ mod aarch64_linux_gnu_ilp32;
)
)]
pub(crate) use aarch64_linux_gnu_ilp32::*;
#[cfg(all(target_arch = "aarch64", target_os = "android"))]
mod aarch64_linux_android;
#[cfg(all(target_arch = "aarch64", target_os = "android"))]
pub(crate) use aarch64_linux_android::*;
#[cfg(all(target_arch = "aarch64", target_os = "openbsd"))]
mod aarch64_openbsd;
#[cfg(all(target_arch = "aarch64", target_os = "openbsd"))]
Expand Down
9 changes: 5 additions & 4 deletions tools/codegen/src/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ static TARGETS: &[Target] = &[
triples: &[
"aarch64-unknown-linux-gnu",
"aarch64-unknown-linux-gnu_ilp32",
"aarch64-linux-android",
],
headers: &[
// TODO
Expand Down Expand Up @@ -127,7 +128,7 @@ pub(crate) fn gen() -> Result<()> {
let target_flag = &*format!("--target={triple}");
let mut clang_args = vec![target_flag, "-nostdinc"];
let include = match target.os {
linux => {
linux | android => {
let arch = match target.arch {
aarch64 => "arm64",
_ => todo!("{target:?}"),
Expand All @@ -152,7 +153,7 @@ pub(crate) fn gen() -> Result<()> {
files.push(out_file);

let header_path = match target.os {
linux => src_dir.join(header.path),
linux | android => src_dir.join(header.path),
openbsd => src_dir.join(format!("sys/{}", header.path)),
_ => todo!("{target:?}"),
};
Expand Down Expand Up @@ -202,7 +203,7 @@ pub(crate) fn gen() -> Result<()> {

fn git_clone(target: &TargetSpec, download_cache_dir: &Utf8Path) -> Result<Utf8PathBuf> {
let repository = match target.os {
linux => "torvalds/linux",
linux | android => "torvalds/linux",
openbsd => "openbsd/src",
_ => todo!("{target:?}"),
};
Expand Down Expand Up @@ -239,7 +240,7 @@ fn git_clone(target: &TargetSpec, download_cache_dir: &Utf8Path) -> Result<Utf8P
// TODO: They should have a script included in their repository that does this automatically, so use it.
fn arch_symlink(target: &TargetSpec, src_dir: &Utf8Path) -> Result<()> {
match target.os {
linux => {}
linux | android => {}
openbsd => {
let arch = match target.arch {
aarch64 => "arm64",
Expand Down

0 comments on commit 6e943cb

Please sign in to comment.