llvm_profparser/instrumentation_profile/
mod.rs1use crate::instrumentation_profile::indexed_profile::*;
2use crate::instrumentation_profile::raw_profile::*;
3use crate::instrumentation_profile::text_profile::*;
4use crate::instrumentation_profile::types::*;
5use nom::{error::VerboseError, Err, IResult};
6use std::fs::File;
7use std::io;
8use std::io::prelude::*;
9use std::path::Path;
10use tracing::trace;
11
12pub mod indexed_profile;
13pub mod raw_profile;
14pub mod summary;
15pub mod text_profile;
16pub mod types;
17
18pub type ParseResult<'a, T> = IResult<&'a [u8], T, VerboseError<&'a [u8]>>;
19
20pub const fn get_num_padding_bytes(len: u64) -> u8 {
21 7 & (8 - (len % 8) as u8)
22}
23
24pub fn parse(filename: impl AsRef<Path>) -> io::Result<InstrumentationProfile> {
25 let mut buffer = Vec::new();
26 let mut f = File::open(filename)?;
27 f.read_to_end(&mut buffer)?;
28 parse_bytes(buffer.as_slice())
29}
30
31pub fn parse_bytes(data: &[u8]) -> io::Result<InstrumentationProfile> {
32 let nom_res = if IndexedInstrProf::has_format(data) {
33 IndexedInstrProf::parse_bytes(data)
34 } else if RawInstrProf64::has_format(data) {
35 RawInstrProf64::parse_bytes(data)
36 } else if RawInstrProf32::has_format(data) {
37 RawInstrProf32::parse_bytes(data)
38 } else if TextInstrProf::has_format(data) {
39 TextInstrProf::parse_bytes(data)
40 } else {
41 return Err(io::Error::new(
42 io::ErrorKind::Other,
43 "Unsupported instrumentation profile format",
44 ));
45 };
46 nom_res.map(|(_bytes, res)| res).map_err(|e| {
47 trace!("{}", e);
48 let verbose_error_message = |err: VerboseError<&[u8]>| {
49 err.errors
50 .iter()
51 .map(|(_, x)| format!("{:?}", x))
52 .collect::<Vec<String>>()
53 .join(" ")
54 };
55 let error_message = match e {
56 Err::Error(e) => format!("parser error: {}", verbose_error_message(e)),
57 Err::Failure(e) => format!("parser failure: {}", verbose_error_message(e)),
58 Err::Incomplete(_) => unreachable!("llvm_profparsers works on complete data"),
59 };
60 io::Error::new(io::ErrorKind::Other, error_message)
61 })
62}
63
64pub trait InstrProfReader {
65 type Header;
66 fn parse_bytes(input: &[u8]) -> ParseResult<'_, InstrumentationProfile>;
68 fn parse_header(input: &[u8]) -> ParseResult<'_, Self::Header>;
70 fn has_format(input: impl Read) -> bool;
73}
74
75pub trait InstrProfWriter {
76 fn write(&self, profile: &InstrumentationProfile, writer: &mut impl Write) -> io::Result<()>;
77}