Skip to content

Commit 32b50d5

Browse files
committed
Powerpc64le linux_raw support.
This mostly follows other architectures, however Rust's inline asm is currently considered experimental on PowerPC, so this uses outline asm by default even on Rust nightly. Fixes #188.
1 parent e325ded commit 32b50d5

File tree

14 files changed

+692
-22
lines changed

14 files changed

+692
-22
lines changed

.github/workflows/main.yml

Lines changed: 95 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ jobs:
6464
riscv64gc-unknown-linux-gnu
6565
aarch64-unknown-linux-gnu
6666
aarch64-unknown-linux-musl
67+
powerpc64le-unknown-linux-gnu
6768
armv5te-unknown-linux-gnueabi
6869
- name: Install cross-compilation tools
6970
run: |
@@ -86,6 +87,7 @@ jobs:
8687
- run: cargo check --workspace --release -vv --target=riscv64gc-unknown-linux-gnu
8788
- run: cargo check --workspace --release -vv --target=aarch64-unknown-linux-gnu
8889
- run: cargo check --workspace --release -vv --target=aarch64-unknown-linux-musl
90+
- run: cargo check --workspace --release -vv --target=powerpc64le-unknown-linux-gnu
8991
- run: cargo check --workspace --release -vv --target=armv5te-unknown-linux-gnueabi
9092

