@@ -172,21 +172,21 @@ libc_enum! {
172
172
}
173
173
}
174
174
175
+ #[ cfg( all(
176
+ target_os = "linux" ,
177
+ target_env = "gnu" ,
178
+ any(
179
+ target_arch = "x86_64" ,
180
+ target_arch = "x86" ,
181
+ target_arch = "aarch64" ,
182
+ target_arch = "riscv64" ,
183
+ )
184
+ ) ) ]
175
185
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
186
#[ repr( i32 ) ]
187
- /// Defining a specific register set, as used in [`getregset`] and [`setregset`] .
187
+ /// Defines a specific register set, as used in `PTRACE_GETREGSET` and `PTRACE_SETREGSET` .
188
188
#[ non_exhaustive]
189
- pub enum RegisterSet {
189
+ pub enum RegisterSetValue {
190
190
NT_PRSTATUS ,
191
191
NT_PRFPREG ,
192
192
NT_PRPSINFO ,
@@ -195,6 +195,64 @@ libc_enum! {
195
195
}
196
196
}
197
197
198
+ #[ cfg( all(
199
+ target_os = "linux" ,
200
+ target_env = "gnu" ,
201
+ any(
202
+ target_arch = "x86_64" ,
203
+ target_arch = "x86" ,
204
+ target_arch = "aarch64" ,
205
+ target_arch = "riscv64" ,
206
+ )
207
+ ) ) ]
208
+ /// Represents register set areas, such as general-purpose registers or
209
+ /// floating-point registers.
210
+ pub unsafe trait RegisterSet {
211
+ /// Corresponding type of registers in the kernel.
212
+ const VALUE : RegisterSetValue ;
213
+
214
+ /// Struct representing the register space.
215
+ type Regs ;
216
+ }
217
+
218
+ #[ cfg( all(
219
+ target_os = "linux" ,
220
+ target_env = "gnu" ,
221
+ any(
222
+ target_arch = "x86_64" ,
223
+ target_arch = "x86" ,
224
+ target_arch = "aarch64" ,
225
+ target_arch = "riscv64" ,
226
+ )
227
+ ) ) ]
228
+ /// Register sets used in [`getregset`] and [`setregset`]
229
+ pub mod regset {
230
+ use super :: * ;
231
+
232
+ #[ derive( Debug , Clone , Copy ) ]
233
+ /// General-purpose registers.
234
+ pub struct NT_PRSTATUS ;
235
+
236
+ unsafe impl RegisterSet for NT_PRSTATUS {
237
+ const VALUE : RegisterSetValue = RegisterSetValue :: NT_PRSTATUS ;
238
+ type Regs = user_regs_struct ;
239
+ }
240
+
241
+ #[ derive( Debug , Clone , Copy ) ]
242
+ /// Floating-point registers.
243
+ pub struct NT_PRFPREG ;
244
+
245
+ unsafe impl RegisterSet for NT_PRFPREG {
246
+ const VALUE : RegisterSetValue = RegisterSetValue :: NT_PRFPREG ;
247
+ #[ cfg( any( target_arch = "x86" , target_arch = "x86_64" ) ) ]
248
+ type Regs = libc:: user_fpregs_struct ;
249
+ #[ cfg( target_arch = "aarch64" ) ]
250
+ type Regs = libc:: user_fpsimd_struct ;
251
+ #[ cfg( target_arch = "riscv64" ) ]
252
+ type Regs = libc:: __riscv_mc_d_ext_state ;
253
+ }
254
+ }
255
+
198
256
libc_bitflags ! {
199
257
/// Ptrace options used in conjunction with the PTRACE_SETOPTIONS request.
200
258
/// See `man ptrace` for more details.
@@ -275,7 +333,7 @@ pub fn getregs(pid: Pid) -> Result<user_regs_struct> {
275
333
any( target_arch = "aarch64" , target_arch = "riscv64" )
276
334
) ) ]
277
335
pub fn getregs ( pid : Pid ) -> Result < user_regs_struct > {
278
- getregset ( pid , RegisterSet :: NT_PRSTATUS )
336
+ getregset :: < regset :: NT_PRSTATUS > ( pid )
279
337
}
280
338
281
339
/// Get a particular set of user registers, as with `ptrace(PTRACE_GETREGSET, ...)`
@@ -289,18 +347,18 @@ pub fn getregs(pid: Pid) -> Result<user_regs_struct> {
289
347
target_arch = "riscv64" ,
290
348
)
291
349
) ) ]
292
- pub fn getregset ( pid : Pid , set : RegisterSet ) -> Result < user_regs_struct > {
350
+ pub fn getregset < S : RegisterSet > ( pid : Pid ) -> Result < S :: Regs > {
293
351
let request = Request :: PTRACE_GETREGSET ;
294
- let mut data = mem:: MaybeUninit :: < user_regs_struct > :: uninit ( ) ;
352
+ let mut data = mem:: MaybeUninit :: < S :: Regs > :: uninit ( ) ;
295
353
let mut iov = libc:: iovec {
296
354
iov_base : data. as_mut_ptr ( ) . cast ( ) ,
297
- iov_len : mem:: size_of :: < user_regs_struct > ( ) ,
355
+ iov_len : mem:: size_of :: < S :: Regs > ( ) ,
298
356
} ;
299
357
unsafe {
300
358
ptrace_other (
301
359
request,
302
360
pid,
303
- set as i32 as AddressType ,
361
+ S :: VALUE as i32 as AddressType ,
304
362
( & mut iov as * mut libc:: iovec ) . cast ( ) ,
305
363
) ?;
306
364
} ;
@@ -349,7 +407,7 @@ pub fn setregs(pid: Pid, regs: user_regs_struct) -> Result<()> {
349
407
any( target_arch = "aarch64" , target_arch = "riscv64" )
350
408
) ) ]
351
409
pub fn setregs ( pid : Pid , regs : user_regs_struct ) -> Result < ( ) > {
352
- setregset ( pid , RegisterSet :: NT_PRSTATUS , regs)
410
+ setregset :: < regset :: NT_PRSTATUS > ( pid , regs)
353
411
}
354
412
355
413
/// Set a particular set of user registers, as with `ptrace(PTRACE_SETREGSET, ...)`
@@ -363,20 +421,16 @@ pub fn setregs(pid: Pid, regs: user_regs_struct) -> Result<()> {
363
421
target_arch = "riscv64" ,
364
422
)
365
423
) ) ]
366
- pub fn setregset (
367
- pid : Pid ,
368
- set : RegisterSet ,
369
- mut regs : user_regs_struct ,
370
- ) -> Result < ( ) > {
424
+ pub fn setregset < S : RegisterSet > ( pid : Pid , mut regs : S :: Regs ) -> Result < ( ) > {
371
425
let mut iov = libc:: iovec {
372
- iov_base : ( & mut regs as * mut user_regs_struct ) . cast ( ) ,
373
- iov_len : mem:: size_of :: < user_regs_struct > ( ) ,
426
+ iov_base : ( & mut regs as * mut S :: Regs ) . cast ( ) ,
427
+ iov_len : mem:: size_of :: < S :: Regs > ( ) ,
374
428
} ;
375
429
unsafe {
376
430
ptrace_other (
377
431
Request :: PTRACE_SETREGSET ,
378
432
pid,
379
- set as i32 as AddressType ,
433
+ S :: VALUE as i32 as AddressType ,
380
434
( & mut iov as * mut libc:: iovec ) . cast ( ) ,
381
435
) ?;
382
436
}
0 commit comments