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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
use super::prelude::*;
use crate::target::ext::tracepoints::Tracepoint;
#[derive(Debug)]
#[allow(clippy::upper_case_acronyms)]
pub enum QTDP<'a> {
Create(CreateTDP<'a>),
Extend(ExtendTDP<'a>),
}
#[derive(Debug)]
pub struct CreateTDP<'a> {
pub number: Tracepoint,
pub addr: &'a [u8],
pub enable: bool,
pub step: u64,
pub pass: u64,
pub unsupported_option: Option<u8>,
pub more: bool,
}
#[derive(Debug)]
pub struct ExtendTDP<'a> {
pub number: Tracepoint,
pub addr: &'a [u8],
pub actions: &'a mut [u8],
}
impl<'a> ParseCommand<'a> for QTDP<'a> {
#[inline(always)]
fn from_packet(buf: PacketBuf<'a>) -> Option<Self> {
let body = buf.into_body();
match body {
[b':', b'-', actions @ ..] => {
let mut params = actions.splitn_mut(4, |b| *b == b':');
let number = Tracepoint(decode_hex(params.next()?).ok()?);
let addr = decode_hex_buf(params.next()?).ok()?;
let actions = params.next()?;
Some(QTDP::Extend(ExtendTDP {
number,
addr,
actions,
}))
}
[b':', tracepoint @ ..] => {
// Strip off the trailing '-' that indicates if there will be
// more packets after this
let (tracepoint, more) = match tracepoint {
[rest @ .., b'-'] => (rest, true),
x => (x, false),
};
let mut params = tracepoint.splitn_mut(6, |b| *b == b':');
let n = Tracepoint(decode_hex(params.next()?).ok()?);
let addr = decode_hex_buf(params.next()?).ok()?;
let ena = params.next()?;
let step = decode_hex(params.next()?).ok()?;
let pass_and_end = params.next()?;
let pass = decode_hex(pass_and_end).ok()?;
// TODO: parse `F` fast tracepoint options
// TODO: parse `X` tracepoint conditions
let options = params.next();
let unsupported_option = match options {
Some([b'F', ..]) => {
/* TODO: fast tracepoints support */
Some(b'F')
}
Some([b'S']) => {
/* TODO: static tracepoint support */
Some(b'S')
}
Some([b'X', ..]) => {
/* TODO: trace conditions support */
Some(b'X')
}
Some(_) => {
/* invalid option */
return None;
}
None => None,
};
Some(QTDP::Create(CreateTDP {
number: n,
addr,
enable: match ena {
[b'E'] => Some(true),
[b'D'] => Some(false),
_ => None,
}?,
step,
pass,
more,
unsupported_option,
}))
}
_ => None,
}
}
}