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
//! # linux-perf-event-reader
//!
//! This crate lets you parse Linux perf events and associated structures.
//!
//! ## Example
//!
//! ```rust
//! use linux_perf_event_reader::{Endianness, PerfEventAttr, RawData, RecordType};
//! use linux_perf_event_reader::records::{CommOrExecRecord, ParsedRecord, RawRecord, RecordParseInfo};
//!
//! # fn it_works() {
//! // Read the perf_event_attr data.
//! let attr_data = vec![
//!     0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 229, 3, 0, 0, 0, 0, 0, 0, 47, 177, 0,
//!     0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 3, 183, 215, 97, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
//!     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 15,
//!     255, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
//!     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 128, 0,
//!     0, 0, 0, 0, 0, 0,
//! ];
//! let attr =
//!     PerfEventAttr::parse::<_, byteorder::LittleEndian>(&attr_data[..], None).unwrap();
//! let parse_info = RecordParseInfo::new(&attr, Endianness::LittleEndian);
//!
//! let body = vec![
//!     108, 71, 8, 0, 108, 71, 8, 0, 100, 117, 109, 112, 95, 115, 121, 109, 115, 0, 0, 0, 0,
//!     0, 0, 0, 108, 71, 8, 0, 108, 71, 8, 0, 56, 27, 248, 24, 104, 88, 4, 0,
//! ];
//! let body_raw_data = RawData::from(&body[..]);
//! let raw_record = RawRecord::new(RecordType(3), 0x2000, body_raw_data, parse_info);
//! let parsed_record = raw_record.parse().unwrap();
//!
//! assert_eq!(
//!     parsed_record,
//!     ParsedRecord::Comm(CommOrExecRecord {
//!         pid: 542572,
//!         tid: 542572,
//!         name: RawData::Single(b"dump_syms"),
//!         is_execve: true
//!     })
//! );
//! # }
//! ```
pub mod consts;
mod endian;
mod perf_event;
mod raw_data;
pub mod records;
mod types;
mod utils;

pub use endian::*;
pub use perf_event::*;
pub use raw_data::*;
pub use types::*;

#[cfg(test)]
mod test {
    use crate::{
        records::{CommOrExecRecord, ParsedRecord, RawRecord, RecordParseInfo},
        Endianness, PerfEventAttr, RawData, RecordType,
    };

    #[test]
    fn it_works() {
        // Read the perf_event_attr data.
        let attr_data = vec![
            0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 229, 3, 0, 0, 0, 0, 0, 0, 47, 177, 0,
            0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 3, 183, 215, 97, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 15,
            255, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 128, 0,
            0, 0, 0, 0, 0, 0,
        ];
        let attr =
            PerfEventAttr::parse::<_, byteorder::LittleEndian>(&attr_data[..], None).unwrap();
        let parse_info = RecordParseInfo::new(&attr, Endianness::LittleEndian);

        let body = vec![
            108, 71, 8, 0, 108, 71, 8, 0, 100, 117, 109, 112, 95, 115, 121, 109, 115, 0, 0, 0, 0,
            0, 0, 0, 108, 71, 8, 0, 108, 71, 8, 0, 56, 27, 248, 24, 104, 88, 4, 0,
        ];
        let body_raw_data = RawData::from(&body[..]);
        let raw_record = RawRecord::new(RecordType(3), 0x2000, body_raw_data, parse_info);
        let parsed_record = raw_record.parse().unwrap();

        assert_eq!(
            parsed_record,
            ParsedRecord::Comm(CommOrExecRecord {
                pid: 542572,
                tid: 542572,
                name: RawData::Single(b"dump_syms"),
                is_execve: true
            })
        );
    }
}