@@ -4,24 +4,30 @@ use nix::unistd;
44
55use crate :: discrete_alloc;
66
7+ #[ cfg( target_pointer_width = "64" ) ]
8+ const BITS : u32 = 64 ;
9+ #[ cfg( target_pointer_width = "32" ) ]
10+ const BITS : u32 = 32 ;
11+
12+ #[ cfg( any( target_arch = "x86" , target_arch = "x86_64" ) ) ]
13+ const BREAKPT_INSTR : i64 = 0xCC ;
14+ #[ cfg( target_arch = "aarch64" ) ]
15+ const BREAKPT_INSTR : i64 = 0xD420 ;
16+
717// We do NOT ever want to block the child from accessing this!!
818static SUPERVISOR : std:: sync:: Mutex < Option < Supervisor > > = std:: sync:: Mutex :: new ( None ) ;
919static mut PAGE_ADDR : * mut libc:: c_void = std:: ptr:: null_mut ( ) ;
1020static mut PAGE_SIZE : usize = 4096 ;
1121static mut CLICK_HERE_4_FREE_STACK : [ u8 ; 1024 ] = [ 0 ; 1024 ] ;
1222
13- #[ cfg( target_pointer_width = "64" ) ]
14- const BITS : u32 = 64 ;
15- #[ cfg( target_pointer_width = "32" ) ]
16- const BITS : u32 = 32 ;
17-
1823trait ArchIndependentRegs {
19- fn ax ( & self ) -> usize ;
20- fn di ( & self ) -> usize ;
21- fn si ( & self ) -> usize ;
24+ // see https://man7.org/linux/man-pages/man2/syscall.2.html
25+ fn retval ( & self ) -> usize ;
26+ fn arg1 ( & self ) -> usize ;
27+ fn arg2 ( & self ) -> usize ;
28+ fn syscall_nr ( & self ) -> usize ;
2229 fn ip ( & self ) -> usize ;
2330 fn sp ( & self ) -> usize ;
24- fn orig_ax ( & self ) -> usize ;
2531 fn set_ip ( & mut self , ip : usize ) ;
2632 fn set_sp ( & mut self , sp : usize ) ;
2733}
@@ -30,12 +36,12 @@ trait ArchIndependentRegs {
3036#[ allow( clippy:: cast_possible_truncation) ]
3137#[ rustfmt:: skip]
3238impl ArchIndependentRegs for libc:: user_regs_struct {
33- fn ax ( & self ) -> usize { self . rax as _ }
34- fn di ( & self ) -> usize { self . rdi as _ }
35- fn si ( & self ) -> usize { self . rsi as _ }
39+ fn retval ( & self ) -> usize { self . rax as _ }
40+ fn arg1 ( & self ) -> usize { self . rdi as _ }
41+ fn arg2 ( & self ) -> usize { self . rsi as _ }
42+ fn syscall_nr ( & self ) -> usize { self . orig_rax as _ }
3643 fn ip ( & self ) -> usize { self . rip as _ }
3744 fn sp ( & self ) -> usize { self . rsp as _ }
38- fn orig_ax ( & self ) -> usize { self . orig_rax as _ }
3945 fn set_ip ( & mut self , ip : usize ) { self . rip = ip as _ }
4046 fn set_sp ( & mut self , sp : usize ) { self . rsp = sp as _ }
4147}
@@ -44,16 +50,30 @@ impl ArchIndependentRegs for libc::user_regs_struct {
4450#[ allow( clippy:: cast_possible_truncation) ]
4551#[ rustfmt:: skip]
4652impl ArchIndependentRegs for libc:: user_regs_struct {
47- fn ax ( & self ) -> usize { self . eax as _ }
48- fn di ( & self ) -> usize { self . edi as _ }
49- fn si ( & self ) -> usize { self . esi as _ }
53+ fn retval ( & self ) -> usize { self . eax as _ }
54+ fn arg1 ( & self ) -> usize { self . edi as _ }
55+ fn arg2 ( & self ) -> usize { self . esi as _ }
56+ fn syscall_nr ( & self ) -> usize { self . orig_eax as _ }
5057 fn ip ( & self ) -> usize { self . eip as _ }
5158 fn sp ( & self ) -> usize { self . esp as _ }
52- fn orig_ax ( & self ) -> usize { self . orig_eax as _ }
5359 fn set_ip ( & mut self , ip : usize ) { self . eip = ip as _ }
5460 fn set_sp ( & mut self , sp : usize ) { self . esp = sp as _ }
5561}
5662
63+ #[ cfg( target_arch = "aarch64" ) ]
64+ #[ allow( clippy:: cast_possible_truncation) ]
65+ #[ rustfmt:: skip]
66+ impl ArchIndependentRegs for libc:: user_regs_struct {
67+ fn retval ( & self ) -> usize { self . regs [ 0 ] as _ }
68+ fn arg1 ( & self ) -> usize { self . regs [ 0 ] as _ }
69+ fn arg2 ( & self ) -> usize { self . regs [ 1 ] as _ }
70+ fn syscall_nr ( & self ) -> usize { self . regs [ 8 ] as _ }
71+ fn ip ( & self ) -> usize { self . pc as _ }
72+ fn sp ( & self ) -> usize { self . sp as _ }
73+ fn set_ip ( & mut self , ip : usize ) { self . pc = ip as _ }
74+ fn set_sp ( & mut self , sp : usize ) { self . sp = sp as _ }
75+ }
76+
5777pub struct Supervisor {
5878 t_message : ipc:: IpcSender < TraceRequest > ,
5979 r_event : ipc:: IpcReceiver < MemEvents > ,
@@ -295,16 +315,16 @@ fn sv_loop(listener: ChildListener, t_event: ipc::IpcSender<MemEvents>) -> ! {
295315 }
296316 wait:: WaitStatus :: PtraceSyscall ( pid) => {
297317 let regs = ptrace:: getregs ( pid) . unwrap ( ) ;
298- let syscall_nr = regs. orig_ax ( ) ;
318+ let syscall_nr = regs. syscall_nr ( ) ;
299319 if enter {
300320 if syscall_nr as i64 == libc:: SYS_mmap {
301- let len = regs. si ( ) ;
321+ let len = regs. arg2 ( ) ;
302322 flush_mapped = Some ( len) ;
303323 } else if syscall_nr as i64 == libc:: SYS_munmap {
304324 // The unmap call might hit multiple mappings we've saved,
305325 // or overlap with them partially (or both)
306- let um_start = regs. di ( ) ;
307- let um_len = regs. si ( ) ;
326+ let um_start = regs. arg1 ( ) ;
327+ let um_len = regs. arg2 ( ) ;
308328 let um_end = um_start + um_len;
309329 let mut idxes = vec ! [ ] ;
310330 for ( idx, & ( mp_start, len) ) in mappings. iter ( ) . enumerate ( ) {
@@ -326,9 +346,9 @@ fn sv_loop(listener: ChildListener, t_event: ipc::IpcSender<MemEvents>) -> ! {
326346 } // TODO: handle brk/sbrk
327347 } else {
328348 if syscall_nr as i64 == libc:: SYS_mmap {
329- if regs. ax ( ) as isize > 0 {
349+ if regs. retval ( ) as isize > 0 {
330350 if let Some ( len) = flush_mapped. take ( ) {
331- let addr = regs. ax ( ) ;
351+ let addr = regs. retval ( ) ;
332352 mappings. push ( ( addr, len as _ ) ) ;
333353 } else {
334354 eprintln ! (
@@ -338,7 +358,7 @@ fn sv_loop(listener: ChildListener, t_event: ipc::IpcSender<MemEvents>) -> ! {
338358 }
339359 } else if syscall_nr as i64 == libc:: SYS_munmap {
340360 if let Some ( ( idxes, um_start, um_len) ) = munmap_args. take ( ) {
341- if regs. ax ( ) as isize > 0 {
361+ if regs. retval ( ) as isize > 0 {
342362 // Unmap succeeded, so take out the mapping(s) from our list
343363 // but it may be only partial so we may readd some sections
344364 for idx in idxes {
@@ -373,9 +393,9 @@ fn sv_loop(listener: ChildListener, t_event: ipc::IpcSender<MemEvents>) -> ! {
373393 ptrace:: seize ( main_pid, ptrace:: Options :: PTRACE_O_TRACESYSGOOD ) . unwrap ( ) ;
374394 let _ = wait:: waitpid ( main_pid, None ) . unwrap ( ) ;
375395
376- ptrace:: write ( main_pid, malloc_addr as _ , 0xcc ) . unwrap ( ) ;
377- ptrace:: write ( main_pid, realloc_addr as _ , 0xcc ) . unwrap ( ) ;
378- ptrace:: write ( main_pid, free_addr as _ , 0xcc ) . unwrap ( ) ;
396+ ptrace:: write ( main_pid, malloc_addr as _ , BREAKPT_INSTR ) . unwrap ( ) ;
397+ ptrace:: write ( main_pid, realloc_addr as _ , BREAKPT_INSTR ) . unwrap ( ) ;
398+ ptrace:: write ( main_pid, free_addr as _ , BREAKPT_INSTR ) . unwrap ( ) ;
379399
380400 ptrace:: syscall ( main_pid, None ) . unwrap ( ) ;
381401 }
@@ -515,13 +535,13 @@ fn handle_sigtrap(
515535 let regs = ptrace:: getregs ( pid) . unwrap ( ) ;
516536 match regs. ip ( ) - 1 {
517537 a if a == malloc_addr => {
518- let size = regs. di ( ) ; // !
538+ let size = regs. arg1 ( ) ; // !
519539 let ptr = intercept_retptr ( pid, regs, malloc_addr, malloc_bytes) ;
520540 mappings. push ( ( ptr as _ , size) ) ;
521541 }
522542 a if a == realloc_addr => {
523- let old_ptr = regs. di ( ) ;
524- let size = regs. si ( ) ;
543+ let old_ptr = regs. arg1 ( ) ;
544+ let size = regs. arg2 ( ) ;
525545 let pos = mappings
526546 . iter ( )
527547 . position ( |& ( ptr, size) | ptr <= old_ptr as _ && ( old_ptr as usize ) < ptr + size) ;
@@ -532,7 +552,7 @@ fn handle_sigtrap(
532552 mappings. push ( ( ptr as _ , size as _ ) ) ;
533553 }
534554 a if a == free_addr => {
535- let old_ptr = regs. di ( ) ;
555+ let old_ptr = regs. arg1 ( ) ;
536556 //let size = regs.rdi;
537557 let pos =
538558 mappings. iter ( ) . position ( |& ( ptr, size) | ptr <= old_ptr && old_ptr < ptr + size) ;
@@ -565,7 +585,7 @@ fn intercept_retptr(
565585 regs. set_ip ( regs. ip ( ) - 1 ) ;
566586 let ret_addr = ptrace:: read ( pid, regs. sp ( ) as _ ) . unwrap ( ) ;
567587 let ret_bytes = ptrace:: read ( pid, ret_addr as _ ) . unwrap ( ) ;
568- ptrace:: write ( pid, ret_addr as _ , 0xcc ) . unwrap ( ) ;
588+ ptrace:: write ( pid, ret_addr as _ , BREAKPT_INSTR ) . unwrap ( ) ;
569589 ptrace:: write ( pid, fn_addr as _ , fn_bytes) . unwrap ( ) ;
570590 ptrace:: setregs ( pid, regs) . unwrap ( ) ;
571591
@@ -574,9 +594,9 @@ fn intercept_retptr(
574594
575595 // now we're getting the return hopefully
576596 let mut regs = ptrace:: getregs ( pid) . unwrap ( ) ;
577- let ptr = regs. ax ( ) ; // !
597+ let ptr = regs. retval ( ) ; // !
578598 regs. set_ip ( regs. ip ( ) - 1 ) ;
579- ptrace:: write ( pid, fn_addr as _ , 0xcc ) . unwrap ( ) ;
599+ ptrace:: write ( pid, fn_addr as _ , BREAKPT_INSTR ) . unwrap ( ) ;
580600 ptrace:: write ( pid, ret_addr as _ , ret_bytes) . unwrap ( ) ;
581601 ptrace:: setregs ( pid, regs) . unwrap ( ) ;
582602
0 commit comments