Line data Source code
1 : use lief_ffi as ffi;
2 : use std::marker::PhantomData;
3 :
4 : use crate::common::FromFFI;
5 : use crate::declare_iterator;
6 : use crate::to_slice;
7 :
8 : pub mod android_ident;
9 : pub mod core;
10 : pub mod gnu_property;
11 : pub mod note_abi;
12 : pub mod properties;
13 : pub mod qnx_stack;
14 :
15 : #[doc(inline)]
16 : pub use android_ident::AndroidIdent;
17 : #[doc(inline)]
18 : pub use core::Auxv as CoreAuxv;
19 : #[doc(inline)]
20 : pub use core::File as CoreFile;
21 : #[doc(inline)]
22 : pub use core::PrPsInfo as CorePrPsInfo;
23 : #[doc(inline)]
24 : pub use core::PrStatus as CorePrStatus;
25 : #[doc(inline)]
26 : pub use core::SigInfo as CoreSigInfo;
27 : #[doc(inline)]
28 : pub use gnu_property::NoteGnuProperty;
29 : #[doc(inline)]
30 : pub use note_abi::NoteAbi;
31 : #[doc(inline)]
32 : pub use properties::Properties;
33 : #[doc(inline)]
34 : pub use qnx_stack::QNXStack;
35 :
36 1859 : #[derive(Debug)]
37 : /// The different notes recognized and supported by LIEF
38 : pub enum Notes<'a> {
39 : /// Android identification note
40 : AndroidIdent(AndroidIdent<'a>),
41 : /// ABI note (e.g. `NT_GNU_ABI_TAG`)
42 : NoteAbi(NoteAbi<'a>),
43 : /// GNU Property note (`NT_GNU_PROPERTY_TYPE_0`)
44 : NoteGnuProperty(NoteGnuProperty<'a>),
45 : /// QNX stack note
46 : QNXStack(QNXStack<'a>),
47 : /// Core auxiliary vector
48 : CoreAuxv(CoreAuxv<'a>),
49 : /// Core mapped files
50 : CoreFile(CoreFile<'a>),
51 : /// Core process info
52 : CorePrPsInfo(CorePrPsInfo<'a>),
53 : /// Core process status (registers)
54 : CorePrStatus(CorePrStatus<'a>),
55 : /// Core signal info
56 : CoreSigInfo(CoreSigInfo<'a>),
57 : /// Generic note
58 : Generic(Generic<'a>),
59 : }
60 :
61 : #[allow(non_camel_case_types)]
62 1872 : #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
63 : /// LIEF representation of the ELF `NT_` values.
64 : pub enum Type {
65 : GNU_ABI_TAG,
66 : GNU_HWCAP,
67 : GNU_BUILD_ID,
68 : GNU_GOLD_VERSION,
69 : GNU_PROPERTY_TYPE_0,
70 : GNU_BUILD_ATTRIBUTE_OPEN,
71 : GNU_BUILD_ATTRIBUTE_FUNC,
72 : CRASHPAD,
73 : CORE_PRSTATUS,
74 : CORE_FPREGSET,
75 : CORE_PRPSINFO,
76 : CORE_TASKSTRUCT,
77 : CORE_AUXV,
78 : CORE_PSTATUS,
79 : CORE_FPREGS,
80 : CORE_PSINFO,
81 : CORE_LWPSTATUS,
82 : CORE_LWPSINFO,
83 : CORE_WIN32PSTATUS,
84 : CORE_FILE,
85 : CORE_PRXFPREG,
86 : CORE_SIGINFO,
87 : CORE_ARM_VFP,
88 : CORE_ARM_TLS,
89 : CORE_ARM_HW_BREAK,
90 : CORE_ARM_HW_WATCH,
91 : CORE_ARM_SYSTEM_CALL,
92 : CORE_ARM_SVE,
93 : CORE_ARM_PAC_MASK,
94 : CORE_ARM_PACA_KEYS,
95 : CORE_ARM_PACG_KEYS,
96 : CORE_TAGGED_ADDR_CTRL,
97 : CORE_PAC_ENABLED_KEYS,
98 : CORE_X86_TLS,
99 : CORE_X86_IOPERM,
100 : CORE_X86_XSTATE,
101 : CORE_X86_CET,
102 : ANDROID_IDENT,
103 : ANDROID_MEMTAG,
104 : ANDROID_KUSER,
105 : GO_BUILDID,
106 : STAPSDT,
107 : QNX_STACK,
108 : UNKNOWN(u32),
109 : }
110 :
111 : impl Type {
112 2028 : pub fn from_value(value: u32) -> Self {
113 2028 : match value {
114 169 : 0x00000001 => Type::GNU_ABI_TAG,
115 0 : 0x00000002 => Type::GNU_HWCAP,
116 130 : 0x00000003 => Type::GNU_BUILD_ID,
117 13 : 0x00000004 => Type::GNU_GOLD_VERSION,
118 117 : 0x00000005 => Type::GNU_PROPERTY_TYPE_0,
119 676 : 0x00000006 => Type::GNU_BUILD_ATTRIBUTE_OPEN,
120 286 : 0x00000007 => Type::GNU_BUILD_ATTRIBUTE_FUNC,
121 0 : 0x00000008 => Type::CRASHPAD,
122 104 : 0x00000009 => Type::CORE_PRSTATUS,
123 52 : 0x0000000a => Type::CORE_FPREGSET,
124 104 : 0x0000000b => Type::CORE_PRPSINFO,
125 0 : 0x0000000c => Type::CORE_TASKSTRUCT,
126 104 : 0x0000000d => Type::CORE_AUXV,
127 0 : 0x0000000e => Type::CORE_PSTATUS,
128 0 : 0x0000000f => Type::CORE_FPREGS,
129 0 : 0x00000010 => Type::CORE_PSINFO,
130 0 : 0x00000011 => Type::CORE_LWPSTATUS,
131 0 : 0x00000012 => Type::CORE_LWPSINFO,
132 0 : 0x00000013 => Type::CORE_WIN32PSTATUS,
133 91 : 0x00000014 => Type::CORE_FILE,
134 0 : 0x00000015 => Type::CORE_PRXFPREG,
135 91 : 0x00000016 => Type::CORE_SIGINFO,
136 26 : 0x00000017 => Type::CORE_ARM_VFP,
137 0 : 0x00000018 => Type::CORE_ARM_TLS,
138 0 : 0x00000019 => Type::CORE_ARM_HW_BREAK,
139 0 : 0x0000001a => Type::CORE_ARM_HW_WATCH,
140 0 : 0x0000001b => Type::CORE_ARM_SYSTEM_CALL,
141 0 : 0x0000001c => Type::CORE_ARM_SVE,
142 0 : 0x0000001d => Type::CORE_ARM_PAC_MASK,
143 0 : 0x0000001e => Type::CORE_ARM_PACA_KEYS,
144 0 : 0x0000001f => Type::CORE_ARM_PACG_KEYS,
145 0 : 0x00000020 => Type::CORE_TAGGED_ADDR_CTRL,
146 0 : 0x00000021 => Type::CORE_PAC_ENABLED_KEYS,
147 0 : 0x00000022 => Type::CORE_X86_TLS,
148 0 : 0x00000023 => Type::CORE_X86_IOPERM,
149 39 : 0x00000024 => Type::CORE_X86_XSTATE,
150 0 : 0x00000025 => Type::CORE_X86_CET,
151 26 : 0x00000026 => Type::ANDROID_IDENT,
152 0 : 0x00000027 => Type::ANDROID_MEMTAG,
153 0 : 0x00000028 => Type::ANDROID_KUSER,
154 0 : 0x00000029 => Type::GO_BUILDID,
155 0 : 0x0000002a => Type::STAPSDT,
156 0 : 0x0000002b => Type::QNX_STACK,
157 0 : _ => Type::UNKNOWN(value),
158 : }
159 2028 : }
160 : }
161 :
162 : impl From<u32> for Type {
163 0 : fn from(value: u32) -> Self {
164 0 : Type::from_value(value)
165 0 : }
166 : }
167 :
168 : impl From<Type> for u32 {
169 0 : fn from(value: Type) -> u32 {
170 0 : match value {
171 0 : Type::GNU_ABI_TAG => 0x00000001,
172 0 : Type::GNU_HWCAP => 0x00000002,
173 0 : Type::GNU_BUILD_ID => 0x00000003,
174 0 : Type::GNU_GOLD_VERSION => 0x00000004,
175 0 : Type::GNU_PROPERTY_TYPE_0 => 0x00000005,
176 0 : Type::GNU_BUILD_ATTRIBUTE_OPEN => 0x00000006,
177 0 : Type::GNU_BUILD_ATTRIBUTE_FUNC => 0x00000007,
178 0 : Type::CRASHPAD => 0x00000008,
179 0 : Type::CORE_PRSTATUS => 0x00000009,
180 0 : Type::CORE_FPREGSET => 0x0000000a,
181 0 : Type::CORE_PRPSINFO => 0x0000000b,
182 0 : Type::CORE_TASKSTRUCT => 0x0000000c,
183 0 : Type::CORE_AUXV => 0x0000000d,
184 0 : Type::CORE_PSTATUS => 0x0000000e,
185 0 : Type::CORE_FPREGS => 0x0000000f,
186 0 : Type::CORE_PSINFO => 0x00000010,
187 0 : Type::CORE_LWPSTATUS => 0x00000011,
188 0 : Type::CORE_LWPSINFO => 0x00000012,
189 0 : Type::CORE_WIN32PSTATUS => 0x00000013,
190 0 : Type::CORE_FILE => 0x00000014,
191 0 : Type::CORE_PRXFPREG => 0x00000015,
192 0 : Type::CORE_SIGINFO => 0x00000016,
193 0 : Type::CORE_ARM_VFP => 0x00000017,
194 0 : Type::CORE_ARM_TLS => 0x00000018,
195 0 : Type::CORE_ARM_HW_BREAK => 0x00000019,
196 0 : Type::CORE_ARM_HW_WATCH => 0x0000001a,
197 0 : Type::CORE_ARM_SYSTEM_CALL => 0x0000001b,
198 0 : Type::CORE_ARM_SVE => 0x0000001c,
199 0 : Type::CORE_ARM_PAC_MASK => 0x0000001d,
200 0 : Type::CORE_ARM_PACA_KEYS => 0x0000001e,
201 0 : Type::CORE_ARM_PACG_KEYS => 0x0000001f,
202 0 : Type::CORE_TAGGED_ADDR_CTRL => 0x00000020,
203 0 : Type::CORE_PAC_ENABLED_KEYS => 0x00000021,
204 0 : Type::CORE_X86_TLS => 0x00000022,
205 0 : Type::CORE_X86_IOPERM => 0x00000023,
206 0 : Type::CORE_X86_XSTATE => 0x00000024,
207 0 : Type::CORE_X86_CET => 0x00000025,
208 0 : Type::ANDROID_IDENT => 0x00000026,
209 0 : Type::ANDROID_MEMTAG => 0x00000027,
210 0 : Type::ANDROID_KUSER => 0x00000028,
211 0 : Type::GO_BUILDID => 0x00000029,
212 0 : Type::STAPSDT => 0x0000002a,
213 0 : Type::QNX_STACK => 0x0000002b,
214 0 : Type::UNKNOWN(value) => value,
215 : }
216 0 : }
217 : }
218 :
219 : /// Trait shared by all [`Notes`]
220 : pub trait NoteBase {
221 : #[doc(hidden)]
222 : fn get_base(&self) -> &ffi::ELF_Note;
223 :
224 : /// Return the *name* of the note (also known as 'owner')
225 1989 : fn name(&self) -> String {
226 1989 : self.get_base().name().to_string()
227 1989 : }
228 :
229 : /// Return the type of the note. This type does not match the `NT_` type
230 : /// value. For accessing the original `NT_` value, check [`NoteBase::original_type`]
231 2028 : fn get_type(&self) -> Type {
232 2028 : Type::from_value(self.get_base().get_type())
233 2028 : }
234 :
235 : /// The original `NT_xxx` integer value. The meaning of this value likely
236 : /// depends on the owner of the note.
237 169 : fn original_type(&self) -> u32 {
238 169 : self.get_base().original_type()
239 169 : }
240 :
241 : /// Size of the **raw** note which includes padding
242 1872 : fn size(&self) -> u64 {
243 1872 : self.get_base().size()
244 1872 : }
245 :
246 : /// Return the description associated with the note
247 182 : fn description(&self) -> &[u8] {
248 182 : to_slice!(self.get_base().description());
249 182 : }
250 : }
251 :
252 : impl NoteBase for Generic<'_> {
253 3887 : fn get_base(&self) -> &ffi::ELF_Note {
254 3887 : self.ptr.as_ref().unwrap()
255 3887 : }
256 : }
257 :
258 : impl NoteBase for Notes<'_> {
259 0 : fn get_base(&self) -> &ffi::ELF_Note {
260 0 : match &self {
261 0 : Notes::AndroidIdent(n) => n.get_base(),
262 0 : Notes::NoteAbi(n) => n.get_base(),
263 0 : Notes::NoteGnuProperty(n) => n.get_base(),
264 0 : Notes::QNXStack(n) => n.get_base(),
265 0 : Notes::CoreAuxv(n) => n.get_base(),
266 0 : Notes::CoreFile(n) => n.get_base(),
267 0 : Notes::CorePrPsInfo(n) => n.get_base(),
268 0 : Notes::CorePrStatus(n) => n.get_base(),
269 0 : Notes::CoreSigInfo(n) => n.get_base(),
270 0 : Notes::Generic(n) => n.get_base(),
271 : }
272 0 : }
273 : }
274 :
275 : impl crate::common::AsFFI<ffi::ELF_Note> for Notes<'_> {
276 0 : fn as_ffi(&self) -> &ffi::ELF_Note {
277 0 : self.get_base()
278 0 : }
279 :
280 0 : fn as_mut_ffi(&mut self) -> std::pin::Pin<&mut ffi::ELF_Note> {
281 0 : match self {
282 0 : Notes::Generic(g) => g.ptr.pin_mut(),
283 : _ => {
284 : // For non-generic notes, we still need pin_mut access to the base
285 : // This follows the same unsafe pattern used by dynamic entries
286 : unsafe {
287 0 : std::pin::Pin::new_unchecked({
288 0 : (self.get_base() as *const ffi::ELF_Note as *mut ffi::ELF_Note)
289 0 : .as_mut()
290 0 : .unwrap()
291 0 : })
292 : }
293 : }
294 : }
295 0 : }
296 : }
297 :
298 : impl FromFFI<ffi::ELF_Note> for Notes<'_> {
299 2951 : fn from_ffi(ffi_entry: cxx::UniquePtr<ffi::ELF_Note>) -> Self {
300 2951 : unsafe {
301 2951 : let note_ref = ffi_entry.as_ref().unwrap();
302 2951 :
303 2951 : if ffi::ELF_AndroidIdent::classof(note_ref) {
304 26 : let raw = {
305 26 : type From = cxx::UniquePtr<ffi::ELF_Note>;
306 26 : type To = cxx::UniquePtr<ffi::ELF_AndroidIdent>;
307 26 : std::mem::transmute::<From, To>(ffi_entry)
308 26 : };
309 26 : Notes::AndroidIdent(AndroidIdent::from_ffi(raw))
310 2925 : } else if ffi::ELF_NoteAbi::classof(note_ref) {
311 195 : let raw = {
312 195 : type From = cxx::UniquePtr<ffi::ELF_Note>;
313 195 : type To = cxx::UniquePtr<ffi::ELF_NoteAbi>;
314 195 : std::mem::transmute::<From, To>(ffi_entry)
315 195 : };
316 195 : Notes::NoteAbi(NoteAbi::from_ffi(raw))
317 2730 : } else if ffi::ELF_NoteGnuProperty::classof(note_ref) {
318 169 : let raw = {
319 169 : type From = cxx::UniquePtr<ffi::ELF_Note>;
320 169 : type To = cxx::UniquePtr<ffi::ELF_NoteGnuProperty>;
321 169 : std::mem::transmute::<From, To>(ffi_entry)
322 169 : };
323 169 : Notes::NoteGnuProperty(NoteGnuProperty::from_ffi(raw))
324 2561 : } else if ffi::ELF_QNXStack::classof(note_ref) {
325 0 : let raw = {
326 0 : type From = cxx::UniquePtr<ffi::ELF_Note>;
327 0 : type To = cxx::UniquePtr<ffi::ELF_QNXStack>;
328 0 : std::mem::transmute::<From, To>(ffi_entry)
329 0 : };
330 0 : Notes::QNXStack(QNXStack::from_ffi(raw))
331 2561 : } else if ffi::ELF_CoreAuxv::classof(note_ref) {
332 104 : let raw = {
333 104 : type From = cxx::UniquePtr<ffi::ELF_Note>;
334 104 : type To = cxx::UniquePtr<ffi::ELF_CoreAuxv>;
335 104 : std::mem::transmute::<From, To>(ffi_entry)
336 104 : };
337 104 : Notes::CoreAuxv(CoreAuxv::from_ffi(raw))
338 2457 : } else if ffi::ELF_CoreFile::classof(note_ref) {
339 104 : let raw = {
340 104 : type From = cxx::UniquePtr<ffi::ELF_Note>;
341 104 : type To = cxx::UniquePtr<ffi::ELF_CoreFile>;
342 104 : std::mem::transmute::<From, To>(ffi_entry)
343 104 : };
344 104 : Notes::CoreFile(CoreFile::from_ffi(raw))
345 2353 : } else if ffi::ELF_CorePrPsInfo::classof(note_ref) {
346 104 : let raw = {
347 104 : type From = cxx::UniquePtr<ffi::ELF_Note>;
348 104 : type To = cxx::UniquePtr<ffi::ELF_CorePrPsInfo>;
349 104 : std::mem::transmute::<From, To>(ffi_entry)
350 104 : };
351 104 : Notes::CorePrPsInfo(CorePrPsInfo::from_ffi(raw))
352 2249 : } else if ffi::ELF_CorePrStatus::classof(note_ref) {
353 104 : let raw = {
354 104 : type From = cxx::UniquePtr<ffi::ELF_Note>;
355 104 : type To = cxx::UniquePtr<ffi::ELF_CorePrStatus>;
356 104 : std::mem::transmute::<From, To>(ffi_entry)
357 104 : };
358 104 : Notes::CorePrStatus(CorePrStatus::from_ffi(raw))
359 2145 : } else if ffi::ELF_CoreSigInfo::classof(note_ref) {
360 104 : let raw = {
361 104 : type From = cxx::UniquePtr<ffi::ELF_Note>;
362 104 : type To = cxx::UniquePtr<ffi::ELF_CoreSigInfo>;
363 104 : std::mem::transmute::<From, To>(ffi_entry)
364 104 : };
365 104 : Notes::CoreSigInfo(CoreSigInfo::from_ffi(raw))
366 : } else {
367 2041 : Notes::Generic(Generic::from_ffi(ffi_entry))
368 : }
369 : }
370 2951 : }
371 : }
372 :
373 : /// Generic note
374 : pub struct Generic<'a> {
375 : ptr: cxx::UniquePtr<ffi::ELF_Note>,
376 : _owner: PhantomData<&'a ffi::ELF_Binary>,
377 : }
378 :
379 : impl std::fmt::Debug for &dyn NoteBase {
380 1872 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
381 1872 : f.debug_struct("NoteBase")
382 1872 : .field("name", &self.name())
383 1872 : .field("type", &self.get_type())
384 1872 : .field("size", &self.size())
385 1872 : .finish()
386 1872 : }
387 : }
388 :
389 : impl std::fmt::Debug for Generic<'_> {
390 1209 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
391 1209 : let base = self as &dyn NoteBase;
392 1209 : f.debug_struct("GenericNote").field("base", &base).finish()
393 1209 : }
394 : }
395 :
396 : impl FromFFI<ffi::ELF_Note> for Generic<'_> {
397 2041 : fn from_ffi(cmd: cxx::UniquePtr<ffi::ELF_Note>) -> Self {
398 2041 : Self {
399 2041 : ptr: cmd,
400 2041 : _owner: PhantomData,
401 2041 : }
402 2041 : }
403 : }
404 :
405 2951 : declare_iterator!(
406 2951 : ItNotes,
407 2951 : Notes<'a>,
408 2951 : ffi::ELF_Note,
409 2951 : ffi::ELF_Binary,
410 2951 : ffi::ELF_Binary_it_notes
411 2951 : );
|