perf_event_data/impls/
perf_event_attr.rs1use perf_event_open_sys::bindings::*;
2
3use crate::error::ParseError;
4use crate::prelude::*;
5
6const PERF_ATTR_SIZE_MAX: u32 = PERF_ATTR_SIZE_VER8;
11
12impl<'p> Parse<'p> for perf_event_attr {
13 fn parse<B, E>(p: &mut Parser<B, E>) -> ParseResult<Self>
14 where
15 E: Endian,
16 B: ParseBuf<'p>,
17 {
18 use std::mem;
19
20 let mut attr = perf_event_attr::default();
21
22 attr.type_ = p.parse()?;
23 attr.size = p.parse()?;
24
25 match attr.size {
26 PERF_ATTR_SIZE_VER0 | PERF_ATTR_SIZE_VER1 | PERF_ATTR_SIZE_VER2
29 | PERF_ATTR_SIZE_VER3 | PERF_ATTR_SIZE_VER4 | PERF_ATTR_SIZE_VER5
30 | PERF_ATTR_SIZE_VER6 | PERF_ATTR_SIZE_VER7 | PERF_ATTR_SIZE_VER8 => (),
31
32 size if size > PERF_ATTR_SIZE_MAX => (),
34
35 size => {
37 return Err(ParseError::custom(
38 ErrorKind::InvalidRecord,
39 format_args!("{size} is not a valid size for a perf_event_attr struct"),
40 ))
41 }
42 }
43
44 let mut p = p.split_at(attr.size as usize - mem::size_of_val(&attr.size))?;
45
46 if attr.size >= PERF_ATTR_SIZE_VER0 {
47 attr.config = p.parse()?;
48 attr.__bindgen_anon_1.sample_period = p.parse()?;
49 attr.sample_type = p.parse()?;
50 attr.read_format = p.parse()?;
51 attr._bitfield_1 = __BindgenBitfieldUnit::new(u64::to_ne_bytes(p.parse()?));
52 attr.__bindgen_anon_2.wakeup_events = p.parse()?;
53 attr.bp_type = p.parse()?;
54 attr.__bindgen_anon_3.config1 = p.parse()?;
55 }
56
57 if attr.size >= PERF_ATTR_SIZE_VER1 {
58 attr.__bindgen_anon_4.config2 = p.parse()?;
59 }
60
61 if attr.size >= PERF_ATTR_SIZE_VER2 {
62 attr.branch_sample_type = p.parse()?;
63 }
64
65 if attr.size >= PERF_ATTR_SIZE_VER3 {
66 attr.sample_regs_user = p.parse()?;
67 attr.sample_stack_user = p.parse()?;
68 attr.clockid = p.parse_u32()? as _;
69 }
70
71 if attr.size >= PERF_ATTR_SIZE_VER4 {
72 attr.sample_regs_intr = p.parse()?;
73 }
74
75 if attr.size >= PERF_ATTR_SIZE_VER5 {
76 attr.aux_watermark = p.parse()?;
77 attr.sample_max_stack = p.parse()?;
78 let _ = p.parse_u16()?;
79 }
80
81 if attr.size >= PERF_ATTR_SIZE_VER6 {
82 attr.aux_sample_size = p.parse()?;
83 let _ = p.parse_u32()?;
84 }
85
86 if attr.size >= PERF_ATTR_SIZE_VER7 {
87 attr.sig_data = p.parse()?;
88 }
89
90 if attr.size >= PERF_ATTR_SIZE_VER8 {
91 attr.config3 = p.parse()?;
92 }
93
94 if attr.size > PERF_ATTR_SIZE_MAX {
95 let rest = p.parse_rest()?;
96 let all_zeros = rest.iter().copied().all(|b| b == 0);
97
98 if !all_zeros {
99 return Err(ParseError::custom(
100 ErrorKind::UnsupportedData,
101 "\
102 serialized perf_event_attr contains fields not supported \
103 by this version of perf-event-data\
104 ",
105 ));
106 }
107 }
108
109 Ok(attr)
110 }
111}