diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 2eb3a1f..99668ae 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -16,47 +16,10 @@ jobs: strategy: fail-fast: false matrix: - 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 + target: + - x86_64-unknown-linux-gnu + - aarch64-unknown-linux-gnu + - riscv64gc-unknown-linux-gnu steps: - name: "Checkout" @@ -65,14 +28,9 @@ jobs: - name: "Setup Rust toolchain" uses: actions-rust-lang/setup-rust-toolchain@v1 with: - toolchain: ${{ matrix.toolchain }} - components: ${{ matrix.components || '' }} + target: ${{ matrix.target }} 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 @@ -82,9 +40,7 @@ jobs: target: ${{ matrix.target }} - name: "Build" - run: cargo build --verbose --target ${{ matrix.target }} ${{ matrix.build_std && '-Z build-std=core,alloc,panic_abort' || '' }} ${{ matrix.extra_args || '' }} + run: cargo build --verbose - # 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 ${{ matrix.build_std && '--target x86_64-unknown-linux-gnu' || '' }} + run: cargo test --workspace --exclude microfetch --verbose diff --git a/Cargo.lock b/Cargo.lock index 96ba19a..ffe0ec6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -448,9 +448,9 @@ checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" [[package]] name = "hotpath" -version = "0.15.1" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdb7d0713302f121f02d93290b6303b320e886f462d2cde84146ce9f9e28f1f0" +checksum = "f7d9982fcb4356a5260502f0e646411ec1feb2962cc98c230777104a8d1c5ed3" dependencies = [ "arc-swap", "cfg-if", @@ -460,8 +460,7 @@ dependencies = [ "eyre", "futures-util", "hdrhistogram", - "hotpath-macros", - "hotpath-meta", + "hotpath-macros 0.14.1", "libc", "mach2", "pin-project-lite", @@ -475,10 +474,21 @@ dependencies = [ ] [[package]] -name = "hotpath-macros" -version = "0.15.1" +name = "hotpath" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51066092dc750f8cbcac4afa04592377bf7463a911d1beca430ddd788deb0757" +checksum = "28594d8a3d30371e1488dcd6ba545bf07e9ce9dff6d8a57d70dbbaa221d3246d" +dependencies = [ + "hotpath-macros 0.15.0", + "hotpath-meta", + "tokio", +] + +[[package]] +name = "hotpath-macros" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4398eddb78466298f1ddcc739abbbd8a942e541d1972c7590bd83de364e626e0" dependencies = [ "proc-macro2", "quote", @@ -486,16 +496,22 @@ dependencies = [ ] [[package]] -name = "hotpath-macros-meta" -version = "0.15.1" +name = "hotpath-macros" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7f6b2adb32728a10077f9eb66ece7c122ae0d86f3430187bbd8605089e3df7e" +checksum = "c7b87d58f92c09858091f328521db329955e9fc960c3c9c55e5dc0ef228a37b0" + +[[package]] +name = "hotpath-macros-meta" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4fcd1a53780c79401c81008b262470386d6dfee64599b337cae37a9674c082d" [[package]] name = "hotpath-meta" -version = "0.15.1" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d45b707a3eae596368fd81132daea5f8a4444a4590b9da2439f7f6dd2c3c3102" +checksum = "4aadd604c1aac308bda11d4792ae46c2076acd0523e401ee8640f101c0b99653" dependencies = [ "hotpath-macros-meta", ] @@ -597,7 +613,7 @@ checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" name = "microfetch" version = "1.1.0" dependencies = [ - "hotpath", + "hotpath 0.15.0", "microfetch-alloc", "microfetch-asm", "microfetch-lib", @@ -624,7 +640,7 @@ dependencies = [ name = "microfetch-lib" version = "1.1.0" dependencies = [ - "hotpath", + "hotpath 0.14.1", "microfetch-asm", ] diff --git a/Cargo.toml b/Cargo.toml index 391e0dd..ab63681 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,7 +6,7 @@ resolver = "3" authors = [ "NotAShelf " ] edition = "2024" license = "GPL-3.0" -rust-version = "1.95.0" +rust-version = "1.92.0" version = "1.1.0" [workspace.dependencies] diff --git a/crates/asm/src/aarch64.rs b/crates/asm/src/aarch64.rs deleted file mode 100644 index 6997f62..0000000 --- a/crates/asm/src/aarch64.rs +++ /dev/null @@ -1,164 +0,0 @@ -//! 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) - ); - } -} diff --git a/crates/asm/src/arm.rs b/crates/asm/src/arm.rs deleted file mode 100644 index 892b012..0000000 --- a/crates/asm/src/arm.rs +++ /dev/null @@ -1,140 +0,0 @@ -//! 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::(), - 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) - ); - } -} diff --git a/crates/asm/src/lib.rs b/crates/asm/src/lib.rs index fff8d7f..04db2db 100644 --- a/crates/asm/src/lib.rs +++ b/crates/asm/src/lib.rs @@ -5,39 +5,19 @@ //! What do you mean I wasted two whole hours to make the program only 100µs //! faster? //! -//! Supports `x86_64`, `aarch64`, `riscv64`, `loongarch64`, `s390x`, -//! `powerpc64`, `arm` (armv7), `riscv32`, `sparc64`, `mips64`, `x86` (i686), -//! `powerpc` (ppc32), `sparc` (sparc32), and `mips` (O32) architectures. +//! Supports `x86_64`, `aarch64`, and `riscv64` architectures. #![no_std] -#![cfg_attr( - any( - target_arch = "sparc64", - target_arch = "sparc", - target_arch = "mips64", - target_arch = "mips" - ), - feature(asm_experimental_arch) -)] -// Per-arch syscall implementations live in their own module files. -core::cfg_select! { - target_arch = "x86_64" => { #[path = "x86_64.rs" ] mod arch; } - target_arch = "aarch64" => { #[path = "aarch64.rs" ] mod arch; } - target_arch = "riscv64" => { #[path = "riscv64.rs" ] mod arch; } - target_arch = "loongarch64" => { #[path = "loongarch64.rs"] mod arch; } - target_arch = "s390x" => { #[path = "s390x.rs" ] mod arch; } - target_arch = "powerpc64" => { #[path = "powerpc64.rs" ] mod arch; } - target_arch = "arm" => { #[path = "arm.rs" ] mod arch; } - target_arch = "riscv32" => { #[path = "riscv32.rs" ] mod arch; } - target_arch = "sparc64" => { #[path = "sparc64.rs" ] mod arch; } - target_arch = "mips64" => { #[path = "mips64.rs" ] mod arch; } - target_arch = "x86" => { #[path = "x86.rs" ] mod arch; } - target_arch = "powerpc" => { #[path = "powerpc.rs" ] mod arch; } - target_arch = "sparc" => { #[path = "sparc.rs" ] mod arch; } - target_arch = "mips" => { #[path = "mips.rs" ] mod arch; } - _ => { compile_error!("Unsupported architecture"); } -} +// Ensure we're compiling for a supported architecture. +#[cfg(not(any( + target_arch = "x86_64", + target_arch = "aarch64", + target_arch = "riscv64" +)))] +compile_error!( + "Unsupported architecture: only x86_64, aarch64, and riscv64 are supported" +); /// Copies `n` bytes from `src` to `dest`. /// @@ -185,7 +165,62 @@ unsafe extern "C" { #[inline] #[must_use] pub unsafe fn sys_open(path: *const u8, flags: i32) -> i32 { - unsafe { arch::sys_open(path, flags) } + #[cfg(target_arch = "x86_64")] + unsafe { + let fd: i64; + core::arch::asm!( + "syscall", + in("rax") 2i64, // SYS_open + in("rdi") path, + in("rsi") flags, + in("rdx") 0i32, // mode (not used for reading) + lateout("rax") fd, + lateout("rcx") _, + lateout("r11") _, + options(nostack) + ); + #[allow(clippy::cast_possible_truncation)] + { + fd as i32 + } + } + #[cfg(target_arch = "aarch64")] + 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 + } + } + #[cfg(target_arch = "riscv64")] + unsafe { + let fd: i64; + core::arch::asm!( + "ecall", + in("a7") 56i64, // SYS_openat + in("a0") -100i32, // AT_FDCWD + in("a1") path, + in("a2") flags, + in("a3") 0i32, // mode + lateout("a0") fd, + options(nostack) + ); + + #[allow(clippy::cast_possible_truncation)] + { + fd as i32 + } + } } /// Direct syscall to read from a file descriptor @@ -202,7 +237,64 @@ pub unsafe fn sys_open(path: *const u8, flags: i32) -> i32 { /// - `fd` is a valid open file descriptor #[inline] pub unsafe fn sys_read(fd: i32, buf: *mut u8, count: usize) -> isize { - unsafe { arch::sys_read(fd, buf, count) } + #[cfg(target_arch = "x86_64")] + unsafe { + let ret: i64; + core::arch::asm!( + "syscall", + in("rax") 0i64, // SYS_read + in("rdi") fd, + in("rsi") buf, + in("rdx") count, + lateout("rax") ret, + lateout("rcx") _, + lateout("r11") _, + options(nostack) + ); + + #[allow(clippy::cast_possible_truncation)] + { + ret as isize + } + } + + #[cfg(target_arch = "aarch64")] + 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 + } + } + + #[cfg(target_arch = "riscv64")] + unsafe { + let ret: i64; + core::arch::asm!( + "ecall", + in("a7") 63i64, // SYS_read + in("a0") fd, + in("a1") buf, + in("a2") count, + lateout("a0") ret, + options(nostack) + ); + + #[allow(clippy::cast_possible_truncation)] + { + ret as isize + } + } } /// Direct syscall to write to a file descriptor @@ -220,7 +312,64 @@ pub unsafe fn sys_read(fd: i32, buf: *mut u8, count: usize) -> isize { #[inline] #[must_use] pub unsafe fn sys_write(fd: i32, buf: *const u8, count: usize) -> isize { - unsafe { arch::sys_write(fd, buf, count) } + #[cfg(target_arch = "x86_64")] + unsafe { + let ret: i64; + core::arch::asm!( + "syscall", + in("rax") 1i64, // SYS_write + in("rdi") fd, + in("rsi") buf, + in("rdx") count, + lateout("rax") ret, + lateout("rcx") _, + lateout("r11") _, + options(nostack) + ); + + #[allow(clippy::cast_possible_truncation)] + { + ret as isize + } + } + + #[cfg(target_arch = "aarch64")] + 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 + } + } + + #[cfg(target_arch = "riscv64")] + unsafe { + let ret: i64; + core::arch::asm!( + "ecall", + in("a7") 64i64, // SYS_write + in("a0") fd, + in("a1") buf, + in("a2") count, + lateout("a0") ret, + options(nostack) + ); + + #[allow(clippy::cast_possible_truncation)] + { + ret as isize + } + } } /// Direct syscall to close a file descriptor @@ -231,7 +380,55 @@ pub unsafe fn sys_write(fd: i32, buf: *const u8, count: usize) -> isize { #[inline] #[must_use] pub unsafe fn sys_close(fd: i32) -> i32 { - unsafe { arch::sys_close(fd) } + #[cfg(target_arch = "x86_64")] + unsafe { + let ret: i64; + core::arch::asm!( + "syscall", + in("rax") 3i64, // SYS_close + in("rdi") fd, + lateout("rax") ret, + lateout("rcx") _, + lateout("r11") _, + options(nostack) + ); + #[allow(clippy::cast_possible_truncation)] + { + ret as i32 + } + } + + #[cfg(target_arch = "aarch64")] + 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 + } + } + + #[cfg(target_arch = "riscv64")] + unsafe { + let ret: i64; + core::arch::asm!( + "ecall", + in("a7") 57i64, // SYS_close + in("a0") fd, + lateout("a0") ret, + options(nostack) + ); + #[allow(clippy::cast_possible_truncation)] + { + ret as i32 + } + } } /// Raw buffer for the `uname(2)` syscall. @@ -262,7 +459,57 @@ pub struct UtsNameBuf { #[inline] #[allow(dead_code)] pub unsafe fn sys_uname(buf: *mut UtsNameBuf) -> i32 { - unsafe { arch::sys_uname(buf) } + #[cfg(target_arch = "x86_64")] + unsafe { + let ret: i64; + core::arch::asm!( + "syscall", + in("rax") 63i64, // SYS_uname + in("rdi") buf, + lateout("rax") ret, + lateout("rcx") _, + lateout("r11") _, + options(nostack) + ); + + #[allow(clippy::cast_possible_truncation)] + { + ret as i32 + } + } + + #[cfg(target_arch = "aarch64")] + 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 + } + } + + #[cfg(target_arch = "riscv64")] + unsafe { + let ret: i64; + core::arch::asm!( + "ecall", + in("a7") 160i64, // SYS_uname + in("a0") buf, + lateout("a0") ret, + options(nostack) + ); + + #[allow(clippy::cast_possible_truncation)] + { + ret as i32 + } + } } /// Raw buffer for the `statfs(2)` syscall. @@ -271,16 +518,6 @@ pub unsafe fn sys_uname(buf: *mut UtsNameBuf) -> i32 { /// offsets on both architectures. Only the fields needed for disk usage are /// declared; the remainder of the 120-byte struct is covered by `_pad`. #[repr(C)] -#[cfg(not(any( - target_arch = "s390x", - target_arch = "arm", - target_arch = "riscv32", - target_arch = "x86", - target_arch = "powerpc", - target_arch = "sparc", - target_arch = "mips64", - target_arch = "mips" -)))] pub struct StatfsBuf { pub f_type: i64, pub f_bsize: i64, @@ -298,96 +535,6 @@ pub struct StatfsBuf { pub _pad: [i64; 4], } -/// on s390x `f_type` and `f_bsize` are 32-bit. -#[repr(C)] -#[cfg(target_arch = "s390x")] -pub struct StatfsBuf { - pub f_type: u32, - pub f_bsize: u32, - pub f_blocks: u64, - pub f_bfree: u64, - pub f_bavail: u64, - pub f_files: u64, - pub f_ffree: u64, - pub f_fsid: [i32; 2], - pub f_namelen: u32, - pub f_frsize: u32, - pub f_flags: u32, - - #[allow(clippy::pub_underscore_fields, reason = "This is not a public API")] - pub _pad: [u32; 5], -} - -/// on armv7 `statfs64(2)` has 32-bit word fields; see -/// https://github.com/torvalds/linux/blob/v6.19/include/uapi/asm-generic/statfs.h -#[repr(C)] -#[cfg(any( - target_arch = "arm", - target_arch = "riscv32", - target_arch = "x86", - target_arch = "powerpc", - target_arch = "sparc" -))] -pub struct StatfsBuf { - pub f_type: u32, - pub f_bsize: u32, - pub f_blocks: u64, - pub f_bfree: u64, - pub f_bavail: u64, - pub f_files: u64, - pub f_ffree: u64, - pub f_fsid: [i32; 2], - pub f_namelen: u32, - pub f_frsize: u32, - pub f_flags: u32, - - #[allow(clippy::pub_underscore_fields, reason = "This is not a public API")] - pub _pad: [u32; 4], -} - -/// mips (O32) uses `compat_statfs64`, same reordering with 32-bit words; see -/// https://github.com/torvalds/linux/blob/v6.19/arch/mips/include/uapi/asm/statfs.h -#[repr(C)] -#[cfg(target_arch = "mips")] -pub struct StatfsBuf { - pub f_type: u32, - pub f_bsize: u32, - pub f_frsize: u32, - _pad: u32, - pub f_blocks: u64, - pub f_bfree: u64, - pub f_files: u64, - pub f_ffree: u64, - pub f_bavail: u64, - pub f_fsid: [i32; 2], - pub f_namelen: u32, - pub f_flags: u32, - - #[allow(clippy::pub_underscore_fields, reason = "This is not a public API")] - pub _pad2: [u32; 5], -} - -/// mips reorders fields; see -/// https://github.com/torvalds/linux/blob/v6.19/arch/mips/include/uapi/asm/statfs.h -#[repr(C)] -#[cfg(target_arch = "mips64")] -pub struct StatfsBuf { - pub f_type: i64, - pub f_bsize: i64, - pub f_frsize: i64, - pub f_blocks: u64, - pub f_bfree: u64, - pub f_files: u64, - pub f_ffree: u64, - pub f_bavail: u64, - pub f_fsid: [i32; 2], - pub f_namelen: i64, - pub f_flags: i64, - - #[allow(clippy::pub_underscore_fields, reason = "This is not a public API")] - pub _pad: [i64; 5], -} - /// Direct `statfs(2)` syscall /// /// # Returns @@ -402,7 +549,61 @@ pub struct StatfsBuf { /// - `buf` points to a valid `StatfsBuf` #[inline] pub unsafe fn sys_statfs(path: *const u8, buf: *mut StatfsBuf) -> i32 { - unsafe { arch::sys_statfs(path, buf) } + #[cfg(target_arch = "x86_64")] + unsafe { + let ret: i64; + core::arch::asm!( + "syscall", + in("rax") 137i64, // SYS_statfs + in("rdi") path, + in("rsi") buf, + lateout("rax") ret, + lateout("rcx") _, + lateout("r11") _, + options(nostack) + ); + + #[allow(clippy::cast_possible_truncation)] + { + ret as i32 + } + } + + #[cfg(target_arch = "aarch64")] + 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 + } + } + + #[cfg(target_arch = "riscv64")] + unsafe { + let ret: i64; + core::arch::asm!( + "ecall", + in("a7") 43i64, // SYS_statfs + in("a0") path, + in("a1") buf, + lateout("a0") ret, + options(nostack) + ); + + #[allow(clippy::cast_possible_truncation)] + { + ret as i32 + } + } } /// Read entire file using direct syscalls. This avoids libc overhead and can be @@ -457,14 +658,6 @@ pub fn read_file_fast(path: &str, buffer: &mut [u8]) -> Result { /// The layout matches the kernel's `struct sysinfo` *exactly*: /// `mem_unit` ends at offset 108, then 4 bytes of implicit padding to 112. #[repr(C)] -#[cfg(not(any( - target_arch = "arm", - target_arch = "riscv32", - target_arch = "x86", - target_arch = "powerpc", - target_arch = "sparc", - target_arch = "mips" -)))] pub struct SysInfo { pub uptime: i64, pub loads: [u64; 3], @@ -485,35 +678,6 @@ pub struct SysInfo { // needed } -/// on armv7 `__kernel_long_t` is 4 bytes; see -/// https://github.com/torvalds/linux/blob/v6.19/include/uapi/linux/sysinfo.h -#[repr(C)] -#[cfg(any( - target_arch = "arm", - target_arch = "riscv32", - target_arch = "x86", - target_arch = "powerpc", - target_arch = "sparc", - target_arch = "mips" -))] -pub struct SysInfo { - pub uptime: i32, - pub loads: [u32; 3], - pub totalram: u32, - pub freeram: u32, - pub sharedram: u32, - pub bufferram: u32, - pub totalswap: u32, - pub freeswap: u32, - pub procs: u16, - _pad: u16, - pub totalhigh: u32, - pub freehigh: u32, - pub mem_unit: u32, - #[allow(clippy::pub_underscore_fields, reason = "This is not a public API")] - pub _f: [u8; 8], -} - /// Direct `sysinfo(2)` syscall /// /// # Returns @@ -525,7 +689,46 @@ pub struct SysInfo { /// The caller must ensure that `info` points to a valid `SysInfo` buffer. #[inline] pub unsafe fn sys_sysinfo(info: *mut SysInfo) -> i64 { - unsafe { arch::sys_sysinfo(info) } + #[cfg(target_arch = "x86_64")] + unsafe { + let ret: i64; + core::arch::asm!( + "syscall", + in("rax") 99_i64, // __NR_sysinfo + in("rdi") info, + out("rcx") _, + out("r11") _, + lateout("rax") ret, + options(nostack) + ); + ret + } + + #[cfg(target_arch = "aarch64")] + unsafe { + let ret: i64; + core::arch::asm!( + "svc #0", + in("x8") 179_i64, // __NR_sysinfo + in("x0") info, + lateout("x0") ret, + options(nostack) + ); + ret + } + + #[cfg(target_arch = "riscv64")] + unsafe { + let ret: i64; + core::arch::asm!( + "ecall", + in("a7") 179_i64, // __NR_sysinfo + in("a0") info, + lateout("a0") ret, + options(nostack) + ); + ret + } } /// Direct `sched_getaffinity(2)` syscall @@ -545,7 +748,61 @@ pub unsafe fn sys_sched_getaffinity( mask_size: usize, mask: *mut u8, ) -> i32 { - unsafe { arch::sys_sched_getaffinity(pid, mask_size, mask) } + #[cfg(target_arch = "x86_64")] + unsafe { + let ret: i64; + core::arch::asm!( + "syscall", + in("rax") 204i64, // __NR_sched_getaffinity + in("rdi") pid, + in("rsi") mask_size, + in("rdx") mask, + lateout("rax") ret, + lateout("rcx") _, + lateout("r11") _, + options(nostack) + ); + #[allow(clippy::cast_possible_truncation)] + { + ret as i32 + } + } + + #[cfg(target_arch = "aarch64")] + 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 + } + } + + #[cfg(target_arch = "riscv64")] + unsafe { + let ret: i64; + core::arch::asm!( + "ecall", + in("a7") 123i64, // __NR_sched_getaffinity + in("a0") pid, + in("a1") mask_size, + in("a2") mask, + lateout("a0") ret, + options(nostack) + ); + #[allow(clippy::cast_possible_truncation)] + { + ret as i32 + } + } } /// Direct syscall to exit the process @@ -555,5 +812,33 @@ pub unsafe fn sys_sched_getaffinity( /// This syscall never returns. The process will terminate immediately. #[inline] pub unsafe fn sys_exit(code: i32) -> ! { - unsafe { arch::sys_exit(code) } + #[cfg(target_arch = "x86_64")] + unsafe { + core::arch::asm!( + "syscall", + in("rax") 60i64, // SYS_exit + in("rdi") code, + options(noreturn, nostack) + ); + } + + #[cfg(target_arch = "aarch64")] + unsafe { + core::arch::asm!( + "svc #0", + in("x8") 93i64, // SYS_exit + in("x0") code, + options(noreturn, nostack) + ); + } + + #[cfg(target_arch = "riscv64")] + unsafe { + core::arch::asm!( + "ecall", + in("a7") 93i64, // SYS_exit + in("a0") code, + options(noreturn, nostack) + ); + } } diff --git a/crates/asm/src/loongarch64.rs b/crates/asm/src/loongarch64.rs deleted file mode 100644 index d5ab5ac..0000000 --- a/crates/asm/src/loongarch64.rs +++ /dev/null @@ -1,161 +0,0 @@ -//! Syscall implementations for `loongarch64`. - -use super::{StatfsBuf, SysInfo, UtsNameBuf}; - -pub(super) unsafe fn sys_open(path: *const u8, flags: i32) -> i32 { - unsafe { - let fd: i64; - core::arch::asm!( - "syscall 0", - in("$a7") 56i64, // SYS_openat - in("$a0") -100i32, // AT_FDCWD - in("$a1") path, - in("$a2") flags, - in("$a3") 0i32, // mode - lateout("$a0") 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!( - "syscall 0", - in("$a7") 63i64, // SYS_read - in("$a0") fd, - in("$a1") buf, - in("$a2") count, - lateout("$a0") 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!( - "syscall 0", - in("$a7") 64i64, // SYS_write - in("$a0") fd, - in("$a1") buf, - in("$a2") count, - lateout("$a0") 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!( - "syscall 0", - in("$a7") 57i64, // SYS_close - in("$a0") fd, - lateout("$a0") 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!( - "syscall 0", - in("$a7") 160i64, // SYS_uname - in("$a0") buf, - lateout("$a0") 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!( - "syscall 0", - in("$a7") 43i64, // SYS_statfs - in("$a0") path, - in("$a1") buf, - lateout("$a0") 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!( - "syscall 0", - in("$a7") 179_i64, // __NR_sysinfo - in("$a0") info, - lateout("$a0") 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!( - "syscall 0", - in("$a7") 123i64, // __NR_sched_getaffinity - in("$a0") pid, - in("$a1") mask_size, - in("$a2") mask, - lateout("$a0") ret, - options(nostack) - ); - #[allow(clippy::cast_possible_truncation)] - { - ret as i32 - } - } -} - -pub(super) unsafe fn sys_exit(code: i32) -> ! { - unsafe { - core::arch::asm!( - "syscall 0", - in("$a7") 93i64, // SYS_exit - in("$a0") code, - options(noreturn, nostack) - ); - } -} diff --git a/crates/asm/src/mips.rs b/crates/asm/src/mips.rs deleted file mode 100644 index c5adf17..0000000 --- a/crates/asm/src/mips.rs +++ /dev/null @@ -1,196 +0,0 @@ -//! Syscall implementations for `mips`. - -use super::{StatfsBuf, SysInfo, UtsNameBuf}; - -pub(super) unsafe fn sys_open(path: *const u8, flags: i32) -> i32 { - unsafe { - let ret: i32; - core::arch::asm!( - "syscall", - "beqz $7, 1f", - "nop", - "subu $2, $0, $2", - "1:", - inlateout("$2") 4000i32 + 5 => ret, // SYS_open - in("$4") path, - in("$5") flags, - in("$6") 0i32, // mode - lateout("$7") _, - lateout("$8") _, lateout("$9") _, lateout("$10") _, lateout("$11") _, - lateout("$12") _, lateout("$13") _, lateout("$14") _, lateout("$15") _, - lateout("$24") _, lateout("$25") _, - options(nostack) - ); - ret - } -} - -pub(super) unsafe fn sys_read(fd: i32, buf: *mut u8, count: usize) -> isize { - unsafe { - let ret: i32; - core::arch::asm!( - "syscall", - "beqz $7, 1f", - "nop", - "subu $2, $0, $2", - "1:", - inlateout("$2") 4000i32 + 3 => ret, // SYS_read - in("$4") fd, - in("$5") buf, - in("$6") count, - lateout("$7") _, - lateout("$8") _, lateout("$9") _, lateout("$10") _, lateout("$11") _, - lateout("$12") _, lateout("$13") _, lateout("$14") _, lateout("$15") _, - lateout("$24") _, lateout("$25") _, - 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!( - "syscall", - "beqz $7, 1f", - "nop", - "subu $2, $0, $2", - "1:", - inlateout("$2") 4000i32 + 4 => ret, // SYS_write - in("$4") fd, - in("$5") buf, - in("$6") count, - lateout("$7") _, - lateout("$8") _, lateout("$9") _, lateout("$10") _, lateout("$11") _, - lateout("$12") _, lateout("$13") _, lateout("$14") _, lateout("$15") _, - lateout("$24") _, lateout("$25") _, - options(nostack) - ); - ret as isize - } -} - -pub(super) unsafe fn sys_close(fd: i32) -> i32 { - unsafe { - let ret: i32; - core::arch::asm!( - "syscall", - "beqz $7, 1f", - "nop", - "subu $2, $0, $2", - "1:", - inlateout("$2") 4000i32 + 6 => ret, // SYS_close - in("$4") fd, - lateout("$7") _, - lateout("$8") _, lateout("$9") _, lateout("$10") _, lateout("$11") _, - lateout("$12") _, lateout("$13") _, lateout("$14") _, lateout("$15") _, - lateout("$24") _, lateout("$25") _, - options(nostack) - ); - ret - } -} - -pub(super) unsafe fn sys_uname(buf: *mut UtsNameBuf) -> i32 { - unsafe { - let ret: i32; - core::arch::asm!( - "syscall", - "beqz $7, 1f", - "nop", - "subu $2, $0, $2", - "1:", - inlateout("$2") 4000i32 + 122 => ret, // SYS_newuname - in("$4") buf, - lateout("$7") _, - lateout("$8") _, lateout("$9") _, lateout("$10") _, lateout("$11") _, - lateout("$12") _, lateout("$13") _, lateout("$14") _, lateout("$15") _, - lateout("$24") _, lateout("$25") _, - options(nostack) - ); - ret - } -} - -pub(super) unsafe fn sys_statfs(path: *const u8, buf: *mut StatfsBuf) -> i32 { - unsafe { - let ret: i32; - core::arch::asm!( - "syscall", - "beqz $7, 1f", - "nop", - "subu $2, $0, $2", - "1:", - inlateout("$2") 4000i32 + 255 => ret, // SYS_statfs64 - in("$4") path, - in("$5") core::mem::size_of::(), - in("$6") buf, - lateout("$7") _, - lateout("$8") _, lateout("$9") _, lateout("$10") _, lateout("$11") _, - lateout("$12") _, lateout("$13") _, lateout("$14") _, lateout("$15") _, - lateout("$24") _, lateout("$25") _, - options(nostack) - ); - ret - } -} - -pub(super) unsafe fn sys_sysinfo(info: *mut SysInfo) -> i64 { - unsafe { - let ret: i32; - core::arch::asm!( - "syscall", - "beqz $7, 1f", - "nop", - "subu $2, $0, $2", - "1:", - inlateout("$2") 4000_i32 + 116 => ret, // __NR_sysinfo - in("$4") info, - lateout("$7") _, - lateout("$8") _, lateout("$9") _, lateout("$10") _, lateout("$11") _, - lateout("$12") _, lateout("$13") _, lateout("$14") _, lateout("$15") _, - lateout("$24") _, lateout("$25") _, - 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!( - "syscall", - "beqz $7, 1f", - "nop", - "subu $2, $0, $2", - "1:", - inlateout("$2") 4000i32 + 240 => ret, // __NR_sched_getaffinity - in("$4") pid, - in("$5") mask_size, - in("$6") mask, - lateout("$7") _, - lateout("$8") _, lateout("$9") _, lateout("$10") _, lateout("$11") _, - lateout("$12") _, lateout("$13") _, lateout("$14") _, lateout("$15") _, - lateout("$24") _, lateout("$25") _, - options(nostack) - ); - ret - } -} - -pub(super) unsafe fn sys_exit(code: i32) -> ! { - unsafe { - core::arch::asm!( - "syscall", - in("$2") 4000i32 + 1, // SYS_exit - in("$4") code, - options(noreturn, nostack) - ); - } -} diff --git a/crates/asm/src/mips64.rs b/crates/asm/src/mips64.rs deleted file mode 100644 index 9127a1e..0000000 --- a/crates/asm/src/mips64.rs +++ /dev/null @@ -1,206 +0,0 @@ -//! Syscall implementations for `mips64`. - -use super::{StatfsBuf, SysInfo, UtsNameBuf}; - -pub(super) unsafe fn sys_open(path: *const u8, flags: i32) -> i32 { - unsafe { - let ret: i64; - core::arch::asm!( - "syscall", - "beqz $7, 1f", - "nop", - "dsubu $2, $0, $2", - "1:", - inlateout("$2") 5000i64 + 2 => ret, // SYS_open - in("$4") path, - in("$5") flags, - in("$6") 0i32, // mode - lateout("$7") _, - lateout("$8") _, lateout("$9") _, lateout("$10") _, lateout("$11") _, - lateout("$12") _, lateout("$13") _, lateout("$14") _, lateout("$15") _, - lateout("$24") _, lateout("$25") _, - options(nostack) - ); - #[allow(clippy::cast_possible_truncation)] - { - ret as i32 - } - } -} - -pub(super) unsafe fn sys_read(fd: i32, buf: *mut u8, count: usize) -> isize { - unsafe { - let ret: i64; - core::arch::asm!( - "syscall", - "beqz $7, 1f", - "nop", - "dsubu $2, $0, $2", - "1:", - inlateout("$2") 5000i64 + 0 => ret, // SYS_read - in("$4") fd, - in("$5") buf, - in("$6") count, - lateout("$7") _, - lateout("$8") _, lateout("$9") _, lateout("$10") _, lateout("$11") _, - lateout("$12") _, lateout("$13") _, lateout("$14") _, lateout("$15") _, - lateout("$24") _, lateout("$25") _, - options(nostack) - ); - ret as isize - } -} - -pub(super) unsafe fn sys_write(fd: i32, buf: *const u8, count: usize) -> isize { - unsafe { - let ret: i64; - core::arch::asm!( - "syscall", - "beqz $7, 1f", - "nop", - "dsubu $2, $0, $2", - "1:", - inlateout("$2") 5000i64 + 1 => ret, // SYS_write - in("$4") fd, - in("$5") buf, - in("$6") count, - lateout("$7") _, - lateout("$8") _, lateout("$9") _, lateout("$10") _, lateout("$11") _, - lateout("$12") _, lateout("$13") _, lateout("$14") _, lateout("$15") _, - lateout("$24") _, lateout("$25") _, - options(nostack) - ); - ret as isize - } -} - -pub(super) unsafe fn sys_close(fd: i32) -> i32 { - unsafe { - let ret: i64; - core::arch::asm!( - "syscall", - "beqz $7, 1f", - "nop", - "dsubu $2, $0, $2", - "1:", - inlateout("$2") 5000i64 + 3 => ret, // SYS_close - in("$4") fd, - lateout("$7") _, - lateout("$8") _, lateout("$9") _, lateout("$10") _, lateout("$11") _, - lateout("$12") _, lateout("$13") _, lateout("$14") _, lateout("$15") _, - lateout("$24") _, lateout("$25") _, - 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!( - "syscall", - "beqz $7, 1f", - "nop", - "dsubu $2, $0, $2", - "1:", - inlateout("$2") 5000i64 + 61 => ret, // SYS_newuname - in("$4") buf, - lateout("$7") _, - lateout("$8") _, lateout("$9") _, lateout("$10") _, lateout("$11") _, - lateout("$12") _, lateout("$13") _, lateout("$14") _, lateout("$15") _, - lateout("$24") _, lateout("$25") _, - 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!( - "syscall", - "beqz $7, 1f", - "nop", - "dsubu $2, $0, $2", - "1:", - inlateout("$2") 5000i64 + 134 => ret, // SYS_statfs - in("$4") path, - in("$5") buf, - lateout("$7") _, - lateout("$8") _, lateout("$9") _, lateout("$10") _, lateout("$11") _, - lateout("$12") _, lateout("$13") _, lateout("$14") _, lateout("$15") _, - lateout("$24") _, lateout("$25") _, - 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!( - "syscall", - "beqz $7, 1f", - "nop", - "dsubu $2, $0, $2", - "1:", - inlateout("$2") 5000_i64 + 97 => ret, // SYS_sysinfo - in("$4") info, - lateout("$7") _, - lateout("$8") _, lateout("$9") _, lateout("$10") _, lateout("$11") _, - lateout("$12") _, lateout("$13") _, lateout("$14") _, lateout("$15") _, - lateout("$24") _, lateout("$25") _, - 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!( - "syscall", - inlateout("$2") 5000i64 + 196 => ret, // __NR_sched_getaffinity - in("$4") pid, - in("$5") mask_size, - in("$6") mask, - lateout("$7") _, - lateout("$8") _, lateout("$9") _, lateout("$10") _, lateout("$11") _, - lateout("$12") _, lateout("$13") _, lateout("$14") _, lateout("$15") _, - lateout("$24") _, lateout("$25") _, - options(nostack) - ); - #[allow(clippy::cast_possible_truncation)] - { - ret as i32 - } - } -} - -pub(super) unsafe fn sys_exit(code: i32) -> ! { - unsafe { - core::arch::asm!( - "syscall", - in("$2") 5000i64 + 58, // SYS_exit - in("$4") code, - options(noreturn, nostack) - ); - } -} diff --git a/crates/asm/src/powerpc.rs b/crates/asm/src/powerpc.rs deleted file mode 100644 index e2e7829..0000000 --- a/crates/asm/src/powerpc.rs +++ /dev/null @@ -1,180 +0,0 @@ -//! Syscall implementations for `powerpc`. - -use super::{StatfsBuf, SysInfo, UtsNameBuf}; - -pub(super) unsafe fn sys_open(path: *const u8, flags: i32) -> i32 { - unsafe { - let ret: i32; - core::arch::asm!( - "sc", - "bns+ 2f", - "neg 3, 3", - "2:", - inlateout("r0") 5i32 => _, // SYS_open - inlateout("r3") path => ret, - inlateout("r4") flags => _, - inlateout("r5") 0i32 => _, - out("r6") _, out("r7") _, out("r8") _, - out("r9") _, out("r10") _, out("r11") _, out("r12") _, - out("cr0") _, - options(nostack) - ); - ret - } -} - -pub(super) unsafe fn sys_read(fd: i32, buf: *mut u8, count: usize) -> isize { - unsafe { - let ret: i32; - core::arch::asm!( - "sc", - "bns+ 2f", - "neg 3, 3", - "2:", - inlateout("r0") 3i32 => _, // SYS_read - inlateout("r3") fd => ret, - inlateout("r4") buf => _, - inlateout("r5") count => _, - out("r6") _, out("r7") _, out("r8") _, - out("r9") _, out("r10") _, out("r11") _, out("r12") _, - out("cr0") _, - 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!( - "sc", - "bns+ 2f", - "neg 3, 3", - "2:", - inlateout("r0") 4i32 => _, // SYS_write - inlateout("r3") fd => ret, - inlateout("r4") buf => _, - inlateout("r5") count => _, - out("r6") _, out("r7") _, out("r8") _, - out("r9") _, out("r10") _, out("r11") _, out("r12") _, - out("cr0") _, - options(nostack) - ); - ret as isize - } -} - -pub(super) unsafe fn sys_close(fd: i32) -> i32 { - unsafe { - let ret: i32; - core::arch::asm!( - "sc", - "bns+ 2f", - "neg 3, 3", - "2:", - inlateout("r0") 6i32 => _, // SYS_close - inlateout("r3") fd => ret, - out("r4") _, out("r5") _, out("r6") _, out("r7") _, out("r8") _, - out("r9") _, out("r10") _, out("r11") _, out("r12") _, - out("cr0") _, - options(nostack) - ); - ret - } -} - -pub(super) unsafe fn sys_uname(buf: *mut UtsNameBuf) -> i32 { - unsafe { - let ret: i32; - core::arch::asm!( - "sc", - "bns+ 2f", - "neg 3, 3", - "2:", - inlateout("r0") 122i32 => _, // SYS_newuname - inlateout("r3") buf => ret, - out("r4") _, out("r5") _, out("r6") _, out("r7") _, out("r8") _, - out("r9") _, out("r10") _, out("r11") _, out("r12") _, - out("cr0") _, - options(nostack) - ); - ret - } -} - -pub(super) unsafe fn sys_statfs(path: *const u8, buf: *mut StatfsBuf) -> i32 { - unsafe { - let ret: i32; - core::arch::asm!( - "sc", - "bns+ 2f", - "neg 3, 3", - "2:", - inlateout("r0") 252i32 => _, // SYS_statfs64 - inlateout("r3") path => ret, - inlateout("r4") core::mem::size_of::() => _, - inlateout("r5") buf => _, - out("r6") _, out("r7") _, out("r8") _, - out("r9") _, out("r10") _, out("r11") _, out("r12") _, - out("cr0") _, - options(nostack) - ); - ret - } -} - -pub(super) unsafe fn sys_sysinfo(info: *mut SysInfo) -> i64 { - unsafe { - let ret: i32; - core::arch::asm!( - "sc", - "bns+ 2f", - "neg 3, 3", - "2:", - inlateout("r0") 116_i32 => _, // __NR_sysinfo - inlateout("r3") info => ret, - out("r4") _, out("r5") _, out("r6") _, out("r7") _, out("r8") _, - out("r9") _, out("r10") _, out("r11") _, out("r12") _, - out("cr0") _, - 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!( - "sc", - "bns+ 2f", - "neg 3, 3", - "2:", - inlateout("r0") 223i32 => _, // __NR_sched_getaffinity - inlateout("r3") pid => ret, - inlateout("r4") mask_size => _, - inlateout("r5") mask => _, - out("r6") _, out("r7") _, out("r8") _, - out("r9") _, out("r10") _, out("r11") _, out("r12") _, - out("cr0") _, - options(nostack) - ); - ret - } -} - -pub(super) unsafe fn sys_exit(code: i32) -> ! { - unsafe { - core::arch::asm!( - "li 0, 1", // SYS_exit - "sc", - in("r3") code, - options(noreturn, nostack) - ); - } -} diff --git a/crates/asm/src/powerpc64.rs b/crates/asm/src/powerpc64.rs deleted file mode 100644 index 13e0b33..0000000 --- a/crates/asm/src/powerpc64.rs +++ /dev/null @@ -1,200 +0,0 @@ -//! Syscall implementations for `powerpc64`. - -use super::{StatfsBuf, SysInfo, UtsNameBuf}; - -pub(super) unsafe fn sys_open(path: *const u8, flags: i32) -> i32 { - unsafe { - let ret: i64; - core::arch::asm!( - "sc", - "bns+ 2f", - "neg 3, 3", - "2:", - inlateout("r0") 5i64 => _, // SYS_open - inlateout("r3") path => ret, - inlateout("r4") flags => _, - inlateout("r5") 0i32 => _, // mode - out("r6") _, out("r7") _, out("r8") _, - out("r9") _, out("r10") _, out("r11") _, out("r12") _, - out("cr0") _, - options(nostack) - ); - #[allow(clippy::cast_possible_truncation)] - { - ret as i32 - } - } -} - -pub(super) unsafe fn sys_read(fd: i32, buf: *mut u8, count: usize) -> isize { - unsafe { - let ret: i64; - core::arch::asm!( - "sc", - "bns+ 2f", - "neg 3, 3", - "2:", - inlateout("r0") 3i64 => _, // SYS_read - inlateout("r3") fd as i64 => ret, - inlateout("r4") buf => _, - inlateout("r5") count => _, - out("r6") _, out("r7") _, out("r8") _, - out("r9") _, out("r10") _, out("r11") _, out("r12") _, - out("cr0") _, - 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!( - "sc", - "bns+ 2f", - "neg 3, 3", - "2:", - inlateout("r0") 4i64 => _, // SYS_write - inlateout("r3") fd as i64 => ret, - inlateout("r4") buf => _, - inlateout("r5") count => _, - out("r6") _, out("r7") _, out("r8") _, - out("r9") _, out("r10") _, out("r11") _, out("r12") _, - out("cr0") _, - 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!( - "sc", - "bns+ 2f", - "neg 3, 3", - "2:", - inlateout("r0") 6i64 => _, // SYS_close - inlateout("r3") fd as i64 => ret, - out("r4") _, out("r5") _, out("r6") _, out("r7") _, out("r8") _, - out("r9") _, out("r10") _, out("r11") _, out("r12") _, - out("cr0") _, - 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!( - "sc", - "bns+ 2f", - "neg 3, 3", - "2:", - inlateout("r0") 122i64 => _, // SYS_uname - inlateout("r3") buf => ret, - out("r4") _, out("r5") _, out("r6") _, out("r7") _, out("r8") _, - out("r9") _, out("r10") _, out("r11") _, out("r12") _, - out("cr0") _, - 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!( - "sc", - "bns+ 2f", - "neg 3, 3", - "2:", - inlateout("r0") 99i64 => _, // SYS_statfs - inlateout("r3") path => ret, - inlateout("r4") buf => _, - out("r5") _, out("r6") _, out("r7") _, out("r8") _, - out("r9") _, out("r10") _, out("r11") _, out("r12") _, - out("cr0") _, - 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!( - "sc", - "bns+ 2f", - "neg 3, 3", - "2:", - inlateout("r0") 116_i64 => _, // __NR_sysinfo - inlateout("r3") info => ret, - out("r4") _, out("r5") _, out("r6") _, out("r7") _, out("r8") _, - out("r9") _, out("r10") _, out("r11") _, out("r12") _, - out("cr0") _, - 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!( - "sc", - "bns+ 2f", - "neg 3, 3", - "2:", - inlateout("r0") 223i64 => _, // __NR_sched_getaffinity - inlateout("r3") pid as i64 => ret, - inlateout("r4") mask_size => _, - inlateout("r5") mask => _, - out("r6") _, out("r7") _, out("r8") _, - out("r9") _, out("r10") _, out("r11") _, out("r12") _, - out("cr0") _, - options(nostack) - ); - #[allow(clippy::cast_possible_truncation)] - { - ret as i32 - } - } -} - -pub(super) unsafe fn sys_exit(code: i32) -> ! { - unsafe { - core::arch::asm!( - "li 0, 1", // SYS_exit - "sc", - in("r3") code, - options(noreturn, nostack) - ); - } -} diff --git a/crates/asm/src/riscv32.rs b/crates/asm/src/riscv32.rs deleted file mode 100644 index 1e4b29a..0000000 --- a/crates/asm/src/riscv32.rs +++ /dev/null @@ -1,142 +0,0 @@ -//! Syscall implementations for `riscv32`. - -use super::{StatfsBuf, SysInfo, UtsNameBuf}; - -pub(super) unsafe fn sys_open(path: *const u8, flags: i32) -> i32 { - unsafe { - let ret: i32; - core::arch::asm!( - "ecall", - in("a7") 56i32, // SYS_openat - in("a0") -100i32, // AT_FDCWD - in("a1") path, - in("a2") flags, - in("a3") 0i32, // mode - lateout("a0") 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!( - "ecall", - in("a7") 63i32, // SYS_read - in("a0") fd, - in("a1") buf, - in("a2") count, - lateout("a0") 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!( - "ecall", - in("a7") 64i32, // SYS_write - in("a0") fd, - in("a1") buf, - in("a2") count, - lateout("a0") ret, - options(nostack) - ); - ret as isize - } -} - -pub(super) unsafe fn sys_close(fd: i32) -> i32 { - unsafe { - let ret: i32; - core::arch::asm!( - "ecall", - in("a7") 57i32, // SYS_close - in("a0") fd, - lateout("a0") ret, - options(nostack) - ); - ret - } -} - -pub(super) unsafe fn sys_uname(buf: *mut UtsNameBuf) -> i32 { - unsafe { - let ret: i32; - core::arch::asm!( - "ecall", - in("a7") 160i32, // SYS_uname - in("a0") buf, - lateout("a0") ret, - options(nostack) - ); - ret - } -} - -pub(super) unsafe fn sys_statfs(path: *const u8, buf: *mut StatfsBuf) -> i32 { - unsafe { - // asm-generic __NR_statfs routes to sys_statfs64 on 32-bit: 3-arg form. - let ret: i32; - core::arch::asm!( - "ecall", - in("a7") 43i32, // __NR_statfs - in("a0") path, - in("a1") core::mem::size_of::(), - in("a2") buf, - lateout("a0") ret, - options(nostack) - ); - ret - } -} - -pub(super) unsafe fn sys_sysinfo(info: *mut SysInfo) -> i64 { - unsafe { - let ret: i32; - core::arch::asm!( - "ecall", - in("a7") 179_i32, // __NR_sysinfo - in("a0") info, - lateout("a0") 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!( - "ecall", - in("a7") 123i32, // __NR_sched_getaffinity - in("a0") pid, - in("a1") mask_size, - in("a2") mask, - lateout("a0") ret, - options(nostack) - ); - ret - } -} - -pub(super) unsafe fn sys_exit(code: i32) -> ! { - unsafe { - core::arch::asm!( - "ecall", - in("a7") 93i32, // SYS_exit - in("a0") code, - options(noreturn, nostack) - ); - } -} diff --git a/crates/asm/src/riscv64.rs b/crates/asm/src/riscv64.rs deleted file mode 100644 index 2a0c10b..0000000 --- a/crates/asm/src/riscv64.rs +++ /dev/null @@ -1,166 +0,0 @@ -//! Syscall implementations for `riscv64`. - -use super::{StatfsBuf, SysInfo, UtsNameBuf}; - -pub(super) unsafe fn sys_open(path: *const u8, flags: i32) -> i32 { - unsafe { - let fd: i64; - core::arch::asm!( - "ecall", - in("a7") 56i64, // SYS_openat - in("a0") -100i32, // AT_FDCWD - in("a1") path, - in("a2") flags, - in("a3") 0i32, // mode - lateout("a0") 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!( - "ecall", - in("a7") 63i64, // SYS_read - in("a0") fd, - in("a1") buf, - in("a2") count, - lateout("a0") 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!( - "ecall", - in("a7") 64i64, // SYS_write - in("a0") fd, - in("a1") buf, - in("a2") count, - lateout("a0") 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!( - "ecall", - in("a7") 57i64, // SYS_close - in("a0") fd, - lateout("a0") 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!( - "ecall", - in("a7") 160i64, // SYS_uname - in("a0") buf, - lateout("a0") 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!( - "ecall", - in("a7") 43i64, // SYS_statfs - in("a0") path, - in("a1") buf, - lateout("a0") 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!( - "ecall", - in("a7") 179_i64, // __NR_sysinfo - in("a0") info, - lateout("a0") 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!( - "ecall", - in("a7") 123i64, // __NR_sched_getaffinity - in("a0") pid, - in("a1") mask_size, - in("a2") mask, - lateout("a0") ret, - options(nostack) - ); - #[allow(clippy::cast_possible_truncation)] - { - ret as i32 - } - } -} - -pub(super) unsafe fn sys_exit(code: i32) -> ! { - unsafe { - core::arch::asm!( - "ecall", - in("a7") 93i64, // SYS_exit - in("a0") code, - options(noreturn, nostack) - ); - } -} diff --git a/crates/asm/src/s390x.rs b/crates/asm/src/s390x.rs deleted file mode 100644 index 3112ed6..0000000 --- a/crates/asm/src/s390x.rs +++ /dev/null @@ -1,160 +0,0 @@ -//! Syscall implementations for `s390x`. - -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("r1") 5i64, // SYS_open - in("r2") path, - in("r3") flags, - in("r4") 0i32, // mode - lateout("r2") 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("r1") 3i64, // SYS_read - in("r2") fd, - in("r3") buf, - in("r4") count, - lateout("r2") 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("r1") 4i64, // SYS_write - in("r2") fd, - in("r3") buf, - in("r4") count, - lateout("r2") 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("r1") 6i64, // SYS_close - in("r2") fd, - lateout("r2") 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("r1") 122i64, // SYS_uname - in("r2") buf, - lateout("r2") 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("r1") 99i64, // SYS_statfs - in("r2") path, - in("r3") buf, - lateout("r2") 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("r1") 116_i64, // __NR_sysinfo - in("r2") info, - lateout("r2") 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("r1") 240i64, // __NR_sched_getaffinity - in("r2") pid, - in("r3") mask_size, - in("r4") mask, - lateout("r2") 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("r1") 1i64, // SYS_exit - in("r2") code, - options(noreturn, nostack) - ); - } -} diff --git a/crates/asm/src/sparc.rs b/crates/asm/src/sparc.rs deleted file mode 100644 index a4cc3f7..0000000 --- a/crates/asm/src/sparc.rs +++ /dev/null @@ -1,165 +0,0 @@ -//! Syscall implementations for `sparc`. - -use super::{StatfsBuf, SysInfo, UtsNameBuf}; - -pub(super) unsafe fn sys_open(path: *const u8, flags: i32) -> i32 { - unsafe { - let ret: i32; - core::arch::asm!( - "mov {nr}, %g1", - "ta 0x10", - "bcs,a 1f", - "sub %g0, %o0, %o0", - "1:", - nr = in(reg) 5i32, // SYS_open - inlateout("o0") path => ret, - in("o1") flags, - in("o2") 0i32, // mode - options(nostack) - ); - ret - } -} - -pub(super) unsafe fn sys_read(fd: i32, buf: *mut u8, count: usize) -> isize { - unsafe { - let ret: i32; - core::arch::asm!( - "mov {nr}, %g1", - "ta 0x10", - "bcs,a 1f", - "sub %g0, %o0, %o0", - "1:", - nr = in(reg) 3i32, // SYS_read - inlateout("o0") fd => ret, - in("o1") buf, - in("o2") count, - 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!( - "mov {nr}, %g1", - "ta 0x10", - "bcs,a 1f", - "sub %g0, %o0, %o0", - "1:", - nr = in(reg) 4i32, // SYS_write - inlateout("o0") fd => ret, - in("o1") buf, - in("o2") count, - options(nostack) - ); - ret as isize - } -} - -pub(super) unsafe fn sys_close(fd: i32) -> i32 { - unsafe { - let ret: i32; - core::arch::asm!( - "mov {nr}, %g1", - "ta 0x10", - "bcs,a 1f", - "sub %g0, %o0, %o0", - "1:", - nr = in(reg) 6i32, // SYS_close - inlateout("o0") fd => ret, - options(nostack) - ); - ret - } -} - -pub(super) unsafe fn sys_uname(buf: *mut UtsNameBuf) -> i32 { - unsafe { - let ret: i32; - core::arch::asm!( - "mov {nr}, %g1", - "ta 0x10", - "bcs,a 1f", - "sub %g0, %o0, %o0", - "1:", - nr = in(reg) 189i32, // SYS_newuname - inlateout("o0") buf => ret, - options(nostack) - ); - ret - } -} - -pub(super) unsafe fn sys_statfs(path: *const u8, buf: *mut StatfsBuf) -> i32 { - unsafe { - let ret: i32; - core::arch::asm!( - "mov {nr}, %g1", - "ta 0x10", - "bcs,a 1f", - "sub %g0, %o0, %o0", - "1:", - nr = in(reg) 234i32, // SYS_statfs64 - inlateout("o0") path => ret, - in("o1") core::mem::size_of::(), - in("o2") buf, - options(nostack) - ); - ret - } -} - -pub(super) unsafe fn sys_sysinfo(info: *mut SysInfo) -> i64 { - unsafe { - let ret: i32; - core::arch::asm!( - "mov {nr}, %g1", - "ta 0x10", - "bcs,a 1f", - "sub %g0, %o0, %o0", - "1:", - nr = in(reg) 214_i32, // __NR_sysinfo - inlateout("o0") info => 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!( - "mov {nr}, %g1", - "ta 0x10", - "bcs,a 1f", - "sub %g0, %o0, %o0", - "1:", - nr = in(reg) 260i32, // __NR_sched_getaffinity - inlateout("o0") pid => ret, - in("o1") mask_size, - in("o2") mask, - options(nostack) - ); - ret - } -} - -pub(super) unsafe fn sys_exit(code: i32) -> ! { - unsafe { - core::arch::asm!( - "mov {nr}, %g1", - "ta 0x10", - nr = in(reg) 1i32, // SYS_exit - in("o0") code, - options(noreturn, nostack) - ); - } -} diff --git a/crates/asm/src/sparc64.rs b/crates/asm/src/sparc64.rs deleted file mode 100644 index 020657e..0000000 --- a/crates/asm/src/sparc64.rs +++ /dev/null @@ -1,179 +0,0 @@ -//! Syscall implementations for `sparc64`. - -use super::{StatfsBuf, SysInfo, UtsNameBuf}; - -pub(super) unsafe fn sys_open(path: *const u8, flags: i32) -> i32 { - unsafe { - let ret: i64; - core::arch::asm!( - "mov {nr}, %g1", - "t 0x6d", - "bcs,a %xcc, 1f", - "sub %g0, %o0, %o0", - "1:", - nr = in(reg) 5i64, // SYS_open - inlateout("o0") path => ret, - in("o1") flags, - in("o2") 0i32, // mode - options(nostack) - ); - #[allow(clippy::cast_possible_truncation)] - { - ret as i32 - } - } -} - -pub(super) unsafe fn sys_read(fd: i32, buf: *mut u8, count: usize) -> isize { - unsafe { - let ret: i64; - core::arch::asm!( - "mov {nr}, %g1", - "t 0x6d", - "bcs,a %xcc, 1f", - "sub %g0, %o0, %o0", - "1:", - nr = in(reg) 3i64, // SYS_read - inlateout("o0") fd as i64 => ret, - in("o1") buf, - in("o2") count, - options(nostack) - ); - ret as isize - } -} - -pub(super) unsafe fn sys_write(fd: i32, buf: *const u8, count: usize) -> isize { - unsafe { - let ret: i64; - core::arch::asm!( - "mov {nr}, %g1", - "t 0x6d", - "bcs,a %xcc, 1f", - "sub %g0, %o0, %o0", - "1:", - nr = in(reg) 4i64, // SYS_write - inlateout("o0") fd as i64 => ret, - in("o1") buf, - in("o2") count, - options(nostack) - ); - ret as isize - } -} - -pub(super) unsafe fn sys_close(fd: i32) -> i32 { - unsafe { - let ret: i64; - core::arch::asm!( - "mov {nr}, %g1", - "t 0x6d", - "bcs,a %xcc, 1f", - "sub %g0, %o0, %o0", - "1:", - nr = in(reg) 6i64, // SYS_close - inlateout("o0") fd as i64 => 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!( - "mov {nr}, %g1", - "t 0x6d", - "bcs,a %xcc, 1f", - "sub %g0, %o0, %o0", - "1:", - nr = in(reg) 189i64, // SYS_newuname - inlateout("o0") buf => 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!( - "mov {nr}, %g1", - "t 0x6d", - "bcs,a %xcc, 1f", - "sub %g0, %o0, %o0", - "1:", - nr = in(reg) 157i64, // SYS_statfs - inlateout("o0") path => ret, - in("o1") buf, - 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!( - "mov {nr}, %g1", - "t 0x6d", - "bcs,a %xcc, 1f", - "sub %g0, %o0, %o0", - "1:", - nr = in(reg) 214_i64, // __NR_sysinfo - inlateout("o0") info => 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!( - "mov {nr}, %g1", - "t 0x6d", - "bcs,a %xcc, 1f", - "sub %g0, %o0, %o0", - "1:", - nr = in(reg) 260i64, // __NR_sched_getaffinity - inlateout("o0") pid as i64 => ret, - in("o1") mask_size, - in("o2") mask, - options(nostack) - ); - #[allow(clippy::cast_possible_truncation)] - { - ret as i32 - } - } -} - -pub(super) unsafe fn sys_exit(code: i32) -> ! { - unsafe { - core::arch::asm!( - "mov {nr}, %g1", - "t 0x6d", - nr = in(reg) 1i64, // SYS_exit - in("o0") code, - options(noreturn, nostack) - ); - } -} diff --git a/crates/asm/src/x86.rs b/crates/asm/src/x86.rs deleted file mode 100644 index f0e619e..0000000 --- a/crates/asm/src/x86.rs +++ /dev/null @@ -1,149 +0,0 @@ -//! Syscall implementations for `x86`. - -use super::{StatfsBuf, SysInfo, UtsNameBuf}; - -pub(super) unsafe fn sys_open(path: *const u8, flags: i32) -> i32 { - unsafe { - let ret: i32; - core::arch::asm!( - "push ebx", - "mov ebx, {arg1:e}", - "int 0x80", - "pop ebx", - arg1 = in(reg) path, - inlateout("eax") 5i32 => ret, // SYS_open - in("ecx") flags, - in("edx") 0i32, // mode - ); - ret - } -} - -pub(super) unsafe fn sys_read(fd: i32, buf: *mut u8, count: usize) -> isize { - unsafe { - let ret: i32; - core::arch::asm!( - "push ebx", - "mov ebx, {arg1:e}", - "int 0x80", - "pop ebx", - arg1 = in(reg) fd, - inlateout("eax") 3i32 => ret, // SYS_read - in("ecx") buf, - in("edx") count, - ); - ret as isize - } -} - -pub(super) unsafe fn sys_write(fd: i32, buf: *const u8, count: usize) -> isize { - unsafe { - let ret: i32; - core::arch::asm!( - "push ebx", - "mov ebx, {arg1:e}", - "int 0x80", - "pop ebx", - arg1 = in(reg) fd, - inlateout("eax") 4i32 => ret, // SYS_write - in("ecx") buf, - in("edx") count, - ); - ret as isize - } -} - -pub(super) unsafe fn sys_close(fd: i32) -> i32 { - unsafe { - let ret: i32; - core::arch::asm!( - "push ebx", - "mov ebx, {arg1:e}", - "int 0x80", - "pop ebx", - arg1 = in(reg) fd, - inlateout("eax") 6i32 => ret, // SYS_close - ); - ret - } -} - -pub(super) unsafe fn sys_uname(buf: *mut UtsNameBuf) -> i32 { - unsafe { - let ret: i32; - core::arch::asm!( - "push ebx", - "mov ebx, {arg1:e}", - "int 0x80", - "pop ebx", - arg1 = in(reg) buf, - inlateout("eax") 122i32 => ret, // SYS_newuname - ); - ret - } -} - -pub(super) unsafe fn sys_statfs(path: *const u8, buf: *mut StatfsBuf) -> i32 { - unsafe { - let ret: i32; - core::arch::asm!( - "push ebx", - "mov ebx, {arg1:e}", - "int 0x80", - "pop ebx", - arg1 = in(reg) path, - inlateout("eax") 268i32 => ret, // SYS_statfs64 - in("ecx") core::mem::size_of::(), - in("edx") buf, - ); - ret - } -} - -pub(super) unsafe fn sys_sysinfo(info: *mut SysInfo) -> i64 { - unsafe { - let ret: i32; - core::arch::asm!( - "push ebx", - "mov ebx, {arg1:e}", - "int 0x80", - "pop ebx", - arg1 = in(reg) info, - inlateout("eax") 116_i32 => ret, // __NR_sysinfo - ); - 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!( - "push ebx", - "mov ebx, {arg1:e}", - "int 0x80", - "pop ebx", - arg1 = in(reg) pid, - inlateout("eax") 242i32 => ret, // __NR_sched_getaffinity - in("ecx") mask_size, - in("edx") mask, - ); - ret - } -} - -pub(super) unsafe fn sys_exit(code: i32) -> ! { - unsafe { - core::arch::asm!( - "mov ebx, {code:e}", - "int 0x80", - code = in(reg) code, - in("eax") 1i32, // SYS_exit - options(noreturn) - ); - } -} diff --git a/crates/asm/src/x86_64.rs b/crates/asm/src/x86_64.rs deleted file mode 100644 index 967ddbf..0000000 --- a/crates/asm/src/x86_64.rs +++ /dev/null @@ -1,180 +0,0 @@ -//! Syscall implementations for `x86_64`. - -use super::{StatfsBuf, SysInfo, UtsNameBuf}; - -pub(super) unsafe fn sys_open(path: *const u8, flags: i32) -> i32 { - unsafe { - let fd: i64; - core::arch::asm!( - "syscall", - in("rax") 2i64, // SYS_open - in("rdi") path, - in("rsi") flags, - in("rdx") 0i32, // mode (not used for reading) - lateout("rax") fd, - lateout("rcx") _, - lateout("r11") _, - 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!( - "syscall", - in("rax") 0i64, // SYS_read - in("rdi") fd, - in("rsi") buf, - in("rdx") count, - lateout("rax") ret, - lateout("rcx") _, - lateout("r11") _, - 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!( - "syscall", - in("rax") 1i64, // SYS_write - in("rdi") fd, - in("rsi") buf, - in("rdx") count, - lateout("rax") ret, - lateout("rcx") _, - lateout("r11") _, - 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!( - "syscall", - in("rax") 3i64, // SYS_close - in("rdi") fd, - lateout("rax") ret, - lateout("rcx") _, - lateout("r11") _, - 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!( - "syscall", - in("rax") 63i64, // SYS_uname - in("rdi") buf, - lateout("rax") ret, - lateout("rcx") _, - lateout("r11") _, - 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!( - "syscall", - in("rax") 137i64, // SYS_statfs - in("rdi") path, - in("rsi") buf, - lateout("rax") ret, - lateout("rcx") _, - lateout("r11") _, - 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!( - "syscall", - in("rax") 99_i64, // __NR_sysinfo - in("rdi") info, - out("rcx") _, - out("r11") _, - lateout("rax") 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!( - "syscall", - in("rax") 204i64, // __NR_sched_getaffinity - in("rdi") pid, - in("rsi") mask_size, - in("rdx") mask, - lateout("rax") ret, - lateout("rcx") _, - lateout("r11") _, - options(nostack) - ); - #[allow(clippy::cast_possible_truncation)] - { - ret as i32 - } - } -} - -pub(super) unsafe fn sys_exit(code: i32) -> ! { - unsafe { - core::arch::asm!( - "syscall", - in("rax") 60i64, // SYS_exit - in("rdi") code, - options(noreturn, nostack) - ); - } -} diff --git a/crates/lib/Cargo.toml b/crates/lib/Cargo.toml index dc20548..176502a 100644 --- a/crates/lib/Cargo.toml +++ b/crates/lib/Cargo.toml @@ -9,7 +9,7 @@ license.workspace = true publish = false [dependencies] -hotpath = { optional = true, version = "0.15.1" } +hotpath = { optional = true, version = "0.14.0" } microfetch-asm.workspace = true [features] diff --git a/crates/lib/src/cpu.rs b/crates/lib/src/cpu.rs index dca327b..c6ed8a0 100644 --- a/crates/lib/src/cpu.rs +++ b/crates/lib/src/cpu.rs @@ -121,78 +121,29 @@ fn parse_num(data: &[u8], i: &mut usize) -> u32 { n } -/// Build `/sys/devices/system/cpu/cpu{n}/cpufreq/cpuinfo_max_freq` into buf, -/// returning the byte length written. -fn format_cpufreq_path(buf: &mut [u8; 64], cpu: u32) -> usize { - const PREFIX: &[u8] = b"/sys/devices/system/cpu/cpu"; - const SUFFIX: &[u8] = b"/cpufreq/cpuinfo_max_freq"; - buf[..PREFIX.len()].copy_from_slice(PREFIX); - let mut i = PREFIX.len(); - let mut tmp = [0u8; 3]; - let mut n = cpu; - let mut digits = 0; - loop { - tmp[digits] = b'0' + (n % 10) as u8; - digits += 1; - n /= 10; - if n == 0 { - break; - } - } - while digits > 0 { - digits -= 1; - buf[i] = tmp[digits]; - i += 1; - } - buf[i..i + SUFFIX.len()].copy_from_slice(SUFFIX); - i + SUFFIX.len() -} - /// Read CPU frequency in MHz. Tries sysfs first, then cpuinfo fields. fn get_cpu_freq_mhz() -> Option { - // Read cpuinfo_max_freq across all CPUs (in kHz) and take the max so - // heterogeneous (big.LITTLE) topologies report the performance cluster. - let mut max_khz = 0u32; - let mut path = [0u8; 64]; - for cpu in 0u32..64 { - let n = format_cpufreq_path(&mut path, cpu); - let p = match core::str::from_utf8(&path[..n]) { - Ok(s) => s, - Err(_) => continue, - }; - let mut buf = [0u8; 32]; - let Ok(m) = read_file_fast(p, &mut buf) else { - if cpu == 0 { - continue; - } - break; - }; + // Try sysfs cpuinfo_max_freq (in kHz) + let mut buf = [0u8; 32]; + if let Ok(n) = read_file_fast( + "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq", + &mut buf, + ) { let mut khz = 0u32; - for &b in &buf[..m] { + for &b in &buf[..n] { if b.is_ascii_digit() { khz = khz * 10 + u32::from(b - b'0'); } } - if khz > max_khz { - max_khz = khz; + if khz > 0 { + return Some(khz / 1000); } } - if max_khz > 0 { - return Some(max_khz / 1000); - } // Fall back to cpuinfo fields - let mut buf2 = [0u8; 4096]; + let mut buf2 = [0u8; 2048]; let n = read_file_fast("/proc/cpuinfo", &mut buf2).ok()?; let data = &buf2[..n]; - for key in &[ - b"cpu MHz" as &[u8], - b"cpu MHz dynamic", - b"cpu MHz static", - b"CPU MHz", - b"clock", - // BogoMIPS on MIPS is calibrated to the clock frequency (unlike x86). - b"BogoMIPS", - ] { + for key in &[b"cpu MHz" as &[u8], b"cpu MHz dynamic", b"CPU MHz"] { if let Some(val) = extract_field(data, key) { // Parse integer part of the MHz value (e.g. "5200.00" -> 5200) let mut mhz = 0u32; @@ -209,32 +160,6 @@ fn get_cpu_freq_mhz() -> Option { } } } - // SPARC exposes its clock as `Cpu0ClkTck : `, - // which signifies ticks per second in hex. - if let Some(val) = extract_field(data, b"Cpu0ClkTck") { - let mut hz = 0u64; - let mut seen = false; - for &b in val.as_bytes() { - let d = match b { - b'0'..=b'9' => Some(u64::from(b - b'0')), - b'a'..=b'f' => Some(u64::from(b - b'a' + 10)), - b'A'..=b'F' => Some(u64::from(b - b'A' + 10)), - _ => None, - }; - match d { - Some(d) => { - hz = hz * 16 + d; - seen = true; - }, - None if seen => break, - None => {}, - } - } - if hz > 0 { - #[allow(clippy::cast_possible_truncation)] - return Some((hz / 1_000_000) as u32); - } - } None } @@ -244,35 +169,10 @@ fn get_model_name() -> Option { let n = read_file_fast("/proc/cpuinfo", &mut buf).ok()?; let data = &buf[..n]; - let base = extract_name(data)?; - let mut name = base; - if let Some(mhz) = get_cpu_freq_mhz() { - name.push_str(" @ "); - // Round to nearest 0.01 GHz, then split so carries (e.g. 1999 MHz) - // roll into the integer part instead of overflowing the fraction. - let rounded_centesimal = (mhz + 5) / 10; - let ghz_int = rounded_centesimal / 100; - let ghz_frac = rounded_centesimal % 100; - write_u64(&mut name, u64::from(ghz_int)); - name.push('.'); - if ghz_frac < 10 { - name.push('0'); - } - write_u64(&mut name, u64::from(ghz_frac)); - name.push_str(" GHz"); - } - Some(name) -} - -/// Extract a human-readable CPU name. Tries cpuinfo fields first, then -/// falls back to the device-tree `compatible` string on SoCs that don't -/// expose a model through cpuinfo. -fn extract_name(data: &[u8]) -> Option { for key in &[ b"model name" as &[u8], b"Model Name", b"uarch", - b"cpu model", b"isa", b"cpu", b"machine", @@ -281,34 +181,28 @@ fn extract_name(data: &[u8]) -> Option { if let Some(val) = extract_field(data, key) { let trimmed = trim(val); if !trimmed.is_empty() { - return Some(String::from(trimmed)); + let mut name = String::from(trimmed); + if let Some(mhz) = get_cpu_freq_mhz() { + name.push_str(" @ "); + // Round to nearest 0.01 GHz, then split so carries (e.g. 1999 MHz) + // roll into the integer part instead of overflowing the fraction. + let rounded_centesimal = (mhz + 5) / 10; + let ghz_int = rounded_centesimal / 100; + let ghz_frac = rounded_centesimal % 100; + write_u64(&mut name, u64::from(ghz_int)); + name.push('.'); + if ghz_frac < 10 { + name.push('0'); + } + write_u64(&mut name, u64::from(ghz_frac)); + name.push_str(" GHz"); + } + return Some(name); } } } - parse_dt_compatible() -} -/// Parse the SoC name from `/sys/firmware/devicetree/base/compatible`. -/// The file holds NUL-separated `vendor,model` strings from most-specific -/// (board) to most-generic (SoC); we take the last entry and return just -/// the model portion after the comma. -fn parse_dt_compatible() -> Option { - let mut buf = [0u8; 256]; - let n = read_file_fast("/sys/firmware/devicetree/base/compatible", &mut buf) - .ok()?; - // Drop the terminating NUL so the rposition below locates the entry - // separator rather than the end-of-string marker. - let end = if n > 0 && buf[n - 1] == 0 { n - 1 } else { n }; - let data = &buf[..end]; - let start = data.iter().rposition(|&b| b == 0).map_or(0, |p| p + 1); - let entry = &data[start..]; - let comma = entry.iter().position(|&b| b == b',')?; - let model = core::str::from_utf8(&entry[comma + 1..]).ok()?; - if model.is_empty() { - None - } else { - Some(String::from(model)) - } + None } /// Extract value of first occurrence of `key` in cpuinfo. diff --git a/crates/lib/src/lib.rs b/crates/lib/src/lib.rs index d33bee1..1f74569 100644 --- a/crates/lib/src/lib.rs +++ b/crates/lib/src/lib.rs @@ -401,13 +401,7 @@ fn print_system_info(fields: &Fields) -> Result<(), Error> { // Row format mirrors the default logo path exactly. let rows: [(&str, &str, &str, &str, &str); 11] = [ ("", "", user_info.as_str(), " ", " ~"), - ( - "\u{F313} ", - "System", - os_name.as_str(), - " \u{E621} ", - "", - ), + ("\u{F313} ", "System", os_name.as_str(), " \u{E621} ", ""), ( "\u{E712} ", "Kernel", @@ -415,41 +409,11 @@ fn print_system_info(fields: &Fields) -> Result<(), Error> { " \u{E621} ", "", ), - ( - "\u{F2DB} ", - "CPU", - cpu_name.as_str(), - " \u{E621} ", - "", - ), - ( - "\u{F4BC} ", - "Topology", - cpu_cores.as_str(), - " \u{E621} ", - "", - ), - ( - "\u{E795} ", - "Shell", - shell.as_str(), - " \u{E621} ", - "", - ), - ( - "\u{F017} ", - "Uptime", - uptime.as_str(), - " \u{E621} ", - "", - ), - ( - "\u{F2D2} ", - "Desktop", - desktop.as_str(), - " \u{E621} ", - "", - ), + ("\u{F2DB} ", "CPU", cpu_name.as_str(), " \u{E621} ", ""), + ("\u{F4BC} ", "Topology", cpu_cores.as_str(), " \u{E621} ", ""), + ("\u{E795} ", "Shell", shell.as_str(), " \u{E621} ", ""), + ("\u{F017} ", "Uptime", uptime.as_str(), " \u{E621} ", ""), + ("\u{F2D2} ", "Desktop", desktop.as_str(), " \u{E621} ", ""), ( "\u{F035B} ", "Memory", @@ -457,20 +421,8 @@ fn print_system_info(fields: &Fields) -> Result<(), Error> { " \u{E621} ", "", ), - ( - "\u{F194E} ", - "Storage (/)", - storage.as_str(), - " \u{E621} ", - "", - ), - ( - "\u{E22B} ", - "Colors", - colors.as_str(), - " \u{E621} ", - "", - ), + ("\u{F194E} ", "Storage (/)", storage.as_str(), " \u{E621} ", ""), + ("\u{E22B} ", "Colors", colors.as_str(), " \u{E621} ", ""), ]; core::fmt::write(&mut w, format_args!("\n")).ok(); diff --git a/flake.lock b/flake.lock index b320b66..e5578c1 100644 --- a/flake.lock +++ b/flake.lock @@ -2,11 +2,11 @@ "nodes": { "nixpkgs": { "locked": { - "lastModified": 1776877367, - "narHash": "sha256-EHq1/OX139R1RvBzOJ0aMRT3xnWyqtHBRUBuO1gFzjI=", + "lastModified": 1770562336, + "narHash": "sha256-ub1gpAONMFsT/GU2hV6ZWJjur8rJ6kKxdm9IlCT0j84=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "0726a0ecb6d4e08f6adced58726b95db924cef57", + "rev": "d6c71932130818840fc8fe9509cf50be8c64634f", "type": "github" }, "original": { @@ -18,28 +18,7 @@ }, "root": { "inputs": { - "nixpkgs": "nixpkgs", - "rust-overlay": "rust-overlay" - } - }, - "rust-overlay": { - "inputs": { - "nixpkgs": [ - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1777346187, - "narHash": "sha256-oVxyGjpiIsrXhWTJVUOs38fZQkLjd0nZGOY9K7Kfot8=", - "owner": "oxalica", - "repo": "rust-overlay", - "rev": "146e7bf7569b8288f24d41d806b9f584f7cfd5b5", - "type": "github" - }, - "original": { - "owner": "oxalica", - "repo": "rust-overlay", - "type": "github" + "nixpkgs": "nixpkgs" } } }, diff --git a/flake.nix b/flake.nix index 50d00b9..90978a2 100644 --- a/flake.nix +++ b/flake.nix @@ -1,31 +1,25 @@ { - description = "Microscopic fetch script in Rust, for NixOS systems"; - inputs = { - nixpkgs.url = "github:NixOS/nixpkgs?ref=nixos-unstable"; - rust-overlay = { - url = "github:oxalica/rust-overlay"; - inputs.nixpkgs.follows = "nixpkgs"; - }; - }; + description = "A microscopic fetch script in Rust, for NixOS systems"; + inputs.nixpkgs.url = "github:NixOS/nixpkgs?ref=nixos-unstable"; outputs = { self, nixpkgs, - rust-overlay, }: let systems = ["x86_64-linux" "aarch64-linux"]; forEachSystem = nixpkgs.lib.genAttrs systems; - pkgsForEach = system: nixpkgs.legacyPackages.${system}.extend rust-overlay.overlays.default; + pkgsForEach = nixpkgs.legacyPackages; in { packages = forEachSystem (system: let - pkgs = pkgsForEach system; + pkgs = pkgsForEach.${system}; in { default = self.packages.${system}.microfetch; microfetch = pkgs.callPackage ./nix/package.nix {}; + microfetch-mold = pkgs.callPackage ./nix/package.nix {useMold = true;}; }); devShells = forEachSystem (system: { - default = (pkgsForEach system).callPackage ./nix/shell.nix {}; + default = pkgsForEach.${system}.callPackage ./nix/shell.nix {}; }); }; } diff --git a/microfetch/Cargo.toml b/microfetch/Cargo.toml index 86d168e..445a473 100644 --- a/microfetch/Cargo.toml +++ b/microfetch/Cargo.toml @@ -11,7 +11,7 @@ repository = "https://github.com/notashelf/microfetch" publish = true [dependencies] -hotpath = { optional = true, version = "0.15.1" } +hotpath = { optional = true, version = "0.15.0" } microfetch-alloc.workspace = true microfetch-asm.workspace = true microfetch-lib.workspace = true diff --git a/microfetch/src/main.rs b/microfetch/src/main.rs index d1b39b0..fcefcc8 100644 --- a/microfetch/src/main.rs +++ b/microfetch/src/main.rs @@ -1,23 +1,14 @@ #![no_std] #![no_main] -#![cfg_attr( - any( - target_arch = "sparc64", - target_arch = "sparc", - target_arch = "mips64", - target_arch = "mips" - ), - feature(asm_experimental_arch) -)] extern crate alloc; use core::{arch::naked_asm, panic::PanicInfo}; use microfetch_alloc::BumpAllocator; -use microfetch_asm::{entry_rust, sys_exit, sys_write}; // Re-export libc replacement functions from asm crate pub use microfetch_asm::{memcpy, memset, strlen}; +use microfetch_asm::{entry_rust, sys_exit, sys_write}; #[cfg(target_arch = "x86_64")] #[unsafe(no_mangle)] @@ -34,23 +25,6 @@ unsafe extern "C" fn _start() { ); } -#[cfg(target_arch = "x86")] -#[unsafe(no_mangle)] -#[unsafe(naked)] -unsafe extern "C" fn _start() { - naked_asm!( - "mov eax, esp", // save original sp (argc/argv) - "and esp, -16", // align stack to 16 bytes - "sub esp, 12", // leave room so that the one-arg push keeps alignment - "push eax", // arg: initial stack pointer - "call {entry_rust}", - "mov ebx, eax", // exit code -> first syscall arg - "mov eax, 1", // SYS_exit - "int 0x80", - entry_rust = sym entry_rust, - ); -} - #[cfg(target_arch = "aarch64")] #[unsafe(no_mangle)] #[unsafe(naked)] @@ -83,218 +57,6 @@ unsafe extern "C" fn _start() { ); } -#[cfg(target_arch = "loongarch64")] -#[unsafe(no_mangle)] -#[unsafe(naked)] -unsafe extern "C" fn _start() { - naked_asm!( - "or $a0, $sp, $zero", - "bstrins.d $sp, $zero, 3, 0", - "bl {entry_rust}", - "or $a0, $a0, $zero", - "li.w $a7, 93", - "syscall 0", - entry_rust = sym entry_rust, - ); -} - -#[cfg(target_arch = "s390x")] -#[unsafe(no_mangle)] -#[unsafe(naked)] -unsafe extern "C" fn _start() { - naked_asm!( - "lgr %r2, %r15", // save original sp (argc/argv) as arg - "aghi %r15, -160", // allocate s390x mandatory stack frame - "lghi %r0, -16", - "ngr %r15, %r0", // align stack to 16 bytes - "brasl %r14, {entry_rust}", - "lghi %r1, 1", // SYS_exit - "svc 0", - entry_rust = sym entry_rust, - ); -} - -// ELFv2 (ppc64le / new BE): entry point is code directly, no function -// descriptor needed. -#[cfg(all(target_arch = "powerpc64", target_abi = "elfv2"))] -#[unsafe(no_mangle)] -#[unsafe(naked)] -unsafe extern "C" fn _start() { - naked_asm!( - // Set up TOC (r2) for ELFv2 by computing from current PC - "bl 0f", - "0: mflr 12", - "addis 2, 12, .TOC. - 0b@ha", - "addi 2, 2, .TOC. - 0b@l", - // Save sp as first arg, set up stack frame - "mr 3, 1", - "clrrdi 1, 1, 4", - "stdu 1, -64(1)", - "bl {entry_rust}", - "nop", - "li 0, 1", - "sc", - entry_rust = sym entry_rust, - ); -} - -// ppc32 has no function descriptors; entry is direct code like ELFv2. -#[cfg(target_arch = "powerpc")] -#[unsafe(no_mangle)] -#[unsafe(naked)] -unsafe extern "C" fn _start() { - naked_asm!( - "mr 3, 1", // first arg = initial sp (argc/argv) - "clrrwi 1, 1, 4", // align sp to 16 bytes - "stwu 1, -64(1)", // reserve a frame with back-chain - "bl {entry_rust}", - "li 0, 1", // SYS_exit - "sc", - entry_rust = sym entry_rust, - ); -} - -// On ELFv1, the ELF entry point must be a function descriptor -// in .opd whose first word is the real code address. We emit both manually via -// `global_asm` so the kernel reads the descriptor and jumps into `_start_impl`. -#[cfg(all(target_arch = "powerpc64", target_abi = "elfv1"))] -core::arch::global_asm!( - ".section .opd, \"aw\"", - ".balign 8", - ".globl _start", - ".type _start, @object", - ".size _start, 24", - "_start:", - " .quad _start_impl", - " .quad .TOC.@tocbase", - " .quad 0", - ".previous", - ".text", - ".type _start_impl, @function", - "_start_impl:", - " mr 3, 1", - " clrrdi 1, 1, 4", - " stdu 1, -64(1)", - " bl entry_rust", - " nop", - " li 0, 1", - " sc", -); - -#[cfg(target_arch = "arm")] -#[unsafe(no_mangle)] -#[unsafe(naked)] -unsafe extern "C" fn _start() { - naked_asm!( - "mov r0, sp", // first arg = original sp (argc/argv) - "bic sp, sp, #7", // align sp to 8 bytes (AAPCS) - "bl {entry_rust}", - "mov r7, #1", // SYS_exit - "svc #0", - entry_rust = sym entry_rust, - ); -} - -#[cfg(target_arch = "riscv32")] -#[unsafe(no_mangle)] -#[unsafe(naked)] -unsafe extern "C" fn _start() { - naked_asm!( - "mv a0, sp", // first arg = original sp (argc/argv) - "andi sp, sp, -16", // align sp to 16 bytes - "call {entry_rust}", - "li a7, 93", // SYS_exit - "ecall", - entry_rust = sym entry_rust, - ); -} - -#[cfg(target_arch = "sparc64")] -#[unsafe(no_mangle)] -#[unsafe(naked)] -unsafe extern "C" fn _start() { - naked_asm!( - // SPARC v9: kernel sets %sp biased by -2047; argc is at - // %sp + 2047 + 128 (bias + 128-byte register save area). - // See glibc sysdeps/sparc/sparc64/start.S. - "mov %g0, %fp", - "add %sp, 2047+128, %o0", // first arg = &argc - "add %sp, 2047, %sp", // unbias - "sub %sp, 176, %sp", // reserve register save area - "and %sp, -16, %sp", // align - "sub %sp, 2047, %sp", // rebias - "call {entry_rust}", - "nop", // delay slot - "mov 1, %g1", // SYS_exit - "t 0x6d", - entry_rust = sym entry_rust, - ); -} - -#[cfg(target_arch = "mips64")] -#[unsafe(no_mangle)] -#[unsafe(naked)] -unsafe extern "C" fn _start() { - naked_asm!( - "move $a0, $sp", // first arg = original sp (argc/argv) - "daddiu $sp, $sp, -16",// reserve + keep 16-byte alignment (N64 ABI) - "jal {entry_rust}", - "nop", // delay slot - "move $a0, $v0", // exit code = entry_rust return value - "li $v0, 5058", // SYS_exit (5000 + 58) - "syscall", - entry_rust = sym entry_rust, - ); -} - -#[cfg(target_arch = "sparc")] -#[unsafe(no_mangle)] -#[unsafe(naked)] -unsafe extern "C" fn _start() { - naked_asm!( - "mov %g0, %fp", - "add %sp, 64, %o0", // first arg = &argc (past the 64-byte window save) - "and %sp, -16, %sp", // align sp to 16 bytes - "sub %sp, 64, %sp", // reserve window save area - "call {entry_rust}", - "nop", // delay slot - "mov 1, %g1", // SYS_exit (code already in %o0) - "ta 0x10", - entry_rust = sym entry_rust, - ); -} - -// SPARC V8 has no 1-byte CAS, so rustc emits calls to libatomic for byte -// atomics. We're single-threaded with panic=abort, so a plain load/store is -// already correct. -#[cfg(all(not(test), target_arch = "sparc"))] -#[unsafe(no_mangle)] -extern "C" fn __atomic_load_1(ptr: *const u8, _order: i32) -> u8 { - unsafe { core::ptr::read_volatile(ptr) } -} - -#[cfg(all(not(test), target_arch = "sparc"))] -#[unsafe(no_mangle)] -extern "C" fn __atomic_store_1(ptr: *mut u8, val: u8, _order: i32) { - unsafe { core::ptr::write_volatile(ptr, val) } -} - -#[cfg(target_arch = "mips")] -#[unsafe(no_mangle)] -#[unsafe(naked)] -unsafe extern "C" fn _start() { - naked_asm!( - "move $a0, $sp", // first arg = original sp (argc/argv) - "addiu $sp, $sp, -24", // reserve 16-byte O32 shadow space + align - "jal {entry_rust}", - "nop", // delay slot - "move $a0, $v0", // exit code = entry_rust return value - "li $v0, 4001", // SYS_exit (4000 + 1) - "syscall", - entry_rust = sym entry_rust, - ); -} - // Global allocator #[global_allocator] static ALLOCATOR: BumpAllocator = BumpAllocator::new(); @@ -348,14 +110,3 @@ const extern "C" fn rust_eh_personality() {} extern "C" fn _Unwind_Resume() -> ! { unsafe { sys_exit(1) } } - -// compiler_builtins emits `.ARM.exidx` entries that reference these even -// with panic=abort. libgcc/libunwind would normally resolve them; we're -// nostdlib, so we stub them. They're never called. -#[cfg(all(not(test), target_arch = "arm"))] -#[unsafe(no_mangle)] -extern "C" fn __aeabi_unwind_cpp_pr0() {} - -#[cfg(all(not(test), target_arch = "arm"))] -#[unsafe(no_mangle)] -extern "C" fn __aeabi_unwind_cpp_pr1() {} diff --git a/nix/package.nix b/nix/package.nix index 1657fd7..2658d73 100644 --- a/nix/package.nix +++ b/nix/package.nix @@ -1,20 +1,13 @@ { lib, - makeRustPlatform, - rust-bin, + rustPlatform, llvm, }: let pname = "microfetch"; toml = (lib.importTOML ../Cargo.toml).workspace.package; inherit (toml) version; - - toolchain = rust-bin.stable.latest; - rustWithToolchain = makeRustPlatform { - cargo = toolchain.minimal; - rustc = toolchain.minimal; - }; in - rustWithToolchain.buildRustPackage.override {inherit (llvm) stdenv;} { + rustPlatform.buildRustPackage.override {inherit (llvm) stdenv;} { inherit pname version; src = let fs = lib.fileset; @@ -23,9 +16,9 @@ in fs.toSource { root = s; fileset = fs.unions [ - (s + /.cargo) (s + /crates) (s + /microfetch) + (s + /.cargo) (s + /scripts/ld-wrapper) (s + /Cargo.lock) (s + /Cargo.toml)