9193
check_no_default_features:
@@ -168,7 +170,7 @@ jobs:
168170
runs-on: ${{ matrix.os }}
169171
strategy:
170172
matrix:
171-
build: [ubuntu, ubuntu-18.04, i686-linux, aarch64-linux, riscv64-linux, arm-linux, ubuntu-stable, i686-linux-stable, aarch64-linux-stable, riscv64-linux-stable, arm-linux-stable, macos, macos-11, windows, windows-2016, windows-2022]
173+
build: [ubuntu, ubuntu-18.04, i686-linux, aarch64-linux, powerpc64le-linux, riscv64-linux, arm-linux, ubuntu-stable, i686-linux-stable, aarch64-linux-stable, riscv64-linux-stable, arm-linux-stable, macos, macos-11, windows, windows-2016, windows-2022]
172174
include:
173175
- build: ubuntu
174176
os: ubuntu-latest
@@ -191,6 +193,14 @@ jobs:
191193
gcc: aarch64-linux-gnu-gcc
192194
qemu: qemu-aarch64 -L /usr/aarch64-linux-gnu
193195
qemu_target: aarch64-linux-user
196+
- build: powerpc64le-linux
197+
os: ubuntu-latest
198+
rust: nightly
199+
target: powerpc64le-unknown-linux-gnu
200+
gcc_package: gcc-powerpc64le-linux-gnu
201+
gcc: powerpc64le-linux-gnu-gcc
202+
qemu: qemu-ppc64le -L /usr/powerpc64le-linux-gnu
203+
qemu_target: ppc64le-linux-user
194204
- build: riscv64-linux
195205
os: ubuntu-latest
196206
rust: nightly
@@ -320,7 +330,7 @@ jobs:
320330
runs-on: ${{ matrix.os }}
321331
strategy:
322332
matrix:
323-
build: [ubuntu, i686-linux, aarch64-linux, riscv64-linux, arm-linux]
333+
build: [ubuntu, i686-linux, aarch64-linux, powerpc64le-linux, riscv64-linux, arm-linux]
324334
include:
325335
- build: ubuntu
326336
os: ubuntu-latest
@@ -340,6 +350,14 @@ jobs:
340350
gcc: aarch64-linux-gnu-gcc
341351
qemu: qemu-aarch64 -L /usr/aarch64-linux-gnu
342352
qemu_target: aarch64-linux-user
353+
- build: powerpc64le-linux
354+
os: ubuntu-latest
355+
rust: stable
356+
target: powerpc64le-unknown-linux-gnu
357+
gcc_package: gcc-powerpc64le-linux-gnu
358+
gcc: powerpc64le-linux-gnu-gcc
359+
qemu: qemu-ppc64le -L /usr/powerpc64le-linux-gnu
360+
qemu_target: ppc64le-linux-user
343361
- build: riscv64-linux
344362
os: ubuntu-latest
345363
rust: stable
@@ -363,6 +381,7 @@ jobs:
363381
CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUSTFLAGS: --cfg rustix_use_libc
364382
CARGO_TARGET_I686_UNKNOWN_LINUX_GNU_RUSTFLAGS: --cfg rustix_use_libc
365383
CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_RUSTFLAGS: --cfg rustix_use_libc
384+
CARGO_TARGET_POWERPC64LE_UNKNOWN_LINUX_GNU_RUSTFLAGS: --cfg rustix_use_libc
366385
CARGO_TARGET_RISCV64_UNKNOWN_LINUX_GNU_RUSTFLAGS: --cfg rustix_use_libc
367386
CARGO_TARGET_ARM_UNKNOWN_LINUX_GNU_RUSTFLAGS: --cfg rustix_use_libc
368387
steps:
@@ -418,3 +437,77 @@ jobs:
418437
cargo test --verbose --features=all-impls,procfs --release --workspace -- --nocapture
419438
env:
420439
RUST_BACKTRACE: 1
440+
441+
test_rustix_use_experimental_asm:
442+
name: Test rustix_use_experimental_asm
443+
runs-on: ${{ matrix.os }}
444+
strategy:
445+
matrix:
446+
build: [powerpc64le-linux]
447+
include:
448+
- build: powerpc64le-linux
449+
os: ubuntu-latest
450+
rust: nightly
451+
target: powerpc64le-unknown-linux-gnu
452+
gcc_package: gcc-powerpc64le-linux-gnu
453+
gcc: powerpc64le-linux-gnu-gcc
454+
qemu: qemu-ppc64le -L /usr/powerpc64le-linux-gnu
455+
qemu_target: ppc64le-linux-user
456+
env:
457+
# -D warnings is commented out in our install-rust action; re-add it here.
458+
RUSTFLAGS: --cfg rustix_use_experimental_asm -D warnings
459+
RUSTDOCFLAGS: --cfg rustix_use_experimental_asm
460+
CARGO_TARGET_POWERPC64LE_UNKNOWN_LINUX_GNU_RUSTFLAGS: --cfg rustix_use_experimental_asm
461+
steps:
462+
- uses: actions/checkout@v2
463+
with:
464+
submodules: true
465+
- uses: ./.github/actions/install-rust
466+
with:
467+
toolchain: ${{ matrix.rust }}
468+
469+
- name: Configure Cargo target
470+
run: |
471+
echo CARGO_BUILD_TARGET=${{ matrix.target }} >> $GITHUB_ENV
472+
rustup target add ${{ matrix.target }}
473+
if: matrix.target != ''
474+
475+
- name: Install cross-compilation tools
476+
run: |
477+
set -ex
478+
sudo apt-get update
479+
sudo apt-get install -y ${{ matrix.gcc_package }} ninja-build
480+
upcase=$(echo ${{ matrix.target }} | awk '{ print toupper($0) }' | sed 's/-/_/g')
481+
echo CARGO_TARGET_${upcase}_LINKER=${{ matrix.gcc }} >> $GITHUB_ENV
482+
if: matrix.gcc_package != '' && matrix.os == 'ubuntu-latest'
483+
484+
- name: Install cross-compilation libraries
485+
run: |
486+
set -ex
487+
sudo apt-get update
488+
sudo apt-get install -y ${{ matrix.libc_package }}
489+
if: matrix.libc_package != '' && matrix.os == 'ubuntu-latest'
490+
491+
- name: Install qemu
492+
run: |
493+
set -ex
494+
# Download and build qemu from source since the most recent release is
495+
# way faster at arm emulation than the current version github actions'
496+
# ubuntu image uses. Disable as much as we can to get it to build
497+
# quickly.
498+
cd
499+
curl https://download.qemu.org/qemu-6.1.0.tar.xz | tar xJf -
500+
cd qemu-6.1.0
501+
./configure --target-list=${{ matrix.qemu_target }} --prefix=$HOME/qemu --disable-tools --disable-slirp --disable-fdt --disable-capstone --disable-docs
502+
make -j$(nproc) install
503+
504+
# Configure Cargo for cross compilation and tell it how it can run
505+
# cross executables
506+
upcase=$(echo ${{ matrix.target }} | awk '{ print toupper($0) }' | sed 's/-/_/g')
507+
echo CARGO_TARGET_${upcase}_RUNNER=$HOME/qemu/bin/${{ matrix.qemu }} >> $GITHUB_ENV
508+
if: matrix.qemu != '' && matrix.os == 'ubuntu-latest'
509+
510+
- run: |
511+
cargo test --verbose --features=all-impls,procfs --release --workspace -- --nocapture
512+
env:
513+
RUST_BACKTRACE: 1

Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,12 @@ compiler_builtins = { version = '0.1.49', optional = true }
3232
once_cell = { version = "1.5.2", optional = true }
3333

