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

Generated by: LCOV version 2.1-1