From 80550b6aebc442c7f4ec4f296a5d4a70b67bc015 Mon Sep 17 00:00:00 2001 From: "Lain \"Fearyncess\" Yang" Date: Wed, 18 Sep 2024 16:46:55 +0800 Subject: [PATCH] Add `getregs()`/`setregs()`/`getregset()`/`setregset()` support for loongarch64-linux-gnu/musl --- src/sys/ptrace/linux.rs | 64 ++++++++++++++++++++++++++++++++++------- test/sys/test_ptrace.rs | 18 +++++++++++- 2 files changed, 71 insertions(+), 11 deletions(-) diff --git a/src/sys/ptrace/linux.rs b/src/sys/ptrace/linux.rs index 762b337687..8655755c2a 100644 --- a/src/sys/ptrace/linux.rs +++ b/src/sys/ptrace/linux.rs @@ -14,7 +14,11 @@ pub type AddressType = *mut ::libc::c_void; target_os = "linux", any( all( - any(target_arch = "x86_64", target_arch = "aarch64"), + any( + target_arch = "x86_64", + target_arch = "aarch64", + target_arch = "loongarch64", + ), any(target_env = "gnu", target_env = "musl") ), all(target_arch = "x86", target_env = "gnu"), @@ -179,6 +183,7 @@ libc_enum! { target_arch = "x86", target_arch = "aarch64", target_arch = "riscv64", + target_arch = "loongarch64", ) ))] libc_enum! { @@ -202,6 +207,7 @@ libc_enum! { target_arch = "x86", target_arch = "aarch64", target_arch = "riscv64", + target_arch = "loongarch64", ) ))] /// Represents register set areas, such as general-purpose registers or @@ -227,6 +233,7 @@ pub unsafe trait RegisterSet { target_arch = "x86", target_arch = "aarch64", target_arch = "riscv64", + target_arch = "loongarch64", ) ))] /// Register sets used in [`getregset`] and [`setregset`] @@ -254,6 +261,8 @@ pub mod regset { type Regs = libc::user_fpsimd_struct; #[cfg(target_arch = "riscv64")] type Regs = libc::__riscv_mc_d_ext_state; + #[cfg(target_arch = "loongarch64")] + type Regs = libc::user_fp_struct; } } @@ -335,10 +344,20 @@ pub fn getregs(pid: Pid) -> Result { target_os = "linux", any( all( - target_arch = "aarch64", - any(target_env = "gnu", target_env = "musl") + target_env = "musl", + any( + target_arch = "aarch64", + target_arch = "loongarch64", + ) ), - all(target_arch = "riscv64", target_env = "gnu") + all( + target_env = "gnu", + any( + target_arch = "aarch64", + target_arch = "loongarch64", + target_arch = "riscv64", + ) + ) ) ))] pub fn getregs(pid: Pid) -> Result { @@ -355,10 +374,18 @@ pub fn getregs(pid: Pid) -> Result { target_arch = "x86_64", target_arch = "x86", target_arch = "aarch64", - target_arch = "riscv64" + target_arch = "riscv64", + target_arch = "loongarch64", + ) ), - all(target_env = "musl", target_arch = "aarch64") + all( + target_env = "musl", + any( + target_arch = "aarch64", + target_arch = "loongarch64", + ) + ) ) ))] pub fn getregset(pid: Pid) -> Result { @@ -420,9 +447,19 @@ pub fn setregs(pid: Pid, regs: user_regs_struct) -> Result<()> { any( all( target_env = "gnu", - any(target_arch = "aarch64", target_arch = "riscv64") + any( + target_arch = "aarch64", + target_arch = "riscv64", + target_arch = "loongarch64", + ) ), - all(target_env = "musl", target_arch = "aarch64") + all( + target_env = "musl", + any( + target_arch = "aarch64", + target_arch = "loongarch64", + ) + ) ) ))] pub fn setregs(pid: Pid, regs: user_regs_struct) -> Result<()> { @@ -439,10 +476,17 @@ pub fn setregs(pid: Pid, regs: user_regs_struct) -> Result<()> { target_arch = "x86_64", target_arch = "x86", target_arch = "aarch64", - target_arch = "riscv64" + target_arch = "riscv64", + target_arch = "loongarch64" ) ), - all(target_env = "musl", target_arch = "aarch64") + all( + target_env = "musl", + any( + target_arch = "aarch64", + target_arch = "loongarch64" + ) + ) ) ))] pub fn setregset(pid: Pid, mut regs: S::Regs) -> Result<()> { diff --git a/test/sys/test_ptrace.rs b/test/sys/test_ptrace.rs index 2e3e809ee8..59a1864063 100644 --- a/test/sys/test_ptrace.rs +++ b/test/sys/test_ptrace.rs @@ -185,6 +185,7 @@ fn test_ptrace_interrupt() { target_arch = "x86", target_arch = "aarch64", target_arch = "riscv64", + target_arch = "loongarch64", ) ))] #[test] @@ -239,6 +240,10 @@ fn test_ptrace_syscall() { let get_syscall_id = || ptrace::getregs(child).unwrap().a7 as libc::c_long; + #[cfg(target_arch = "loongarch64")] + let get_syscall_id = + || ptrace::getregs(child).unwrap().regs[11] as libc::c_long; + // this duplicates `get_syscall_id` for the purpose of testing `ptrace::read_user`. #[cfg(target_arch = "x86_64")] let rax_offset = offset_of!(libc::user_regs_struct, orig_rax); @@ -299,10 +304,17 @@ fn test_ptrace_syscall() { target_arch = "x86_64", target_arch = "x86", target_arch = "aarch64", + target_arch = "loongarch64", target_arch = "riscv64" ) ), - all(target_env = "musl", target_arch = "aarch64") + all( + target_env = "musl", + any( + target_arch = "aarch64", + target_arch = "loongarch64" + ) + ) ) ))] #[test] @@ -348,6 +360,8 @@ fn test_ptrace_regsets() { (&mut regstruct.regs[16], &mut fpregstruct.vregs[5]); #[cfg(target_arch = "riscv64")] let (reg, fpreg) = (&mut regstruct.t1, &mut fpregstruct.__f[5]); + #[cfg(target_arch = "loongarch64")] + let (reg, fpreg) = (&mut regstruct.regs[12], &mut fpregstruct.fpr[5]); *reg = 0xdeadbeefu32 as _; *fpreg = 0xfeedfaceu32 as _; @@ -364,6 +378,8 @@ fn test_ptrace_regsets() { let (reg, fpreg) = (regstruct.regs[16], fpregstruct.vregs[5]); #[cfg(target_arch = "riscv64")] let (reg, fpreg) = (regstruct.t1, fpregstruct.__f[5]); + #[cfg(target_arch = "loongarch64")] + let (reg, fpreg) = (regstruct.regs[12], fpregstruct.fpr[5]); assert_eq!(reg, 0xdeadbeefu32 as _); assert_eq!(fpreg, 0xfeedfaceu32 as _);