3434
# For the linux_raw backend, linux-raw-sys provides Linux ABI details.
35-
[target.'cfg(all(not(rustix_use_libc), any(target_os = "linux"), any(target_arch = "x86", all(target_arch = "x86_64", not(target_pointer_width = "32")), target_arch = "arm", target_arch = "aarch64", target_arch = "riscv64")))'.dependencies]
35+
[target.'cfg(all(not(rustix_use_libc), any(target_os = "linux"), any(target_arch = "x86", all(target_arch = "x86_64", not(target_pointer_width = "32")), target_arch = "arm", target_arch = "aarch64", target_arch = "powerpc64", target_arch = "riscv64")))'.dependencies]
3636
linux-raw-sys = { version = "0.0.40", default-features = false, features = ["general", "errno", "ioctl", "no_std"] }
3737

3838
# For the libc backend on Unix platforms, use the libc crate, and errno for
3939
# setting `errno`.
40-
[target.'cfg(any(rustix_use_libc, not(all(any(target_os = "linux"), any(target_arch = "x86", all(target_arch = "x86_64", not(target_pointer_width = "32")), target_arch = "arm", target_arch = "aarch64", target_arch = "riscv64")))))'.dependencies]
40+
[target.'cfg(any(rustix_use_libc, not(all(any(target_os = "linux"), any(target_arch = "x86", all(target_arch = "x86_64", not(target_pointer_width = "32")), target_arch = "arm", target_arch = "aarch64", target_arch = "powerpc64", target_arch = "riscv64")))))'.dependencies]
4141
errno = { version = "0.2.8", default-features = false }
4242
libc = { version = "0.2.114", features = ["extra_traits"] }
4343

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ portable APIs built on this functionality, see the [`system-interface`],
3131
`rustix` currently has two backends available: `linux_raw` and `libc`.
3232

3333
The `linux_raw` backend is enabled by default on Linux on x86-64, x86, aarch64,
34-
riscv64gc and arm (v5 onwards), and uses raw Linux system calls and vDSO calls.
35-
It supports stable as well as nightly and 1.48 Rust.
34+
riscv64gc, powerpc64le, and arm (v5 onwards), and uses raw Linux system calls
35+
and vDSO calls. It supports stable as well as nightly and 1.48 Rust.
3636
- By being implemented entirely in Rust, avoiding `libc`, `errno`, and pthread
3737
cancellation, and employing some specialized optimizations, most functions
3838
compile down to very efficient code. On nightly Rust, they can often be

