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