Line data Source code
1 : use lief_ffi as ffi;
2 : use std::marker::PhantomData;
3 :
4 : use crate::common::FromFFI;
5 :
6 : #[allow(non_camel_case_types)]
7 91 : #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
8 : /// Type of the GNU property
9 : pub enum PropertyType {
10 : UNKNOWN,
11 : GENERIC,
12 : AARCH64_FEATURES,
13 : AARCH64_PAUTH,
14 : STACK_SIZE,
15 : NO_COPY_ON_PROTECTED,
16 : X86_ISA,
17 : X86_FEATURE,
18 : NEEDED,
19 : }
20 :
21 : impl From<u32> for PropertyType {
22 195 : fn from(value: u32) -> Self {
23 195 : match value {
24 0 : 0 => PropertyType::UNKNOWN,
25 0 : 1 => PropertyType::GENERIC,
26 26 : 2 => PropertyType::AARCH64_FEATURES,
27 0 : 3 => PropertyType::AARCH64_PAUTH,
28 0 : 4 => PropertyType::STACK_SIZE,
29 0 : 5 => PropertyType::NO_COPY_ON_PROTECTED,
30 104 : 6 => PropertyType::X86_ISA,
31 52 : 7 => PropertyType::X86_FEATURE,
32 0 : 8 => PropertyType::NEEDED,
33 13 : _ => PropertyType::UNKNOWN,
34 : }
35 195 : }
36 : }
37 :
38 : impl From<PropertyType> for u32 {
39 26 : fn from(value: PropertyType) -> u32 {
40 26 : match value {
41 13 : PropertyType::UNKNOWN => 0,
42 0 : PropertyType::GENERIC => 1,
43 0 : PropertyType::AARCH64_FEATURES => 2,
44 0 : PropertyType::AARCH64_PAUTH => 3,
45 0 : PropertyType::STACK_SIZE => 4,
46 0 : PropertyType::NO_COPY_ON_PROTECTED => 5,
47 13 : PropertyType::X86_ISA => 6,
48 0 : PropertyType::X86_FEATURE => 7,
49 0 : PropertyType::NEEDED => 8,
50 : }
51 26 : }
52 : }
53 :
54 : /// Trait shared by all GNU property types
55 : pub trait NoteProperty {
56 : #[doc(hidden)]
57 : fn get_base(&self) -> &ffi::ELF_NoteGnuProperty_Property;
58 :
59 : /// Return the type of the property
60 158 : fn property_type(&self) -> PropertyType {
61 158 : PropertyType::from(self.get_base().get_type())
62 158 : }
63 : }
64 :
65 13 : #[derive(Debug)]
66 : /// Enum of the different GNU property subtypes
67 : pub enum Properties<'a> {
68 : AArch64Feature(AArch64Feature<'a>),
69 : AArch64PAuth(AArch64PAuth<'a>),
70 : X86Features(X86Features<'a>),
71 : X86ISA(X86ISA<'a>),
72 : StackSize(StackSize<'a>),
73 : NoCopyOnProtected(NoCopyOnProtected<'a>),
74 : Needed(Needed<'a>),
75 : Generic(GenericProperty<'a>),
76 : }
77 :
78 : impl NoteProperty for Properties<'_> {
79 26 : fn get_base(&self) -> &ffi::ELF_NoteGnuProperty_Property {
80 26 : match &self {
81 0 : Properties::AArch64Feature(p) => p.get_base(),
82 0 : Properties::AArch64PAuth(p) => p.get_base(),
83 0 : Properties::X86Features(p) => p.get_base(),
84 26 : Properties::X86ISA(p) => p.get_base(),
85 0 : Properties::StackSize(p) => p.get_base(),
86 0 : Properties::NoCopyOnProtected(p) => p.get_base(),
87 0 : Properties::Needed(p) => p.get_base(),
88 0 : Properties::Generic(p) => p.get_base(),
89 : }
90 26 : }
91 : }
92 :
93 : impl FromFFI<ffi::ELF_NoteGnuProperty_Property> for Properties<'_> {
94 117 : fn from_ffi(ffi_entry: cxx::UniquePtr<ffi::ELF_NoteGnuProperty_Property>) -> Self {
95 117 : unsafe {
96 117 : let prop_ref = ffi_entry.as_ref().unwrap();
97 117 :
98 117 : if ffi::ELF_NoteGnuProperty_AArch64Feature::classof(prop_ref) {
99 13 : let raw = {
100 13 : type From = cxx::UniquePtr<ffi::ELF_NoteGnuProperty_Property>;
101 13 : type To = cxx::UniquePtr<ffi::ELF_NoteGnuProperty_AArch64Feature>;
102 13 : std::mem::transmute::<From, To>(ffi_entry)
103 13 : };
104 13 : Properties::AArch64Feature(AArch64Feature::from_ffi(raw))
105 104 : } else if ffi::ELF_NoteGnuProperty_AArch64PAuth::classof(prop_ref) {
106 0 : let raw = {
107 0 : type From = cxx::UniquePtr<ffi::ELF_NoteGnuProperty_Property>;
108 0 : type To = cxx::UniquePtr<ffi::ELF_NoteGnuProperty_AArch64PAuth>;
109 0 : std::mem::transmute::<From, To>(ffi_entry)
110 0 : };
111 0 : Properties::AArch64PAuth(AArch64PAuth::from_ffi(raw))
112 104 : } else if ffi::ELF_NoteGnuProperty_X86Features::classof(prop_ref) {
113 26 : let raw = {
114 26 : type From = cxx::UniquePtr<ffi::ELF_NoteGnuProperty_Property>;
115 26 : type To = cxx::UniquePtr<ffi::ELF_NoteGnuProperty_X86Features>;
116 26 : std::mem::transmute::<From, To>(ffi_entry)
117 26 : };
118 26 : Properties::X86Features(X86Features::from_ffi(raw))
119 78 : } else if ffi::ELF_NoteGnuProperty_X86ISA::classof(prop_ref) {
120 78 : let raw = {
121 78 : type From = cxx::UniquePtr<ffi::ELF_NoteGnuProperty_Property>;
122 78 : type To = cxx::UniquePtr<ffi::ELF_NoteGnuProperty_X86ISA>;
123 78 : std::mem::transmute::<From, To>(ffi_entry)
124 78 : };
125 78 : Properties::X86ISA(X86ISA::from_ffi(raw))
126 0 : } else if ffi::ELF_NoteGnuProperty_StackSize::classof(prop_ref) {
127 0 : let raw = {
128 0 : type From = cxx::UniquePtr<ffi::ELF_NoteGnuProperty_Property>;
129 0 : type To = cxx::UniquePtr<ffi::ELF_NoteGnuProperty_StackSize>;
130 0 : std::mem::transmute::<From, To>(ffi_entry)
131 0 : };
132 0 : Properties::StackSize(StackSize::from_ffi(raw))
133 0 : } else if ffi::ELF_NoteGnuProperty_NoteNoCopyOnProtected::classof(prop_ref) {
134 0 : let raw = {
135 0 : type From = cxx::UniquePtr<ffi::ELF_NoteGnuProperty_Property>;
136 0 : type To = cxx::UniquePtr<ffi::ELF_NoteGnuProperty_NoteNoCopyOnProtected>;
137 0 : std::mem::transmute::<From, To>(ffi_entry)
138 0 : };
139 0 : Properties::NoCopyOnProtected(NoCopyOnProtected::from_ffi(raw))
140 0 : } else if ffi::ELF_NoteGnuProperty_Needed::classof(prop_ref) {
141 0 : let raw = {
142 0 : type From = cxx::UniquePtr<ffi::ELF_NoteGnuProperty_Property>;
143 0 : type To = cxx::UniquePtr<ffi::ELF_NoteGnuProperty_Needed>;
144 0 : std::mem::transmute::<From, To>(ffi_entry)
145 0 : };
146 0 : Properties::Needed(Needed::from_ffi(raw))
147 : } else {
148 0 : assert!(ffi::ELF_NoteGnuProperty_Generic::classof(prop_ref));
149 0 : Properties::Generic(GenericProperty {
150 0 : ptr: std::mem::transmute::<
151 0 : cxx::UniquePtr<ffi::ELF_NoteGnuProperty_Property>,
152 0 : cxx::UniquePtr<ffi::ELF_NoteGnuProperty_Generic>,
153 0 : >(ffi_entry),
154 0 : _owner: PhantomData,
155 0 : })
156 : }
157 : }
158 117 : }
159 : }
160 :
161 : #[allow(non_camel_case_types)]
162 13 : #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
163 : pub enum AArch64FeatureFlag {
164 : UNKNOWN,
165 : BTI,
166 : PAC,
167 : }
168 :
169 : impl From<u64> for AArch64FeatureFlag {
170 26 : fn from(value: u64) -> Self {
171 26 : match value {
172 0 : 0 => AArch64FeatureFlag::UNKNOWN,
173 26 : 1 => AArch64FeatureFlag::BTI,
174 0 : 2 => AArch64FeatureFlag::PAC,
175 0 : _ => AArch64FeatureFlag::UNKNOWN,
176 : }
177 26 : }
178 : }
179 :
180 : /// AArch64 feature property (`GNU_PROPERTY_AARCH64_FEATURE_1_AND`)
181 : pub struct AArch64Feature<'a> {
182 : ptr: cxx::UniquePtr<ffi::ELF_NoteGnuProperty_AArch64Feature>,
183 : _owner: PhantomData<&'a ffi::ELF_NoteGnuProperty>,
184 : }
185 :
186 : impl AArch64Feature<'_> {
187 : /// Return the list of features
188 26 : pub fn features(&self) -> Vec<AArch64FeatureFlag> {
189 26 : Vec::from(self.ptr.features().as_slice())
190 26 : .into_iter()
191 26 : .map(AArch64FeatureFlag::from)
192 26 : .collect()
193 26 : }
194 : }
195 :
196 : impl NoteProperty for AArch64Feature<'_> {
197 26 : fn get_base(&self) -> &ffi::ELF_NoteGnuProperty_Property {
198 26 : self.ptr.as_ref().unwrap().as_ref()
199 26 : }
200 : }
201 :
202 : impl FromFFI<ffi::ELF_NoteGnuProperty_AArch64Feature> for AArch64Feature<'_> {
203 13 : fn from_ffi(ptr: cxx::UniquePtr<ffi::ELF_NoteGnuProperty_AArch64Feature>) -> Self {
204 13 : Self {
205 13 : ptr,
206 13 : _owner: PhantomData,
207 13 : }
208 13 : }
209 : }
210 :
211 : impl std::fmt::Debug for AArch64Feature<'_> {
212 13 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
213 13 : f.debug_struct("AArch64Feature")
214 13 : .field("type", &self.property_type())
215 13 : .field("features", &self.features())
216 13 : .finish()
217 13 : }
218 : }
219 :
220 : /// AArch64 pointer authentication property
221 : pub struct AArch64PAuth<'a> {
222 : ptr: cxx::UniquePtr<ffi::ELF_NoteGnuProperty_AArch64PAuth>,
223 : _owner: PhantomData<&'a ffi::ELF_NoteGnuProperty>,
224 : }
225 :
226 : impl AArch64PAuth<'_> {
227 : /// Platform identifier
228 0 : pub fn platform(&self) -> u64 {
229 0 : self.ptr.platform()
230 0 : }
231 :
232 : /// Version
233 0 : pub fn version(&self) -> u64 {
234 0 : self.ptr.version()
235 0 : }
236 : }
237 :
238 : impl NoteProperty for AArch64PAuth<'_> {
239 0 : fn get_base(&self) -> &ffi::ELF_NoteGnuProperty_Property {
240 0 : self.ptr.as_ref().unwrap().as_ref()
241 0 : }
242 : }
243 :
244 : impl FromFFI<ffi::ELF_NoteGnuProperty_AArch64PAuth> for AArch64PAuth<'_> {
245 0 : fn from_ffi(ptr: cxx::UniquePtr<ffi::ELF_NoteGnuProperty_AArch64PAuth>) -> Self {
246 0 : Self {
247 0 : ptr,
248 0 : _owner: PhantomData,
249 0 : }
250 0 : }
251 : }
252 :
253 : impl std::fmt::Debug for AArch64PAuth<'_> {
254 0 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
255 0 : f.debug_struct("AArch64PAuth")
256 0 : .field("type", &self.property_type())
257 0 : .field("platform", &self.platform())
258 0 : .field("version", &self.version())
259 0 : .finish()
260 0 : }
261 : }
262 :
263 : #[allow(non_camel_case_types)]
264 143 : #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
265 : pub enum X86FeatureFlag {
266 : NONE,
267 : USED,
268 : NEEDED,
269 : UNKNOWN(u64),
270 : }
271 :
272 : impl From<u64> for X86FeatureFlag {
273 286 : fn from(value: u64) -> Self {
274 286 : match value {
275 52 : 0 => X86FeatureFlag::NONE,
276 234 : 1 => X86FeatureFlag::USED,
277 0 : 2 => X86FeatureFlag::NEEDED,
278 0 : _ => X86FeatureFlag::UNKNOWN(value),
279 : }
280 286 : }
281 : }
282 :
283 : #[allow(non_camel_case_types)]
284 143 : #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
285 : pub enum X86Feature {
286 : UNKNOWN,
287 : IBT,
288 : SHSTK,
289 : LAM_U48,
290 : LAM_U57,
291 : X86,
292 : X87,
293 : MMX,
294 : XMM,
295 : YMM,
296 : ZMM,
297 : FXSR,
298 : XSAVE,
299 : XSAVEOPT,
300 : XSAVEC,
301 : TMM,
302 : MASK,
303 : }
304 :
305 : impl From<u64> for X86Feature {
306 286 : fn from(value: u64) -> Self {
307 286 : match value {
308 0 : 0 => X86Feature::UNKNOWN,
309 26 : 1 => X86Feature::IBT,
310 26 : 2 => X86Feature::SHSTK,
311 0 : 3 => X86Feature::LAM_U48,
312 0 : 4 => X86Feature::LAM_U57,
313 26 : 5 => X86Feature::X86,
314 26 : 6 => X86Feature::X87,
315 0 : 7 => X86Feature::MMX,
316 26 : 8 => X86Feature::XMM,
317 26 : 9 => X86Feature::YMM,
318 26 : 10 => X86Feature::ZMM,
319 26 : 11 => X86Feature::FXSR,
320 26 : 12 => X86Feature::XSAVE,
321 0 : 13 => X86Feature::XSAVEOPT,
322 26 : 14 => X86Feature::XSAVEC,
323 0 : 15 => X86Feature::TMM,
324 26 : 16 => X86Feature::MASK,
325 0 : _ => X86Feature::UNKNOWN,
326 : }
327 286 : }
328 : }
329 :
330 : /// X86 feature property (`GNU_PROPERTY_X86_FEATURE_*`)
331 : pub struct X86Features<'a> {
332 : ptr: cxx::UniquePtr<ffi::ELF_NoteGnuProperty_X86Features>,
333 : _owner: PhantomData<&'a ffi::ELF_NoteGnuProperty>,
334 : }
335 :
336 : impl X86Features<'_> {
337 : /// Return pairs of (flag, feature)
338 52 : pub fn features(&self) -> Vec<(X86FeatureFlag, X86Feature)> {
339 52 : self.ptr
340 52 : .features()
341 52 : .as_slice()
342 52 : .chunks_exact(2)
343 286 : .map(|c| (X86FeatureFlag::from(c[0]), X86Feature::from(c[1])))
344 52 : .collect()
345 52 : }
346 : }
347 :
348 : impl NoteProperty for X86Features<'_> {
349 52 : fn get_base(&self) -> &ffi::ELF_NoteGnuProperty_Property {
350 52 : self.ptr.as_ref().unwrap().as_ref()
351 52 : }
352 : }
353 :
354 : impl FromFFI<ffi::ELF_NoteGnuProperty_X86Features> for X86Features<'_> {
355 26 : fn from_ffi(ptr: cxx::UniquePtr<ffi::ELF_NoteGnuProperty_X86Features>) -> Self {
356 26 : Self {
357 26 : ptr,
358 26 : _owner: PhantomData,
359 26 : }
360 26 : }
361 : }
362 :
363 : impl std::fmt::Debug for X86Features<'_> {
364 26 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
365 26 : f.debug_struct("X86Features")
366 26 : .field("type", &self.property_type())
367 26 : .field("features", &self.features())
368 26 : .finish()
369 26 : }
370 : }
371 :
372 : #[allow(non_camel_case_types)]
373 91 : #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
374 : pub enum X86ISAFlag {
375 : NONE,
376 : USED,
377 : NEEDED,
378 : UNKNOWN(u64),
379 : }
380 :
381 : impl From<u64> for X86ISAFlag {
382 156 : fn from(value: u64) -> Self {
383 156 : match value {
384 0 : 0 => X86ISAFlag::NONE,
385 104 : 1 => X86ISAFlag::USED,
386 52 : 2 => X86ISAFlag::NEEDED,
387 0 : _ => X86ISAFlag::UNKNOWN(value),
388 : }
389 156 : }
390 : }
391 :
392 : #[allow(non_camel_case_types)]
393 91 : #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
394 : pub enum X86ISAValue {
395 : UNKNOWN,
396 : BASELINE,
397 : V2,
398 : V3,
399 : V4,
400 : CMOV,
401 : FMA,
402 : I486,
403 : I586,
404 : I686,
405 : SSE,
406 : SSE2,
407 : SSE3,
408 : SSSE3,
409 : SSE4_1,
410 : SSE4_2,
411 : AVX,
412 : AVX2,
413 : AVX512F,
414 : AVX512CD,
415 : AVX512ER,
416 : AVX512PF,
417 : AVX512VL,
418 : AVX512DQ,
419 : AVX512BW,
420 : AVX512_4FMAPS,
421 : AVX512_4VNNIW,
422 : AVX512_BITALG,
423 : AVX512_IFMA,
424 : AVX512_VBMI,
425 : AVX512_VBMI2,
426 : AVX512_VNNI,
427 : AVX512_BF16,
428 : }
429 :
430 : impl From<u64> for X86ISAValue {
431 156 : fn from(value: u64) -> Self {
432 156 : match value {
433 0 : 0 => X86ISAValue::UNKNOWN,
434 78 : 1 => X86ISAValue::BASELINE,
435 26 : 2 => X86ISAValue::V2,
436 26 : 3 => X86ISAValue::V3,
437 26 : 4 => X86ISAValue::V4,
438 0 : 5 => X86ISAValue::CMOV,
439 0 : 6 => X86ISAValue::FMA,
440 0 : 7 => X86ISAValue::I486,
441 0 : 8 => X86ISAValue::I586,
442 0 : 9 => X86ISAValue::I686,
443 0 : 10 => X86ISAValue::SSE,
444 0 : 11 => X86ISAValue::SSE2,
445 0 : 12 => X86ISAValue::SSE3,
446 0 : 13 => X86ISAValue::SSSE3,
447 0 : 14 => X86ISAValue::SSE4_1,
448 0 : 15 => X86ISAValue::SSE4_2,
449 0 : 16 => X86ISAValue::AVX,
450 0 : 17 => X86ISAValue::AVX2,
451 0 : 18 => X86ISAValue::AVX512F,
452 0 : 19 => X86ISAValue::AVX512CD,
453 0 : 20 => X86ISAValue::AVX512ER,
454 0 : 21 => X86ISAValue::AVX512PF,
455 0 : 22 => X86ISAValue::AVX512VL,
456 0 : 23 => X86ISAValue::AVX512DQ,
457 0 : 24 => X86ISAValue::AVX512BW,
458 0 : 25 => X86ISAValue::AVX512_4FMAPS,
459 0 : 26 => X86ISAValue::AVX512_4VNNIW,
460 0 : 27 => X86ISAValue::AVX512_BITALG,
461 0 : 28 => X86ISAValue::AVX512_IFMA,
462 0 : 29 => X86ISAValue::AVX512_VBMI,
463 0 : 30 => X86ISAValue::AVX512_VBMI2,
464 0 : 31 => X86ISAValue::AVX512_VNNI,
465 0 : 32 => X86ISAValue::AVX512_BF16,
466 0 : _ => X86ISAValue::UNKNOWN,
467 : }
468 156 : }
469 : }
470 :
471 : /// X86 ISA property (`GNU_PROPERTY_X86_ISA_1_*`)
472 : pub struct X86ISA<'a> {
473 : ptr: cxx::UniquePtr<ffi::ELF_NoteGnuProperty_X86ISA>,
474 : _owner: PhantomData<&'a ffi::ELF_NoteGnuProperty>,
475 : }
476 :
477 : impl X86ISA<'_> {
478 : /// Return pairs of (flag, isa)
479 78 : pub fn values(&self) -> Vec<(X86ISAFlag, X86ISAValue)> {
480 78 : self.ptr
481 78 : .values()
482 78 : .as_slice()
483 78 : .chunks_exact(2)
484 156 : .map(|c| (X86ISAFlag::from(c[0]), X86ISAValue::from(c[1])))
485 78 : .collect()
486 78 : }
487 : }
488 :
489 : impl NoteProperty for X86ISA<'_> {
490 104 : fn get_base(&self) -> &ffi::ELF_NoteGnuProperty_Property {
491 104 : self.ptr.as_ref().unwrap().as_ref()
492 104 : }
493 : }
494 :
495 : impl FromFFI<ffi::ELF_NoteGnuProperty_X86ISA> for X86ISA<'_> {
496 78 : fn from_ffi(ptr: cxx::UniquePtr<ffi::ELF_NoteGnuProperty_X86ISA>) -> Self {
497 78 : Self {
498 78 : ptr,
499 78 : _owner: PhantomData,
500 78 : }
501 78 : }
502 : }
503 :
504 : impl std::fmt::Debug for X86ISA<'_> {
505 52 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
506 52 : f.debug_struct("X86ISA")
507 52 : .field("type", &self.property_type())
508 52 : .field("values", &self.values())
509 52 : .finish()
510 52 : }
511 : }
512 :
513 : /// Stack size property (`GNU_PROPERTY_STACK_SIZE`)
514 : pub struct StackSize<'a> {
515 : ptr: cxx::UniquePtr<ffi::ELF_NoteGnuProperty_StackSize>,
516 : _owner: PhantomData<&'a ffi::ELF_NoteGnuProperty>,
517 : }
518 :
519 : impl StackSize<'_> {
520 : /// The stack size
521 0 : pub fn stack_size(&self) -> u64 {
522 0 : self.ptr.stack_size()
523 0 : }
524 : }
525 :
526 : impl NoteProperty for StackSize<'_> {
527 0 : fn get_base(&self) -> &ffi::ELF_NoteGnuProperty_Property {
528 0 : self.ptr.as_ref().unwrap().as_ref()
529 0 : }
530 : }
531 :
532 : impl FromFFI<ffi::ELF_NoteGnuProperty_StackSize> for StackSize<'_> {
533 0 : fn from_ffi(ptr: cxx::UniquePtr<ffi::ELF_NoteGnuProperty_StackSize>) -> Self {
534 0 : Self {
535 0 : ptr,
536 0 : _owner: PhantomData,
537 0 : }
538 0 : }
539 : }
540 :
541 : impl std::fmt::Debug for StackSize<'_> {
542 0 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
543 0 : f.debug_struct("StackSize")
544 0 : .field("type", &self.property_type())
545 0 : .field("stack_size", &self.stack_size())
546 0 : .finish()
547 0 : }
548 : }
549 :
550 : /// No copy on protected property (`GNU_PROPERTY_NO_COPY_ON_PROTECTED`)
551 : pub struct NoCopyOnProtected<'a> {
552 : ptr: cxx::UniquePtr<ffi::ELF_NoteGnuProperty_NoteNoCopyOnProtected>,
553 : _owner: PhantomData<&'a ffi::ELF_NoteGnuProperty>,
554 : }
555 :
556 : impl NoteProperty for NoCopyOnProtected<'_> {
557 0 : fn get_base(&self) -> &ffi::ELF_NoteGnuProperty_Property {
558 0 : self.ptr.as_ref().unwrap().as_ref()
559 0 : }
560 : }
561 :
562 : impl FromFFI<ffi::ELF_NoteGnuProperty_NoteNoCopyOnProtected> for NoCopyOnProtected<'_> {
563 0 : fn from_ffi(ptr: cxx::UniquePtr<ffi::ELF_NoteGnuProperty_NoteNoCopyOnProtected>) -> Self {
564 0 : Self {
565 0 : ptr,
566 0 : _owner: PhantomData,
567 0 : }
568 0 : }
569 : }
570 :
571 : impl std::fmt::Debug for NoCopyOnProtected<'_> {
572 0 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
573 0 : f.debug_struct("NoCopyOnProtected")
574 0 : .field("type", &self.property_type())
575 0 : .finish()
576 0 : }
577 : }
578 :
579 : #[allow(non_camel_case_types)]
580 0 : #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
581 : /// Flags for the `GNU_PROPERTY_1_NEEDED` property
582 : pub enum NeedFlag {
583 : UNKNOWN,
584 : /// The object needs indirect external access
585 : INDIRECT_EXTERN_ACCESS,
586 : }
587 :
588 : impl From<u64> for NeedFlag {
589 0 : fn from(value: u64) -> Self {
590 0 : match value {
591 0 : 0 => NeedFlag::UNKNOWN,
592 0 : 1 => NeedFlag::INDIRECT_EXTERN_ACCESS,
593 0 : _ => NeedFlag::UNKNOWN,
594 : }
595 0 : }
596 : }
597 :
598 : /// Needed property (`GNU_PROPERTY_1_NEEDED`)
599 : ///
600 : /// This property conveys information about additional features that the
601 : /// object file needs at runtime (e.g. indirect external access).
602 : pub struct Needed<'a> {
603 : ptr: cxx::UniquePtr<ffi::ELF_NoteGnuProperty_Needed>,
604 : _owner: PhantomData<&'a ffi::ELF_NoteGnuProperty>,
605 : }
606 :
607 : impl Needed<'_> {
608 : /// Return the list of needed features
609 0 : pub fn needs(&self) -> Vec<NeedFlag> {
610 0 : Vec::from(self.ptr.needs().as_slice())
611 0 : .into_iter()
612 0 : .map(NeedFlag::from)
613 0 : .collect()
614 0 : }
615 : }
616 :
617 : impl NoteProperty for Needed<'_> {
618 0 : fn get_base(&self) -> &ffi::ELF_NoteGnuProperty_Property {
619 0 : self.ptr.as_ref().unwrap().as_ref()
620 0 : }
621 : }
622 :
623 : impl FromFFI<ffi::ELF_NoteGnuProperty_Needed> for Needed<'_> {
624 0 : fn from_ffi(ptr: cxx::UniquePtr<ffi::ELF_NoteGnuProperty_Needed>) -> Self {
625 0 : Self {
626 0 : ptr,
627 0 : _owner: PhantomData,
628 0 : }
629 0 : }
630 : }
631 :
632 : impl std::fmt::Debug for Needed<'_> {
633 0 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
634 0 : f.debug_struct("Needed")
635 0 : .field("type", &self.property_type())
636 0 : .field("needs", &self.needs())
637 0 : .finish()
638 0 : }
639 : }
640 :
641 : /// Generic property (unrecognized by LIEF)
642 : pub struct GenericProperty<'a> {
643 : ptr: cxx::UniquePtr<ffi::ELF_NoteGnuProperty_Generic>,
644 : _owner: PhantomData<&'a ffi::ELF_NoteGnuProperty>,
645 : }
646 :
647 : impl GenericProperty<'_> {
648 : /// The raw type value
649 0 : pub fn raw_type(&self) -> u32 {
650 0 : self.ptr.raw_type()
651 0 : }
652 : }
653 :
654 : impl NoteProperty for GenericProperty<'_> {
655 0 : fn get_base(&self) -> &ffi::ELF_NoteGnuProperty_Property {
656 0 : self.ptr.as_ref().unwrap().as_ref()
657 0 : }
658 : }
659 :
660 : impl FromFFI<ffi::ELF_NoteGnuProperty_Generic> for GenericProperty<'_> {
661 0 : fn from_ffi(ptr: cxx::UniquePtr<ffi::ELF_NoteGnuProperty_Generic>) -> Self {
662 0 : Self {
663 0 : ptr,
664 0 : _owner: PhantomData,
665 0 : }
666 0 : }
667 : }
668 :
669 : impl std::fmt::Debug for GenericProperty<'_> {
670 0 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
671 0 : f.debug_struct("GenericProperty")
672 0 : .field("type", &self.property_type())
673 0 : .field("raw_type", &self.raw_type())
674 0 : .finish()
675 0 : }
676 : }
|