@@ -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
@@ -152,6 +154,29 @@ libc_enum! {
152
154
}
153
155
}
154
156
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
+
155
180
libc_bitflags ! {
156
181
/// Ptrace options used in conjunction with the PTRACE_SETOPTIONS request.
157
182
/// See `man ptrace` for more details.
@@ -213,6 +238,48 @@ pub fn getregs(pid: Pid) -> Result<user_regs_struct> {
213
238
ptrace_get_data :: < user_regs_struct > ( Request :: PTRACE_GETREGS , pid)
214
239
}
215
240
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 AddressType ,
277
+ & mut iov as * mut _ as * mut c_void ,
278
+ ) ?;
279
+ } ;
280
+ Ok ( unsafe { data. assume_init ( ) } )
281
+ }
282
+
216
283
/// Set user registers, as with `ptrace(PTRACE_SETREGS, ...)`
217
284
#[ cfg( all(
218
285
target_os = "linux" ,
@@ -236,6 +303,50 @@ pub fn setregs(pid: Pid, regs: user_regs_struct) -> Result<()> {
236
303
Errno :: result ( res) . map ( drop)
237
304
}
238
305
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 c_void ,
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 AddressType ,
344
+ & iov as * const _ as * mut c_void ,
345
+ ) ?;
346
+ }
347
+ Ok ( ( ) )
348
+ }
349
+
239
350
/// Function for ptrace requests that return values from the data field.
240
351
/// Some ptrace get requests populate structs or larger elements than `c_long`
241
352
/// and therefore use the data field to return values. This function handles these
0 commit comments