LCOV - code coverage report
Current view: top level - src/coff - symbol.rs (source / functions) Coverage Total Hit
Test: lief.lcov Lines: 54.4 % 445 242
Test Date: 2025-06-24:00:00:00 Functions: 56.8 % 88 50

            Line data    Source code
       1              : use lief_ffi as ffi;
       2              : 
       3              : use std::marker::PhantomData;
       4              : use std::pin::Pin;
       5              : 
       6              : use crate::to_slice;
       7              : use crate::common::{into_optional, FromFFI};
       8              : use crate::{generic, declare_iterator};
       9              : 
      10              : use super::Section;
      11              : 
      12              : #[allow(non_camel_case_types)]
      13       387960 : #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
      14              : pub enum StorageClass {
      15              :     INVALID,
      16              :     END_OF_FUNCTION,
      17              :     NONE,
      18              :     AUTOMATIC,
      19              :     EXTERNAL,
      20              :     STATIC,
      21              :     REGISTER,
      22              :     EXTERNAL_DEF,
      23              :     LABEL,
      24              :     UNDEFINED_LABEL,
      25              :     MEMBER_OF_STRUCT,
      26              :     ARGUMENT,
      27              :     STRUCT_TAG,
      28              :     MEMBER_OF_UNION,
      29              :     UNION_TAG,
      30              :     TYPE_DEFINITION,
      31              :     UNDEFINED_STATIC,
      32              :     ENUM_TAG,
      33              :     MEMBER_OF_ENUM,
      34              :     REGISTER_PARAM,
      35              :     BIT_FIELD,
      36              :     BLOCK,
      37              :     FUNCTION,
      38              :     END_OF_STRUCT,
      39              :     FILE,
      40              :     SECTION,
      41              :     WEAK_EXTERNAL,
      42              :     CLR_TOKEN,
      43              :     UNKNOWN(u32),
      44              : }
      45              : 
      46              : impl From<u32> for StorageClass {
      47       387960 :     fn from(value: u32) -> Self {
      48       387960 :         match value {
      49            0 :             0x000000ff => StorageClass::INVALID,
      50            0 :             0xffffffff => StorageClass::END_OF_FUNCTION,
      51            0 :             0x00000000 => StorageClass::NONE,
      52            0 :             0x00000001 => StorageClass::AUTOMATIC,
      53       102804 :             0x00000002 => StorageClass::EXTERNAL,
      54       280824 :             0x00000003 => StorageClass::STATIC,
      55            0 :             0x00000004 => StorageClass::REGISTER,
      56            0 :             0x00000005 => StorageClass::EXTERNAL_DEF,
      57          816 :             0x00000006 => StorageClass::LABEL,
      58            0 :             0x00000007 => StorageClass::UNDEFINED_LABEL,
      59            0 :             0x00000008 => StorageClass::MEMBER_OF_STRUCT,
      60            0 :             0x00000009 => StorageClass::ARGUMENT,
      61            0 :             0x0000000a => StorageClass::STRUCT_TAG,
      62            0 :             0x0000000b => StorageClass::MEMBER_OF_UNION,
      63            0 :             0x0000000c => StorageClass::UNION_TAG,
      64            0 :             0x0000000d => StorageClass::TYPE_DEFINITION,
      65            0 :             0x0000000e => StorageClass::UNDEFINED_STATIC,
      66            0 :             0x0000000f => StorageClass::ENUM_TAG,
      67            0 :             0x00000010 => StorageClass::MEMBER_OF_ENUM,
      68            0 :             0x00000011 => StorageClass::REGISTER_PARAM,
      69            0 :             0x00000012 => StorageClass::BIT_FIELD,
      70            0 :             0x00000064 => StorageClass::BLOCK,
      71            0 :             0x00000065 => StorageClass::FUNCTION,
      72            0 :             0x00000066 => StorageClass::END_OF_STRUCT,
      73         3300 :             0x00000067 => StorageClass::FILE,
      74            0 :             0x00000068 => StorageClass::SECTION,
      75           96 :             0x00000069 => StorageClass::WEAK_EXTERNAL,
      76          120 :             0x0000006b => StorageClass::CLR_TOKEN,
      77            0 :             _ => StorageClass::UNKNOWN(value),
      78              : 
      79              :         }
      80       387960 :     }
      81              : }
      82              : impl From<StorageClass> for u32 {
      83            0 :     fn from(value: StorageClass) -> u32 {
      84            0 :         match value {
      85            0 :             StorageClass::INVALID => 0x000000ff,
      86            0 :             StorageClass::END_OF_FUNCTION => 0xffffffff,
      87            0 :             StorageClass::NONE => 0x00000000,
      88            0 :             StorageClass::AUTOMATIC => 0x00000001,
      89            0 :             StorageClass::EXTERNAL => 0x00000002,
      90            0 :             StorageClass::STATIC => 0x00000003,
      91            0 :             StorageClass::REGISTER => 0x00000004,
      92            0 :             StorageClass::EXTERNAL_DEF => 0x00000005,
      93            0 :             StorageClass::LABEL => 0x00000006,
      94            0 :             StorageClass::UNDEFINED_LABEL => 0x00000007,
      95            0 :             StorageClass::MEMBER_OF_STRUCT => 0x00000008,
      96            0 :             StorageClass::ARGUMENT => 0x00000009,
      97            0 :             StorageClass::STRUCT_TAG => 0x0000000a,
      98            0 :             StorageClass::MEMBER_OF_UNION => 0x0000000b,
      99            0 :             StorageClass::UNION_TAG => 0x0000000c,
     100            0 :             StorageClass::TYPE_DEFINITION => 0x0000000d,
     101            0 :             StorageClass::UNDEFINED_STATIC => 0x0000000e,
     102            0 :             StorageClass::ENUM_TAG => 0x0000000f,
     103            0 :             StorageClass::MEMBER_OF_ENUM => 0x00000010,
     104            0 :             StorageClass::REGISTER_PARAM => 0x00000011,
     105            0 :             StorageClass::BIT_FIELD => 0x00000012,
     106            0 :             StorageClass::BLOCK => 0x00000064,
     107            0 :             StorageClass::FUNCTION => 0x00000065,
     108            0 :             StorageClass::END_OF_STRUCT => 0x00000066,
     109            0 :             StorageClass::FILE => 0x00000067,
     110            0 :             StorageClass::SECTION => 0x00000068,
     111            0 :             StorageClass::WEAK_EXTERNAL => 0x00000069,
     112            0 :             StorageClass::CLR_TOKEN => 0x0000006b,
     113            0 :             StorageClass::UNKNOWN(value) => value,
     114              :         }
     115            0 :     }
     116              : }
     117              : 
     118              : 
     119              : #[allow(non_camel_case_types)]
     120       387960 : #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
     121              : pub enum BaseType {
     122              :     TY_NULL,
     123              :     TY_VOID,
     124              :     TY_CHAR,
     125              :     TY_SHORT,
     126              :     TY_INT,
     127              :     TY_LONG,
     128              :     TY_FLOAT,
     129              :     TY_DOUBLE,
     130              :     TY_STRUCT,
     131              :     TY_UNION,
     132              :     TY_ENUM,
     133              :     TY_MOE,
     134              :     TY_BYTE,
     135              :     TY_WORD,
     136              :     TY_UINT,
     137              :     TY_DWORD,
     138              :     UNKNOWN(u32),
     139              : }
     140              : 
     141              : impl From<u32> for BaseType {
     142       387960 :     fn from(value: u32) -> Self {
     143       387960 :         match value {
     144       387960 :             0x00000000 => BaseType::TY_NULL,
     145            0 :             0x00000001 => BaseType::TY_VOID,
     146            0 :             0x00000002 => BaseType::TY_CHAR,
     147            0 :             0x00000003 => BaseType::TY_SHORT,
     148            0 :             0x00000004 => BaseType::TY_INT,
     149            0 :             0x00000005 => BaseType::TY_LONG,
     150            0 :             0x00000006 => BaseType::TY_FLOAT,
     151            0 :             0x00000007 => BaseType::TY_DOUBLE,
     152            0 :             0x00000008 => BaseType::TY_STRUCT,
     153            0 :             0x00000009 => BaseType::TY_UNION,
     154            0 :             0x0000000a => BaseType::TY_ENUM,
     155            0 :             0x0000000b => BaseType::TY_MOE,
     156            0 :             0x0000000c => BaseType::TY_BYTE,
     157            0 :             0x0000000d => BaseType::TY_WORD,
     158            0 :             0x0000000e => BaseType::TY_UINT,
     159            0 :             0x0000000f => BaseType::TY_DWORD,
     160            0 :             _ => BaseType::UNKNOWN(value),
     161              : 
     162              :         }
     163       387960 :     }
     164              : }
     165              : impl From<BaseType> for u32 {
     166            0 :     fn from(value: BaseType) -> u32 {
     167            0 :         match value {
     168            0 :             BaseType::TY_NULL => 0x00000000,
     169            0 :             BaseType::TY_VOID => 0x00000001,
     170            0 :             BaseType::TY_CHAR => 0x00000002,
     171            0 :             BaseType::TY_SHORT => 0x00000003,
     172            0 :             BaseType::TY_INT => 0x00000004,
     173            0 :             BaseType::TY_LONG => 0x00000005,
     174            0 :             BaseType::TY_FLOAT => 0x00000006,
     175            0 :             BaseType::TY_DOUBLE => 0x00000007,
     176            0 :             BaseType::TY_STRUCT => 0x00000008,
     177            0 :             BaseType::TY_UNION => 0x00000009,
     178            0 :             BaseType::TY_ENUM => 0x0000000a,
     179            0 :             BaseType::TY_MOE => 0x0000000b,
     180            0 :             BaseType::TY_BYTE => 0x0000000c,
     181            0 :             BaseType::TY_WORD => 0x0000000d,
     182            0 :             BaseType::TY_UINT => 0x0000000e,
     183            0 :             BaseType::TY_DWORD => 0x0000000f,
     184            0 :             BaseType::UNKNOWN(value) => value,
     185              : 
     186              :         }
     187            0 :     }
     188              : }
     189              : 
     190              : 
     191              : 
     192              : #[allow(non_camel_case_types)]
     193       387960 : #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
     194              : pub enum ComplexType {
     195              :     TY_NULL,
     196              :     TY_POINTER,
     197              :     TY_FUNCTION,
     198              :     TY_ARRAY,
     199              :     UNKNOWN(u32),
     200              : }
     201              : 
     202              : impl From<u32> for ComplexType {
     203       387960 :     fn from(value: u32) -> Self {
     204       387960 :         match value {
     205       298392 :             0x00000000 => ComplexType::TY_NULL,
     206            0 :             0x00000001 => ComplexType::TY_POINTER,
     207        89568 :             0x00000002 => ComplexType::TY_FUNCTION,
     208            0 :             0x00000003 => ComplexType::TY_ARRAY,
     209            0 :             _ => ComplexType::UNKNOWN(value),
     210              : 
     211              :         }
     212       387960 :     }
     213              : }
     214              : impl From<ComplexType> for u32 {
     215            0 :     fn from(value: ComplexType) -> u32 {
     216            0 :         match value {
     217            0 :             ComplexType::TY_NULL => 0x00000000,
     218            0 :             ComplexType::TY_POINTER => 0x00000001,
     219            0 :             ComplexType::TY_FUNCTION => 0x00000002,
     220            0 :             ComplexType::TY_ARRAY => 0x00000003,
     221            0 :             ComplexType::UNKNOWN(value) => value,
     222              : 
     223              :         }
     224            0 :     }
     225              : }
     226              : 
     227              : /// Structure that represents a COFF symbol.
     228              : ///
     229              : /// **Warning:** The [`crate::generic::Symbol::value`] should be interpreted in perspective of
     230              : /// the [`Symbol::storage_class`].
     231              : ///
     232              : /// Reference: <https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#coff-symbol-table>
     233              : pub struct Symbol<'a> {
     234              :     pub(crate) ptr: cxx::UniquePtr<ffi::COFF_Symbol>,
     235              :     _owner: PhantomData<&'a ()>
     236              : }
     237              : 
     238              : impl FromFFI<ffi::COFF_Symbol> for Symbol<'_> {
     239       399144 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::COFF_Symbol>) -> Self {
     240       399144 :         Self {
     241       399144 :             ptr,
     242       399144 :             _owner: PhantomData
     243       399144 :         }
     244       399144 :     }
     245              : }
     246              : 
     247              : impl std::fmt::Debug for Symbol<'_> {
     248       387960 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
     249       387960 :         let base = self as &dyn generic::Symbol;
     250       387960 :         f.debug_struct("Symbol")
     251       387960 :             .field("base", &base)
     252       387960 :             .field("storage_class", &self.storage_class())
     253       387960 :             .field("base_type", &self.base_type())
     254       387960 :             .field("complex_type", &self.complex_type())
     255       387960 :             .field("section_idx", &self.section_idx())
     256       387960 :             .finish()
     257       387960 :     }
     258              : }
     259              : 
     260              : 
     261              : impl std::fmt::Display for Symbol<'_> {
     262        19176 :     fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
     263        19176 :         write!(f, "{}", self.ptr.to_string())
     264        19176 :     }
     265              : }
     266              : 
     267              : impl Symbol<'_> {
     268              :     /// Auxiliary symbols associated with this symbol.
     269       375588 :     pub fn auxiliary_symbols(&self) -> ItAuxiliarySymbols {
     270       375588 :         ItAuxiliarySymbols::new(self.ptr.auxiliary_symbols())
     271       375588 :     }
     272              : 
     273              :     /// Storage class of the symbol which indicates what kind of definition a
     274              :     /// symbol represents.
     275       387960 :     pub fn storage_class(&self) -> StorageClass {
     276       387960 :         StorageClass::from(self.ptr.storage_class())
     277       387960 :     }
     278              : 
     279              :     /// The simple (base) data type
     280       387960 :     pub fn base_type(&self) -> BaseType {
     281       387960 :         BaseType::from(self.ptr.base_type())
     282       387960 :     }
     283              : 
     284              :     /// The complex type (if any)
     285       387960 :     pub fn complex_type(&self) -> ComplexType {
     286       387960 :         ComplexType::from(self.ptr.complex_type())
     287       387960 :     }
     288              : 
     289              :     /// The signed integer that identifies the section, using a one-based index
     290              :     /// into the section table. Some values have special meaning:
     291              :     ///
     292              :     /// * 0: The symbol record is not yet assigned a section. A value of zero
     293              :     ///      indicates that a reference to an external symbol is defined elsewhere.
     294              :     ///      A value of non-zero is a common symbol with a size that is specified
     295              :     ///      by the value.
     296              :     /// * -1: The symbol has an absolute (non-relocatable) value and is not an
     297              :     ///       address.
     298              :     /// * -2: The symbol provides general type or debugging information but does
     299              :     ///       not correspond to a section. Microsoft tools use this setting along
     300              :     ///       with `.file` records
     301       387960 :     pub fn section_idx(&self) -> i16 {
     302       387960 :         self.ptr.section_idx()
     303       387960 :     }
     304              : 
     305              :     /// Section associated with this symbol (if any)
     306         9384 :     pub fn section(&self) -> Option<Section> {
     307         9384 :         into_optional(self.ptr.section())
     308         9384 :     }
     309              : 
     310            0 :     pub fn is_external(&self) -> bool {
     311            0 :         self.ptr.is_external()
     312            0 :     }
     313              : 
     314            0 :     pub fn is_weak_external(&self) -> bool {
     315            0 :         self.ptr.is_weak_external()
     316            0 :     }
     317              : 
     318            0 :     pub fn is_undefined(&self) -> bool {
     319            0 :         self.ptr.is_undefined()
     320            0 :     }
     321              : 
     322            0 :     pub fn is_function_line_info(&self) -> bool {
     323            0 :         self.ptr.is_function_line_info()
     324            0 :     }
     325              : 
     326            0 :     pub fn is_absolute(&self) -> bool {
     327            0 :         self.ptr.is_absolute()
     328            0 :     }
     329              : 
     330            0 :     pub fn is_file_record(&self) -> bool {
     331            0 :         self.ptr.is_file_record()
     332            0 :     }
     333              : 
     334            0 :     pub fn is_function(&self) -> bool {
     335            0 :         self.ptr.is_function()
     336            0 :     }
     337              : 
     338              :     /// Demangled representation of the symbol or an empty string if it can't be demangled
     339            0 :     pub fn demangled_name(&self) -> String {
     340            0 :         self.ptr.demangled_name().to_string()
     341            0 :     }
     342              : }
     343              : 
     344              : impl generic::Symbol for Symbol<'_> {
     345      1175064 :     fn as_generic(&self) -> &ffi::AbstractSymbol {
     346      1175064 :         self.ptr.as_ref().unwrap().as_ref()
     347      1175064 :     }
     348              : 
     349            0 :     fn as_pin_mut_generic(&mut self) -> Pin<&mut ffi::AbstractSymbol> {
     350            0 :         unsafe {
     351            0 :             Pin::new_unchecked({
     352            0 :                 (self.ptr.as_ref().unwrap().as_ref() as *const ffi::AbstractSymbol
     353            0 :                     as *mut ffi::AbstractSymbol)
     354            0 :                     .as_mut()
     355            0 :                     .unwrap()
     356            0 :             })
     357            0 :         }
     358            0 :     }
     359              : }
     360              : 
     361              : /// Class that represents an auxiliary symbols.
     362              : ///
     363              : /// An auxiliary symbol has the same size as a regular [`Symbol`] (18 bytes) but its content
     364              : /// depends on the the parent symbol.
     365       244896 : #[derive(Debug)]
     366              : pub enum AuxiliarySymbols<'a> {
     367              :     /// Auxiliary Format 1 from the PE-COFF documentation
     368              :     FunctionDefinition(AuxiliaryFunctionDefinition<'a>),
     369              :     /// Auxiliary Format 2: .bf and .ef Symbols from the PE-COFF documentation
     370              :     BfAndEf(AuxiliaryBfAndEf<'a>),
     371              :     /// Auxiliary Format 3: Weak Externals from the PE-COFF documentation
     372              :     WeakExternal(AuxiliaryWeakExternal<'a>),
     373              :     /// Auxiliary Format 4: Files from the PE-COFF documentation
     374              :     File(AuxiliaryFile<'a>),
     375              :     /// Auxiliary Format 5: Section Definitions from the PE-COFF documentation
     376              :     SectionDefinition(AuxiliarySectionDefinition<'a>),
     377              :     CLRToken(AuxiliaryCLRToken<'a>),
     378              :     Unknown(AuxiliarySymbol<'a>),
     379              : }
     380              : 
     381              : 
     382              : impl FromFFI<ffi::COFF_AuxiliarySymbol> for AuxiliarySymbols<'_> {
     383       244896 :     fn from_ffi(ffi_entry: cxx::UniquePtr<ffi::COFF_AuxiliarySymbol>) -> Self {
     384       244896 :         unsafe {
     385       244896 :             let aux_ref = ffi_entry.as_ref().unwrap();
     386       244896 :             if ffi::COFF_AuxiliaryFile::classof(aux_ref) {
     387         3300 :                 let raw = {
     388         3300 :                     type From = cxx::UniquePtr<ffi::COFF_AuxiliarySymbol>;
     389         3300 :                     type To = cxx::UniquePtr<ffi::COFF_AuxiliaryFile>;
     390         3300 :                     std::mem::transmute::<From, To>(ffi_entry)
     391         3300 :                 };
     392         3300 :                 AuxiliarySymbols::File(AuxiliaryFile::from_ffi(raw))
     393       241596 :             } else if ffi::COFF_AuxiliarybfAndefSymbol::classof(aux_ref) {
     394            0 :                 let raw = {
     395            0 :                     type From = cxx::UniquePtr<ffi::COFF_AuxiliarySymbol>;
     396            0 :                     type To = cxx::UniquePtr<ffi::COFF_AuxiliarybfAndefSymbol>;
     397            0 :                     std::mem::transmute::<From, To>(ffi_entry)
     398            0 :                 };
     399            0 :                 AuxiliarySymbols::BfAndEf(AuxiliaryBfAndEf::from_ffi(raw))
     400       241596 :             } else if ffi::COFF_AuxiliaryCLRToken::classof(aux_ref) {
     401           24 :                 let raw = {
     402           24 :                     type From = cxx::UniquePtr<ffi::COFF_AuxiliarySymbol>;
     403           24 :                     type To = cxx::UniquePtr<ffi::COFF_AuxiliaryCLRToken>;
     404           24 :                     std::mem::transmute::<From, To>(ffi_entry)
     405           24 :                 };
     406           24 :                 AuxiliarySymbols::CLRToken(AuxiliaryCLRToken::from_ffi(raw))
     407       241572 :             } else if ffi::COFF_AuxiliaryFunctionDefinition::classof(aux_ref) {
     408         1932 :                 let raw = {
     409         1932 :                     type From = cxx::UniquePtr<ffi::COFF_AuxiliarySymbol>;
     410         1932 :                     type To = cxx::UniquePtr<ffi::COFF_AuxiliaryFunctionDefinition>;
     411         1932 :                     std::mem::transmute::<From, To>(ffi_entry)
     412         1932 :                 };
     413         1932 :                 AuxiliarySymbols::FunctionDefinition(AuxiliaryFunctionDefinition::from_ffi(raw))
     414       239640 :             } else if ffi::COFF_AuxiliaryWeakExternal::classof(aux_ref) {
     415          672 :                 let raw = {
     416          672 :                     type From = cxx::UniquePtr<ffi::COFF_AuxiliarySymbol>;
     417          672 :                     type To = cxx::UniquePtr<ffi::COFF_AuxiliaryWeakExternal>;
     418          672 :                     std::mem::transmute::<From, To>(ffi_entry)
     419          672 :                 };
     420          672 :                 AuxiliarySymbols::WeakExternal(AuxiliaryWeakExternal::from_ffi(raw))
     421       238968 :             } else if ffi::COFF_AuxiliarySectionDefinition::classof(aux_ref) {
     422       238968 :                 let raw = {
     423       238968 :                     type From = cxx::UniquePtr<ffi::COFF_AuxiliarySymbol>;
     424       238968 :                     type To = cxx::UniquePtr<ffi::COFF_AuxiliarySectionDefinition>;
     425       238968 :                     std::mem::transmute::<From, To>(ffi_entry)
     426       238968 :                 };
     427       238968 :                 AuxiliarySymbols::SectionDefinition(AuxiliarySectionDefinition::from_ffi(raw))
     428              :             } else {
     429            0 :                 AuxiliarySymbols::Unknown(AuxiliarySymbol::from_ffi(ffi_entry))
     430              :             }
     431              :         }
     432       244896 :     }
     433              : }
     434              : 
     435              : /// This auxiliary symbol represents a filename (auxiliary format 4)
     436              : ///
     437              : /// The [`crate::generic::Symbol::name`] itself should start with `.file`, and this auxiliary record
     438              : /// gives the name of a source-code file.
     439              : ///
     440              : /// Reference: <https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#auxiliary-format-4-files>
     441              : pub struct AuxiliaryFile<'a> {
     442              :     ptr: cxx::UniquePtr<ffi::COFF_AuxiliaryFile>,
     443              :     _owner: PhantomData<&'a ffi::COFF_Symbol>,
     444              : }
     445              : 
     446              : impl std::fmt::Debug for AuxiliaryFile<'_> {
     447         3300 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
     448         3300 :         f.debug_struct("AuxiliaryFile")
     449         3300 :             .field("filename", &self.filename())
     450         3300 :             .finish()
     451         3300 :     }
     452              : }
     453              : 
     454              : impl FromFFI<ffi::COFF_AuxiliaryFile> for AuxiliaryFile<'_> {
     455         3300 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::COFF_AuxiliaryFile>) -> Self {
     456         3300 :         Self {
     457         3300 :             ptr,
     458         3300 :             _owner: PhantomData,
     459         3300 :         }
     460         3300 :     }
     461              : }
     462              : 
     463              : impl AuxiliaryFile<'_> {
     464              :     /// The associated filename
     465         3300 :     pub fn filename(&self) -> String {
     466         3300 :         self.ptr.filename().to_string()
     467         3300 :     }
     468              : }
     469              : 
     470              : pub struct AuxiliaryBfAndEf<'a> {
     471              :     #[allow(dead_code)]
     472              :     ptr: cxx::UniquePtr<ffi::COFF_AuxiliarybfAndefSymbol>,
     473              :     _owner: PhantomData<&'a ffi::COFF_Symbol>,
     474              : }
     475              : 
     476              : impl std::fmt::Debug for AuxiliaryBfAndEf<'_> {
     477            0 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
     478            0 :         f.debug_struct("AuxiliaryBfAndEf")
     479            0 :             .finish()
     480            0 :     }
     481              : }
     482              : 
     483              : impl FromFFI<ffi::COFF_AuxiliarybfAndefSymbol> for AuxiliaryBfAndEf<'_> {
     484            0 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::COFF_AuxiliarybfAndefSymbol>) -> Self {
     485            0 :         Self {
     486            0 :             ptr,
     487            0 :             _owner: PhantomData,
     488            0 :         }
     489            0 :     }
     490              : }
     491              : 
     492              : pub struct AuxiliaryCLRToken<'a> {
     493              :     #[allow(dead_code)]
     494              :     ptr: cxx::UniquePtr<ffi::COFF_AuxiliaryCLRToken>,
     495              :     _owner: PhantomData<&'a ffi::COFF_Symbol>,
     496              : }
     497              : 
     498              : impl AuxiliaryCLRToken<'_> {
     499              :     /// `IMAGE_AUX_SYMBOL_TYPE` which should be `IMAGE_AUX_SYMBOL_TYPE_TOKEN_DEF` (1)
     500           24 :     pub fn aux_type(&self) -> u8 {
     501           24 :         self.ptr.aux_type()
     502           24 :     }
     503              : 
     504              :     /// Reserved value (should be 0)
     505           24 :     pub fn reserved(&self) -> u8 {
     506           24 :         self.ptr.reserved()
     507           24 :     }
     508              : 
     509              :     /// Index in the symbol table
     510           24 :     pub fn symbol_idx(&self) -> u32 {
     511           24 :         self.ptr.symbol_idx()
     512           24 :     }
     513              : 
     514              :     /// Symbol referenced by [`AuxiliaryCLRToken::symbol_idx`] (if resolved)
     515            0 :     pub fn symbol(&self) -> Option<Symbol> {
     516            0 :         into_optional(self.ptr.symbol())
     517            0 :     }
     518              : 
     519              :     /// Reserved (padding) values. Should be 0
     520            0 :     pub fn rgb_reserved(&self) -> &[u8] {
     521            0 :         to_slice!(self.ptr.rgb_reserved());
     522            0 :     }
     523              : }
     524              : 
     525              : 
     526              : impl std::fmt::Debug for AuxiliaryCLRToken<'_> {
     527           24 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
     528           24 :         f.debug_struct("AuxiliaryCLRToken")
     529           24 :             .field("aux_type", &self.aux_type())
     530           24 :             .field("reserved", &self.reserved())
     531           24 :             .field("symbol_idx", &self.symbol_idx())
     532           24 :             .finish()
     533           24 :     }
     534              : }
     535              : 
     536              : impl FromFFI<ffi::COFF_AuxiliaryCLRToken> for AuxiliaryCLRToken<'_> {
     537           24 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::COFF_AuxiliaryCLRToken>) -> Self {
     538           24 :         Self {
     539           24 :             ptr,
     540           24 :             _owner: PhantomData,
     541           24 :         }
     542           24 :     }
     543              : }
     544              : 
     545              : /// This auxiliary symbols marks the beginning of a function definition.
     546              : ///
     547              : /// Reference: <https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#auxiliary-format-1-function-definitions>
     548              : pub struct AuxiliaryFunctionDefinition<'a> {
     549              :     ptr: cxx::UniquePtr<ffi::COFF_AuxiliaryFunctionDefinition>,
     550              :     _owner: PhantomData<&'a ffi::COFF_Symbol>,
     551              : }
     552              : 
     553              : impl FromFFI<ffi::COFF_AuxiliaryFunctionDefinition> for AuxiliaryFunctionDefinition<'_> {
     554         1932 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::COFF_AuxiliaryFunctionDefinition>) -> Self {
     555         1932 :         Self {
     556         1932 :             ptr,
     557         1932 :             _owner: PhantomData,
     558         1932 :         }
     559         1932 :     }
     560              : }
     561              : 
     562              : impl std::fmt::Debug for AuxiliaryFunctionDefinition<'_> {
     563         1932 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
     564         1932 :         f.debug_struct("AuxiliaryFunctionDefinition")
     565         1932 :             .field("tag_index", &self.tag_index())
     566         1932 :             .field("total_size", &self.total_size())
     567         1932 :             .field("ptr_to_line_number", &self.ptr_to_line_number())
     568         1932 :             .field("ptr_to_next_func", &self.ptr_to_next_func())
     569         1932 :             .field("padding", &self.padding())
     570         1932 :             .finish()
     571         1932 :     }
     572              : }
     573              : 
     574              : impl AuxiliaryFunctionDefinition<'_> {
     575              :     /// The symbol-table index of the corresponding `.bf` (begin function)
     576              :     /// symbol record.
     577         1932 :     pub fn tag_index(&self) -> u32 {
     578         1932 :         self.ptr.tag_index()
     579         1932 :     }
     580              : 
     581              :     /// The size of the executable code for the function itself.
     582              :     ///
     583              :     /// If the function is in its own section, the `SizeOfRawData` in the section
     584              :     /// header is greater or equal to this field, depending on alignment considerations.
     585         1932 :     pub fn total_size(&self) -> u32 {
     586         1932 :         self.ptr.total_size()
     587         1932 :     }
     588              : 
     589              :     /// The file offset of the first COFF line-number entry for the function,
     590              :     /// or zero if none exists (deprecated)
     591         1932 :     pub fn ptr_to_line_number(&self) -> u32 {
     592         1932 :         self.ptr.ptr_to_line_number()
     593         1932 :     }
     594              : 
     595              :     /// The symbol-table index of the record for the next function. If the function
     596              :     /// is the last in the symbol table, this field is set to zero.
     597         1932 :     pub fn ptr_to_next_func(&self) -> u32 {
     598         1932 :         self.ptr.ptr_to_next_func()
     599         1932 :     }
     600              : 
     601              :     /// Padding value (should be 0)
     602         1932 :     pub fn padding(&self) -> u16 {
     603         1932 :         self.ptr.padding()
     604         1932 :     }
     605              : 
     606              : }
     607              : 
     608              : /// This auxiliary symbol exposes information about the associated section.
     609              : ///
     610              : /// It **duplicates** some information that are provided in the section header
     611              : pub struct AuxiliarySectionDefinition<'a> {
     612              :     ptr: cxx::UniquePtr<ffi::COFF_AuxiliarySectionDefinition>,
     613              :     _owner: PhantomData<&'a ffi::COFF_Symbol>,
     614              : }
     615              : 
     616              : impl FromFFI<ffi::COFF_AuxiliarySectionDefinition> for AuxiliarySectionDefinition<'_> {
     617       238968 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::COFF_AuxiliarySectionDefinition>) -> Self {
     618       238968 :         Self {
     619       238968 :             ptr,
     620       238968 :             _owner: PhantomData,
     621       238968 :         }
     622       238968 :     }
     623              : }
     624              : 
     625              : impl std::fmt::Debug for AuxiliarySectionDefinition<'_> {
     626       238968 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
     627       238968 :         f.debug_struct("AuxiliarySectionDefinition")
     628       238968 :             .field("length", &self.length())
     629       238968 :             .field("nb_relocs", &self.nb_relocs())
     630       238968 :             .field("nb_line_numbers", &self.nb_line_numbers())
     631       238968 :             .field("checksum", &self.checksum())
     632       238968 :             .field("section_idx", &self.section_idx())
     633       238968 :             .field("selection", &self.selection())
     634       238968 :             .finish()
     635       238968 :     }
     636              : }
     637              : 
     638              : impl AuxiliarySectionDefinition<'_> {
     639              :     /// The size of section data. The same as `SizeOfRawData` in the section header.
     640       238968 :     pub fn length(&self) -> u32 {
     641       238968 :         self.ptr.length()
     642       238968 :     }
     643              : 
     644              :     /// The number of relocation entries for the section.
     645       238968 :     pub fn nb_relocs(&self) -> u16 {
     646       238968 :         self.ptr.nb_relocs()
     647       238968 :     }
     648              : 
     649              :     /// The number of line-number entries for the section.
     650       238968 :     pub fn nb_line_numbers(&self) -> u16 {
     651       238968 :         self.ptr.nb_line_numbers()
     652       238968 :     }
     653              : 
     654              :     /// The checksum for communal data. It is applicable if the `IMAGE_SCN_LNK_COMDAT` flag is set
     655              :     /// in the section header.
     656       238968 :     pub fn checksum(&self) -> u32 {
     657       238968 :         self.ptr.checksum()
     658       238968 :     }
     659              : 
     660              :     /// One-based index into the section table for the associated section.
     661              :     /// This is used when the COMDAT selection setting is 5.
     662       238968 :     pub fn section_idx(&self) -> u32 {
     663       238968 :         self.ptr.section_idx()
     664       238968 :     }
     665              : 
     666              :     /// The COMDAT selection number. This is applicable if the section is a
     667              :     /// COMDAT section.
     668       238968 :     pub fn selection(&self) -> ComdatSelection {
     669       238968 :         ComdatSelection::from(self.ptr.selection())
     670       238968 :     }
     671              : 
     672              :     /// Reserved value (should be 0)
     673            0 :     pub fn reserved(&self) -> u8 {
     674            0 :         self.ptr.reserved()
     675            0 :     }
     676              : }
     677              : 
     678              : 
     679              : #[allow(non_camel_case_types)]
     680       241548 : #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
     681              : pub enum ComdatSelection {
     682              :     NONE,
     683              :     NODUPLICATES,
     684              :     ANY,
     685              :     SAME_SIZE,
     686              :     EXACT_MATCH,
     687              :     ASSOCIATIVE,
     688              :     LARGEST,
     689              :     UNKNOWN(u8),
     690              : }
     691              : 
     692              : impl From<u8> for ComdatSelection {
     693       241548 :     fn from(value: u8) -> Self {
     694       241548 :         match value {
     695        70536 :             0x00000000 => ComdatSelection::NONE,
     696          240 :             0x00000001 => ComdatSelection::NODUPLICATES,
     697       155964 :             0x00000002 => ComdatSelection::ANY,
     698        11040 :             0x00000003 => ComdatSelection::SAME_SIZE,
     699            0 :             0x00000004 => ComdatSelection::EXACT_MATCH,
     700         3768 :             0x00000005 => ComdatSelection::ASSOCIATIVE,
     701            0 :             0x00000006 => ComdatSelection::LARGEST,
     702            0 :             _ => ComdatSelection::UNKNOWN(value),
     703              : 
     704              :         }
     705       241548 :     }
     706              : }
     707              : impl From<ComdatSelection> for u8 {
     708            0 :     fn from(value: ComdatSelection) -> u8 {
     709            0 :         match value {
     710            0 :             ComdatSelection::NONE => 0x00000000,
     711            0 :             ComdatSelection::NODUPLICATES => 0x00000001,
     712            0 :             ComdatSelection::ANY => 0x00000002,
     713            0 :             ComdatSelection::SAME_SIZE => 0x00000003,
     714            0 :             ComdatSelection::EXACT_MATCH => 0x00000004,
     715            0 :             ComdatSelection::ASSOCIATIVE => 0x00000005,
     716            0 :             ComdatSelection::LARGEST => 0x00000006,
     717            0 :             ComdatSelection::UNKNOWN(value) => value,
     718              : 
     719              :         }
     720            0 :     }
     721              : }
     722              : 
     723              : 
     724              : /// "Weak externals" are a mechanism for object files that allows flexibility at
     725              : /// link time. A module can contain an unresolved external symbol (`sym1`), but
     726              : /// it can also include an auxiliary record that indicates that if `sym1` is not
     727              : /// present at link time, another external symbol (`sym2`) is used to resolve
     728              : /// references instead.
     729              : ///
     730              : /// If a definition of `sym1` is linked, then an external reference to the
     731              : /// symbol is resolved normally. If a definition of `sym1` is not linked, then all
     732              : /// references to the weak external for `sym1` refer to `sym2` instead. The external
     733              : /// symbol, `sym2`, must always be linked; typically, it is defined in the module
     734              : /// that contains the weak reference to `sym1`.
     735              : ///
     736              : /// Reference: <https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#auxiliary-format-3-weak-externals>
     737              : pub struct AuxiliaryWeakExternal<'a> {
     738              :     ptr: cxx::UniquePtr<ffi::COFF_AuxiliaryWeakExternal>,
     739              :     _owner: PhantomData<&'a ffi::COFF_Symbol>,
     740              : }
     741              : 
     742              : 
     743              : #[allow(non_camel_case_types)]
     744          672 : #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
     745              : pub enum Characteristics {
     746              :     SEARCH_NOLIBRARY,
     747              :     SEARCH_LIBRARY,
     748              :     SEARCH_ALIAS,
     749              :     ANTI_DEPENDENCY,
     750              :     UNKNOWN(u32),
     751              : }
     752              : 
     753              : impl From<u32> for Characteristics {
     754          672 :     fn from(value: u32) -> Self {
     755          672 :         match value {
     756          108 :             0x00000001 => Characteristics::SEARCH_NOLIBRARY,
     757            0 :             0x00000002 => Characteristics::SEARCH_LIBRARY,
     758            0 :             0x00000003 => Characteristics::SEARCH_ALIAS,
     759            0 :             0x00000004 => Characteristics::ANTI_DEPENDENCY,
     760          564 :             _ => Characteristics::UNKNOWN(value),
     761              : 
     762              :         }
     763          672 :     }
     764              : }
     765              : impl From<Characteristics> for u32 {
     766            0 :     fn from(value: Characteristics) -> u32 {
     767            0 :         match value {
     768            0 :             Characteristics::SEARCH_NOLIBRARY => 0x00000001,
     769            0 :             Characteristics::SEARCH_LIBRARY => 0x00000002,
     770            0 :             Characteristics::SEARCH_ALIAS => 0x00000003,
     771            0 :             Characteristics::ANTI_DEPENDENCY => 0x00000004,
     772            0 :             Characteristics::UNKNOWN(value) => value,
     773              : 
     774              :         }
     775            0 :     }
     776              : }
     777              : 
     778              : impl FromFFI<ffi::COFF_AuxiliaryWeakExternal> for AuxiliaryWeakExternal<'_> {
     779          672 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::COFF_AuxiliaryWeakExternal>) -> Self {
     780          672 :         Self {
     781          672 :             ptr,
     782          672 :             _owner: PhantomData,
     783          672 :         }
     784          672 :     }
     785              : }
     786              : 
     787              : impl std::fmt::Debug for AuxiliaryWeakExternal<'_> {
     788          672 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
     789          672 :         f.debug_struct("AuxiliaryWeakExternal")
     790          672 :             .field("sym_idx", &self.sym_idx())
     791          672 :             .field("characteristics", &self.characteristics())
     792          672 :             .finish()
     793          672 :     }
     794              : }
     795              : 
     796              : impl AuxiliaryWeakExternal<'_> {
     797              :     /// The symbol-table index of `sym2`, the symbol to be linked if `sym1` is not
     798              :     /// found.
     799          672 :     pub fn sym_idx(&self) -> u32 {
     800          672 :         self.ptr.sym_idx()
     801          672 :     }
     802              : 
     803          672 :     pub fn characteristics(&self) -> Characteristics{
     804          672 :         Characteristics::from(self.ptr.characteristics())
     805          672 :     }
     806              : 
     807            0 :     pub fn padding(&self) -> &[u8] {
     808            0 :         to_slice!(self.ptr.padding());
     809            0 :     }
     810              : }
     811              : 
     812              : 
     813              : pub struct AuxiliarySymbol<'a> {
     814              :     ptr: cxx::UniquePtr<ffi::COFF_AuxiliarySymbol>,
     815              :     _owner: PhantomData<&'a ffi::COFF_Symbol>,
     816              : }
     817              : 
     818              : impl FromFFI<ffi::COFF_AuxiliarySymbol> for AuxiliarySymbol<'_> {
     819            0 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::COFF_AuxiliarySymbol>) -> Self {
     820            0 :         Self {
     821            0 :             ptr,
     822            0 :             _owner: PhantomData,
     823            0 :         }
     824            0 :     }
     825              : }
     826              : 
     827              : impl std::fmt::Debug for AuxiliarySymbol<'_> {
     828            0 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
     829            0 :         f.debug_struct("AuxiliarySymbol")
     830            0 :             .finish()
     831            0 :     }
     832              : }
     833              : 
     834              : impl AuxiliarySymbol<'_> {
     835              :     /// Return the raw representation of this symbol
     836            0 :     pub fn payload(&self) -> &[u8] {
     837            0 :         to_slice!(self.ptr.payload());
     838            0 :     }
     839              : }
     840              : 
     841       244896 : declare_iterator!(
     842       244896 :     ItAuxiliarySymbols,
     843       244896 :     AuxiliarySymbols<'a>,
     844       244896 :     ffi::COFF_AuxiliarySymbol,
     845       244896 :     ffi::COFF_Symbol,
     846       244896 :     ffi::COFF_Symbol_it_auxiliary_symbols
     847       244896 : );
        

Generated by: LCOV version 2.1-1