1use crate::constants::*;
2use bitflags::bitflags;
3
4bitflags! {
5 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
6 pub struct SampleFormat: u64 {
7 const IP = PERF_SAMPLE_IP;
8 const TID = PERF_SAMPLE_TID;
9 const TIME = PERF_SAMPLE_TIME;
10 const ADDR = PERF_SAMPLE_ADDR;
11 const READ = PERF_SAMPLE_READ;
12 const CALLCHAIN = PERF_SAMPLE_CALLCHAIN;
13 const ID = PERF_SAMPLE_ID;
14 const CPU = PERF_SAMPLE_CPU;
15 const PERIOD = PERF_SAMPLE_PERIOD;
16 const STREAM_ID = PERF_SAMPLE_STREAM_ID;
17 const RAW = PERF_SAMPLE_RAW;
18 const BRANCH_STACK = PERF_SAMPLE_BRANCH_STACK;
19 const REGS_USER = PERF_SAMPLE_REGS_USER;
20 const STACK_USER = PERF_SAMPLE_STACK_USER;
21 const WEIGHT = PERF_SAMPLE_WEIGHT;
22 const DATA_SRC = PERF_SAMPLE_DATA_SRC;
23 const IDENTIFIER = PERF_SAMPLE_IDENTIFIER;
24 const TRANSACTION = PERF_SAMPLE_TRANSACTION;
25 const REGS_INTR = PERF_SAMPLE_REGS_INTR;
26 const PHYS_ADDR = PERF_SAMPLE_PHYS_ADDR;
27 const AUX = PERF_SAMPLE_AUX;
28 const CGROUP = PERF_SAMPLE_CGROUP;
29 const DATA_PAGE_SIZE = PERF_SAMPLE_DATA_PAGE_SIZE;
30 const CODE_PAGE_SIZE = PERF_SAMPLE_CODE_PAGE_SIZE;
31 const WEIGHT_STRUCT = PERF_SAMPLE_WEIGHT_STRUCT;
32 }
33
34 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
35 pub struct BranchSampleFormat: u64 {
36 const USER = PERF_SAMPLE_BRANCH_USER;
38 const KERNEL = PERF_SAMPLE_BRANCH_KERNEL;
40 const HV = PERF_SAMPLE_BRANCH_HV;
42 const ANY = PERF_SAMPLE_BRANCH_ANY;
44 const ANY_CALL = PERF_SAMPLE_BRANCH_ANY_CALL;
46 const ANY_RETURN = PERF_SAMPLE_BRANCH_ANY_RETURN;
48 const IND_CALL = PERF_SAMPLE_BRANCH_IND_CALL;
50 const ABORT_TX = PERF_SAMPLE_BRANCH_ABORT_TX;
52 const IN_TX = PERF_SAMPLE_BRANCH_IN_TX;
54 const NO_TX = PERF_SAMPLE_BRANCH_NO_TX;
56 const COND = PERF_SAMPLE_BRANCH_COND;
58 const CALL_STACK = PERF_SAMPLE_BRANCH_CALL_STACK;
60 const IND_JUMP = PERF_SAMPLE_BRANCH_IND_JUMP;
62 const CALL = PERF_SAMPLE_BRANCH_CALL;
64 const NO_FLAGS = PERF_SAMPLE_BRANCH_NO_FLAGS;
66 const NO_CYCLES = PERF_SAMPLE_BRANCH_NO_CYCLES;
68 const TYPE_SAVE = PERF_SAMPLE_BRANCH_TYPE_SAVE;
70 const HW_INDEX = PERF_SAMPLE_BRANCH_HW_INDEX;
72 }
73
74 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
75 pub struct AttrFlags: u64 {
76 const DISABLED = ATTR_FLAG_BIT_DISABLED;
78 const INHERIT = ATTR_FLAG_BIT_INHERIT;
80 const PINNED = ATTR_FLAG_BIT_PINNED;
82 const EXCLUSIVE = ATTR_FLAG_BIT_EXCLUSIVE;
84 const EXCLUDE_USER = ATTR_FLAG_BIT_EXCLUDE_USER;
86 const EXCLUDE_KERNEL = ATTR_FLAG_BIT_EXCLUDE_KERNEL;
88 const EXCLUDE_HV = ATTR_FLAG_BIT_EXCLUDE_HV;
90 const EXCLUDE_IDLE = ATTR_FLAG_BIT_EXCLUDE_IDLE;
92 const MMAP = ATTR_FLAG_BIT_MMAP;
94 const COMM = ATTR_FLAG_BIT_COMM;
96 const FREQ = ATTR_FLAG_BIT_FREQ;
98 const INHERIT_STAT = ATTR_FLAG_BIT_INHERIT_STAT;
100 const ENABLE_ON_EXEC = ATTR_FLAG_BIT_ENABLE_ON_EXEC;
102 const TASK = ATTR_FLAG_BIT_TASK;
104 const WATERMARK = ATTR_FLAG_BIT_WATERMARK;
106 const PRECISE_IP_BIT_15 = 1 << 15;
108 const PRECISE_IP_BIT_16 = 1 << 16;
110 const PRECISE_IP_BITMASK = ATTR_FLAG_BITMASK_PRECISE_IP;
112 const MMAP_DATA = ATTR_FLAG_BIT_MMAP_DATA;
114 const SAMPLE_ID_ALL = ATTR_FLAG_BIT_SAMPLE_ID_ALL;
116 const EXCLUDE_HOST = ATTR_FLAG_BIT_EXCLUDE_HOST;
118 const EXCLUDE_GUEST = ATTR_FLAG_BIT_EXCLUDE_GUEST;
120 const EXCLUDE_CALLCHAIN_KERNEL = ATTR_FLAG_BIT_EXCLUDE_CALLCHAIN_KERNEL;
122 const EXCLUDE_CALLCHAIN_USER = ATTR_FLAG_BIT_EXCLUDE_CALLCHAIN_USER;
124 const MMAP2 = ATTR_FLAG_BIT_MMAP2;
126 const COMM_EXEC = ATTR_FLAG_BIT_COMM_EXEC;
128 const USE_CLOCKID = ATTR_FLAG_BIT_USE_CLOCKID;
130 const CONTEXT_SWITCH = ATTR_FLAG_BIT_CONTEXT_SWITCH;
132 const WRITE_BACKWARD = ATTR_FLAG_BIT_WRITE_BACKWARD;
134 const NAMESPACES = ATTR_FLAG_BIT_NAMESPACES;
136 const KSYMBOL = ATTR_FLAG_BIT_KSYMBOL;
138 const BPF_EVENT = ATTR_FLAG_BIT_BPF_EVENT;
140 const AUX_OUTPUT = ATTR_FLAG_BIT_AUX_OUTPUT;
142 const CGROUP = ATTR_FLAG_BIT_CGROUP;
144 const TEXT_POKE = ATTR_FLAG_BIT_TEXT_POKE;
146 const BUILD_ID = ATTR_FLAG_BIT_BUILD_ID;
148 const INHERIT_THREAD = ATTR_FLAG_BIT_INHERIT_THREAD;
150 const REMOVE_ON_EXEC = ATTR_FLAG_BIT_REMOVE_ON_EXEC;
152 const SIGTRAP = ATTR_FLAG_BIT_SIGTRAP;
154 }
155
156 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
157 pub struct HwBreakpointType: u32 {
158 const EMPTY = 0;
160 const R = 1;
162 const W = 2;
164 const RW = Self::R.bits() | Self::W.bits();
166 const X = 4;
168 const INVALID = Self::RW.bits() | Self::X.bits();
171 }
172
173 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
194 pub struct ReadFormat: u64 {
195 const TOTAL_TIME_ENABLED = PERF_FORMAT_TOTAL_TIME_ENABLED;
196 const TOTAL_TIME_RUNNING = PERF_FORMAT_TOTAL_TIME_RUNNING;
197 const ID = PERF_FORMAT_ID;
198 const GROUP = PERF_FORMAT_GROUP;
199 }
200}
201
202#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
206pub enum IpSkidConstraint {
207 ArbitrarySkid,
209 ConstantSkid,
211 ZeroSkid,
213 ZeroSkidOrRandomization,
216}
217
218impl AttrFlags {
219 pub fn ip_skid_constraint(&self) -> IpSkidConstraint {
221 match (self.bits() & Self::PRECISE_IP_BITMASK.bits()) >> 15 {
222 0 => IpSkidConstraint::ArbitrarySkid,
223 1 => IpSkidConstraint::ConstantSkid,
224 2 => IpSkidConstraint::ZeroSkid,
225 3 => IpSkidConstraint::ZeroSkidOrRandomization,
226 _ => unreachable!(),
227 }
228 }
229}
230
231#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
232#[non_exhaustive]
233pub enum ClockId {
234 Realtime,
235 Monotonic,
236 ProcessCputimeId,
237 ThreadCputimeId,
238 MonotonicRaw,
239 RealtimeCoarse,
240 MonotonicCoarse,
241 Boottime,
242 RealtimeAlarm,
243 BoottimeAlarm,
244}
245
246impl ClockId {
247 pub fn from_u32(clockid: u32) -> Option<Self> {
248 Some(match clockid {
249 0 => Self::Realtime,
250 1 => Self::Monotonic,
251 2 => Self::ProcessCputimeId,
252 3 => Self::ThreadCputimeId,
253 4 => Self::MonotonicRaw,
254 5 => Self::RealtimeCoarse,
255 6 => Self::MonotonicCoarse,
256 7 => Self::Boottime,
257 8 => Self::RealtimeAlarm,
258 9 => Self::BoottimeAlarm,
259 _ => return None,
260 })
261 }
262}
263
264#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
265pub struct RecordType(pub u32);
266
267impl RecordType {
268 pub const MMAP: Self = Self(PERF_RECORD_MMAP);
270 pub const LOST: Self = Self(PERF_RECORD_LOST);
271 pub const COMM: Self = Self(PERF_RECORD_COMM);
272 pub const EXIT: Self = Self(PERF_RECORD_EXIT);
273 pub const THROTTLE: Self = Self(PERF_RECORD_THROTTLE);
274 pub const UNTHROTTLE: Self = Self(PERF_RECORD_UNTHROTTLE);
275 pub const FORK: Self = Self(PERF_RECORD_FORK);
276 pub const READ: Self = Self(PERF_RECORD_READ);
277 pub const SAMPLE: Self = Self(PERF_RECORD_SAMPLE);
278 pub const MMAP2: Self = Self(PERF_RECORD_MMAP2);
279 pub const AUX: Self = Self(PERF_RECORD_AUX);
280 pub const ITRACE_START: Self = Self(PERF_RECORD_ITRACE_START);
281 pub const LOST_SAMPLES: Self = Self(PERF_RECORD_LOST_SAMPLES);
282 pub const SWITCH: Self = Self(PERF_RECORD_SWITCH);
283 pub const SWITCH_CPU_WIDE: Self = Self(PERF_RECORD_SWITCH_CPU_WIDE);
284 pub const NAMESPACES: Self = Self(PERF_RECORD_NAMESPACES);
285 pub const KSYMBOL: Self = Self(PERF_RECORD_KSYMBOL);
286 pub const BPF_EVENT: Self = Self(PERF_RECORD_BPF_EVENT);
287 pub const CGROUP: Self = Self(PERF_RECORD_CGROUP);
288 pub const TEXT_POKE: Self = Self(PERF_RECORD_TEXT_POKE);
289 pub const AUX_OUTPUT_HW_ID: Self = Self(PERF_RECORD_AUX_OUTPUT_HW_ID);
290
291 pub fn is_builtin_type(&self) -> bool {
292 self.0 < PERF_RECORD_USER_TYPE_START
293 }
294
295 pub fn is_user_type(&self) -> bool {
296 self.0 >= PERF_RECORD_USER_TYPE_START
297 }
298}
299
300impl std::fmt::Debug for RecordType {
301 fn fmt(&self, fmt: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
302 let s = match *self {
303 Self::MMAP => "MMAP",
304 Self::LOST => "LOST",
305 Self::COMM => "COMM",
306 Self::EXIT => "EXIT",
307 Self::THROTTLE => "THROTTLE",
308 Self::UNTHROTTLE => "UNTHROTTLE",
309 Self::FORK => "FORK",
310 Self::READ => "READ",
311 Self::SAMPLE => "SAMPLE",
312 Self::MMAP2 => "MMAP2",
313 Self::AUX => "AUX",
314 Self::ITRACE_START => "ITRACE_START",
315 Self::LOST_SAMPLES => "LOST_SAMPLES",
316 Self::SWITCH => "SWITCH",
317 Self::SWITCH_CPU_WIDE => "SWITCH_CPU_WIDE",
318 Self::NAMESPACES => "NAMESPACES",
319 Self::KSYMBOL => "KSYMBOL",
320 Self::BPF_EVENT => "BPF_EVENT",
321 Self::CGROUP => "CGROUP",
322 Self::TEXT_POKE => "TEXT_POKE",
323 Self::AUX_OUTPUT_HW_ID => "AUX_OUTPUT_HW_ID",
324 other if self.is_builtin_type() => {
325 return fmt.write_fmt(format_args!("Unknown built-in: {}", other.0));
326 }
327 other => {
328 return fmt.write_fmt(format_args!("User type: {}", other.0));
329 }
330 };
331 fmt.write_str(s)
332 }
333}
334
335#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
336#[non_exhaustive]
337pub enum CpuMode {
338 Unknown,
339 Kernel,
340 User,
341 Hypervisor,
342 GuestKernel,
343 GuestUser,
344}
345
346impl CpuMode {
347 pub fn from_misc(misc: u16) -> Self {
349 match misc & PERF_RECORD_MISC_CPUMODE_MASK {
350 PERF_RECORD_MISC_CPUMODE_UNKNOWN => Self::Unknown,
351 PERF_RECORD_MISC_KERNEL => Self::Kernel,
352 PERF_RECORD_MISC_USER => Self::User,
353 PERF_RECORD_MISC_HYPERVISOR => Self::Hypervisor,
354 PERF_RECORD_MISC_GUEST_KERNEL => Self::GuestKernel,
355 PERF_RECORD_MISC_GUEST_USER => Self::GuestUser,
356 _ => Self::Unknown,
357 }
358 }
359}