perf_event_data/records/
mmap2.rs1use std::borrow::Cow;
2use std::ffi::OsStr;
3use std::fmt;
4
5use perf_event_open_sys::bindings;
6
7use crate::error::ParseError;
8use crate::prelude::*;
9use crate::Mmap;
10
11used_in_docs!(OsStr);
12
13#[derive(Clone)]
21pub struct Mmap2<'a> {
22 pub pid: u32,
24
25 pub tid: u32,
27
28 pub addr: u64,
31
32 pub len: u64,
34
35 pub pgoff: u64,
37
38 pub prot: u32,
40
41 pub flags: u32,
43
44 pub filename: Cow<'a, [u8]>,
57
58 detail: MmapDetail,
59}
60
61#[derive(Clone)]
62enum MmapDetail {
63 Default {
64 maj: u32,
65 min: u32,
66 ino: u64,
67 ino_generation: u64,
68 },
69 BuildId {
70 build_id: [u8; 20],
71 len: u8,
72 },
73}
74
75impl<'a> Mmap2<'a> {
76 #[cfg(unix)]
89 pub fn filename_os(&self) -> &OsStr {
90 use std::os::unix::ffi::OsStrExt;
91
92 OsStrExt::from_bytes(&self.filename)
93 }
94
95 pub fn maj(&self) -> Option<u32> {
97 match &self.detail {
98 MmapDetail::Default { maj, .. } => Some(*maj),
99 _ => None,
100 }
101 }
102
103 pub fn min(&self) -> Option<u32> {
105 match &self.detail {
106 MmapDetail::Default { min, .. } => Some(*min),
107 _ => None,
108 }
109 }
110
111 pub fn ino(&self) -> Option<u64> {
113 match &self.detail {
114 MmapDetail::Default { ino, .. } => Some(*ino),
115 _ => None,
116 }
117 }
118
119 pub fn ino_generation(&self) -> Option<u64> {
121 match &self.detail {
122 MmapDetail::Default { ino_generation, .. } => Some(*ino_generation),
123 _ => None,
124 }
125 }
126
127 pub fn build_id(&self) -> Option<&[u8]> {
132 match &self.detail {
133 MmapDetail::BuildId { build_id, len } => Some(&build_id[..*len as usize]),
134 _ => None,
135 }
136 }
137
138 pub fn to_mmap(&self) -> Mmap<'a> {
140 self.clone().into_mmap()
141 }
142
143 #[inline]
145 pub fn into_mmap(self) -> Mmap<'a> {
146 Mmap {
147 pid: self.pid,
148 tid: self.tid,
149 addr: self.addr,
150 len: self.len,
151 pgoff: self.pgoff,
152 filename: self.filename,
153 }
154 }
155
156 pub fn into_owned(self) -> Mmap2<'static> {
158 Mmap2 {
159 filename: self.filename.into_owned().into(),
160 ..self
161 }
162 }
163}
164
165impl<'p> Parse<'p> for Mmap2<'p> {
166 fn parse<B, E>(p: &mut Parser<B, E>) -> ParseResult<Self>
167 where
168 E: Endian,
169 B: ParseBuf<'p>,
170 {
171 Ok(Self {
172 pid: p.parse()?,
173 tid: p.parse()?,
174 addr: p.parse()?,
175 len: p.parse()?,
176 pgoff: p.parse()?,
177 detail: p.parse()?,
178 prot: p.parse()?,
179 flags: p.parse()?,
180 filename: p.parse_rest_trim_nul()?,
181 })
182 }
183}
184
185impl<'p> Parse<'p> for MmapDetail {
186 fn parse<B, E>(p: &mut Parser<B, E>) -> ParseResult<Self>
187 where
188 E: Endian,
189 B: ParseBuf<'p>,
190 {
191 if p.config().misc() & bindings::PERF_RECORD_MISC_MMAP_BUILD_ID as u16 != 0 {
192 let len: u8 = p.parse()?;
193 let _ = p.parse_u8()?;
194 let _ = p.parse_u16()?;
195 let build_id = p.parse_array()?;
196
197 if len as usize > build_id.len() {
198 return Err(ParseError::custom(
199 ErrorKind::InvalidRecord,
200 format_args!("build_id had invalid length ({len} > 20)"),
201 ));
202 }
203
204 Ok(Self::BuildId { build_id, len })
205 } else {
206 Ok(Self::Default {
207 maj: p.parse()?,
208 min: p.parse()?,
209 ino: p.parse()?,
210 ino_generation: p.parse()?,
211 })
212 }
213 }
214}
215
216impl fmt::Debug for Mmap2<'_> {
217 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
218 let mut dbg = f.debug_struct("Mmap2");
219 dbg.field("pid", &self.pid)
220 .field("tid", &self.tid)
221 .field("addr", &crate::util::fmt::HexAddr(self.addr))
222 .field("len", &self.len)
223 .field("pgoff", &self.pgoff);
224
225 match &self.detail {
226 MmapDetail::Default {
227 maj,
228 min,
229 ino,
230 ino_generation,
231 } => {
232 dbg.field("maj", maj)
233 .field("min", min)
234 .field("ino", ino)
235 .field("ino_generation", ino_generation);
236 }
237 MmapDetail::BuildId { .. } => {
238 if let Some(build_id) = self.build_id() {
239 dbg.field("build_id", &crate::util::fmt::HexStr(build_id));
240 }
241 }
242 }
243
244 dbg.field("prot", &self.prot)
245 .field("flags", &self.flags)
246 .field("filename", &crate::util::fmt::ByteStr(&self.filename));
247
248 dbg.finish()
249 }
250}