LCOV - code coverage report
Current view: top level - src/pe - symbol.rs (source / functions) Coverage Total Hit
Test: lief.lcov Lines: 52.7 % 376 198
Test Date: 2025-02-23:00:00:00 Functions: 58.6 % 70 41

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

Generated by: LCOV version 2.1-1