linux_perf_data/jitdump/
header.rs1use std::io::ErrorKind;
2
3use byteorder::{BigEndian, ByteOrder, LittleEndian};
4use linux_perf_event_reader::RawData;
5
6use super::error::JitDumpError;
7
8#[derive(Debug, Clone)]
10pub struct JitDumpHeader {
11    pub magic: [u8; 4],
15    pub version: u32,
17    pub total_size: u32,
19    pub elf_machine_arch: u32,
21    pub pid: u32,
23    pub timestamp: u64,
25    pub flags: u64,
27}
28
29impl JitDumpHeader {
30    pub const SIZE: usize = 40; pub fn parse(mut data: RawData) -> Result<Self, JitDumpError> {
33        let mut magic = [0; 4];
34        data.read_exact(&mut magic)?;
35        let header_result = match &magic {
36            b"JiTD" => Self::parse_after_magic::<BigEndian>(magic, data),
37            b"DTiJ" => Self::parse_after_magic::<LittleEndian>(magic, data),
38            _ => return Err(JitDumpError::InvalidMagicBytes(magic)),
39        };
40        let header = match header_result {
41            Ok(header) => header,
42            Err(e) if e.kind() == ErrorKind::UnexpectedEof => {
43                return Err(JitDumpError::NotEnoughBytesForHeader)
44            }
45            Err(e) => panic!("Unexpected error type {e}"),
46        };
47        if header.total_size < Self::SIZE as u32 {
48            return Err(JitDumpError::InvalidHeaderSize(header.total_size));
49        }
50
51        Ok(header)
52    }
53
54    pub fn parse_after_magic<O: ByteOrder>(
55        magic: [u8; 4],
56        data: RawData,
57    ) -> Result<Self, std::io::Error> {
58        let mut cur = data;
59        let version = cur.read_u32::<O>()?;
60        let total_size = cur.read_u32::<O>()?;
61
62        let mut full_header = data;
64        full_header.skip(total_size.saturating_sub(4) as usize)?;
65
66        let elf_machine_arch = cur.read_u32::<O>()?;
67        let _pad1 = cur.read_u32::<O>()?;
68        let pid = cur.read_u32::<O>()?;
69        let timestamp = cur.read_u64::<O>()?;
70        let flags = cur.read_u64::<O>()?;
71        Ok(Self {
72            magic,
73            version,
74            total_size,
75            elf_machine_arch,
76            pid,
77            timestamp,
78            flags,
79        })
80    }
81}