aboutsummaryrefslogtreecommitdiff
path: root/src/stub/core_impl/catch_syscalls.rs
blob: b7dde2eddbb45c6b280dabf9f348f3d4be6c17a5 (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
use super::prelude::*;
use crate::protocol::commands::ext::CatchSyscalls;

use crate::arch::Arch;
use crate::protocol::commands::_QCatchSyscalls::QCatchSyscalls;
use crate::target::ext::catch_syscalls::SyscallNumbers;

impl<T: Target, C: Connection> GdbStubImpl<T, C> {
    pub(crate) fn handle_catch_syscalls(
        &mut self,
        _res: &mut ResponseWriter<'_, C>,
        target: &mut T,
        command: CatchSyscalls<'_>,
    ) -> Result<HandlerStatus, Error<T::Error, C::Error>> {
        let ops = match target.support_catch_syscalls() {
            Some(ops) => ops,
            None => return Ok(HandlerStatus::Handled),
        };

        crate::__dead_code_marker!("catch_syscalls", "impl");

        let handler_status = match command {
            CatchSyscalls::QCatchSyscalls(cmd) => {
                match cmd {
                    QCatchSyscalls::Disable => ops.disable_catch_syscalls().handle_error()?,
                    QCatchSyscalls::Enable(sysno) => {
                        let mut error = false;
                        let mut filter = sysno
                            .into_iter()
                            .map(<T::Arch as Arch>::Usize::from_be_bytes)
                            .take_while(|x| {
                                error = x.is_none();
                                !error
                            })
                            .flatten();
                        ops.enable_catch_syscalls(Some(SyscallNumbers { inner: &mut filter }))
                            .handle_error()?;
                        if error {
                            return Err(Error::TargetMismatch);
                        }
                    }
                    QCatchSyscalls::EnableAll => ops.enable_catch_syscalls(None).handle_error()?,
                }
                HandlerStatus::NeedsOk
            }
        };

        Ok(handler_status)
    }
}