1 //! Enable or disable catching syscalls from the inferior process.
2 
3 use crate::arch::Arch;
4 use crate::target::Target;
5 use crate::target::TargetResult;
6 
7 /// Target Extension - Enable and disable catching syscalls from the inferior
8 /// process.
9 ///
10 /// Implementing this extension allows the target to support the `catch syscall`
11 /// GDB client command. See [GDB documentation](https://sourceware.org/gdb/onlinedocs/gdb/Set-Catchpoints.html)
12 /// for further details.
13 pub trait CatchSyscalls: Target {
14     /// Enables catching syscalls from the inferior process.
15     ///
16     /// If `filter` is `None`, then all syscalls should be reported to GDB. If a
17     /// filter is provided, only the syscalls listed in the filter should be
18     /// reported to GDB.
19     ///
20     /// Note: filters are not combined, subsequent calls this method should
21     /// replace any existing syscall filtering.
enable_catch_syscalls( &mut self, filter: Option<SyscallNumbers<'_, <Self::Arch as Arch>::Usize>>, ) -> TargetResult<(), Self>22     fn enable_catch_syscalls(
23         &mut self,
24         filter: Option<SyscallNumbers<'_, <Self::Arch as Arch>::Usize>>,
25     ) -> TargetResult<(), Self>;
26 
27     /// Disables catching syscalls from the inferior process.
disable_catch_syscalls(&mut self) -> TargetResult<(), Self>28     fn disable_catch_syscalls(&mut self) -> TargetResult<(), Self>;
29 }
30 
31 define_ext!(CatchSyscallsOps, CatchSyscalls);
32 
33 /// Describes where the syscall catchpoint was triggered at.
34 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
35 pub enum CatchSyscallPosition {
36     /// Reached the entry location of the syscall.
37     Entry,
38     /// Reached the return location of the syscall.
39     Return,
40 }
41 
42 /// Iterator of syscall numbers that should be reported to GDB.
43 pub struct SyscallNumbers<'a, U> {
44     pub(crate) inner: &'a mut dyn Iterator<Item = U>,
45 }
46 
47 impl<U> Iterator for SyscallNumbers<'_, U> {
48     type Item = U;
49 
next(&mut self) -> Option<Self::Item>50     fn next(&mut self) -> Option<Self::Item> {
51         self.inner.next()
52     }
53 }
54