Skip to content
Merged
58 changes: 51 additions & 7 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,47 @@ jobs:
strategy:
fail-fast: false
matrix:
target:
- x86_64-unknown-linux-gnu
- aarch64-unknown-linux-gnu
- riscv64gc-unknown-linux-gnu
include:
- target: x86_64-unknown-linux-gnu
toolchain: stable
- target: aarch64-unknown-linux-gnu
toolchain: stable
- target: riscv64gc-unknown-linux-gnu
toolchain: stable
- target: loongarch64-unknown-linux-gnu
toolchain: stable
- target: s390x-unknown-linux-gnu
toolchain: stable
# powerpc64 uses experimental asm features
- target: powerpc64le-unknown-linux-gnu
toolchain: nightly
- target: powerpc64-unknown-linux-gnu
toolchain: nightly
- target: armv7-unknown-linux-gnueabihf
toolchain: stable
# riscv32 is tier-3
- target: riscv32gc-unknown-linux-gnu
toolchain: nightly
components: rust-src
build_std: true
# sparc64 uses experimental asm features
- target: sparc64-unknown-linux-gnu
toolchain: nightly
# mips64 is tier-3 and uses experimental asm features
- target: mips64-unknown-linux-gnuabi64
toolchain: nightly
components: rust-src
build_std: true
- target: i686-unknown-linux-gnu
toolchain: stable
# powerpc uses experimental asm features
- target: powerpc-unknown-linux-gnu
toolchain: nightly
# mips is tier-3 and uses experimental asm features
- target: mips-unknown-linux-gnu
toolchain: nightly
components: rust-src
build_std: true

steps:
- name: "Checkout"
Expand All @@ -28,9 +65,14 @@ jobs:
- name: "Setup Rust toolchain"
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
target: ${{ matrix.target }}
toolchain: ${{ matrix.toolchain }}
components: ${{ matrix.components || '' }}
rustflags: ""

- name: "Add Rust target"
if: ${{ !matrix.build_std }}
run: rustup target add ${{ matrix.target }}

- name: "Make Mold the default linker"
uses: rui314/setup-mold@v1

Expand All @@ -40,7 +82,9 @@ jobs:
target: ${{ matrix.target }}

- name: "Build"
run: cargo build --verbose
run: cargo build --verbose --target ${{ matrix.target }} ${{ matrix.build_std && '-Z build-std=core,alloc,panic_abort' || '' }} ${{ matrix.extra_args || '' }}

# tier-3 targets have no prebuilt std and tests are arch-agnostic, so
# run them against the host toolchain instead of the cross target.
- name: "Run tests"
run: cargo test --workspace --exclude microfetch --verbose
run: cargo test --workspace --exclude microfetch --verbose ${{ matrix.build_std && '--target x86_64-unknown-linux-gnu' || '' }}
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ resolver = "3"
authors = [ "NotAShelf <raf@notashelf.dev>" ]
edition = "2024"
license = "GPL-3.0"
rust-version = "1.92.0"
rust-version = "1.95.0"
version = "1.1.0"

[workspace.dependencies]
Expand Down
164 changes: 164 additions & 0 deletions crates/asm/src/aarch64.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
//! Syscall implementations for `aarch64`.

use super::{StatfsBuf, SysInfo, UtsNameBuf};

pub(super) unsafe fn sys_open(path: *const u8, flags: i32) -> i32 {
unsafe {
let fd: i64;
core::arch::asm!(
"svc #0",
in("x8") 56i64, // SYS_openat
in("x0") -100i32, // AT_FDCWD
in("x1") path,
in("x2") flags,
in("x3") 0i32, // mode
lateout("x0") fd,
options(nostack)
);
#[allow(clippy::cast_possible_truncation)]
{
fd as i32
}
}
}

pub(super) unsafe fn sys_read(fd: i32, buf: *mut u8, count: usize) -> isize {
unsafe {
let ret: i64;
core::arch::asm!(
"svc #0",
in("x8") 63i64, // SYS_read
in("x0") fd,
in("x1") buf,
in("x2") count,
lateout("x0") ret,
options(nostack)
);

#[allow(clippy::cast_possible_truncation)]
{
ret as isize
}
}
}

pub(super) unsafe fn sys_write(fd: i32, buf: *const u8, count: usize) -> isize {
unsafe {
let ret: i64;
core::arch::asm!(
"svc #0",
in("x8") 64i64, // SYS_write
in("x0") fd,
in("x1") buf,
in("x2") count,
lateout("x0") ret,
options(nostack)
);

#[allow(clippy::cast_possible_truncation)]
{
ret as isize
}
}
}

pub(super) unsafe fn sys_close(fd: i32) -> i32 {
unsafe {
let ret: i64;
core::arch::asm!(
"svc #0",
in("x8") 57i64, // SYS_close
in("x0") fd,
lateout("x0") ret,
options(nostack)
);
#[allow(clippy::cast_possible_truncation)]
{
ret as i32
}
}
}

