diff --git a/Cargo.toml b/Cargo.toml index 1710d8ac7..e6b909518 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -38,7 +38,7 @@ once_cell = { version = "1.5.2", optional = true } # addition to the libc backend. The linux_raw backend is used by default. The # libc backend can be selected via adding `--cfg=rustix_use_libc` to # `RUSTFLAGS` or enabling the `use-libc` cargo feature. -[target.'cfg(all(not(rustix_use_libc), not(miri), target_os = "linux", any(target_arch = "x86", all(target_arch = "x86_64", target_pointer_width = "64"), all(target_endian = "little", any(target_arch = "arm", all(target_arch = "aarch64", target_pointer_width = "64"), target_arch = "powerpc64", target_arch = "riscv64", target_arch = "mips", target_arch = "mips64")))))'.dependencies] +[target.'cfg(all(not(rustix_use_libc), not(miri), target_os = "linux", any(target_arch = "x86", all(target_arch = "x86_64", target_pointer_width = "64"), all(target_endian = "little", any(target_arch = "arm", all(target_arch = "aarch64", target_pointer_width = "64"), target_arch = "powerpc64", target_arch = "riscv64", target_arch = "mips", target_arch = "mips64", target_arch = "loongarch64")))))'.dependencies] linux-raw-sys = { version = "0.3.0", default-features = false, features = ["general", "errno", "ioctl", "no_std"] } libc_errno = { package = "errno", version = "0.3.0", default-features = false, optional = true } libc = { version = "0.2.133", features = ["extra_traits"], optional = true } @@ -47,7 +47,7 @@ libc = { version = "0.2.133", features = ["extra_traits"], optional = true } # # On all other Unix-family platforms, and under Miri, we always use the libc # backend, so enable its dependencies unconditionally. -[target.'cfg(any(rustix_use_libc, miri, not(all(target_os = "linux", any(target_arch = "x86", all(target_arch = "x86_64", target_pointer_width = "64"), all(target_endian = "little", any(target_arch = "arm", all(target_arch = "aarch64", target_pointer_width = "64"), target_arch = "powerpc64", target_arch = "riscv64", target_arch = "mips", target_arch = "mips64")))))))'.dependencies] +[target.'cfg(any(rustix_use_libc, miri, not(all(target_os = "linux", any(target_arch = "x86", all(target_arch = "x86_64", target_pointer_width = "64"), all(target_endian = "little", any(target_arch = "arm", all(target_arch = "aarch64", target_pointer_width = "64"), target_arch = "powerpc64", target_arch = "riscv64", target_arch = "mips", target_arch = "mips64", target_arch = "loongarch64")))))))'.dependencies] libc_errno = { package = "errno", version = "0.3.0", default-features = false } libc = { version = "0.2.133", features = ["extra_traits"] } diff --git a/src/backend/linux_raw/arch/inline/loongarch64.rs b/src/backend/linux_raw/arch/inline/loongarch64.rs new file mode 100644 index 000000000..91216a7e0 --- /dev/null +++ b/src/backend/linux_raw/arch/inline/loongarch64.rs @@ -0,0 +1,265 @@ +//! loongarch64 Linux system calls. + +use crate::backend::reg::{ + ArgReg, FromAsm, RetReg, SyscallNumber, ToAsm, A0, A1, A2, A3, A4, A5, R0, +}; +use core::arch::asm; + +#[inline] +pub(in crate::backend) unsafe fn syscall0_readonly(nr: SyscallNumber<'_>) -> RetReg { + let r0; + asm!( + "syscall 0", + in("$a7") nr.to_asm(), + lateout("$a0") r0, + options(nostack, preserves_flags, readonly) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall1(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> RetReg { + let r0; + asm!( + "syscall 0", + in("$a7") nr.to_asm(), + inlateout("$a0") a0.to_asm() => r0, + options(nostack, preserves_flags) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall1_readonly( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, +) -> RetReg { + let r0; + asm!( + "syscall 0", + in("$a7") nr.to_asm(), + inlateout("$a0") a0.to_asm() => r0, + options(nostack, preserves_flags, readonly) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall1_noreturn(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> ! { + asm!( + "syscall 0", + in("$a7") nr.to_asm(), + in("$a0") a0.to_asm(), + options(noreturn) + ); +} + +#[inline] +pub(in crate::backend) unsafe fn syscall2( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, +) -> RetReg { + let r0; + asm!( + "syscall 0", + in("$a7") nr.to_asm(), + inlateout("$a0") a0.to_asm() => r0, + in("$a1") a1.to_asm(), + options(nostack, preserves_flags) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall2_readonly( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, +) -> RetReg { + let r0; + asm!( + "syscall 0", + in("$a7") nr.to_asm(), + inlateout("$a0") a0.to_asm() => r0, + in("$a1") a1.to_asm(), + options(nostack, preserves_flags, readonly) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall3( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, +) -> RetReg { + let r0; + asm!( + "syscall 0", + in("$a7") nr.to_asm(), + inlateout("$a0") a0.to_asm() => r0, + in("$a1") a1.to_asm(), + in("$a2") a2.to_asm(), + options(nostack, preserves_flags) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall3_readonly( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, +) -> RetReg { + let r0; + asm!( + "syscall 0", + in("$a7") nr.to_asm(), + inlateout("$a0") a0.to_asm() => r0, + in("$a1") a1.to_asm(), + in("$a2") a2.to_asm(), + options(nostack, preserves_flags, readonly) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall4( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, +) -> RetReg { + let r0; + asm!( + "syscall 0", + in("$a7") nr.to_asm(), + inlateout("$a0") a0.to_asm() => r0, + in("$a1") a1.to_asm(), + in("$a2") a2.to_asm(), + in("$a3") a3.to_asm(), + options(nostack, preserves_flags) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall4_readonly( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, +) -> RetReg { + let r0; + asm!( + "syscall 0", + in("$a7") nr.to_asm(), + inlateout("$a0") a0.to_asm() => r0, + in("$a1") a1.to_asm(), + in("$a2") a2.to_asm(), + in("$a3") a3.to_asm(), + options(nostack, preserves_flags, readonly) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall5( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, + a4: ArgReg<'_, A4>, +) -> RetReg { + let r0; + asm!( + "syscall 0", + in("$a7") nr.to_asm(), + inlateout("$a0") a0.to_asm() => r0, + in("$a1") a1.to_asm(), + in("$a2") a2.to_asm(), + in("$a3") a3.to_asm(), + in("$a4") a4.to_asm(), + options(nostack, preserves_flags) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall5_readonly( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, + a4: ArgReg<'_, A4>, +) -> RetReg { + let r0; + asm!( + "syscall 0", + in("$a7") nr.to_asm(), + inlateout("$a0") a0.to_asm() => r0, + in("$a1") a1.to_asm(), + in("$a2") a2.to_asm(), + in("$a3") a3.to_asm(), + in("$a4") a4.to_asm(), + options(nostack, preserves_flags, readonly) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall6( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, + a4: ArgReg<'_, A4>, + a5: ArgReg<'_, A5>, +) -> RetReg { + let r0; + asm!( + "syscall 0", + in("$a7") nr.to_asm(), + inlateout("$a0") a0.to_asm() => r0, + in("$a1") a1.to_asm(), + in("$a2") a2.to_asm(), + in("$a3") a3.to_asm(), + in("$a4") a4.to_asm(), + in("$a5") a5.to_asm(), + options(nostack, preserves_flags) + ); + FromAsm::from_asm(r0) +} + +#[inline] +pub(in crate::backend) unsafe fn syscall6_readonly( + nr: SyscallNumber<'_>, + a0: ArgReg<'_, A0>, + a1: ArgReg<'_, A1>, + a2: ArgReg<'_, A2>, + a3: ArgReg<'_, A3>, + a4: ArgReg<'_, A4>, + a5: ArgReg<'_, A5>, +) -> RetReg { + let r0; + asm!( + "syscall 0", + in("$a7") nr.to_asm(), + inlateout("$a0") a0.to_asm() => r0, + in("$a1") a1.to_asm(), + in("$a2") a2.to_asm(), + in("$a3") a3.to_asm(), + in("$a4") a4.to_asm(), + in("$a5") a5.to_asm(), + options(nostack, preserves_flags, readonly) + ); + FromAsm::from_asm(r0) +} diff --git a/src/backend/linux_raw/arch/inline/mod.rs b/src/backend/linux_raw/arch/inline/mod.rs index 524c449d9..2aa82d7b6 100644 --- a/src/backend/linux_raw/arch/inline/mod.rs +++ b/src/backend/linux_raw/arch/inline/mod.rs @@ -7,6 +7,7 @@ #[cfg_attr(target_arch = "aarch64", path = "aarch64.rs")] #[cfg_attr(all(target_arch = "arm", not(thumb_mode)), path = "arm.rs")] #[cfg_attr(all(target_arch = "arm", thumb_mode), path = "thumb.rs")] +#[cfg_attr(target_arch = "loongarch64", path = "loongarch64.rs")] #[cfg_attr(target_arch = "mips", path = "mips.rs")] #[cfg_attr(target_arch = "mips64", path = "mips64.rs")] #[cfg_attr(target_arch = "powerpc64", path = "powerpc64.rs")] diff --git a/src/backend/linux_raw/arch/mod.rs b/src/backend/linux_raw/arch/mod.rs index e13f675fd..44c989431 100644 --- a/src/backend/linux_raw/arch/mod.rs +++ b/src/backend/linux_raw/arch/mod.rs @@ -30,6 +30,7 @@ pub(in crate::backend) mod asm; #[cfg(any( target_arch = "arm", target_arch = "aarch64", + target_arch = "loongarch64", target_arch = "mips", target_arch = "mips64", target_arch = "powerpc64", diff --git a/src/backend/linux_raw/arch/outline/loongarch64.s b/src/backend/linux_raw/arch/outline/loongarch64.s new file mode 100644 index 000000000..409406ddd --- /dev/null +++ b/src/backend/linux_raw/arch/outline/loongarch64.s @@ -0,0 +1,116 @@ +# Assembly code for making loongarch64 syscalls. +# +# loongarch64 syscall argument register ordering is the same as the loongarch64 +# userspace argument register ordering except that the syscall number +# (nr) is passed in a7. +# +# nr_last.rs takes care of reordering the nr argument to the end for us, +# so we only need to move nr into a7. + + .file "loongarch64.s" + + .section .text.rustix_syscall0_nr_last,"ax",@progbits + .p2align 4 + .weak rustix_syscall0_nr_last + .hidden rustix_syscall0_nr_last + .type rustix_syscall0_nr_last, @function +rustix_syscall0_nr_last: + .cfi_startproc + move $a7, $a0 + syscall 0 + jr $ra + .cfi_endproc + .size rustix_syscall0_nr_last, .-rustix_syscall0_nr_last + + .section .text.rustix_syscall1_nr_last,"ax",@progbits + .p2align 4 + .weak rustix_syscall1_nr_last + .hidden rustix_syscall1_nr_last + .type rustix_syscall1_nr_last, @function +rustix_syscall1_nr_last: + .cfi_startproc + move $a7, $a1 + syscall 0 + jr $ra + .cfi_endproc + .size rustix_syscall1_nr_last, .-rustix_syscall1_nr_last + + .section .text.rustix_syscall1_noreturn_nr_last,"ax",@progbits + .p2align 4 + .weak rustix_syscall1_noreturn_nr_last + .hidden rustix_syscall1_noreturn_nr_last + .type rustix_syscall1_noreturn_nr_last, @function +rustix_syscall1_noreturn_nr_last: + .cfi_startproc + move $a7, $a1 + syscall 0 + break 0 + .cfi_endproc + .size rustix_syscall1_noreturn_nr_last, .-rustix_syscall1_noreturn_nr_last + + .section .text.rustix_syscall2_nr_last,"ax",@progbits + .p2align 4 + .weak rustix_syscall2_nr_last + .hidden rustix_syscall2_nr_last + .type rustix_syscall2_nr_last, @function +rustix_syscall2_nr_last: + .cfi_startproc + move $a7, $a2 + syscall 0 + jr $ra + .cfi_endproc + .size rustix_syscall2_nr_last, .-rustix_syscall2_nr_last + + .section .text.rustix_syscall3_nr_last,"ax",@progbits + .p2align 4 + .weak rustix_syscall3_nr_last + .hidden rustix_syscall3_nr_last + .type rustix_syscall3_nr_last, @function +rustix_syscall3_nr_last: + .cfi_startproc + move $a7, $a3 + syscall 0 + jr $ra + .cfi_endproc + .size rustix_syscall3_nr_last, .-rustix_syscall3_nr_last + + .section .text.rustix_syscall4_nr_last,"ax",@progbits + .p2align 4 + .weak rustix_syscall4_nr_last + .hidden rustix_syscall4_nr_last + .type rustix_syscall4_nr_last, @function +rustix_syscall4_nr_last: + .cfi_startproc + move $a7, $a4 + syscall 0 + jr $ra + .cfi_endproc + .size rustix_syscall4_nr_last, .-rustix_syscall4_nr_last + + .section .text.rustix_syscall5_nr_last,"ax",@progbits + .p2align 4 + .weak rustix_syscall5_nr_last + .hidden rustix_syscall5_nr_last + .type rustix_syscall5_nr_last, @function +rustix_syscall5_nr_last: + .cfi_startproc + move $a7, $a5 + syscall 0 + jr $ra + .cfi_endproc + .size rustix_syscall5_nr_last, .-rustix_syscall5_nr_last + + .section .text.rustix_syscall6_nr_last,"ax",@progbits + .p2align 4 + .weak rustix_syscall6_nr_last + .hidden rustix_syscall6_nr_last + .type rustix_syscall6_nr_last, @function +rustix_syscall6_nr_last: + .cfi_startproc + move $a7, $a6 + syscall 0 + jr $ra + .cfi_endproc + .size rustix_syscall6_nr_last, .-rustix_syscall6_nr_last + + .section .note.GNU-stack,"",@progbits diff --git a/src/backend/linux_raw/arch/outline/mod.rs b/src/backend/linux_raw/arch/outline/mod.rs index a6a5f270d..69fc46720 100644 --- a/src/backend/linux_raw/arch/outline/mod.rs +++ b/src/backend/linux_raw/arch/outline/mod.rs @@ -11,6 +11,7 @@ mod x86; #[cfg(any( target_arch = "arm", target_arch = "aarch64", + target_arch = "loongarch64", target_arch = "mips", target_arch = "mips64", target_arch = "powerpc64", @@ -22,6 +23,7 @@ mod nr_last; #[cfg(any( target_arch = "arm", target_arch = "aarch64", + target_arch = "loongarch64", target_arch = "mips", target_arch = "mips64", target_arch = "powerpc64", diff --git a/src/backend/linux_raw/conv.rs b/src/backend/linux_raw/conv.rs index 03170a52f..bd5dd960f 100644 --- a/src/backend/linux_raw/conv.rs +++ b/src/backend/linux_raw/conv.rs @@ -228,7 +228,11 @@ pub(super) fn opt_mut(t: Option<&mut T>) -> ArgReg(t: Option<&T>) -> ArgReg { // This optimizes into the equivalent of `transmute(t)`, and has the diff --git a/src/backend/linux_raw/elf.rs b/src/backend/linux_raw/elf.rs index 87fb5fa0f..ac3f0a18b 100644 --- a/src/backend/linux_raw/elf.rs +++ b/src/backend/linux_raw/elf.rs @@ -70,6 +70,8 @@ pub(super) const EM_CURRENT: u16 = 62; // EM_X86_64 pub(super) const EM_CURRENT: u16 = 183; // EM_AARCH64 #[cfg(target_arch = "riscv64")] pub(super) const EM_CURRENT: u16 = 243; // EM_RISCV +#[cfg(target_arch = "loongarch64")] +pub(super) const EM_CURRENT: u16 = 258; // EM_LOONGARCH #[inline] pub(super) const fn ELF_ST_VISIBILITY(o: u8) -> u8 { diff --git a/src/backend/linux_raw/fs/dir.rs b/src/backend/linux_raw/fs/dir.rs index cfa347d03..9377295fe 100644 --- a/src/backend/linux_raw/fs/dir.rs +++ b/src/backend/linux_raw/fs/dir.rs @@ -1,8 +1,8 @@ use crate::fd::{AsFd, BorrowedFd, OwnedFd}; use crate::ffi::{CStr, CString}; -use crate::fs::{ - fcntl_getfl, fstat, fstatfs, fstatvfs, openat, FileType, Mode, OFlags, Stat, StatFs, StatVfs, -}; +use crate::fs::{fcntl_getfl, fstatfs, fstatvfs, openat, FileType, Mode, OFlags, StatFs, StatVfs}; +#[cfg(not(target_arch = "loongarch64"))] +use crate::fs::{fstat, Stat}; use crate::io; use crate::process::fchdir; use crate::utils::as_ptr; @@ -157,6 +157,7 @@ impl Dir { } /// `fstat(self)` + #[cfg(not(target_arch = "loongarch64"))] #[inline] pub fn stat(&self) -> io::Result { fstat(&self.fd) diff --git a/src/backend/linux_raw/fs/syscalls.rs b/src/backend/linux_raw/fs/syscalls.rs index eba0268e0..7051a6865 100644 --- a/src/backend/linux_raw/fs/syscalls.rs +++ b/src/backend/linux_raw/fs/syscalls.rs @@ -18,14 +18,17 @@ use super::super::conv::{loff_t, loff_t_from_u64, ret_u64}; target_arch = "aarch64", target_arch = "riscv64", target_arch = "mips64", + target_arch = "loongarch64", target_pointer_width = "32", ))] use crate::fd::AsFd; use crate::fd::{BorrowedFd, OwnedFd}; use crate::ffi::CStr; +#[cfg(not(target_arch = "loongarch64"))] +use crate::fs::Stat; use crate::fs::{ inotify, Access, Advice, AtFlags, FallocateFlags, FileType, FlockOperation, MemfdFlags, Mode, - OFlags, RenameFlags, ResolveFlags, SealFlags, Stat, StatFs, StatVfs, StatVfsMountFlags, + OFlags, RenameFlags, ResolveFlags, SealFlags, StatFs, StatVfs, StatVfsMountFlags, StatxFlags, Timestamps, }; use crate::io::{self, SeekFrom}; @@ -50,20 +53,32 @@ use { #[inline] pub(crate) fn open(filename: &CStr, flags: OFlags, mode: Mode) -> io::Result { - #[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))] + #[cfg(any( + target_arch = "aarch64", + target_arch = "loongarch64", + target_arch = "riscv64" + ))] { openat(crate::fs::cwd().as_fd(), filename, flags, mode) } #[cfg(all( target_pointer_width = "32", - not(any(target_arch = "aarch64", target_arch = "riscv64")), + not(any( + target_arch = "aarch64", + target_arch = "loongarch64", + target_arch = "riscv64" + )), ))] unsafe { ret_owned_fd(syscall_readonly!(__NR_open, filename, flags, mode)) } #[cfg(all( target_pointer_width = "64", - not(any(target_arch = "aarch64", target_arch = "riscv64")), + not(any( + target_arch = "aarch64", + target_arch = "loongarch64", + target_arch = "riscv64" + )), ))] unsafe { ret_owned_fd(syscall_readonly!(__NR_open, filename, flags, mode)) @@ -413,6 +428,7 @@ pub(crate) fn flock(fd: BorrowedFd<'_>, operation: FlockOperation) -> io::Result unsafe { ret(syscall!(__NR_flock, fd, c_uint(operation as c::c_uint))) } } +#[cfg(not(target_arch = "loongarch64"))] #[inline] pub(crate) fn fstat(fd: BorrowedFd<'_>) -> io::Result { #[cfg(any(target_pointer_width = "32", target_arch = "mips64"))] @@ -449,6 +465,7 @@ fn fstat_old(fd: BorrowedFd<'_>) -> io::Result { } } +#[cfg(not(target_arch = "loongarch64"))] #[inline] pub(crate) fn stat(filename: &CStr) -> io::Result { #[cfg(any(target_pointer_width = "32", target_arch = "mips64"))] @@ -508,6 +525,7 @@ fn stat_old(filename: &CStr) -> io::Result { } } +#[cfg(not(target_arch = "loongarch64"))] #[inline] pub(crate) fn statat(dirfd: BorrowedFd<'_>, filename: &CStr, flags: AtFlags) -> io::Result { #[cfg(any(target_pointer_width = "32", target_arch = "mips64"))] @@ -562,6 +580,7 @@ fn statat_old(dirfd: BorrowedFd<'_>, filename: &CStr, flags: AtFlags) -> io::Res } } +#[cfg(not(target_arch = "loongarch64"))] #[inline] pub(crate) fn lstat(filename: &CStr) -> io::Result { #[cfg(any(target_pointer_width = "32", target_arch = "mips64"))] @@ -1076,7 +1095,7 @@ pub(crate) fn fcntl_lock(fd: BorrowedFd<'_>, operation: FlockOperation) -> io::R #[inline] pub(crate) fn rename(oldname: &CStr, newname: &CStr) -> io::Result<()> { - #[cfg(target_arch = "riscv64")] + #[cfg(any(target_arch = "loongarch64", target_arch = "riscv64"))] unsafe { ret(syscall_readonly!( __NR_renameat2, @@ -1087,7 +1106,7 @@ pub(crate) fn rename(oldname: &CStr, newname: &CStr) -> io::Result<()> { c_uint(0) )) } - #[cfg(not(target_arch = "riscv64"))] + #[cfg(not(any(target_arch = "loongarch64", target_arch = "riscv64")))] unsafe { ret(syscall_readonly!( __NR_renameat, @@ -1106,7 +1125,7 @@ pub(crate) fn renameat( new_dirfd: BorrowedFd<'_>, newname: &CStr, ) -> io::Result<()> { - #[cfg(target_arch = "riscv64")] + #[cfg(any(target_arch = "loongarch64", target_arch = "riscv64"))] unsafe { ret(syscall_readonly!( __NR_renameat2, @@ -1117,7 +1136,7 @@ pub(crate) fn renameat( c_uint(0) )) } - #[cfg(not(target_arch = "riscv64"))] + #[cfg(not(any(target_arch = "loongarch64", target_arch = "riscv64")))] unsafe { ret(syscall_readonly!( __NR_renameat, diff --git a/src/backend/linux_raw/fs/types.rs b/src/backend/linux_raw/fs/types.rs index 4a221f674..393af1998 100644 --- a/src/backend/linux_raw/fs/types.rs +++ b/src/backend/linux_raw/fs/types.rs @@ -573,7 +573,10 @@ pub struct Stat { /// /// [`statat`]: crate::fs::statat /// [`fstat`]: crate::fs::fstat -#[cfg(all(target_pointer_width = "64", not(target_arch = "mips64")))] +#[cfg(all( + target_pointer_width = "64", + not(any(target_arch = "mips64", target_arch = "loongarch64")) +))] pub type Stat = linux_raw_sys::general::stat; /// `struct statfs` for use with [`statfs`] and [`fstatfs`]. diff --git a/src/backend/linux_raw/io/syscalls.rs b/src/backend/linux_raw/io/syscalls.rs index 2cc7898af..d308dad57 100644 --- a/src/backend/linux_raw/io/syscalls.rs +++ b/src/backend/linux_raw/io/syscalls.rs @@ -33,7 +33,11 @@ use linux_raw_sys::general::{ UIO_MAXIOV, }; use linux_raw_sys::ioctl::{BLKPBSZGET, BLKSSZGET, FIONBIO, FIONREAD, TIOCEXCL, TIOCNXCL}; -#[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))] +#[cfg(any( + target_arch = "aarch64", + target_arch = "loongarch64", + target_arch = "riscv64" +))] use { super::super::conv::{opt_ref, size_of}, linux_raw_sys::general::{__kernel_timespec, sigset_t}, @@ -402,7 +406,11 @@ pub(crate) fn dup(fd: BorrowedFd<'_>) -> io::Result { #[inline] pub(crate) fn dup2(fd: BorrowedFd<'_>, new: &mut OwnedFd) -> io::Result<()> { - #[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))] + #[cfg(any( + target_arch = "aarch64", + target_arch = "loongarch64", + target_arch = "riscv64" + ))] { // We don't need to worry about the difference between `dup2` and // `dup3` when the file descriptors are equal because we have an @@ -410,7 +418,11 @@ pub(crate) fn dup2(fd: BorrowedFd<'_>, new: &mut OwnedFd) -> io::Result<()> { dup3(fd, new, DupFlags::empty()) } - #[cfg(not(any(target_arch = "aarch64", target_arch = "riscv64")))] + #[cfg(not(any( + target_arch = "aarch64", + target_arch = "loongarch64", + target_arch = "riscv64" + )))] unsafe { ret_discarded_fd(syscall_readonly!(__NR_dup2, fd, new.as_fd())) } @@ -509,6 +521,7 @@ pub(crate) fn pipe() -> io::Result<(OwnedFd, OwnedFd)> { // wrapping infrastructure at this time. #[cfg(any( target_arch = "aarch64", + target_arch = "loongarch64", target_arch = "mips", target_arch = "mips64", target_arch = "riscv64", @@ -518,6 +531,7 @@ pub(crate) fn pipe() -> io::Result<(OwnedFd, OwnedFd)> { } #[cfg(not(any( target_arch = "aarch64", + target_arch = "loongarch64", target_arch = "mips", target_arch = "mips64", target_arch = "riscv64", @@ -534,7 +548,11 @@ pub(crate) fn pipe() -> io::Result<(OwnedFd, OwnedFd)> { pub(crate) fn poll(fds: &mut [PollFd<'_>], timeout: c::c_int) -> io::Result { let (fds_addr_mut, fds_len) = slice_mut(fds); - #[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))] + #[cfg(any( + target_arch = "aarch64", + target_arch = "loongarch64", + target_arch = "riscv64" + ))] unsafe { let timeout = if timeout >= 0 { Some(__kernel_timespec { @@ -553,7 +571,11 @@ pub(crate) fn poll(fds: &mut [PollFd<'_>], timeout: c::c_int) -> io::Result() )) } - #[cfg(not(any(target_arch = "aarch64", target_arch = "riscv64")))] + #[cfg(not(any( + target_arch = "aarch64", + target_arch = "loongarch64", + target_arch = "riscv64" + )))] unsafe { ret_usize(syscall!(__NR_poll, fds_addr_mut, fds_len, c_int(timeout))) } @@ -612,7 +634,11 @@ pub(crate) fn epoll_wait( num_events: usize, timeout: c::c_int, ) -> io::Result { - #[cfg(not(any(target_arch = "aarch64", target_arch = "riscv64")))] + #[cfg(not(any( + target_arch = "aarch64", + target_arch = "loongarch64", + target_arch = "riscv64" + )))] unsafe { ret_usize(syscall!( __NR_epoll_wait, @@ -622,7 +648,11 @@ pub(crate) fn epoll_wait( c_int(timeout) )) } - #[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))] + #[cfg(any( + target_arch = "aarch64", + target_arch = "loongarch64", + target_arch = "riscv64" + ))] unsafe { ret_usize(syscall!( __NR_epoll_pwait, diff --git a/src/backend/linux_raw/net/syscalls.rs b/src/backend/linux_raw/net/syscalls.rs index 7b9947a03..c69291c22 100644 --- a/src/backend/linux_raw/net/syscalls.rs +++ b/src/backend/linux_raw/net/syscalls.rs @@ -265,6 +265,7 @@ pub(crate) fn send(fd: BorrowedFd<'_>, buf: &[u8], flags: SendFlags) -> io::Resu #[cfg(not(any( target_arch = "aarch64", + target_arch = "loongarch64", target_arch = "mips64", target_arch = "riscv64", target_arch = "x86", @@ -275,6 +276,7 @@ pub(crate) fn send(fd: BorrowedFd<'_>, buf: &[u8], flags: SendFlags) -> io::Resu } #[cfg(any( target_arch = "aarch64", + target_arch = "loongarch64", target_arch = "mips64", target_arch = "riscv64", target_arch = "x86_64", @@ -420,6 +422,7 @@ pub(crate) fn recv(fd: BorrowedFd<'_>, buf: &mut [u8], flags: RecvFlags) -> io:: #[cfg(not(any( target_arch = "aarch64", + target_arch = "loongarch64", target_arch = "mips64", target_arch = "riscv64", target_arch = "x86", @@ -430,6 +433,7 @@ pub(crate) fn recv(fd: BorrowedFd<'_>, buf: &mut [u8], flags: RecvFlags) -> io:: } #[cfg(any( target_arch = "aarch64", + target_arch = "loongarch64", target_arch = "mips64", target_arch = "riscv64", target_arch = "x86_64", diff --git a/src/backend/linux_raw/process/syscalls.rs b/src/backend/linux_raw/process/syscalls.rs index ece8e97fa..f9bd1a71e 100644 --- a/src/backend/linux_raw/process/syscalls.rs +++ b/src/backend/linux_raw/process/syscalls.rs @@ -115,7 +115,11 @@ pub(crate) fn getpgid(pid: Option) -> io::Result { #[inline] pub(crate) fn getpgrp() -> Pid { // Use the `getpgrp` syscall if available. - #[cfg(not(any(target_arch = "aarch64", target_arch = "riscv64")))] + #[cfg(not(any( + target_arch = "aarch64", + target_arch = "loongarch64", + target_arch = "riscv64" + )))] unsafe { let pgid: i32 = ret_usize_infallible(syscall_readonly!(__NR_getpgrp)) as __kernel_pid_t; debug_assert!(pgid > 0); @@ -123,7 +127,11 @@ pub(crate) fn getpgrp() -> Pid { } // Otherwise use `getpgrp` and pass it zero. - #[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))] + #[cfg(any( + target_arch = "aarch64", + target_arch = "loongarch64", + target_arch = "riscv64" + ))] unsafe { let pgid: i32 = ret_usize_infallible(syscall_readonly!(__NR_getpgid, c_uint(0))) as __kernel_pid_t; @@ -328,6 +336,7 @@ pub(crate) fn setpriority_process(pid: Option, priority: i32) -> io::Result } } +#[cfg(not(target_arch = "loongarch64"))] #[inline] pub(crate) fn getrlimit(limit: Resource) -> Rlimit { let mut result = MaybeUninit::::uninit(); @@ -350,6 +359,7 @@ pub(crate) fn getrlimit(limit: Resource) -> Rlimit { /// The old 32-bit-only `getrlimit` syscall, for when we lack the new /// `prlimit64`. +#[cfg(not(target_arch = "loongarch64"))] unsafe fn getrlimit_old(limit: Resource) -> Rlimit { let mut result = MaybeUninit::::uninit(); @@ -367,6 +377,7 @@ unsafe fn getrlimit_old(limit: Resource) -> Rlimit { // On these platforms, it's just `__NR_getrlimit`. #[cfg(not(any( target_arch = "arm", + target_arch = "loongarch64", target_arch = "powerpc", target_arch = "powerpc64", target_arch = "x86", @@ -378,6 +389,7 @@ unsafe fn getrlimit_old(limit: Resource) -> Rlimit { rlimit_from_linux_old(result.assume_init()) } +#[cfg(not(target_arch = "loongarch64"))] #[inline] pub(crate) fn setrlimit(limit: Resource, new: Rlimit) -> io::Result<()> { unsafe { @@ -398,6 +410,7 @@ pub(crate) fn setrlimit(limit: Resource, new: Rlimit) -> io::Result<()> { /// The old 32-bit-only `setrlimit` syscall, for when we lack the new /// `prlimit64`. +#[cfg(not(target_arch = "loongarch64"))] unsafe fn setrlimit_old(limit: Resource, new: Rlimit) -> io::Result<()> { let lim = rlimit_to_linux_old(new)?; ret(syscall_readonly!(__NR_setrlimit, limit, by_ref(&lim))) diff --git a/src/backend/linux_raw/vdso_wrappers.rs b/src/backend/linux_raw/vdso_wrappers.rs index 5b2e084ea..44976239d 100644 --- a/src/backend/linux_raw/vdso_wrappers.rs +++ b/src/backend/linux_raw/vdso_wrappers.rs @@ -361,6 +361,8 @@ fn init() { let ptr = vdso.sym(cstr!("LINUX_2.6"), cstr!("__vdso_clock_gettime64")); #[cfg(target_arch = "mips64")] let ptr = vdso.sym(cstr!("LINUX_2.6"), cstr!("__vdso_clock_gettime")); + #[cfg(target_arch = "loongarch64")] + let ptr = vdso.sym(cstr!("LINUX_5.19"), cstr!("__vdso_clock_gettime")); // On all 64-bit platforms, the 64-bit `clock_gettime` symbols are // always available. diff --git a/src/fs/at.rs b/src/fs/at.rs index eece3337d..3a20df33a 100644 --- a/src/fs/at.rs +++ b/src/fs/at.rs @@ -15,7 +15,9 @@ use crate::fs::CloneFlags; use crate::fs::FileType; #[cfg(any(target_os = "android", target_os = "linux"))] use crate::fs::RenameFlags; -use crate::fs::{AtFlags, Mode, OFlags, Stat, Timestamps}; +#[cfg(not(target_arch = "loongarch64"))] +use crate::fs::Stat; +use crate::fs::{AtFlags, Mode, OFlags, Timestamps}; use crate::path::SMALL_PATH_BUFFER_SIZE; #[cfg(not(target_os = "wasi"))] use crate::process::{Gid, Uid}; @@ -256,6 +258,7 @@ pub fn symlinkat( /// [Linux]: https://man7.org/linux/man-pages/man2/fstatat.2.html /// [`Mode::from_raw_mode`]: crate::fs::Mode::from_raw_mode /// [`FileType::from_raw_mode`]: crate::fs::FileType::from_raw_mode +#[cfg(not(target_arch = "loongarch64"))] #[inline] #[doc(alias = "fstatat")] pub fn statat(dirfd: Fd, path: P, flags: AtFlags) -> io::Result { diff --git a/src/fs/fd.rs b/src/fs/fd.rs index 303a684e4..3f3958557 100644 --- a/src/fs/fd.rs +++ b/src/fs/fd.rs @@ -20,6 +20,7 @@ pub use backend::fs::types::FlockOperation; )))] pub use backend::fs::types::FallocateFlags; +#[cfg(not(target_arch = "loongarch64"))] pub use backend::fs::types::Stat; #[cfg(not(any( @@ -145,6 +146,7 @@ pub fn fchown(fd: Fd, owner: Option, group: Option) -> io::R /// [Linux]: https://man7.org/linux/man-pages/man2/fstat.2.html /// [`Mode::from_raw_mode`]: crate::fs::Mode::from_raw_mode /// [`FileType::from_raw_mode`]: crate::fs::FileType::from_raw_mode +#[cfg(not(target_arch = "loongarch64"))] #[inline] pub fn fstat(fd: Fd) -> io::Result { backend::fs::syscalls::fstat(fd.as_fd()) diff --git a/src/process/mod.rs b/src/process/mod.rs index 1fb29c61d..b69c47c3f 100644 --- a/src/process/mod.rs +++ b/src/process/mod.rs @@ -49,8 +49,15 @@ pub use prctl::*; pub use priority::*; #[cfg(target_os = "freebsd")] pub use procctl::*; +#[cfg(not(any( + target_os = "fuchsia", + target_os = "redox", + target_os = "wasi", + target_arch = "loongarch64" +)))] +pub use rlimit::{getrlimit, setrlimit}; #[cfg(not(any(target_os = "fuchsia", target_os = "redox", target_os = "wasi")))] -pub use rlimit::*; +pub use rlimit::{Resource, Rlimit}; #[cfg(any( target_os = "android", target_os = "dragonfly", diff --git a/src/process/rlimit.rs b/src/process/rlimit.rs index 089f6b4bb..fe85b1fa6 100644 --- a/src/process/rlimit.rs +++ b/src/process/rlimit.rs @@ -22,6 +22,7 @@ pub struct Rlimit { /// /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getrlimit.html /// [Linux]: https://man7.org/linux/man-pages/man2/getrlimit.2.html +#[cfg(not(target_arch = "loongarch64"))] #[inline] pub fn getrlimit(resource: Resource) -> Rlimit { backend::process::syscalls::getrlimit(resource) @@ -35,6 +36,7 @@ pub fn getrlimit(resource: Resource) -> Rlimit { /// /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/setrlimit.html /// [Linux]: https://man7.org/linux/man-pages/man2/setrlimit.2.html +#[cfg(not(target_arch = "loongarch64"))] #[inline] pub fn setrlimit(resource: Resource, new: Rlimit) -> io::Result<()> { backend::process::syscalls::setrlimit(resource, new)