|
3 | 3 | // For the full copyright and license information, please view the LICENSE |
4 | 4 | // file that was distributed with this source code. |
5 | 5 |
|
| 6 | +use crate::pmap_config::PmapConfig; |
6 | 7 | use std::fmt; |
7 | 8 | use std::io::{Error, ErrorKind}; |
8 | 9 |
|
@@ -40,13 +41,25 @@ impl From<&str> for Perms { |
40 | 41 | } |
41 | 42 | } |
42 | 43 |
|
43 | | -// Please note: While `Perms` has four boolean fields, it's string representation has five |
44 | | -// characters because pmap's default and device formats use five characters for the perms, |
45 | | -// with the last character always being '-'. |
46 | 44 | impl fmt::Display for Perms { |
47 | 45 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
48 | 46 | write!( |
49 | 47 | f, |
| 48 | + "{}{}{}{}", |
| 49 | + if self.readable { 'r' } else { '-' }, |
| 50 | + if self.writable { 'w' } else { '-' }, |
| 51 | + if self.executable { 'x' } else { '-' }, |
| 52 | + if self.shared { 's' } else { 'p' }, |
| 53 | + ) |
| 54 | + } |
| 55 | +} |
| 56 | + |
| 57 | +// Please note: While `Perms` has four boolean fields, its `Mode` representation |
| 58 | +// used in pmap's default and device formats has five characters for the perms, |
| 59 | +// with the last character always being '-'. |
| 60 | +impl Perms { |
| 61 | + pub fn mode(&self) -> String { |
| 62 | + format!( |
50 | 63 | "{}{}{}{}-", |
51 | 64 | if self.readable { 'r' } else { '-' }, |
52 | 65 | if self.writable { 'w' } else { '-' }, |
@@ -90,8 +103,7 @@ pub fn parse_map_line(line: &str) -> Result<MapLine, Error> { |
90 | 103 | let inode = inode |
91 | 104 | .parse::<u64>() |
92 | 105 | .map_err(|_| Error::from(ErrorKind::InvalidData))?; |
93 | | - let mapping = mapping.trim_ascii_start(); |
94 | | - let mapping = parse_mapping(mapping); |
| 106 | + let mapping = mapping.trim_ascii_start().to_string(); |
95 | 107 |
|
96 | 108 | Ok(MapLine { |
97 | 109 | address, |
@@ -126,18 +138,29 @@ fn parse_device(device: &str) -> Result<String, Error> { |
126 | 138 | Ok(format!("{major:0>3}:{minor:0>5}")) |
127 | 139 | } |
128 | 140 |
|
129 | | -fn parse_mapping(mapping: &str) -> String { |
130 | | - if mapping == "[stack]" { |
131 | | - return " [ stack ]".into(); |
132 | | - } |
133 | | - |
134 | | - if mapping.is_empty() || mapping.starts_with('[') || mapping.starts_with("anon") { |
135 | | - return " [ anon ]".into(); |
136 | | - } |
| 141 | +impl MapLine { |
| 142 | + pub fn parse_mapping(&self, pmap_config: &PmapConfig) -> String { |
| 143 | + if pmap_config.custom_format_enabled { |
| 144 | + if self.mapping.starts_with('[') { |
| 145 | + return self.mapping.clone(); |
| 146 | + } |
| 147 | + } else { |
| 148 | + if self.mapping == "[stack]" { |
| 149 | + return " [ stack ]".into(); |
| 150 | + } |
| 151 | + |
| 152 | + if self.mapping.is_empty() |
| 153 | + || self.mapping.starts_with('[') |
| 154 | + || self.mapping.starts_with("anon") |
| 155 | + { |
| 156 | + return " [ anon ]".into(); |
| 157 | + } |
| 158 | + } |
137 | 159 |
|
138 | | - match mapping.rsplit_once('/') { |
139 | | - Some((_, name)) => name.into(), |
140 | | - None => mapping.into(), |
| 160 | + match self.mapping.rsplit_once('/') { |
| 161 | + Some((_, name)) => name.into(), |
| 162 | + None => self.mapping.clone(), |
| 163 | + } |
141 | 164 | } |
142 | 165 | } |
143 | 166 |
|
@@ -167,40 +190,47 @@ mod test { |
167 | 190 |
|
168 | 191 | #[test] |
169 | 192 | fn test_perms_to_string() { |
170 | | - assert_eq!("-----", Perms::from("---p").to_string()); |
171 | | - assert_eq!("---s-", Perms::from("---s").to_string()); |
172 | | - assert_eq!("rwx--", Perms::from("rwxp").to_string()); |
| 193 | + assert_eq!("---p", Perms::from("---p").to_string()); |
| 194 | + assert_eq!("---s", Perms::from("---s").to_string()); |
| 195 | + assert_eq!("rwxp", Perms::from("rwxp").to_string()); |
| 196 | + } |
| 197 | + |
| 198 | + #[test] |
| 199 | + fn test_perms_mode() { |
| 200 | + assert_eq!("-----", Perms::from("---p").mode()); |
| 201 | + assert_eq!("---s-", Perms::from("---s").mode()); |
| 202 | + assert_eq!("rwx--", Perms::from("rwxp").mode()); |
173 | 203 | } |
174 | 204 |
|
175 | 205 | #[test] |
176 | 206 | fn test_parse_map_line() { |
177 | 207 | let data = [ |
178 | 208 | ( |
179 | | - create_map_line("000062442eb9e000", 16, Perms::from("r--p"), "0000000000000000", "008:00008", 10813151, "konsole"), |
| 209 | + create_map_line("000062442eb9e000", 16, Perms::from("r--p"), "0000000000000000", "008:00008", 10813151, "/usr/bin/konsole"), |
180 | 210 | "62442eb9e000-62442eba2000 r--p 00000000 08:08 10813151 /usr/bin/konsole" |
181 | 211 | ), |
182 | 212 | ( |
183 | | - create_map_line("000071af50000000", 132, Perms::from("rw-p"), "0000000000000000", "000:00000", 0, " [ anon ]"), |
| 213 | + create_map_line("000071af50000000", 132, Perms::from("rw-p"), "0000000000000000", "000:00000", 0, ""), |
184 | 214 | "71af50000000-71af50021000 rw-p 00000000 00:00 0 " |
185 | 215 | ), |
186 | 216 | ( |
187 | | - create_map_line("00007ffc3f8df000", 132, Perms::from("rw-p"), "0000000000000000", "000:00000", 0, " [ stack ]"), |
| 217 | + create_map_line("00007ffc3f8df000", 132, Perms::from("rw-p"), "0000000000000000", "000:00000", 0, "[stack]"), |
188 | 218 | "7ffc3f8df000-7ffc3f900000 rw-p 00000000 00:00 0 [stack]" |
189 | 219 | ), |
190 | 220 | ( |
191 | | - create_map_line("000071af8c9e6000", 16, Perms::from("rw-s"), "0000000105830000", "000:00010", 1075, " [ anon ]"), |
| 221 | + create_map_line("000071af8c9e6000", 16, Perms::from("rw-s"), "0000000105830000", "000:00010", 1075, "anon_inode:i915.gem"), |
192 | 222 | "71af8c9e6000-71af8c9ea000 rw-s 105830000 00:10 1075 anon_inode:i915.gem" |
193 | 223 | ), |
194 | 224 | ( |
195 | | - create_map_line("000071af6cf0c000", 3560, Perms::from("rw-s"), "0000000000000000", "000:00001", 256481, "memfd:wayland-shm (deleted)"), |
| 225 | + create_map_line("000071af6cf0c000", 3560, Perms::from("rw-s"), "0000000000000000", "000:00001", 256481, "/memfd:wayland-shm (deleted)"), |
196 | 226 | "71af6cf0c000-71af6d286000 rw-s 00000000 00:01 256481 /memfd:wayland-shm (deleted)" |
197 | 227 | ), |
198 | 228 | ( |
199 | | - create_map_line("ffffffffff600000", 4, Perms::from("--xp"), "0000000000000000", "000:00000", 0, " [ anon ]"), |
| 229 | + create_map_line("ffffffffff600000", 4, Perms::from("--xp"), "0000000000000000", "000:00000", 0, "[vsyscall]"), |
200 | 230 | "ffffffffff600000-ffffffffff601000 --xp 00000000 00:00 0 [vsyscall]" |
201 | 231 | ), |
202 | 232 | ( |
203 | | - create_map_line("00005e8187da8000", 24, Perms::from("r--p"), "0000000000000000", "008:00008", 9524160, "hello world"), |
| 233 | + create_map_line("00005e8187da8000", 24, Perms::from("r--p"), "0000000000000000", "008:00008", 9524160, "/usr/bin/hello world"), |
204 | 234 | "5e8187da8000-5e8187dae000 r--p 00000000 08:08 9524160 /usr/bin/hello world" |
205 | 235 | ), |
206 | 236 | ]; |
@@ -250,14 +280,37 @@ mod test { |
250 | 280 |
|
251 | 281 | #[test] |
252 | 282 | fn test_parse_mapping() { |
253 | | - assert_eq!(" [ anon ]", parse_mapping("")); |
254 | | - assert_eq!(" [ anon ]", parse_mapping("[vvar]")); |
255 | | - assert_eq!(" [ anon ]", parse_mapping("[vdso]")); |
256 | | - assert_eq!(" [ anon ]", parse_mapping("anon_inode:i915.gem")); |
257 | | - assert_eq!(" [ stack ]", parse_mapping("[stack]")); |
258 | | - assert_eq!( |
259 | | - "ld-linux-x86-64.so.2", |
260 | | - parse_mapping("/usr/lib/ld-linux-x86-64.so.2") |
261 | | - ); |
| 283 | + let mut mapline = MapLine::default(); |
| 284 | + let mut pmap_config = PmapConfig::default(); |
| 285 | + |
| 286 | + mapline.mapping = "".to_string(); |
| 287 | + pmap_config.custom_format_enabled = false; |
| 288 | + assert_eq!(" [ anon ]", mapline.parse_mapping(&pmap_config)); |
| 289 | + pmap_config.custom_format_enabled = true; |
| 290 | + assert_eq!("", mapline.parse_mapping(&pmap_config)); |
| 291 | + |
| 292 | + mapline.mapping = "[vvar]".to_string(); |
| 293 | + pmap_config.custom_format_enabled = false; |
| 294 | + assert_eq!(" [ anon ]", mapline.parse_mapping(&pmap_config)); |
| 295 | + pmap_config.custom_format_enabled = true; |
| 296 | + assert_eq!("[vvar]", mapline.parse_mapping(&pmap_config)); |
| 297 | + |
| 298 | + mapline.mapping = "anon_inode:i915.gem".to_string(); |
| 299 | + pmap_config.custom_format_enabled = false; |
| 300 | + assert_eq!(" [ anon ]", mapline.parse_mapping(&pmap_config)); |
| 301 | + pmap_config.custom_format_enabled = true; |
| 302 | + assert_eq!("anon_inode:i915.gem", mapline.parse_mapping(&pmap_config)); |
| 303 | + |
| 304 | + mapline.mapping = "[stack]".to_string(); |
| 305 | + pmap_config.custom_format_enabled = false; |
| 306 | + assert_eq!(" [ stack ]", mapline.parse_mapping(&pmap_config)); |
| 307 | + pmap_config.custom_format_enabled = true; |
| 308 | + assert_eq!("[stack]", mapline.parse_mapping(&pmap_config)); |
| 309 | + |
| 310 | + mapline.mapping = "/usr/lib/ld-linux-x86-64.so.2".to_string(); |
| 311 | + pmap_config.custom_format_enabled = false; |
| 312 | + assert_eq!("ld-linux-x86-64.so.2", mapline.parse_mapping(&pmap_config)); |
| 313 | + pmap_config.custom_format_enabled = true; |
| 314 | + assert_eq!("ld-linux-x86-64.so.2", mapline.parse_mapping(&pmap_config)); |
262 | 315 | } |
263 | 316 | } |
0 commit comments