build.rs

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -27,27 +27,40 @@ fn main() {
2727
let asm_name = format!("{}/{}.s", OUTLINE_PATH, arch);
2828
let os_name = var("CARGO_CFG_TARGET_OS").unwrap();
2929
let pointer_width = var("CARGO_CFG_TARGET_POINTER_WIDTH").unwrap();
30+
let endian = var("CARGO_CFG_TARGET_ENDIAN").unwrap();
3031
let is_x32 = arch == "x86_64" && pointer_width == "32";
3132
let is_arm64_ilp32 = arch == "aarch64" && pointer_width == "32";
32-
println!("cargo:rerun-if-env-changed=CARGO_CFG_TARGET_ARCH");
33+
let is_powerpc64be = arch == "powerpc64" && endian == "big";
34+
let rustix_use_libc = var("CARGO_CFG_RUSTIX_USE_LIBC").is_ok();
35+
let rustix_use_experimental_asm = var("CARGO_CFG_RUSTIX_USE_EXPERIMENTAL_ASM").is_ok();
3336

3437
// If rustix_use_libc is set, or if we're on an architecture/OS that doesn't
3538
// have raw syscall support, use libc.
36-
if var("CARGO_CFG_RUSTIX_USE_LIBC").is_ok()
39+
if rustix_use_libc
3740
|| os_name != "linux"
3841
|| std::fs::metadata(&asm_name).is_err()
3942
|| is_x32
4043
|| is_arm64_ilp32
44+
|| is_powerpc64be
4145
{
4246
use_feature("libc");
4347
} else {
4448
use_feature("linux_raw");
4549
use_feature_or_nothing("core_intrinsics");
46-
use_feature_or_else("asm", || {
50+
51+
// On PowerPC, Rust's inline asm is considered experimental, so only
52+
// use it if `--cfg=rustix_use_experimental_asm` is given.
53+
if has_feature("asm") && (arch != "powerpc64" || rustix_use_experimental_asm) {
54+
use_feature("asm");
55+
if rustix_use_experimental_asm {
56+
use_feature("asm_experimental_arch");
57+
}
58+
} else {
4759
link_in_librustix_outline(&arch, &asm_name);
48-
});
60+
}
4961
}
5062
println!("cargo:rerun-if-env-changed=CARGO_CFG_RUSTIX_USE_LIBC");
63+
println!("cargo:rerun-if-env-changed=CARGO_CFG_RUSTIX_USE_EXPERIMENTAL_ASM");
5164
}
5265

5366
fn link_in_librustix_outline(arch: &str, asm_name: &str) {
@@ -101,14 +114,6 @@ fn use_feature_or_nothing(feature: &str) {
101114
}
102115
}
103116

104-
fn use_feature_or_else<F: FnOnce()>(feature: &str, or_else: F) {
105-
if has_feature(feature) {
106-
use_feature(feature);
107-
} else {
108-
or_else();
109-
}
110-
}
111-
112117
fn use_feature(feature: &str) {
113118
println!("cargo:rustc-cfg={}", feature);
114119
}

src/imp/linux_raw/arch/inline/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
mod aarch64;
77
#[cfg(target_arch = "arm")]
88
mod arm;
9+
#[cfg(target_arch = "powerpc64")]
10+
mod powerpc64;
911
#[cfg(target_arch = "riscv64")]
1012
mod riscv64;
1113
#[cfg(target_arch = "x86")]
@@ -17,6 +19,8 @@ mod x86_64;
1719
pub(in crate::imp) use self::aarch64::*;
1820
#[cfg(target_arch = "arm")]
1921
pub(in crate::imp) use self::arm::*;
22+
#[cfg(target_arch = "powerpc64")]
23+
pub(in crate::imp) use self::powerpc64::*;
2024
#[cfg(target_arch = "riscv64")]
2125
pub(in crate::imp) use self::riscv64::*;
2226
#[cfg(target_arch = "x86")]

0 commit comments

Comments
 (0)