@@ -17,8 +17,10 @@ pub type AddressType = *mut ::libc::c_void;
1717 target_arch = "x86_64" ,
1818 any( target_env = "gnu" , target_env = "musl" )
1919 ) ,
20- all( target_arch = "x86" , target_env = "gnu" )
21- )
20+ all( target_arch = "x86" , target_env = "gnu" ) ,
21+ all( target_arch = "aarch64" , target_env = "gnu" ) ,
22+ all( target_arch = "riscv64" , target_env = "gnu" ) ,
23+ ) ,
2224) ) ]
2325use libc:: user_regs_struct;
2426
@@ -152,6 +154,29 @@ libc_enum! {
152154 }
153155}
154156
157+ libc_enum ! {
158+ #[ cfg( all(
159+ target_os = "linux" ,
160+ target_env = "gnu" ,
161+ any(
162+ target_arch = "x86_64" ,
163+ target_arch = "x86" ,
164+ target_arch = "aarch64" ,
165+ target_arch = "riscv64" ,
166+ )
167+ ) ) ]
168+ #[ repr( i32 ) ]
169+ /// Defining a specific register set, as used in [`getregset`] and [`setregset`].
170+ #[ non_exhaustive]
171+ pub enum RegisterSet {
172+ NT_PRSTATUS ,
173+ NT_PRFPREG ,
174+ NT_PRPSINFO ,
175+ NT_TASKSTRUCT ,
176+ NT_AUXV ,
177+ }
178+ }
179+
155180libc_bitflags ! {
156181 /// Ptrace options used in conjunction with the PTRACE_SETOPTIONS request.
157182 /// See `man ptrace` for more details.
@@ -213,6 +238,48 @@ pub fn getregs(pid: Pid) -> Result<user_regs_struct> {
213238 ptrace_get_data :: < user_regs_struct > ( Request :: PTRACE_GETREGS , pid)
214239}
215240
241+ /// Get user registers, as with `ptrace(PTRACE_GETREGSET, pid, NT_PRSTATUS, ...)`
242+ #[ cfg( all(
243+ target_os = "linux" ,
244+ target_env = "gnu" ,
245+ any(
246+ target_arch = "aarch64" ,
247+ target_arch = "riscv64" ,
248+ )
249+ ) ) ]
250+ pub fn getregs ( pid : Pid ) -> Result < user_regs_struct > {
251+ getregset ( pid, RegisterSet :: NT_PRSTATUS )
252+ }
253+
254+ /// Get a particular set of user registers, as with `ptrace(PTRACE_GETREGSET, ...)`
255+ #[ cfg( all(
256+ target_os = "linux" ,
257+ target_env = "gnu" ,
258+ any(
259+ target_arch = "x86_64" ,
260+ target_arch = "x86" ,
261+ target_arch = "aarch64" ,
262+ target_arch = "riscv64" ,
263+ )
264+ ) ) ]
265+ pub fn getregset ( pid : Pid , set : RegisterSet ) -> Result < user_regs_struct > {
266+ let request = Request :: PTRACE_GETREGSET ;
267+ let mut data = mem:: MaybeUninit :: < user_regs_struct > :: uninit ( ) ;
268+ let mut iov = libc:: iovec {
269+ iov_base : data. as_mut_ptr ( ) as * mut _ ,
270+ iov_len : mem:: size_of :: < user_regs_struct > ( ) ,
271+ } ;
272+ unsafe {
273+ ptrace_other (
274+ request,
275+ pid,
276+ set as i32 as _ ,
277+ & mut iov as * mut _ as * mut _ ,
278+ ) ?;
279+ } ;
280+ Ok ( unsafe { data. assume_init ( ) } )
281+ }
282+
216283/// Set user registers, as with `ptrace(PTRACE_SETREGS, ...)`
217284#[ cfg( all(
218285 target_os = "linux" ,
@@ -236,6 +303,50 @@ pub fn setregs(pid: Pid, regs: user_regs_struct) -> Result<()> {
236303 Errno :: result ( res) . map ( drop)
237304}
238305
306+ /// Set user registers, as with `ptrace(PTRACE_SETREGSET, pid, NT_PRSTATUS, ...)`
307+ #[ cfg( all(
308+ target_os = "linux" ,
309+ target_env = "gnu" ,
310+ any(
311+ target_arch = "aarch64" ,
312+ target_arch = "riscv64" ,
313+ )
314+ ) ) ]
315+ pub fn setregs ( pid : Pid , regs : user_regs_struct ) -> Result < ( ) > {
316+ setregset ( pid, RegisterSet :: NT_PRSTATUS , regs)
317+ }
318+
319+ /// Set a particular set of user registers, as with `ptrace(PTRACE_SETREGSET, ...)`
320+ #[ cfg( all(
321+ target_os = "linux" ,
322+ target_env = "gnu" ,
323+ any(
324+ target_arch = "x86_64" ,
325+ target_arch = "x86" ,
326+ target_arch = "aarch64" ,
327+ target_arch = "riscv64" ,
328+ )
329+ ) ) ]
330+ pub fn setregset (
331+ pid : Pid ,
332+ set : RegisterSet ,
333+ regs : user_regs_struct ,
334+ ) -> Result < ( ) > {
335+ let iov = libc:: iovec {
336+ iov_base : & regs as * const _ as * mut _ ,
337+ iov_len : mem:: size_of :: < user_regs_struct > ( ) ,
338+ } ;
339+ unsafe {
340+ ptrace_other (
341+ Request :: PTRACE_SETREGSET ,
342+ pid,
343+ set as i32 as _ ,
344+ & iov as * const _ as * mut _ ,
345+ ) ?;
346+ }
347+ Ok ( ( ) )
348+ }
349+
239350/// Function for ptrace requests that return values from the data field.
240351/// Some ptrace get requests populate structs or larger elements than `c_long`
241352/// and therefore use the data field to return values. This function handles these
0 commit comments