@@ -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,87 @@ 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
+ #[ cfg( any( all( target_os = "linux" , target_env = "gnu" , target_arch = "aarch64" ) ) ) ]
512
+ pub fn setregset ( pid : Pid , regs : user_regs_struct ) -> Result < ( ) > {
513
+ ptrace_set_iovec_data (
514
+ Request :: PTRACE_SETREGSET ,
515
+ pid,
516
+ libc:: NT_PRSTATUS ,
517
+ regs,
518
+ )
519
+ }
520
+
521
+ /// As with `ptrace_get_data` but with an `iovec`
522
+ #[ cfg( any( all( target_os = "linux" , target_env = "gnu" , target_arch = "aarch64" ) ) ) ]
523
+ fn ptrace_get_iovec_data < T > (
524
+ request : Request ,
525
+ pid : Pid ,
526
+ nt_req : libc:: c_int ,
527
+ ) -> Result < T > {
528
+ let mut data = mem:: MaybeUninit :: < T > :: uninit ( ) ;
529
+ let mut iov = libc:: iovec {
530
+ iov_base : data. as_mut_ptr ( ) as * mut c_void ,
531
+ iov_len : mem:: size_of :: < T > ( ) ,
532
+ } ;
533
+
534
+ let res = unsafe {
535
+ libc:: ptrace (
536
+ request as RequestType ,
537
+ pid,
538
+ nt_req as AddressType ,
539
+ & mut iov as * mut _ as * mut c_void ,
540
+ )
541
+ } ;
542
+
543
+ Errno :: result ( res) ?;
544
+ Ok ( unsafe { data. assume_init ( ) } )
545
+ }
546
+
547
+ #[ cfg( any( all( target_os = "linux" , target_env = "gnu" , target_arch = "aarch64" ) ) ) ]
548
+ fn ptrace_set_iovec_data < T > (
549
+ request : Request ,
550
+ pid : Pid ,
551
+ nt_req : libc:: c_int ,
552
+ data : T ,
553
+ ) -> Result < ( ) > {
554
+ let iov = libc:: iovec {
555
+ iov_base : & data as * const _ as * mut c_void ,
556
+ iov_len : mem:: size_of :: < T > ( ) ,
557
+ } ;
558
+
559
+ unsafe {
560
+ ptrace_other (
561
+ request,
562
+ pid,
563
+ nt_req as AddressType ,
564
+ & iov as * const _ as * mut c_void ,
565
+ )
566
+ . map ( drop)
567
+ }
568
+ }
0 commit comments