LCOV - code coverage report
Current view: top level - src/pe - relocation.rs (source / functions) Coverage Total Hit
Test: lief.lcov Lines: 67.0 % 103 69
Test Date: 2025-06-24:00:00:00 Functions: 78.9 % 19 15

            Line data    Source code
       1              : //! This module includes the different structures related to the relocation process in a PE binary
       2              : 
       3              : use std::marker::PhantomData;
       4              : 
       5              : use lief_ffi as ffi;
       6              : 
       7              : use crate::common::FromFFI;
       8              : use crate::{declare_iterator, generic};
       9              : 
      10              : /// Class which represents the *Base Relocation Block*
      11              : /// We usually find this structure in the `.reloc` section
      12              : pub struct Relocation<'a> {
      13              :     ptr: cxx::UniquePtr<ffi::PE_Relocation>,
      14              :     _owner: PhantomData<&'a ffi::PE_Binary>,
      15              : }
      16              : 
      17              : impl Relocation<'_> {
      18              :     /// The RVA for which the offset of the relocation entries is added
      19        26196 :     pub fn virtual_address(&self) -> u32 {
      20        26196 :         self.ptr.virtual_address()
      21        26196 :     }
      22              : 
      23              :     /// The total number of bytes in the base relocation block.
      24              :     /// `block_size = sizeof(BaseRelocationBlock) + nb_of_relocs * sizeof(uint16_t = RelocationEntry)`
      25        26196 :     pub fn block_size(&self) -> u32 {
      26        26196 :         self.ptr.block_size()
      27        26196 :     }
      28              :     /// Iterator over the Relocation [`Entry`]
      29        26196 :     pub fn entries(&self) -> RelocationEntries {
      30        26196 :         RelocationEntries::new(self.ptr.entries())
      31        26196 :     }
      32              : }
      33              : 
      34              : impl std::fmt::Debug for Relocation<'_> {
      35        26196 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
      36        26196 :         f.debug_struct("Relocation")
      37        26196 :             .field("virtual_address", &self.virtual_address())
      38        26196 :             .field("block_size", &self.block_size())
      39        26196 :             .finish()
      40        26196 :     }
      41              : }
      42              : 
      43              : impl<'a> FromFFI<ffi::PE_Relocation> for Relocation<'a> {
      44        26196 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_Relocation>) -> Self {
      45        26196 :         Relocation {
      46        26196 :             ptr,
      47        26196 :             _owner: PhantomData,
      48        26196 :         }
      49        26196 :     }
      50              : }
      51              : 
      52              : 
      53              : #[allow(non_camel_case_types)]
      54      2697480 : #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
      55              : pub enum BaseType {
      56              :     ABS,
      57              :     HIGH,
      58              :     LOW,
      59              :     HIGHLOW,
      60              :     HIGHADJ,
      61              :     MIPS_JMPADDR,
      62              :     ARM_MOV32,
      63              :     RISCV_HI20,
      64              :     SECTION,
      65              :     THUMB_MOV32,
      66              :     RISCV_LOW12I,
      67              :     RISCV_LOW12S,
      68              :     LOONARCH_MARK_LA,
      69              :     MIPS_JMPADDR16,
      70              :     DIR64,
      71              :     HIGH3ADJ,
      72              :     UNKNOWN(u32),
      73              : }
      74              : 
      75              : impl From<u32> for BaseType {
      76      2697480 :     fn from(value: u32) -> Self {
      77      2697480 :         match value {
      78        13020 :             0x00000000 => BaseType::ABS,
      79            0 :             0x00000001 => BaseType::HIGH,
      80            0 :             0x00000002 => BaseType::LOW,
      81      1469088 :             0x00000003 => BaseType::HIGHLOW,
      82            0 :             0x00000004 => BaseType::HIGHADJ,
      83            0 :             0x00000105 => BaseType::MIPS_JMPADDR,
      84            0 :             0x00000205 => BaseType::ARM_MOV32,
      85            0 :             0x00000405 => BaseType::RISCV_HI20,
      86            0 :             0x00000006 => BaseType::SECTION,
      87            0 :             0x00000807 => BaseType::THUMB_MOV32,
      88            0 :             0x00001007 => BaseType::RISCV_LOW12I,
      89            0 :             0x00002008 => BaseType::RISCV_LOW12S,
      90            0 :             0x00004008 => BaseType::LOONARCH_MARK_LA,
      91            0 :             0x00000009 => BaseType::MIPS_JMPADDR16,
      92      1215372 :             0x0000000a => BaseType::DIR64,
      93            0 :             0x0000000b => BaseType::HIGH3ADJ,
      94            0 :             _ => BaseType::UNKNOWN(value),
      95              :         }
      96      2697480 :     }
      97              : }
      98              : impl From<BaseType> for u32 {
      99            0 :     fn from(value: BaseType) -> u32 {
     100            0 :         match value {
     101            0 :             BaseType::ABS => 0x00000000,
     102            0 :             BaseType::HIGH => 0x00000001,
     103            0 :             BaseType::LOW => 0x00000002,
     104            0 :             BaseType::HIGHLOW => 0x00000003,
     105            0 :             BaseType::HIGHADJ => 0x00000004,
     106            0 :             BaseType::MIPS_JMPADDR => 0x00000105,
     107            0 :             BaseType::ARM_MOV32 => 0x00000205,
     108            0 :             BaseType::RISCV_HI20 => 0x00000405,
     109            0 :             BaseType::SECTION => 0x00000006,
     110            0 :             BaseType::THUMB_MOV32 => 0x00000807,
     111            0 :             BaseType::RISCV_LOW12I => 0x00001007,
     112            0 :             BaseType::RISCV_LOW12S => 0x00002008,
     113            0 :             BaseType::LOONARCH_MARK_LA => 0x00004008,
     114            0 :             BaseType::MIPS_JMPADDR16 => 0x00000009,
     115            0 :             BaseType::DIR64 => 0x0000000a,
     116            0 :             BaseType::HIGH3ADJ => 0x0000000b,
     117            0 :             BaseType::UNKNOWN(value) => value,
     118              :         }
     119            0 :     }
     120              : }
     121              : 
     122              : /// Class which represents an entry in the relocation table
     123              : ///
     124              : /// It implements the [`generic::Relocation`] trait which provides additional functions
     125              : pub struct Entry<'a> {
     126              :     ptr: cxx::UniquePtr<ffi::PE_RelocationEntry>,
     127              :     _owner: PhantomData<&'a ffi::PE_Relocation>,
     128              : }
     129              : 
     130              : impl generic::Relocation for Entry<'_> {
     131      5394960 :     fn as_generic(&self) -> &ffi::AbstractRelocation {
     132      5394960 :         self.ptr.as_ref().unwrap().as_ref()
     133      5394960 :     }
     134              : }
     135              : 
     136              : impl Entry<'_> {
     137              :     /// Offset relative to [`Relocation::virtual_address`] where the relocation occurs.
     138      2697480 :     pub fn position(&self) -> u64 {
     139      2697480 :         self.ptr.position()
     140      2697480 :     }
     141              : 
     142              :     /// Type of the relocation
     143      2697480 :     pub fn get_type(&self) -> BaseType {
     144      2697480 :         BaseType::from(self.ptr.get_type())
     145      2697480 :     }
     146              : 
     147              :     /// Raw data of the relocation:
     148              :     /// - The **high** 4 bits store the relocation type
     149              :     /// - The **low** 12 bits store the relocation offset
     150      2697480 :     pub fn data(&self) -> u16 {
     151      2697480 :         self.ptr.data()
     152      2697480 :     }
     153              : }
     154              : 
     155              : impl std::fmt::Debug for Entry<'_> {
     156      2697480 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
     157      2697480 :         let base = self as &dyn generic::Relocation;
     158      2697480 :         f.debug_struct("RelocationEntry")
     159      2697480 :             .field("base", &base)
     160      2697480 :             .field("type", &self.get_type())
     161      2697480 :             .field("data", &self.data())
     162      2697480 :             .field("position", &self.position())
     163      2697480 :             .finish()
     164      2697480 :     }
     165              : }
     166              : 
     167              : impl<'a> FromFFI<ffi::PE_RelocationEntry> for Entry<'a> {
     168      2697480 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_RelocationEntry>) -> Self {
     169      2697480 :         Entry {
     170      2697480 :             ptr,
     171      2697480 :             _owner: PhantomData,
     172      2697480 :         }
     173      2697480 :     }
     174              : }
     175              : 
     176      2697480 : declare_iterator!(
     177      2697480 :     RelocationEntries,
     178      2697480 :     Entry<'a>,
     179      2697480 :     ffi::PE_RelocationEntry,
     180      2697480 :     ffi::PE_Relocation,
     181      2697480 :     ffi::PE_Relocation_it_entries
     182      2697480 : );
     183        26196 : declare_iterator!(
     184        26196 :     Relocations,
     185        26196 :     Relocation<'a>,
     186        26196 :     ffi::PE_Relocation,
     187        26196 :     ffi::PE_Binary,
     188        26196 :     ffi::PE_Binary_it_relocations
     189        26196 : );
        

Generated by: LCOV version 2.1-1