LCOV - code coverage report
Current view: top level - src/elf/note - mod.rs (source / functions) Coverage Total Hit
Test: lief.lcov Lines: 53.2 % 235 125
Test Date: 2026-04-12:00:00:00 Functions: 66.2 % 74 49

            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 : );
        

Generated by: LCOV version 2.1-1