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-02-23: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        21830 :     pub fn virtual_address(&self) -> u32 {
      20        21830 :         self.ptr.virtual_address()
      21        21830 :     }
      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        21830 :     pub fn block_size(&self) -> u32 {
      26        21830 :         self.ptr.block_size()
      27        21830 :     }
      28              :     /// Iterator over the Relocation [`Entry`]
      29        21830 :     pub fn entries(&self) -> RelocationEntries {
      30        21830 :         RelocationEntries::new(self.ptr.entries())
      31        21830 :     }
      32              : }
      33              : 
      34              : impl std::fmt::Debug for Relocation<'_> {
      35        21830 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
      36        21830 :         f.debug_struct("Relocation")
      37        21830 :             .field("virtual_address", &self.virtual_address())
      38        21830 :             .field("block_size", &self.block_size())
      39        21830 :             .finish()
      40        21830 :     }
      41              : }
      42              : 
      43              : impl<'a> FromFFI<ffi::PE_Relocation> for Relocation<'a> {
      44        21830 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_Relocation>) -> Self {
      45        21830 :         Relocation {
      46        21830 :             ptr,
      47        21830 :             _owner: PhantomData,
      48        21830 :         }
      49        21830 :     }
      50              : }
      51              : 
      52              : 
      53              : #[allow(non_camel_case_types)]
      54      2247900 : #[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      2247900 :     fn from(value: u32) -> Self {
      77      2247900 :         match value {
      78        10850 :             0x00000000 => BaseType::ABS,
      79            0 :             0x00000001 => BaseType::HIGH,
      80            0 :             0x00000002 => BaseType::LOW,
      81      1224240 :             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      1012810 :             0x0000000a => BaseType::DIR64,
      93            0 :             0x0000000b => BaseType::HIGH3ADJ,
      94            0 :             _ => BaseType::UNKNOWN(value),
      95              :         }
      96      2247900 :     }
      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      4495800 :     fn as_generic(&self) -> &ffi::AbstractRelocation {
     132      4495800 :         self.ptr.as_ref().unwrap().as_ref()
     133      4495800 :     }
     134              : }
     135              : 
     136              : impl Entry<'_> {
     137              :     /// Offset relative to [`Relocation::virtual_address`] where the relocation occurs.
     138      2247900 :     pub fn position(&self) -> u64 {
     139      2247900 :         self.ptr.position()
     140      2247900 :     }
     141              : 
     142              :     /// Type of the relocation
     143      2247900 :     pub fn get_type(&self) -> BaseType {
     144      2247900 :         BaseType::from(self.ptr.get_type())
     145      2247900 :     }
     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      2247900 :     pub fn data(&self) -> u16 {
     151      2247900 :         self.ptr.data()
     152      2247900 :     }
     153              : }
     154              : 
     155              : impl std::fmt::Debug for Entry<'_> {
     156      2247900 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
     157      2247900 :         let base = self as &dyn generic::Relocation;
     158      2247900 :         f.debug_struct("RelocationEntry")
     159      2247900 :             .field("base", &base)
     160      2247900 :             .field("type", &self.get_type())
     161      2247900 :             .field("data", &self.data())
     162      2247900 :             .field("position", &self.position())
     163      2247900 :             .finish()
     164      2247900 :     }
     165              : }
     166              : 
     167              : impl<'a> FromFFI<ffi::PE_RelocationEntry> for Entry<'a> {
     168      2247900 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_RelocationEntry>) -> Self {
     169      2247900 :         Entry {
     170      2247900 :             ptr,
     171      2247900 :             _owner: PhantomData,
     172      2247900 :         }
     173      2247900 :     }
     174              : }
     175              : 
     176      2247900 : declare_iterator!(
     177      2247900 :     RelocationEntries,
     178      2247900 :     Entry<'a>,
     179      2247900 :     ffi::PE_RelocationEntry,
     180      2247900 :     ffi::PE_Relocation,
     181      2247900 :     ffi::PE_Relocation_it_entries
     182      2247900 : );
     183        21830 : declare_iterator!(
     184        21830 :     Relocations,
     185        21830 :     Relocation<'a>,
     186        21830 :     ffi::PE_Relocation,
     187        21830 :     ffi::PE_Binary,
     188        21830 :     ffi::PE_Binary_it_relocations
     189        21830 : );
        

Generated by: LCOV version 2.1-1