use crate::arch::Arch;
use crate::common::Signal;
use crate::common::Tid;
use crate::target::ext::base::reverse_exec::ReplayLogPosition;
use crate::target::ext::breakpoints::WatchKind;
use crate::target::ext::catch_syscalls::CatchSyscallPosition;
use crate::target::Target;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[non_exhaustive]
pub enum BaseStopReason<Tid, U> {
DoneStep,
Exited(u8),
Terminated(Signal),
Signal(Signal),
SignalWithThread {
tid: Tid,
signal: Signal,
},
SwBreak(Tid),
HwBreak(Tid),
Watch {
tid: Tid,
kind: WatchKind,
addr: U,
},
ReplayLog {
tid: Option<Tid>,
pos: ReplayLogPosition,
},
CatchSyscall {
tid: Option<Tid>,
number: U,
position: CatchSyscallPosition,
},
Library(Tid),
Fork {
cur_tid: Tid,
new_tid: core::num::NonZeroUsize,
},
VFork {
cur_tid: Tid,
new_tid: core::num::NonZeroUsize,
},
VForkDone(Tid),
}
impl<Tid, U> BaseStopReason<Tid, U> {
pub(crate) fn is_t_packet(&self) -> bool {
match self {
Self::SignalWithThread { .. }
| Self::SwBreak(_)
| Self::HwBreak(_)
| Self::Watch { .. }
| Self::ReplayLog { .. }
| Self::CatchSyscall { .. }
| Self::Library(_)
| Self::Fork { .. }
| Self::VFork { .. }
| Self::VForkDone(_) => true,
Self::DoneStep | Self::Signal(_) | Self::Exited(_) | Self::Terminated(_) => false,
}
}
}
pub type SingleThreadStopReason<U> = BaseStopReason<(), U>;
pub type MultiThreadStopReason<U> = BaseStopReason<Tid, U>;
impl<U> From<BaseStopReason<(), U>> for BaseStopReason<Tid, U> {
fn from(st_stop_reason: BaseStopReason<(), U>) -> BaseStopReason<Tid, U> {
match st_stop_reason {
BaseStopReason::DoneStep => BaseStopReason::DoneStep,
BaseStopReason::Exited(code) => BaseStopReason::Exited(code),
BaseStopReason::Terminated(sig) => BaseStopReason::Terminated(sig),
BaseStopReason::SignalWithThread { signal, .. } => BaseStopReason::SignalWithThread {
tid: crate::SINGLE_THREAD_TID,
signal,
},
BaseStopReason::SwBreak(_) => BaseStopReason::SwBreak(crate::SINGLE_THREAD_TID),
BaseStopReason::HwBreak(_) => BaseStopReason::HwBreak(crate::SINGLE_THREAD_TID),
BaseStopReason::Watch { kind, addr, .. } => BaseStopReason::Watch {
tid: crate::SINGLE_THREAD_TID,
kind,
addr,
},
BaseStopReason::Signal(sig) => BaseStopReason::Signal(sig),
BaseStopReason::ReplayLog { pos, .. } => BaseStopReason::ReplayLog { tid: None, pos },
BaseStopReason::CatchSyscall {
number, position, ..
} => BaseStopReason::CatchSyscall {
tid: None,
number,
position,
},
BaseStopReason::Library(_) => BaseStopReason::Library(crate::SINGLE_THREAD_TID),
BaseStopReason::Fork { new_tid, .. } => BaseStopReason::Fork {
cur_tid: crate::SINGLE_THREAD_TID,
new_tid,
},
BaseStopReason::VFork { new_tid, .. } => BaseStopReason::VFork {
cur_tid: crate::SINGLE_THREAD_TID,
new_tid,
},
BaseStopReason::VForkDone(_) => BaseStopReason::VForkDone(crate::SINGLE_THREAD_TID),
}
}
}
mod private {
pub trait Sealed {}
impl<U> Sealed for super::SingleThreadStopReason<U> {}
impl<U> Sealed for super::MultiThreadStopReason<U> {}
}
pub trait IntoStopReason<T: Target>:
private::Sealed + Into<MultiThreadStopReason<<<T as Target>::Arch as Arch>::Usize>>
{
}
impl<T: Target> IntoStopReason<T> for SingleThreadStopReason<<<T as Target>::Arch as Arch>::Usize> {}
impl<T: Target> IntoStopReason<T> for MultiThreadStopReason<<<T as Target>::Arch as Arch>::Usize> {}