@@ -17,8 +17,10 @@ pub type AddressType = *mut ::libc::c_void;
17
17
target_arch = "x86_64" ,
18
18
any( target_env = "gnu" , target_env = "musl" )
19
19
) ,
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
+ ) ,
22
24
) ) ]
23
25
use libc:: user_regs_struct;
24
26
@@ -170,6 +172,29 @@ libc_enum! {
170
172
}
171
173
}
172
174
175
+ libc_enum ! {
176
+ #[ cfg( all(
177
+ target_os = "linux" ,
178
+ target_env = "gnu" ,
179
+ any(
180
+ target_arch = "x86_64" ,
181
+ target_arch = "x86" ,
182
+ target_arch = "aarch64" ,
183
+ target_arch = "riscv64" ,
184
+ )
185
+ ) ) ]
186
+ #[ repr( i32 ) ]
187
+ /// Defining a specific register set, as used in [`getregset`] and [`setregset`].
188
+ #[ non_exhaustive]
189
+ pub enum RegisterSet {
190
+ NT_PRSTATUS ,
191
+ NT_PRFPREG ,
192
+ NT_PRPSINFO ,
193
+ NT_TASKSTRUCT ,
194
+ NT_AUXV ,
195
+ }
196
+ }
197
+
173
198
libc_bitflags ! {
174
199
/// Ptrace options used in conjunction with the PTRACE_SETOPTIONS request.
175
200
/// See `man ptrace` for more details.
@@ -231,6 +256,48 @@ pub fn getregs(pid: Pid) -> Result<user_regs_struct> {
231
256
ptrace_get_data :: < user_regs_struct > ( Request :: PTRACE_GETREGS , pid)
232
257
}
233
258
259
+ /// Get user registers, as with `ptrace(PTRACE_GETREGSET, pid, NT_PRSTATUS, ...)`
260
+ #[ cfg( all(
261
+ target_os = "linux" ,
262
+ target_env = "gnu" ,
263
+ any(
264
+ target_arch = "aarch64" ,
265
+ target_arch = "riscv64" ,
266
+ )
267
+ ) ) ]
268
+ pub fn getregs ( pid : Pid ) -> Result < user_regs_struct > {
269
+ getregset ( pid, RegisterSet :: NT_PRSTATUS )
270
+ }
271
+
272
+ /// Get a particular set of user registers, as with `ptrace(PTRACE_GETREGSET, ...)`
273
+ #[ cfg( all(
274
+ target_os = "linux" ,
275
+ target_env = "gnu" ,
276
+ any(
277
+ target_arch = "x86_64" ,
278
+ target_arch = "x86" ,
279
+ target_arch = "aarch64" ,
280
+ target_arch = "riscv64" ,
281
+ )
282
+ ) ) ]
283
+ pub fn getregset ( pid : Pid , set : RegisterSet ) -> Result < user_regs_struct > {
284
+ let request = Request :: PTRACE_GETREGSET ;
285
+ let mut data = mem:: MaybeUninit :: < user_regs_struct > :: uninit ( ) ;
286
+ let mut iov = libc:: iovec {
287
+ iov_base : data. as_mut_ptr ( ) as * mut _ ,
288
+ iov_len : mem:: size_of :: < user_regs_struct > ( ) ,
289
+ } ;
290
+ unsafe {
291
+ ptrace_other (
292
+ request,
293
+ pid,
294
+ set as i32 as AddressType ,
295
+ & mut iov as * mut _ as * mut c_void ,
296
+ ) ?;
297
+ } ;
298
+ Ok ( unsafe { data. assume_init ( ) } )
299
+ }
300
+
234
301
/// Set user registers, as with `ptrace(PTRACE_SETREGS, ...)`
235
302
#[ cfg( all(
236
303
target_os = "linux" ,
@@ -254,6 +321,50 @@ pub fn setregs(pid: Pid, regs: user_regs_struct) -> Result<()> {
254
321
Errno :: result ( res) . map ( drop)
255
322
}
256
323
324
+ /// Set user registers, as with `ptrace(PTRACE_SETREGSET, pid, NT_PRSTATUS, ...)`
325
+ #[ cfg( all(
326
+ target_os = "linux" ,
327
+ target_env = "gnu" ,
328
+ any(
329
+ target_arch = "aarch64" ,
330
+ target_arch = "riscv64" ,
331
+ )
332
+ ) ) ]
333
+ pub fn setregs ( pid : Pid , regs : user_regs_struct ) -> Result < ( ) > {
334
+ setregset ( pid, RegisterSet :: NT_PRSTATUS , regs)
335
+ }
336
+
337
+ /// Set a particular set of user registers, as with `ptrace(PTRACE_SETREGSET, ...)`
338
+ #[ cfg( all(
339
+ target_os = "linux" ,
340
+ target_env = "gnu" ,
341
+ any(
342
+ target_arch = "x86_64" ,
343
+ target_arch = "x86" ,
344
+ target_arch = "aarch64" ,
345
+ target_arch = "riscv64" ,
346
+ )
347
+ ) ) ]
348
+ pub fn setregset (
349
+ pid : Pid ,
350
+ set : RegisterSet ,
351
+ regs : user_regs_struct ,
352
+ ) -> Result < ( ) > {
353
+ let iov = libc:: iovec {
354
+ iov_base : & regs as * const _ as * mut c_void ,
355
+ iov_len : mem:: size_of :: < user_regs_struct > ( ) ,
356
+ } ;
357
+ unsafe {
358
+ ptrace_other (
359
+ Request :: PTRACE_SETREGSET ,
360
+ pid,
361
+ set as i32 as AddressType ,
362
+ & iov as * const _ as * mut c_void ,
363
+ ) ?;
364
+ }
365
+ Ok ( ( ) )
366
+ }
367
+
257
368
/// Function for ptrace requests that return values from the data field.
258
369
/// Some ptrace get requests populate structs or larger elements than `c_long`
259
370
/// and therefore use the data field to return values. This function handles these
0 commit comments