@@ -14,8 +14,9 @@ pub type AddressType = *mut ::libc::c_void;
14
14
target_os = "linux" ,
15
15
any( all( target_arch = "x86_64" ,
16
16
any( target_env = "gnu" , target_env = "musl" ) ) ,
17
- all( target_arch = "x86" , target_env = "gnu" ) )
18
- ) ) ]
17
+ all( target_arch = "x86" , target_env = "gnu" ) ,
18
+ all( target_arch = "aarch64" , target_os = "linux" ) ,
19
+ ) ) ) ]
19
20
use libc:: user_regs_struct;
20
21
21
22
cfg_if ! {
@@ -481,3 +482,88 @@ pub unsafe fn write(
481
482
{
482
483
ptrace_other ( Request :: PTRACE_POKEDATA , pid, addr, data) . map ( drop)
483
484
}
485
+
486
+ /// Read the tracee's registers.
487
+ ///
488
+ /// as with `ptrace(PTRACE_GETREGSET, ...)`
489
+ ///
490
+ /// # Arguments
491
+ ///
492
+ /// * `pid` - tracee's `nix::unistd::Pid`
493
+ #[ cfg( any( all( target_os = "linux" , target_env = "gnu" , target_arch = "aarch64" ) ) ) ]
494
+ pub fn getregset ( pid : Pid ) -> Result < user_regs_struct > {
495
+ ptrace_get_iovec_data :: < user_regs_struct > (
496
+ Request :: PTRACE_GETREGSET ,
497
+ pid,
498
+ libc:: NT_PRSTATUS ,
499
+ )
500
+ }
501
+
502
+ /// Modify the tracee's registers.
503
+ ///
504
+ /// as with `ptrace(PTRACE_SETREGSET, ...)`
505
+ ///
506
+ /// # Arguments
507
+ ///
508
+ /// * `pid` - tracee's `nix::unistd::Pid`
509
+ ///
510
+ /// * `regs` - `libc::user_regs_struct` to set
511
+ ///
512
+ #[ cfg( any( all( target_os = "linux" , target_env = "gnu" , target_arch = "aarch64" ) ) ) ]
513
+ pub fn setregset ( pid : Pid , regs : user_regs_struct ) -> Result < ( ) > {
514
+ ptrace_set_iovec_data (
515
+ Request :: PTRACE_SETREGSET ,
516
+ pid,
517
+ libc:: NT_PRSTATUS ,
518
+ regs,
519
+ )
520
+ }
521
+
522
+ /// As with `ptrace_get_data` but with an `iovec`
523
+ #[ cfg( any( all( target_os = "linux" , target_env = "gnu" , target_arch = "aarch64" ) ) ) ]
524
+ fn ptrace_get_iovec_data < T > (
525
+ request : Request ,
526
+ pid : Pid ,
527
+ nt_req : libc:: c_int ,
528
+ ) -> Result < T > {
529
+ let mut data = mem:: MaybeUninit :: < T > :: uninit ( ) ;
530
+ let mut iov = libc:: iovec {
531
+ iov_base : data. as_mut_ptr ( ) as * mut c_void ,
532
+ iov_len : mem:: size_of :: < T > ( ) ,
533
+ } ;
534
+
535
+ let res = unsafe {
536
+ libc:: ptrace (
537
+ request as RequestType ,
538
+ pid,
539
+ nt_req as AddressType ,
540
+ & mut iov as * mut _ as * mut c_void ,
541
+ )
542
+ } ;
543
+
544
+ Errno :: result ( res) ?;
545
+ Ok ( unsafe { data. assume_init ( ) } )
546
+ }
547
+
548
+ #[ cfg( any( all( target_os = "linux" , target_env = "gnu" , target_arch = "aarch64" ) ) ) ]
549
+ fn ptrace_set_iovec_data < T > (
550
+ request : Request ,
551
+ pid : Pid ,
552
+ nt_req : libc:: c_int ,
553
+ data : T ,
554
+ ) -> Result < ( ) > {
555
+ let iov = libc:: iovec {
556
+ iov_base : & data as * const _ as * mut c_void ,
557
+ iov_len : mem:: size_of :: < T > ( ) ,
558
+ } ;
559
+
560
+ unsafe {
561
+ ptrace_other (
562
+ request,
563
+ pid,
564
+ nt_req as AddressType ,
565
+ & iov as * const _ as * mut c_void ,
566
+ )
567
+ . map ( drop)
568
+ }
569
+ }
0 commit comments