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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
use linux_perf_event_reader::CpuMode;
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum DsoKey {
Kernel,
GuestKernel,
Vdso32,
VdsoX32,
Vdso64,
Vsyscall,
KernelModule {
name: String,
},
User {
file_name: String,
full_path: Vec<u8>,
},
}
impl DsoKey {
pub fn detect(path: &[u8], cpu_mode: CpuMode) -> Option<Self> {
if path == b"//anon" || path == b"[stack]" || path == b"[heap]" || path == b"[vvar]" {
return None;
}
if path.starts_with(b"[kernel.kallsyms]") {
let dso_key = if cpu_mode == CpuMode::GuestKernel {
DsoKey::GuestKernel
} else {
DsoKey::Kernel
};
return Some(dso_key);
}
if path.starts_with(b"[guest.kernel.kallsyms") {
return Some(DsoKey::GuestKernel);
}
if path == b"[vdso32]" {
return Some(DsoKey::Vdso32);
}
if path == b"[vdsox32]" {
return Some(DsoKey::VdsoX32);
}
if path == b"[vdso]" {
return Some(DsoKey::Vdso64);
}
if path == b"[vsyscall]" {
return Some(DsoKey::Vsyscall);
}
if (cpu_mode == CpuMode::Kernel || cpu_mode == CpuMode::GuestKernel)
&& path.starts_with(b"[")
{
return Some(DsoKey::KernelModule {
name: String::from_utf8_lossy(path).into(),
});
}
let filename = if let Some(final_slash_pos) = path.iter().rposition(|b| *b == b'/') {
&path[final_slash_pos + 1..]
} else {
path
};
let dso_key = match (cpu_mode, filename.strip_suffix(b".ko")) {
(CpuMode::Kernel | CpuMode::GuestKernel, Some(kmod_name)) => {
let kmod_name = String::from_utf8_lossy(kmod_name);
DsoKey::KernelModule {
name: format!("[{}]", kmod_name),
}
}
(CpuMode::Kernel, _) => DsoKey::Kernel,
(CpuMode::GuestKernel, _) => DsoKey::GuestKernel,
(CpuMode::User | CpuMode::GuestUser, _) => DsoKey::User {
file_name: String::from_utf8_lossy(filename).into(),
full_path: path.to_owned(),
},
_ => return None,
};
Some(dso_key)
}
pub fn name(&self) -> &str {
match self {
DsoKey::Kernel => "[kernel.kallsyms]", DsoKey::GuestKernel => "[guest.kernel.kallsyms]",
DsoKey::Vdso32 => "[vdso32]",
DsoKey::VdsoX32 => "[vdsox32]",
DsoKey::Vdso64 => "[vdso]",
DsoKey::Vsyscall => "[vsyscall]",
DsoKey::KernelModule { name } => name,
DsoKey::User { file_name, .. } => file_name,
}
}
}