twizzler_abi/syscall/
trace.rs1use twizzler_rt_abi::{error::TwzError, object::ObjID};
2
3use super::{convert_codes_to_result, twzerr, Syscall};
4use crate::{
5 arch::syscall::raw_syscall,
6 trace::{TraceEntryHead, TraceFlags, TraceKind},
7};
8
9#[derive(Debug, Clone, Copy)]
12pub struct TraceSpec {
13 pub kind: TraceKind,
15 pub flags: TraceFlags,
17 pub enable_events: u64,
19 pub disable_events: u64,
21 pub sctx: Option<ObjID>,
23 pub mctx: Option<ObjID>,
25 pub thread: Option<ObjID>,
27 pub cpuid: Option<u64>,
29 pub extra: ObjID,
31}
32
33impl TraceSpec {
34 pub fn accepts(&self, header: &TraceEntryHead) -> bool {
36 if header.kind != self.kind {
37 return false;
38 }
39
40 let events_match = (self.enable_events & (header.event & !self.disable_events)) != 0;
41
42 let cpu_ok = self.cpuid.is_none_or(|x| x == header.cpuid);
43 let sctx_ok = self.sctx.is_none_or(|x| x == header.sctx);
44 let mctx_ok = self.mctx.is_none_or(|x| x == header.mctx);
45 let thread_ok = self.thread.is_none_or(|x| x == header.thread);
46
47 cpu_ok && sctx_ok && mctx_ok && thread_ok && events_match
48 }
49}
50
51pub fn sys_ktrace(object: ObjID, spec: Option<&TraceSpec>) -> Result<(), TwzError> {
60 let [hi, lo] = object.parts();
61 let (code, val) = unsafe {
62 raw_syscall(
63 Syscall::Ktrace,
64 &[
65 hi,
66 lo,
67 spec.map(|spec| spec as *const _ as usize as u64)
68 .unwrap_or(0),
69 ],
70 )
71 };
72 convert_codes_to_result(code, val, |c, _| c != 0, |_, _| (), twzerr)
73}