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 180 : #[derive(Debug)]
9 : /// The different notes recognized and supported by LIEF
10 : pub enum Notes<'a> {
11 : Generic(Generic<'a>),
12 : }
13 :
14 : #[allow(non_camel_case_types)]
15 180 : #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
16 : /// LIEF representation of the ELF `NT_` values.
17 : pub enum Type {
18 : /// Match `NT_GNU_ABI_TAG`: Operating system (OS) ABI information
19 : GNU_ABI_TAG,
20 : /// Match `NT_HWCAP`: Synthetic hardware capabilities information
21 : GNU_HWCAP,
22 : /// Match `NT_GNU_BUILD_ID`: Unique build ID as generated by the GNU ld
23 : GNU_BUILD_ID,
24 : /// Match `NT_GNU_GOLD_VERSION`: The version of gold used to link
25 : GNU_GOLD_VERSION,
26 : /// Match `NT_GNU_PROPERTY_TYPE_0`: Program property note, as described in
27 : /// "Linux Extensions to the gABI".
28 : GNU_PROPERTY_TYPE_0,
29 : GNU_BUILD_ATTRIBUTE_OPEN,
30 : GNU_BUILD_ATTRIBUTE_FUNC,
31 : /// Crashpad note used by the Chromium project
32 : CRASHPAD,
33 : /// Coredump that wraps the `elf_prstatus` structure
34 : CORE_PRSTATUS,
35 : CORE_FPREGSET,
36 : /// Coredump that wraps the `elf_prpsinfo` structure
37 : CORE_PRPSINFO,
38 : CORE_TASKSTRUCT,
39 : /// Coredump that contains a copy of all the auxiliary vectors (auxv)
40 : CORE_AUXV,
41 : CORE_PSTATUS,
42 : /// Coredump that wraps the `fpregset` structure
43 : CORE_FPREGS,
44 : /// Coredump that wraps the `psinfo` structure
45 : CORE_PSINFO,
46 : CORE_LWPSTATUS,
47 : CORE_LWPSINFO,
48 : CORE_WIN32PSTATUS,
49 : CORE_FILE,
50 : CORE_PRXFPREG,
51 : CORE_SIGINFO,
52 : CORE_ARM_VFP,
53 : CORE_ARM_TLS,
54 : CORE_ARM_HW_BREAK,
55 : CORE_ARM_HW_WATCH,
56 : CORE_ARM_SYSTEM_CALL,
57 : CORE_ARM_SVE,
58 : CORE_ARM_PAC_MASK,
59 : CORE_ARM_PACA_KEYS,
60 : CORE_ARM_PACG_KEYS,
61 : CORE_TAGGED_ADDR_CTRL,
62 : CORE_PAC_ENABLED_KEYS,
63 : CORE_X86_TLS,
64 : CORE_X86_IOPERM,
65 : CORE_X86_XSTATE,
66 : CORE_X86_CET,
67 : /// Note that is specific to Android and that describes information such as
68 : /// the NDK version or the SDK build number.
69 : ANDROID_IDENT,
70 : ANDROID_MEMTAG,
71 : ANDROID_KUSER,
72 : /// Note specific to Go binaries
73 : GO_BUILDID,
74 : /// Note for SystemTap probes
75 : STAPSDT,
76 : /// Note for QNX Stack info
77 : QNX_STACK,
78 : UNKNOWN(u32),
79 : }
80 :
81 : impl Type {
82 180 : pub fn from_value(value: u32) -> Self {
83 180 : match value {
84 40 : 0x00000001 => Type::GNU_ABI_TAG,
85 0 : 0x00000002 => Type::GNU_HWCAP,
86 40 : 0x00000003 => Type::GNU_BUILD_ID,
87 10 : 0x00000004 => Type::GNU_GOLD_VERSION,
88 20 : 0x00000005 => Type::GNU_PROPERTY_TYPE_0,
89 0 : 0x00000006 => Type::GNU_BUILD_ATTRIBUTE_OPEN,
90 0 : 0x00000007 => Type::GNU_BUILD_ATTRIBUTE_FUNC,
91 0 : 0x00000008 => Type::CRASHPAD,
92 10 : 0x00000009 => Type::CORE_PRSTATUS,
93 10 : 0x0000000a => Type::CORE_FPREGSET,
94 10 : 0x0000000b => Type::CORE_PRPSINFO,
95 0 : 0x0000000c => Type::CORE_TASKSTRUCT,
96 10 : 0x0000000d => Type::CORE_AUXV,
97 0 : 0x0000000e => Type::CORE_PSTATUS,
98 0 : 0x0000000f => Type::CORE_FPREGS,
99 0 : 0x00000010 => Type::CORE_PSINFO,
100 0 : 0x00000011 => Type::CORE_LWPSTATUS,
101 0 : 0x00000012 => Type::CORE_LWPSINFO,
102 0 : 0x00000013 => Type::CORE_WIN32PSTATUS,
103 10 : 0x00000014 => Type::CORE_FILE,
104 0 : 0x00000015 => Type::CORE_PRXFPREG,
105 10 : 0x00000016 => Type::CORE_SIGINFO,
106 0 : 0x00000017 => Type::CORE_ARM_VFP,
107 0 : 0x00000018 => Type::CORE_ARM_TLS,
108 0 : 0x00000019 => Type::CORE_ARM_HW_BREAK,
109 0 : 0x0000001a => Type::CORE_ARM_HW_WATCH,
110 0 : 0x0000001b => Type::CORE_ARM_SYSTEM_CALL,
111 0 : 0x0000001c => Type::CORE_ARM_SVE,
112 0 : 0x0000001d => Type::CORE_ARM_PAC_MASK,
113 0 : 0x0000001e => Type::CORE_ARM_PACA_KEYS,
114 0 : 0x0000001f => Type::CORE_ARM_PACG_KEYS,
115 0 : 0x00000020 => Type::CORE_TAGGED_ADDR_CTRL,
116 0 : 0x00000021 => Type::CORE_PAC_ENABLED_KEYS,
117 0 : 0x00000022 => Type::CORE_X86_TLS,
118 0 : 0x00000023 => Type::CORE_X86_IOPERM,
119 10 : 0x00000024 => Type::CORE_X86_XSTATE,
120 0 : 0x00000025 => Type::CORE_X86_CET,
121 0 : 0x00000026 => Type::ANDROID_IDENT,
122 0 : 0x00000027 => Type::ANDROID_MEMTAG,
123 0 : 0x00000028 => Type::ANDROID_KUSER,
124 0 : 0x00000029 => Type::GO_BUILDID,
125 0 : 0x0000002a => Type::STAPSDT,
126 0 : 0x0000002b => Type::QNX_STACK,
127 0 : _ => Type::UNKNOWN(value),
128 : }
129 180 : }
130 : }
131 :
132 : /// Trait shared by all [`Notes`]
133 : pub trait NoteBase {
134 : #[doc(hidden)]
135 : fn get_base(&self) -> &ffi::ELF_Note;
136 :
137 : /// Return the *name* of the note (also known as 'owner' )
138 180 : fn name(&self) -> String {
139 180 : self.get_base().name().to_string()
140 180 : }
141 :
142 : /// Return the type of the note. This type does not match the `NT_` type
143 : /// value. For accessing the original `NT_` value, check [`NoteBase::original_type`]
144 180 : fn get_type(&self) -> Type {
145 180 : Type::from_value(self.get_base().get_type())
146 180 : }
147 :
148 : /// The original `NT_xxx` integer value. The meaning of this value likely
149 : /// depends on the owner of the note.
150 180 : fn original_type(&self) -> u32 {
151 180 : self.get_base().original_type()
152 180 : }
153 :
154 : /// Size of the **raw** note which includes padding
155 180 : fn size(&self) -> u64 {
156 180 : self.get_base().size()
157 180 : }
158 :
159 : /// Return the description associated with the note
160 180 : fn description(&self) -> &[u8] {
161 180 : to_slice!(self.get_base().description());
162 180 : }
163 : }
164 :
165 : impl NoteBase for Generic<'_> {
166 900 : fn get_base(&self) -> &ffi::ELF_Note {
167 900 : self.ptr.as_ref().unwrap()
168 900 : }
169 : }
170 :
171 : impl FromFFI<ffi::ELF_Note> for Notes<'_> {
172 180 : fn from_ffi(entry: cxx::UniquePtr<ffi::ELF_Note>) -> Self {
173 180 : Notes::Generic(Generic::from_ffi(entry))
174 180 : }
175 : }
176 :
177 : /// Generic note
178 : pub struct Generic<'a> {
179 : ptr: cxx::UniquePtr<ffi::ELF_Note>,
180 : _owner: PhantomData<&'a ffi::ELF_Binary>,
181 : }
182 :
183 : impl std::fmt::Debug for &dyn NoteBase {
184 180 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
185 180 : f.debug_struct("NoteBase")
186 180 : .field("name", &self.name())
187 180 : .field("type", &self.get_type())
188 180 : .field("size", &self.size())
189 180 : .finish()
190 180 : }
191 : }
192 :
193 : impl std::fmt::Debug for Generic<'_> {
194 180 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
195 180 : let base = self as &dyn NoteBase;
196 180 : f.debug_struct("GenericNote").field("base", &base).finish()
197 180 : }
198 : }
199 :
200 : impl FromFFI<ffi::ELF_Note> for Generic<'_> {
201 180 : fn from_ffi(cmd: cxx::UniquePtr<ffi::ELF_Note>) -> Self {
202 180 : Self {
203 180 : ptr: cmd,
204 180 : _owner: PhantomData,
205 180 : }
206 180 : }
207 : }
208 :
209 180 : declare_iterator!(
210 180 : ItNotes,
211 180 : Notes<'a>,
212 180 : ffi::ELF_Note,
213 180 : ffi::ELF_Binary,
214 180 : ffi::ELF_Binary_it_notes
215 180 : );
|