pub(super) unsafe fn sys_uname(buf: *mut UtsNameBuf) -> i32 {
unsafe {
let ret: i64;
core::arch::asm!(
"svc #0",
in("x8") 160i64, // SYS_uname
in("x0") buf,
lateout("x0") ret,
options(nostack)
);
#[allow(clippy::cast_possible_truncation)]
{
ret as i32
}
}
}

pub(super) unsafe fn sys_statfs(path: *const u8, buf: *mut StatfsBuf) -> i32 {
unsafe {
let ret: i64;
core::arch::asm!(
"svc #0",
in("x8") 43i64, // SYS_statfs
in("x0") path,
in("x1") buf,
lateout("x0") ret,
options(nostack)
);

#[allow(clippy::cast_possible_truncation)]
{
ret as i32
}
}
}

pub(super) unsafe fn sys_sysinfo(info: *mut SysInfo) -> i64 {
unsafe {
let ret: i64;
core::arch::asm!(
"svc #0",
in("x8") 179_i64, // __NR_sysinfo
in("x0") info,
lateout("x0") ret,
options(nostack)
);
ret
}
}

pub(super) unsafe fn sys_sched_getaffinity(
pid: i32,
mask_size: usize,
mask: *mut u8,
) -> i32 {
unsafe {
let ret: i64;
core::arch::asm!(
"svc #0",
in("x8") 123i64, // __NR_sched_getaffinity
in("x0") pid,
in("x1") mask_size,
in("x2") mask,
lateout("x0") ret,
options(nostack)
);
#[allow(clippy::cast_possible_truncation)]
{
ret as i32
}
}
}

pub(super) unsafe fn sys_exit(code: i32) -> ! {
unsafe {
core::arch::asm!(
"svc #0",
in("x8") 93i64, // SYS_exit
in("x0") code,
options(noreturn, nostack)
);
}
}
140 changes: 140 additions & 0 deletions crates/asm/src/arm.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
//! Syscall implementations for `arm`.

use super::{StatfsBuf, SysInfo, UtsNameBuf};

pub(super) unsafe fn sys_open(path: *const u8, flags: i32) -> i32 {
unsafe {
let ret: i32;
core::arch::asm!(
"svc #0",
in("r7") 5i32, // SYS_open
in("r0") path,
in("r1") flags,
in("r2") 0i32, // mode
lateout("r0") ret,
options(nostack)
);
ret
}
}

pub(super) unsafe fn sys_read(fd: i32, buf: *mut u8, count: usize) -> isize {
unsafe {
let ret: i32;
core::arch::asm!(
"svc #0",
in("r7") 3i32, // SYS_read
in("r0") fd,
in("r1") buf,
in("r2") count,
lateout("r0") ret,
options(nostack)
);
ret as isize
}
}

pub(super) unsafe fn sys_write(fd: i32, buf: *const u8, count: usize) -> isize {
unsafe {
let ret: i32;
core::arch::asm!(
"svc #0",
in("r7") 4i32, // SYS_write
in("r0") fd,
in("r1") buf,
in("r2") count,
lateout("r0") ret,
options(nostack)
);
ret as isize
}
}

pub(super) unsafe fn sys_close(fd: i32) -> i32 {
unsafe {
let ret: i32;
core::arch::asm!(
"svc #0",
in("r7") 6i32, // SYS_close
in("r0") fd,
lateout("r0") ret,
options(nostack)
);
ret
}
}

pub(super) unsafe fn sys_uname(buf: *mut UtsNameBuf) -> i32 {
unsafe {
let ret: i32;
core::arch::asm!(
"svc #0",
in("r7") 122i32, // SYS_newuname
in("r0") buf,
lateout("r0") ret,
options(nostack)
);
ret
}
}

pub(super) unsafe fn sys_statfs(path: *const u8, buf: *mut StatfsBuf) -> i32 {
unsafe {
let ret: i32;
core::arch::asm!(
"svc #0",
in("r7") 266i32, // SYS_statfs64
in("r0") path,
in("r1") core::mem::size_of::<StatfsBuf>(),
in("r2") buf,
lateout("r0") ret,
options(nostack)
);
ret
}
}

pub(super) unsafe fn sys_sysinfo(info: *mut SysInfo) -> i64 {
unsafe {
let ret: i32;
core::arch::asm!(
"svc #0",
in("r7") 116_i32, // __NR_sysinfo
in("r0") info,
lateout("r0") ret,
options(nostack)
);
i64::from(ret)
}
}

pub(super) unsafe fn sys_sched_getaffinity(
pid: i32,
mask_size: usize,
mask: *mut u8,
) -> i32 {
unsafe {
let ret: i32;
core::arch::asm!(
"svc #0",
in("r7") 242i32, // __NR_sched_getaffinity
in("r0") pid,
in("r1") mask_size,
in("r2") mask,
lateout("r0") ret,
options(nostack)
);
ret
}
}

pub(super) unsafe fn sys_exit(code: i32) -> ! {
unsafe {
core::arch::asm!(
"svc #0",
in("r7") 1i32, // SYS_exit
in("r0") code,
options(noreturn, nostack)
);
}
}
Loading