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

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

Generated by: LCOV version 2.1-1