@@ -109,6 +109,12 @@ libc_enum!{
109
109
#[ cfg( all( target_os = "linux" , not( any( target_arch = "mips" ,
110
110
target_arch = "mips64" ) ) ) ) ]
111
111
PTRACE_PEEKSIGINFO ,
112
+ #[ cfg( all( target_os = "linux" , target_env = "gnu" ,
113
+ any( target_arch = "x86" , target_arch = "x86_64" ) ) ) ]
114
+ PTRACE_SYSEMU ,
115
+ #[ cfg( all( target_os = "linux" , target_env = "gnu" ,
116
+ any( target_arch = "x86" , target_arch = "x86_64" ) ) ) ]
117
+ PTRACE_SYSEMU_SINGLESTEP ,
112
118
}
113
119
}
114
120
@@ -278,7 +284,7 @@ pub fn traceme() -> Result<()> {
278
284
}
279
285
}
280
286
281
- /// Ask for next syscall, as with `ptrace(PTRACE_SYSCALL, ...)`
287
+ /// Continue execution until the next syscall, as with `ptrace(PTRACE_SYSCALL, ...)`
282
288
///
283
289
/// Arranges for the tracee to be stopped at the next entry to or exit from a system call,
284
290
/// optionally delivering a signal specified by `sig`.
@@ -297,6 +303,23 @@ pub fn syscall<T: Into<Option<Signal>>>(pid: Pid, sig: T) -> Result<()> {
297
303
}
298
304
}
299
305
306
+ /// Continue execution until the next syscall, as with `ptrace(PTRACE_SYSEMU, ...)`
307
+ ///
308
+ /// In contrast to the `syscall` function, the syscall stopped at will not be executed.
309
+ /// Thus the the tracee will only be stopped once per syscall,
310
+ /// optionally delivering a signal specified by `sig`.
311
+ #[ cfg( all( target_os = "linux" , target_env = "gnu" , any( target_arch = "x86" , target_arch = "x86_64" ) ) ) ]
312
+ pub fn sysemu < T : Into < Option < Signal > > > ( pid : Pid , sig : T ) -> Result < ( ) > {
313
+ let data = match sig. into ( ) {
314
+ Some ( s) => s as i32 as * mut c_void ,
315
+ None => ptr:: null_mut ( ) ,
316
+ } ;
317
+ unsafe {
318
+ ptrace_other ( Request :: PTRACE_SYSEMU , pid, ptr:: null_mut ( ) , data) . map ( drop)
319
+ // ignore the useless return value
320
+ }
321
+ }
322
+
300
323
/// Attach to a running process, as with `ptrace(PTRACE_ATTACH, ...)`
301
324
///
302
325
/// Attaches to the process specified by `pid`, making it a tracee of the calling process.
@@ -402,6 +425,28 @@ pub fn step<T: Into<Option<Signal>>>(pid: Pid, sig: T) -> Result<()> {
402
425
}
403
426
}
404
427
428
+ /// Move the stopped tracee process forward by a single step or stop at the next syscall
429
+ /// as with `ptrace(PTRACE_SYSEMU_SINGLESTEP, ...)`
430
+ ///
431
+ /// Advances the execution by a single step or until the next syscall.
432
+ /// In case the tracee is stopped at a syscall, the syscall will not be executed.
433
+ /// Optionally, the signal specified by `sig` is delivered to the tracee upon continuation.
434
+ #[ cfg( all( target_os = "linux" , target_env = "gnu" , any( target_arch = "x86" , target_arch = "x86_64" ) ) ) ]
435
+ pub fn sysemu_step < T : Into < Option < Signal > > > ( pid : Pid , sig : T ) -> Result < ( ) > {
436
+ let data = match sig. into ( ) {
437
+ Some ( s) => s as i32 as * mut c_void ,
438
+ None => ptr:: null_mut ( ) ,
439
+ } ;
440
+ unsafe {
441
+ ptrace_other (
442
+ Request :: PTRACE_SYSEMU_SINGLESTEP ,
443
+ pid,
444
+ ptr:: null_mut ( ) ,
445
+ data,
446
+ )
447
+ . map ( drop) // ignore the useless return value
448
+ }
449
+ }
405
450
406
451
/// Reads a word from a processes memory at the given address
407
452
pub fn read ( pid : Pid , addr : AddressType ) -> Result < c_long > {
0 commit comments