aboutsummaryrefslogtreecommitdiff
path: root/src/target/ext/catch_syscalls.rs
blob: b5f0ee9799ee60910dfbd961146c5b4e22b25187 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
//! Enable or disable catching syscalls from the inferior process.

use crate::arch::Arch;
use crate::target::Target;
use crate::target::TargetResult;

/// Target Extension - Enable and disable catching syscalls from the inferior
/// process.
///
/// Implementing this extension allows the target to support the `catch syscall`
/// GDB client command. See [GDB documentation](https://sourceware.org/gdb/onlinedocs/gdb/Set-Catchpoints.html)
/// for further details.
pub trait CatchSyscalls: Target {
    /// Enables catching syscalls from the inferior process.
    ///
    /// If `filter` is `None`, then all syscalls should be reported to GDB. If a
    /// filter is provided, only the syscalls listed in the filter should be
    /// reported to GDB.
    ///
    /// Note: filters are not combined, subsequent calls this method should
    /// replace any existing syscall filtering.
    fn enable_catch_syscalls(
        &mut self,
        filter: Option<SyscallNumbers<'_, <Self::Arch as Arch>::Usize>>,
    ) -> TargetResult<(), Self>;

    /// Disables catching syscalls from the inferior process.
    fn disable_catch_syscalls(&mut self) -> TargetResult<(), Self>;
}

define_ext!(CatchSyscallsOps, CatchSyscalls);

/// Describes where the syscall catchpoint was triggered at.
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum CatchSyscallPosition {
    /// Reached the entry location of the syscall.
    Entry,
    /// Reached the return location of the syscall.
    Return,
}

/// Iterator of syscall numbers that should be reported to GDB.
pub struct SyscallNumbers<'a, U> {
    pub(crate) inner: &'a mut dyn Iterator<Item = U>,
}

impl<U> Iterator for SyscallNumbers<'_, U> {
    type Item = U;

    fn next(&mut self) -> Option<Self::Item> {
        self.inner.next()
    }
}