LCOV - code coverage report
Current view: top level - src/pe - dynamic_fixups.rs (source / functions) Coverage Total Hit
Test: lief.lcov Lines: 0.0 % 367 0
Test Date: 2025-02-23:00:00:00 Functions: 0.0 % 76 0

            Line data    Source code
       1              : use lief_ffi as ffi;
       2              : 
       3              : use crate::pe::Relocation;
       4              : use crate::common::{into_optional, FromFFI};
       5              : use crate::{declare_fwd_iterator, declare_iterator, to_slice};
       6              : use std::marker::PhantomData;
       7              : 
       8              : /// This enum wraps the different fixups that can be associated with a
       9              : /// [`crate::pe::DynamicRelocation`]
      10            0 : #[derive(Debug)]
      11              : pub enum DynamicFixup<'a> {
      12              :     /// Entry when [`crate::pe::dynamic_relocation::AsDynamicRelocation::symbol`] is not
      13              :     /// a special value
      14              :     Generic(Generic<'a>),
      15              : 
      16              :     /// Entry when [`crate::pe::dynamic_relocation::AsDynamicRelocation::symbol`] is set
      17              :     /// to [`crate::pe::dynamic_relocation::IMAGE_DYNAMIC_RELOCATION_ARM64X`]
      18              :     Arm64X(Arm64X<'a>),
      19              : 
      20              :     /// Entry when [`crate::pe::dynamic_relocation::AsDynamicRelocation::symbol`] is set
      21              :     /// to [`crate::pe::dynamic_relocation::IMAGE_DYNAMIC_RELOCATION_FUNCTION_OVERRIDE`]
      22              :     FunctionOverride(FunctionOverride<'a>),
      23              : 
      24              :     /// Entry when [`crate::pe::dynamic_relocation::AsDynamicRelocation::symbol`] is set
      25              :     /// to [`crate::pe::dynamic_relocation::IMAGE_DYNAMIC_RELOCATION_ARM64_KERNEL_IMPORT_CALL_TRANSFER`]
      26              :     ARM64Kernel(ARM64Kernel<'a>),
      27              : 
      28              :     /// Entry when [`crate::pe::dynamic_relocation::AsDynamicRelocation::symbol`] is set
      29              :     /// to [`crate::pe::dynamic_relocation::IMAGE_DYNAMIC_RELOCATION_GUARD_IMPORT_CONTROL_TRANSFER`]
      30              :     ControlTransfer(ControlTransfer<'a>),
      31              : 
      32              :     /// Entry when [`crate::pe::dynamic_relocation::AsDynamicRelocation::symbol`] is set
      33              :     /// to a special value that is not supported by LIEF.
      34              :     Unknown(Unknown<'a>)
      35              : }
      36              : 
      37              : impl<'a> FromFFI<ffi::PE_DynamicFixup> for DynamicFixup<'a> {
      38            0 :     fn from_ffi(ffi_entry: cxx::UniquePtr<ffi::PE_DynamicFixup>) -> Self {
      39            0 :         unsafe {
      40            0 :             let obj_ref = ffi_entry.as_ref().unwrap();
      41            0 :             if ffi::PE_DynamicFixupARM64Kernel::classof(obj_ref) {
      42            0 :                 let raw = {
      43            0 :                     type From = cxx::UniquePtr<ffi::PE_DynamicFixup>;
      44            0 :                     type To = cxx::UniquePtr<ffi::PE_DynamicFixupARM64Kernel>;
      45            0 :                     std::mem::transmute::<From, To>(ffi_entry)
      46            0 :                 };
      47            0 :                 DynamicFixup::ARM64Kernel(ARM64Kernel::from_ffi(raw))
      48            0 :             } else if ffi::PE_DynamicFixupARM64X::classof(obj_ref) {
      49            0 :                 let raw = {
      50            0 :                     type From = cxx::UniquePtr<ffi::PE_DynamicFixup>;
      51            0 :                     type To = cxx::UniquePtr<ffi::PE_DynamicFixupARM64X>;
      52            0 :                     std::mem::transmute::<From, To>(ffi_entry)
      53            0 :                 };
      54            0 :                 DynamicFixup::Arm64X(Arm64X::from_ffi(raw))
      55            0 :             } else if ffi::PE_DynamicFixupControlTransfer::classof(obj_ref) {
      56            0 :                 let raw = {
      57            0 :                     type From = cxx::UniquePtr<ffi::PE_DynamicFixup>;
      58            0 :                     type To = cxx::UniquePtr<ffi::PE_DynamicFixupControlTransfer>;
      59            0 :                     std::mem::transmute::<From, To>(ffi_entry)
      60            0 :                 };
      61            0 :                 DynamicFixup::ControlTransfer(ControlTransfer::from_ffi(raw))
      62            0 :             } else if ffi::PE_DynamicFixupGeneric::classof(obj_ref) {
      63            0 :                 let raw = {
      64            0 :                     type From = cxx::UniquePtr<ffi::PE_DynamicFixup>;
      65            0 :                     type To = cxx::UniquePtr<ffi::PE_DynamicFixupGeneric>;
      66            0 :                     std::mem::transmute::<From, To>(ffi_entry)
      67            0 :                 };
      68            0 :                 DynamicFixup::Generic(Generic::from_ffi(raw))
      69            0 :             } else if ffi::PE_DynamicFixupUnknown::classof(obj_ref) {
      70            0 :                 let raw = {
      71            0 :                     type From = cxx::UniquePtr<ffi::PE_DynamicFixup>;
      72            0 :                     type To = cxx::UniquePtr<ffi::PE_DynamicFixupUnknown>;
      73            0 :                     std::mem::transmute::<From, To>(ffi_entry)
      74            0 :                 };
      75            0 :                 DynamicFixup::Unknown(Unknown::from_ffi(raw))
      76            0 :             } else if ffi::PE_FunctionOverride::classof(obj_ref) {
      77            0 :                 let raw = {
      78            0 :                     type From = cxx::UniquePtr<ffi::PE_DynamicFixup>;
      79            0 :                     type To = cxx::UniquePtr<ffi::PE_FunctionOverride>;
      80            0 :                     std::mem::transmute::<From, To>(ffi_entry)
      81            0 :                 };
      82            0 :                 DynamicFixup::FunctionOverride(FunctionOverride::from_ffi(raw))
      83              :             } else {
      84            0 :                 panic!("unsupported version");
      85              :             }
      86              :         }
      87            0 :     }
      88              : }
      89              : 
      90              : pub trait AsDynamicFixup {
      91              :     #[doc(hidden)]
      92              :     fn as_generic(&self) -> &ffi::PE_DynamicFixup;
      93              : }
      94              : 
      95              : impl std::fmt::Display for DynamicFixup<'_> {
      96            0 :     fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
      97            0 :         match self {
      98            0 :             DynamicFixup::Generic(fixup) => {
      99            0 :                 write!(f, "{}", fixup.as_generic().to_string())
     100              :             }
     101              : 
     102            0 :             DynamicFixup::Arm64X(fixup) => {
     103            0 :                 write!(f, "{}", fixup.as_generic().to_string())
     104              :             }
     105              : 
     106            0 :             DynamicFixup::FunctionOverride(fixup) => {
     107            0 :                 write!(f, "{}", fixup.as_generic().to_string())
     108              :             }
     109              : 
     110            0 :             DynamicFixup::ARM64Kernel(fixup) => {
     111            0 :                 write!(f, "{}", fixup.as_generic().to_string())
     112              :             }
     113              : 
     114            0 :             DynamicFixup::ControlTransfer(fixup) => {
     115            0 :                 write!(f, "{}", fixup.as_generic().to_string())
     116              :             }
     117              : 
     118            0 :             DynamicFixup::Unknown(fixup) => {
     119            0 :                 write!(f, "{}", fixup.as_generic().to_string())
     120              :             }
     121              :         }
     122            0 :     }
     123              : }
     124              : 
     125              : /// This structure represents a generic entry where fixups are regular
     126              : /// relocations: [`crate::pe::Relocation`]
     127              : pub struct Generic<'a> {
     128              :     ptr: cxx::UniquePtr<ffi::PE_DynamicFixupGeneric>,
     129              :     _owner: PhantomData<&'a ffi::PE_DynamicRelocation>,
     130              : }
     131              : 
     132              : impl<'a> FromFFI<ffi::PE_DynamicFixupGeneric> for Generic<'a> {
     133            0 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_DynamicFixupGeneric>) -> Self {
     134            0 :         Self {
     135            0 :             ptr,
     136            0 :             _owner: PhantomData,
     137            0 :         }
     138            0 :     }
     139              : }
     140              : 
     141              : impl AsDynamicFixup for Generic<'_> {
     142            0 :     fn as_generic(&self) -> &ffi::PE_DynamicFixup {
     143            0 :         self.ptr.as_ref().unwrap().as_ref()
     144            0 :     }
     145              : }
     146              : 
     147              : impl std::fmt::Debug for Generic<'_> {
     148            0 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
     149            0 :         f.debug_struct("Generic")
     150            0 :         .finish()
     151            0 :     }
     152              : }
     153              : 
     154              : impl std::fmt::Display for Generic<'_> {
     155            0 :     fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
     156            0 :         write!(f, "{}", self.as_generic().to_string())
     157            0 :     }
     158              : }
     159              : 
     160              : impl Generic<'_> {
     161              :     /// Iterator over the (regular) relocations
     162            0 :     pub fn relocations(&self) -> GenericRelocations {
     163            0 :         GenericRelocations::new(self.ptr.relocations())
     164            0 :     }
     165              : }
     166              : 
     167              : /// This structure represents the [`crate::pe::dynamic_relocation::IMAGE_DYNAMIC_RELOCATION_ARM64X`]
     168              : /// special value
     169              : pub struct Arm64X<'a> {
     170              :     ptr: cxx::UniquePtr<ffi::PE_DynamicFixupARM64X>,
     171              :     _owner: PhantomData<&'a ffi::PE_DynamicRelocation>,
     172              : }
     173              : 
     174              : impl<'a> FromFFI<ffi::PE_DynamicFixupARM64X> for Arm64X<'a> {
     175            0 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_DynamicFixupARM64X>) -> Self {
     176            0 :         Self {
     177            0 :             ptr,
     178            0 :             _owner: PhantomData,
     179            0 :         }
     180            0 :     }
     181              : }
     182              : 
     183              : impl AsDynamicFixup for Arm64X<'_> {
     184            0 :     fn as_generic(&self) -> &ffi::PE_DynamicFixup {
     185            0 :         self.ptr.as_ref().unwrap().as_ref()
     186            0 :     }
     187              : }
     188              : 
     189              : 
     190              : impl std::fmt::Debug for Arm64X<'_> {
     191            0 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
     192            0 :         f.debug_struct("Arm64X")
     193            0 :         .finish()
     194            0 :     }
     195              : }
     196              : 
     197              : impl std::fmt::Display for Arm64X<'_> {
     198            0 :     fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
     199            0 :         write!(f, "{}", self.as_generic().to_string())
     200            0 :     }
     201              : }
     202              : 
     203              : impl Arm64X<'_> {
     204              :     /// Iterator over the relocations
     205            0 :     pub fn relocations(&self) -> Arm64XRelocEntries {
     206            0 :         Arm64XRelocEntries::new(self.ptr.relocations())
     207            0 :     }
     208              : }
     209              : 
     210              : /// Structure that describes a relocation entry for [`Arm64X`]
     211              : pub struct Arm64XRelocEntry<'a> {
     212              :     ptr: cxx::UniquePtr<ffi::PE_DynamicFixupARM64X_entry>,
     213              :     _owner: PhantomData<&'a ffi::PE_DynamicFixupARM64X>,
     214              : }
     215              : 
     216              : impl<'a> FromFFI<ffi::PE_DynamicFixupARM64X_entry> for Arm64XRelocEntry<'a> {
     217            0 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_DynamicFixupARM64X_entry>) -> Self {
     218            0 :         Self {
     219            0 :             ptr,
     220            0 :             _owner: PhantomData,
     221            0 :         }
     222            0 :     }
     223              : }
     224              : 
     225              : 
     226              : pub const ARM64X_RELOC_ZERO_FILL: u32 = 0;
     227              : 
     228              : pub const ARM64X_RELOC_VALUE: u32 = 1;
     229              : 
     230              : pub const ARM64X_RELOC_DELTA: u32 = 2;
     231              : 
     232              : impl Arm64XRelocEntry<'_> {
     233              :     /// RVA where the fixup takes place
     234            0 :     pub fn rva(&self) -> u32 {
     235            0 :         self.ptr.rva()
     236            0 :     }
     237              : 
     238            0 :     pub fn size(&self) -> u32 {
     239            0 :         self.ptr.size()
     240            0 :     }
     241              : 
     242              :     /// If the fixup is [`ARM64X_RELOC_DELTA`], return the associated delta.
     243            0 :     pub fn value(&self) -> Option<i64> {
     244            0 :         if self.kind() != ARM64X_RELOC_DELTA {
     245            0 :             return None;
     246            0 :         }
     247            0 :         Some(self.ptr.value())
     248            0 :     }
     249              : 
     250              : 
     251              :     /// If the fixup is [`ARM64X_RELOC_VALUE`], return the associated bytes.
     252            0 :     pub fn bytes(&self) -> Option<&[u8]> {
     253            0 :         if self.kind() != ARM64X_RELOC_VALUE {
     254            0 :             return None;
     255            0 :         }
     256            0 :         unsafe {
     257            0 :             let raw = self.ptr.get_bytes();
     258            0 :             if raw.size > 0 {
     259            0 :                 return Some(std::slice::from_raw_parts_mut(raw.ptr, raw.size as usize));
     260            0 :             }
     261            0 :             return Some(&[]);
     262              :         }
     263            0 :     }
     264              : 
     265              :     /// Fixup's kind can be either:
     266              :     ///
     267              :     /// - [`ARM64X_RELOC_ZERO_FILL`]
     268              :     /// - [`ARM64X_RELOC_VALUE`]
     269              :     /// - [`ARM64X_RELOC_DELTA`]
     270            0 :     pub fn kind(&self) -> u32 {
     271            0 :         self.ptr.get_type()
     272            0 :     }
     273              : }
     274              : 
     275              : 
     276              : /// This structure represents the
     277              : /// [`crate::pe::dynamic_relocation::IMAGE_DYNAMIC_RELOCATION_FUNCTION_OVERRIDE`] special value
     278              : pub struct FunctionOverride<'a> {
     279              :     ptr: cxx::UniquePtr<ffi::PE_FunctionOverride>,
     280              :     _owner: PhantomData<&'a ffi::PE_DynamicRelocation>,
     281              : }
     282              : 
     283              : impl<'a> FromFFI<ffi::PE_FunctionOverride> for FunctionOverride<'a> {
     284            0 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_FunctionOverride>) -> Self {
     285            0 :         Self {
     286            0 :             ptr,
     287            0 :             _owner: PhantomData,
     288            0 :         }
     289            0 :     }
     290              : }
     291              : 
     292              : impl AsDynamicFixup for FunctionOverride<'_> {
     293            0 :     fn as_generic(&self) -> &ffi::PE_DynamicFixup {
     294            0 :         self.ptr.as_ref().unwrap().as_ref()
     295            0 :     }
     296              : }
     297              : 
     298              : 
     299              : impl std::fmt::Debug for FunctionOverride<'_> {
     300            0 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
     301            0 :         f.debug_struct("FunctionOverride")
     302            0 :         .finish()
     303            0 :     }
     304              : }
     305              : 
     306              : impl std::fmt::Display for FunctionOverride<'_> {
     307            0 :     fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
     308            0 :         write!(f, "{}", self.as_generic().to_string())
     309            0 :     }
     310              : }
     311              : 
     312              : 
     313              : 
     314              : impl FunctionOverride<'_> {
     315              :     /// Iterator over the overriding info
     316            0 :     pub fn func_overriding_info(&self) -> ItFuncOverrideInfo {
     317            0 :         ItFuncOverrideInfo::new(self.ptr.func_overriding_info())
     318            0 :     }
     319              : 
     320              :     /// Find the `IMAGE_BDD_INFO` associated with the given info
     321            0 :     pub fn bdd_info(&self) -> ItImageBddInfo {
     322            0 :         ItImageBddInfo::new(self.ptr.bdd_info())
     323            0 :     }
     324              : 
     325              :     /// Find the `IMAGE_BDD_INFO` at the given offset
     326            0 :     pub fn bdd_info_at(&self, offset: u32) -> Option<ImageBddInfo> {
     327            0 :         into_optional(self.ptr.bdd_info_at(offset))
     328            0 :     }
     329              : 
     330              :     /// Find the `IMAGE_BDD_INFO` associated with the given info
     331            0 :     pub fn bdd_info_for(&self, info: &FunctionOverrideInfo) -> Option<ImageBddInfo> {
     332            0 :         into_optional(self.ptr.bdd_info_for(info.ptr.as_ref().unwrap()))
     333            0 :     }
     334              : }
     335              : 
     336              : /// Mirror `IMAGE_BDD_DYNAMIC_RELOCATION`
     337              : pub struct ImageBddDynamicRelocation<'a> {
     338              :     ptr: cxx::UniquePtr<ffi::PE_FunctionOverride_image_bdd_dynamic_relocation_t>,
     339              :     _owner: PhantomData<&'a ffi::PE_FunctionOverride>,
     340              : }
     341              : 
     342              : impl<'a> FromFFI<ffi::PE_FunctionOverride_image_bdd_dynamic_relocation_t> for ImageBddDynamicRelocation<'a> {
     343            0 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_FunctionOverride_image_bdd_dynamic_relocation_t>) -> Self {
     344            0 :         Self {
     345            0 :             ptr,
     346            0 :             _owner: PhantomData,
     347            0 :         }
     348            0 :     }
     349              : }
     350              : 
     351              : impl ImageBddDynamicRelocation<'_> {
     352            0 :     pub fn left(&self) -> u16 {
     353            0 :         self.ptr.left()
     354            0 :     }
     355              : 
     356            0 :     pub fn right(&self) -> u16 {
     357            0 :         self.ptr.right()
     358            0 :     }
     359              : 
     360            0 :     pub fn value(&self) -> u32 {
     361            0 :         self.ptr.value()
     362            0 :     }
     363              : }
     364              : 
     365              : /// Mirror `IMAGE_BDD_INFO`
     366              : pub struct ImageBddInfo<'a> {
     367              :     ptr: cxx::UniquePtr<ffi::PE_FunctionOverride_image_bdd_info_t>,
     368              :     _owner: PhantomData<&'a ffi::PE_FunctionOverride>,
     369              : }
     370              : 
     371              : impl<'a> FromFFI<ffi::PE_FunctionOverride_image_bdd_info_t> for ImageBddInfo<'a> {
     372            0 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_FunctionOverride_image_bdd_info_t>) -> Self {
     373            0 :         Self {
     374            0 :             ptr,
     375            0 :             _owner: PhantomData,
     376            0 :         }
     377            0 :     }
     378              : }
     379              : 
     380              : impl ImageBddInfo<'_> {
     381            0 :     pub fn version(&self) -> u32 {
     382            0 :         self.ptr.version()
     383            0 :     }
     384              : 
     385            0 :     pub fn original_size(&self) -> u32 {
     386            0 :         self.ptr.original_size()
     387            0 :     }
     388              : 
     389            0 :     pub fn original_offset(&self) -> u32 {
     390            0 :         self.ptr.original_offset()
     391            0 :     }
     392              : 
     393              :     /// If [`ImageBddInfo::version`] is 1
     394            0 :     pub fn payload(&self) -> &[u8] {
     395            0 :         to_slice!(self.ptr.payload());
     396            0 :     }
     397              : 
     398              :     /// If [`ImageBddInfo::version`] is not 1
     399            0 :     pub fn relocations(&self) -> ImageBddDynRelocations {
     400            0 :         ImageBddDynRelocations::new(self.ptr.relocations())
     401            0 :     }
     402              : }
     403              : 
     404              : pub struct FunctionOverrideInfo<'a> {
     405              :     ptr: cxx::UniquePtr<ffi::PE_FunctionOverrideInfo>,
     406              :     _owner: PhantomData<&'a ffi::PE_FunctionOverride>,
     407              : }
     408              : 
     409              : impl<'a> FromFFI<ffi::PE_FunctionOverrideInfo> for FunctionOverrideInfo<'a> {
     410            0 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_FunctionOverrideInfo>) -> Self {
     411            0 :         Self {
     412            0 :             ptr,
     413            0 :             _owner: PhantomData,
     414            0 :         }
     415            0 :     }
     416              : }
     417              : 
     418              : impl FunctionOverrideInfo<'_> {
     419              :     /// RVA of the original function
     420            0 :     pub fn original_rva(&self) -> u32 {
     421            0 :         self.ptr.original_rva()
     422            0 :     }
     423              : 
     424              :     /// Offset into the BDD region
     425            0 :     pub fn bdd_offset(&self) -> u32 {
     426            0 :         self.ptr.bdd_offset()
     427            0 :     }
     428              : 
     429              :     /// Size in bytes taken by RVAs
     430            0 :     pub fn rva_size(&self) -> u32 {
     431            0 :         self.ptr.rva_size()
     432            0 :     }
     433              : 
     434              :     /// Size in bytes taken by BaseRelocs
     435            0 :     pub fn base_reloc_size(&self) -> u32 {
     436            0 :         self.ptr.base_reloc_size()
     437            0 :     }
     438              : 
     439            0 :     pub fn functions_rva(&self) -> Vec<u32> {
     440            0 :         Vec::from(self.ptr.functions_rva().as_slice())
     441            0 :     }
     442              : 
     443            0 :     pub fn relocations(&self) -> FuncOverrideRelocations {
     444            0 :         FuncOverrideRelocations::new(self.ptr.relocations())
     445            0 :     }
     446              : }
     447              : 
     448              : /// This class wraps fixups associated with the (special) symbol value:
     449              : /// [`crate::pe::dynamic_relocation::IMAGE_DYNAMIC_RELOCATION_ARM64_KERNEL_IMPORT_CALL_TRANSFER`].
     450              : pub struct ARM64Kernel<'a> {
     451              :     ptr: cxx::UniquePtr<ffi::PE_DynamicFixupARM64Kernel>,
     452              :     _owner: PhantomData<&'a ffi::PE_DynamicRelocation>,
     453              : }
     454              : 
     455              : impl<'a> FromFFI<ffi::PE_DynamicFixupARM64Kernel> for ARM64Kernel<'a> {
     456            0 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_DynamicFixupARM64Kernel>) -> Self {
     457            0 :         Self {
     458            0 :             ptr,
     459            0 :             _owner: PhantomData,
     460            0 :         }
     461            0 :     }
     462              : }
     463              : 
     464              : impl AsDynamicFixup for ARM64Kernel<'_> {
     465            0 :     fn as_generic(&self) -> &ffi::PE_DynamicFixup {
     466            0 :         self.ptr.as_ref().unwrap().as_ref()
     467            0 :     }
     468              : }
     469              : 
     470              : impl std::fmt::Debug for ARM64Kernel<'_> {
     471            0 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
     472            0 :         f.debug_struct("ARM64Kernel")
     473            0 :         .finish()
     474            0 :     }
     475              : }
     476              : 
     477              : impl std::fmt::Display for ARM64Kernel<'_> {
     478            0 :     fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
     479            0 :         write!(f, "{}", self.as_generic().to_string())
     480            0 :     }
     481              : }
     482              : 
     483              : impl ARM64Kernel<'_> {
     484              :     /// Iterator over the different relocations
     485            0 :     pub fn relocations(&self) -> ARM64KernelEntries {
     486            0 :         ARM64KernelEntries::new(self.ptr.relocations())
     487            0 :     }
     488              : }
     489              : 
     490              : /// Mirror `IMAGE_IMPORT_CONTROL_TRANSFER_ARM64_RELOCATION`
     491              : pub struct ARM64KernelEntry<'a> {
     492              :     ptr: cxx::UniquePtr<ffi::PE_DynamicFixupARM64Kernel_entry>,
     493              :     _owner: PhantomData<&'a ffi::PE_DynamicFixupARM64Kernel>,
     494              : }
     495              : 
     496              : impl<'a> FromFFI<ffi::PE_DynamicFixupARM64Kernel_entry> for ARM64KernelEntry<'a> {
     497            0 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_DynamicFixupARM64Kernel_entry>) -> Self {
     498            0 :         Self {
     499            0 :             ptr,
     500            0 :             _owner: PhantomData,
     501            0 :         }
     502            0 :     }
     503              : }
     504              : 
     505              : impl ARM64KernelEntry<'_> {
     506              :     /// RVA to the call instruction
     507            0 :     pub fn rva(&self) -> u32 {
     508            0 :         self.ptr.rva()
     509            0 :     }
     510              : 
     511              :     /// True if target instruction is a `blr`, false if it's a `br`.
     512            0 :     pub fn indirect_call(&self) -> bool {
     513            0 :         self.ptr.indirect_call()
     514            0 :     }
     515              : 
     516              :     /// Register index used for the indirect call/jump.
     517              :     /// For instance, if the instruction is `br x3`, this index is set to `3`
     518            0 :     pub fn register_index(&self) -> u8 {
     519            0 :         self.ptr.register_index()
     520            0 :     }
     521              : 
     522              :     /// IAT index of the corresponding import. `0x7FFF` is a special value
     523              :     /// indicating no index.
     524            0 :     pub fn iat_index(&self) -> u16 {
     525            0 :         self.ptr.iat_index()
     526            0 :     }
     527              : }
     528              : 
     529              : /// This class wraps fixups associated with the (special) symbol value:
     530              : /// [`crate::pe::dynamic_relocation::IMAGE_DYNAMIC_RELOCATION_GUARD_IMPORT_CONTROL_TRANSFER`].
     531              : pub struct ControlTransfer<'a> {
     532              :     ptr: cxx::UniquePtr<ffi::PE_DynamicFixupControlTransfer>,
     533              :     _owner: PhantomData<&'a ffi::PE_DynamicRelocation>,
     534              : }
     535              : 
     536              : impl<'a> FromFFI<ffi::PE_DynamicFixupControlTransfer> for ControlTransfer<'a> {
     537            0 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_DynamicFixupControlTransfer>) -> Self {
     538            0 :         Self {
     539            0 :             ptr,
     540            0 :             _owner: PhantomData,
     541            0 :         }
     542            0 :     }
     543              : }
     544              : 
     545              : impl AsDynamicFixup for ControlTransfer<'_> {
     546            0 :     fn as_generic(&self) -> &ffi::PE_DynamicFixup {
     547            0 :         self.ptr.as_ref().unwrap().as_ref()
     548            0 :     }
     549              : }
     550              : 
     551              : impl std::fmt::Debug for ControlTransfer<'_> {
     552            0 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
     553            0 :         f.debug_struct("ControlTransfer")
     554            0 :         .finish()
     555            0 :     }
     556              : }
     557              : 
     558              : impl std::fmt::Display for ControlTransfer<'_> {
     559            0 :     fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
     560            0 :         write!(f, "{}", self.as_generic().to_string())
     561            0 :     }
     562              : }
     563              : 
     564              : impl ControlTransfer<'_> {
     565              :     /// Iterator over the relocations
     566            0 :     pub fn relocations(&self) -> ControlTransferEntries {
     567            0 :         ControlTransferEntries::new(self.ptr.relocations())
     568            0 :     }
     569              : }
     570              : 
     571              : /// Mirror `IMAGE_IMPORT_CONTROL_TRANSFER_DYNAMIC_RELOCATION`
     572              : pub struct ControlTransferEntry<'a> {
     573              :     ptr: cxx::UniquePtr<ffi::PE_DynamicFixupControlTransfer_entry>,
     574              :     _owner: PhantomData<&'a ffi::PE_DynamicFixupControlTransfer>,
     575              : }
     576              : 
     577              : impl<'a> FromFFI<ffi::PE_DynamicFixupControlTransfer_entry> for ControlTransferEntry<'a> {
     578            0 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_DynamicFixupControlTransfer_entry>) -> Self {
     579            0 :         Self {
     580            0 :             ptr,
     581            0 :             _owner: PhantomData,
     582            0 :         }
     583            0 :     }
     584              : }
     585              : 
     586              : impl ControlTransferEntry<'_> {
     587              :     /// RVA to the call instruction
     588            0 :     pub fn rva(&self) -> u32 {
     589            0 :         self.ptr.rva()
     590            0 :     }
     591              : 
     592              :     /// True if target instruction is a `call`, false otherwise.
     593            0 :     pub fn is_call(&self) -> bool {
     594            0 :         self.ptr.is_call()
     595            0 :     }
     596              : 
     597              :     /// IAT index of the corresponding import. `0x7FFF` is a special value
     598              :     /// indicating no index.
     599            0 :     pub fn iat_index(&self) -> u16 {
     600            0 :         self.ptr.iat_index()
     601            0 :     }
     602              : }
     603              : 
     604              : 
     605              : /// This class represents an special dynamic relocation where the format of the
     606              : /// fixups is not supported by LIEF.
     607              : pub struct Unknown<'a> {
     608              :     ptr: cxx::UniquePtr<ffi::PE_DynamicFixupUnknown>,
     609              :     _owner: PhantomData<&'a ffi::PE_DynamicRelocation>,
     610              : }
     611              : 
     612              : impl<'a> FromFFI<ffi::PE_DynamicFixupUnknown> for Unknown<'a> {
     613            0 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_DynamicFixupUnknown>) -> Self {
     614            0 :         Self {
     615            0 :             ptr,
     616            0 :             _owner: PhantomData,
     617            0 :         }
     618            0 :     }
     619              : }
     620              : 
     621              : impl AsDynamicFixup for Unknown<'_> {
     622            0 :     fn as_generic(&self) -> &ffi::PE_DynamicFixup {
     623            0 :         self.ptr.as_ref().unwrap().as_ref()
     624            0 :     }
     625              : }
     626              : 
     627              : 
     628              : impl std::fmt::Debug for Unknown<'_> {
     629            0 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
     630            0 :         f.debug_struct("Unknown")
     631            0 :         .finish()
     632            0 :     }
     633              : }
     634              : 
     635              : impl std::fmt::Display for Unknown<'_> {
     636            0 :     fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
     637            0 :         write!(f, "{}", self.as_generic().to_string())
     638            0 :     }
     639              : }
     640              : 
     641              : impl Unknown<'_> {
     642            0 :     pub fn payload(&self) -> &[u8] {
     643            0 :         to_slice!(self.ptr.payload());
     644            0 :     }
     645              : }
     646              : 
     647            0 : declare_iterator!(
     648            0 :     ARM64KernelEntries,
     649            0 :     ARM64KernelEntry<'a>,
     650            0 :     ffi::PE_DynamicFixupARM64Kernel_entry,
     651            0 :     ffi::PE_DynamicFixupARM64Kernel,
     652            0 :     ffi::PE_DynamicFixupARM64Kernel_it_relocations
     653            0 : );
     654              : 
     655            0 : declare_iterator!(
     656            0 :     Arm64XRelocEntries,
     657            0 :     Arm64XRelocEntry<'a>,
     658            0 :     ffi::PE_DynamicFixupARM64X_entry,
     659            0 :     ffi::PE_DynamicFixupARM64X,
     660            0 :     ffi::PE_DynamicFixupARM64X_it_relocations
     661            0 : );
     662              : 
     663            0 : declare_iterator!(
     664            0 :     ControlTransferEntries,
     665            0 :     ControlTransferEntry<'a>,
     666            0 :     ffi::PE_DynamicFixupControlTransfer_entry,
     667            0 :     ffi::PE_DynamicFixupControlTransfer,
     668            0 :     ffi::PE_DynamicFixupControlTransfer_it_relocations
     669            0 : );
     670              : 
     671            0 : declare_iterator!(
     672            0 :     GenericRelocations,
     673            0 :     Relocation<'a>,
     674            0 :     ffi::PE_Relocation,
     675            0 :     ffi::PE_DynamicFixupGeneric,
     676            0 :     ffi::PE_DynamicFixupGeneric_it_relocations
     677            0 : );
     678              : 
     679            0 : declare_fwd_iterator!(
     680            0 :     ImageBddDynRelocations,
     681            0 :     ImageBddDynamicRelocation<'a>,
     682            0 :     ffi::PE_FunctionOverride_image_bdd_dynamic_relocation_t,
     683            0 :     ffi::PE_FunctionOverride_image_bdd_info_t,
     684            0 :     ffi::PE_FunctionOverride_image_bdd_info_t_it_relocations
     685            0 : );
     686              : 
     687            0 : declare_iterator!(
     688            0 :     FuncOverrideRelocations,
     689            0 :     Relocation<'a>,
     690            0 :     ffi::PE_Relocation,
     691            0 :     ffi::PE_FunctionOverrideInfo,
     692            0 :     ffi::PE_FunctionOverrideInfo_it_relocations
     693            0 : );
     694              : 
     695            0 : declare_iterator!(
     696            0 :     ItFuncOverrideInfo,
     697            0 :     FunctionOverrideInfo<'a>,
     698            0 :     ffi::PE_FunctionOverrideInfo,
     699            0 :     ffi::PE_FunctionOverride,
     700            0 :     ffi::PE_FunctionOverride_it_func_overriding_info
     701            0 : );
     702              : 
     703            0 : declare_iterator!(
     704            0 :     ItImageBddInfo,
     705            0 :     ImageBddInfo<'a>,
     706            0 :     ffi::PE_FunctionOverride_image_bdd_info_t,
     707            0 :     ffi::PE_FunctionOverride,
     708            0 :     ffi::PE_FunctionOverride_it_bdd_info
     709            0 : );
     710              : 
     711              : 
     712              : 
        

Generated by: LCOV version 2.1-1