@@ -5,7 +5,7 @@ use crate::sys::signal::Signal;
5
5
use crate :: unistd:: Pid ;
6
6
use crate :: Result ;
7
7
use cfg_if:: cfg_if;
8
- use libc:: { self , c_long, c_void, siginfo_t} ;
8
+ use libc:: { self , c_long, c_void, ptrace_syscall_info , siginfo_t} ;
9
9
use std:: { mem, ptr} ;
10
10
11
11
pub type AddressType = * mut :: libc:: c_void ;
@@ -121,6 +121,7 @@ libc_enum! {
121
121
#[ cfg( all( target_os = "linux" , target_env = "gnu" ,
122
122
any( target_arch = "x86" , target_arch = "x86_64" ) ) ) ]
123
123
PTRACE_SYSEMU_SINGLESTEP ,
124
+ PTRACE_GET_SYSCALL_INFO ,
124
125
}
125
126
}
126
127
@@ -152,6 +153,77 @@ libc_enum! {
152
153
}
153
154
}
154
155
156
+ #[ cfg_attr( docsrs, doc( cfg( all( ) ) ) ) ]
157
+ #[ derive( Clone , Copy , Debug , Eq , Hash , PartialEq ) ]
158
+ pub struct SyscallInfo {
159
+ /// Type of system call stop
160
+ pub op : SyscallInfoOp ,
161
+ /// AUDIT_ARCH_* value; see seccomp(2)
162
+ pub arch : u32 ,
163
+ /// CPU instruction pointer
164
+ pub instruction_pointer : u64 ,
165
+ /// CPU stack pointer
166
+ pub stack_pointer : u64 ,
167
+ }
168
+
169
+ #[ cfg_attr( docsrs, doc( cfg( all( ) ) ) ) ]
170
+ #[ derive( Clone , Copy , Debug , Eq , Hash , PartialEq ) ]
171
+ pub enum SyscallInfoOp {
172
+ None ,
173
+ /// System call entry.
174
+ Entry {
175
+ /// System call number.
176
+ nr : i64 ,
177
+ /// System call arguments.
178
+ args : [ u64 ; 6 ] ,
179
+ } ,
180
+ /// System call exit.
181
+ Exit {
182
+ /// System call return value.
183
+ ret_val : i64 ,
184
+ /// System call error flag.
185
+ is_error : u8 ,
186
+ } ,
187
+ /// PTRACE_EVENT_SECCOMP stop.
188
+ Seccomp {
189
+ /// System call number.
190
+ nr : i64 ,
191
+ /// System call arguments.
192
+ args : [ u64 ; 6 ] ,
193
+ /// SECCOMP_RET_DATA portion of SECCOMP_RET_TRACE return value.
194
+ ret_data : u32 ,
195
+ } ,
196
+ }
197
+
198
+ impl SyscallInfo {
199
+ pub fn from_raw ( raw : ptrace_syscall_info ) -> Result < SyscallInfo > {
200
+ let op = match raw. op {
201
+ libc:: PTRACE_SYSCALL_INFO_NONE => Ok ( SyscallInfoOp :: None ) ,
202
+ libc:: PTRACE_SYSCALL_INFO_ENTRY => Ok ( SyscallInfoOp :: Entry {
203
+ nr : unsafe { raw. u . entry . nr as _ } ,
204
+ args : unsafe { raw. u . entry . args } ,
205
+ } ) ,
206
+ libc:: PTRACE_SYSCALL_INFO_EXIT => Ok ( SyscallInfoOp :: Exit {
207
+ ret_val : unsafe { raw. u . exit . sval } ,
208
+ is_error : unsafe { raw. u . exit . is_error } ,
209
+ } ) ,
210
+ libc:: PTRACE_SYSCALL_INFO_SECCOMP => Ok ( SyscallInfoOp :: Seccomp {
211
+ nr : unsafe { raw. u . seccomp . nr as _ } ,
212
+ args : unsafe { raw. u . seccomp . args } ,
213
+ ret_data : unsafe { raw. u . seccomp . ret_data } ,
214
+ } ) ,
215
+ _ => Err ( Errno :: ENOSYS ) ,
216
+ } ?;
217
+
218
+ Ok ( SyscallInfo {
219
+ op,
220
+ arch : raw. arch ,
221
+ instruction_pointer : raw. instruction_pointer ,
222
+ stack_pointer : raw. stack_pointer ,
223
+ } )
224
+ }
225
+ }
226
+
155
227
libc_bitflags ! {
156
228
/// Ptrace options used in conjunction with the PTRACE_SETOPTIONS request.
157
229
/// See `man ptrace` for more details.
@@ -292,6 +364,21 @@ pub fn getsiginfo(pid: Pid) -> Result<siginfo_t> {
292
364
ptrace_get_data :: < siginfo_t > ( Request :: PTRACE_GETSIGINFO , pid)
293
365
}
294
366
367
+ /// Get ptrace syscall info as with `ptrace(PTRACE_GET_SYSCALL_INFO,...)`
368
+ /// Only available on Linux 5.3+
369
+ pub fn getsyscallinfo ( pid : Pid ) -> Result < SyscallInfo > {
370
+ let mut data = mem:: MaybeUninit :: uninit ( ) ;
371
+ unsafe {
372
+ ptrace_other (
373
+ Request :: PTRACE_GET_SYSCALL_INFO ,
374
+ pid,
375
+ mem:: size_of :: < ptrace_syscall_info > ( ) as * mut c_void ,
376
+ data. as_mut_ptr ( ) as * mut _ as * mut c_void ,
377
+ ) ?;
378
+ }
379
+ SyscallInfo :: from_raw ( unsafe { data. assume_init ( ) } )
380
+ }
381
+
295
382
/// Set siginfo as with `ptrace(PTRACE_SETSIGINFO,...)`
296
383
pub fn setsiginfo ( pid : Pid , sig : & siginfo_t ) -> Result < ( ) > {
297
384
let ret = unsafe {
0 commit comments