LCOV - code coverage report
Current view: top level - src - generic.rs (source / functions) Coverage Total Hit
Test: lief.lcov Lines: 66.3 % 95 63
Test Date: 2024-11-30:00:00:00 Functions: 44.6 % 92 41

            Line data    Source code
       1              : use lief_ffi as ffi;
       2              : use crate::{to_slice, declare_fwd_iterator};
       3              : use crate::common::{into_optional, FromFFI};
       4              : use crate::assembly::Instructions;
       5              : 
       6              : use std::pin::Pin;
       7              : 
       8              : /// Trait shared by all the symbols in executable formats
       9              : pub trait Symbol {
      10              :     #[doc(hidden)]
      11              :     fn as_generic(&self) -> &ffi::AbstractSymbol;
      12              : 
      13              :     /// Symbol's name
      14       493710 :     fn name(&self) -> String {
      15       493710 :         self.as_generic().name().to_string()
      16       493710 :     }
      17              :     /// Symbol's value whose interpretation depends on the symbol's kind.
      18              :     /// Usually this is the address of the symbol though.
      19       451630 :     fn value(&self) -> u64 {
      20       451630 :         self.as_generic().value()
      21       451630 :     }
      22              :     /// Size of the symbol (can be 0)
      23       451630 :     fn size(&self) -> u64 {
      24       451630 :         self.as_generic().size()
      25       451630 :     }
      26              : }
      27              : 
      28              : impl std::fmt::Debug for &dyn Symbol {
      29       443860 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
      30       443860 :         f.debug_struct("Symbol")
      31       443860 :             .field("name", &self.name())
      32       443860 :             .field("value", &self.value())
      33       443860 :             .field("size", &self.size())
      34       443860 :             .finish()
      35       443860 :     }
      36              : }
      37              : 
      38              : /// Trait shared by all the sections in executable formats
      39              : pub trait Section {
      40              :     #[doc(hidden)]
      41              :     fn as_generic(&self) -> &ffi::AbstractSection;
      42              : 
      43              :     /// Name of the section
      44       229180 :     fn name(&self) -> String {
      45       229180 :         self.as_generic().name().to_string()
      46       229180 :     }
      47              : 
      48              :     /// Size of the section **in the file**
      49       227260 :     fn size(&self) -> u64 {
      50       227260 :         self.as_generic().size()
      51       227260 :     }
      52              : 
      53              :     /// Offset of the section **in the file**
      54       227190 :     fn offset(&self) -> u64 {
      55       227190 :         self.as_generic().offset()
      56       227190 :     }
      57              : 
      58              :     /// Address of the section **in memory**
      59       227190 :     fn virtual_address(&self) -> u64 {
      60       227190 :         self.as_generic().virtual_address()
      61       227190 :     }
      62              : 
      63              :     /// Content of the section
      64            0 :     fn content(&self) -> &[u8] {
      65            0 :         to_slice!(self.as_generic().content());
      66            0 :     }
      67              : }
      68              : 
      69              : impl std::fmt::Debug for &dyn Section {
      70       225200 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
      71       225200 :         f.debug_struct("Section")
      72       225200 :             .field("name", &self.name())
      73       225200 :             .field("size", &self.size())
      74       225200 :             .field("offset", &self.offset())
      75       225200 :             .field("virtual_address", &self.virtual_address())
      76       225200 :             .finish()
      77       225200 :     }
      78              : }
      79              : 
      80              : pub trait Relocation {
      81              :     #[doc(hidden)]
      82              :     fn as_generic(&self) -> &ffi::AbstractRelocation;
      83              : 
      84              :     /// Address where the relocation should take place
      85      1421480 :     fn address(&self) -> u64 {
      86      1421480 :         self.as_generic().address()
      87      1421480 :     }
      88              : 
      89              :     /// Size of the relocation
      90      1421480 :     fn size(&self) -> u64 {
      91      1421480 :         self.as_generic().size()
      92      1421480 :     }
      93              : }
      94              : 
      95              : impl std::fmt::Debug for &dyn Relocation {
      96      1421480 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
      97      1421480 :         f.debug_struct("Relocation")
      98      1421480 :             .field("address", &self.address())
      99      1421480 :             .field("size", &self.size())
     100      1421480 :             .finish()
     101      1421480 :     }
     102              : }
     103              : 
     104              : pub trait Binary {
     105              :     #[doc(hidden)]
     106              :     fn as_generic(&self) -> &ffi::AbstractBinary;
     107              : 
     108              :     #[doc(hidden)]
     109              :     fn as_pin_mut_generic(&mut self) -> Pin<&mut ffi::AbstractBinary>;
     110              : 
     111              :     /// Binary's entrypoint
     112           30 :     fn entrypoint(&self) -> u64 {
     113           30 :         self.as_generic().entrypoint()
     114           30 :     }
     115              : 
     116              :     /// Default base address where the binary should be mapped
     117            8 :     fn imagebase(&self) -> u64 {
     118            8 :         self.as_generic().imagebase()
     119            8 :     }
     120              : 
     121              :     /// Whether the current binary is **an executable** and **position independent**
     122            8 :     fn is_pie(&self) -> bool {
     123            8 :         self.as_generic().is_pie()
     124            8 :     }
     125              : 
     126              :     /// Whether the binary defines a non-executable stack
     127            8 :     fn has_nx(&self) -> bool {
     128            8 :         self.as_generic().has_nx()
     129            8 :     }
     130              : 
     131              :     /// Original file size of the binary
     132            8 :     fn original_size(&self) -> u64 {
     133            8 :         self.as_generic().original_size()
     134            8 :     }
     135              : 
     136              :     /// Return the debug info if present. It can be either a
     137              :     /// [`crate::pdb::DebugInfo`] or [`crate::dwarf::DebugInfo`].
     138              :     ///
     139              :     /// For ELF and Mach-O binaries, it returns the given DebugInfo object **only**
     140              :     /// if the binary embeds the DWARF debug info in the binary itself.
     141              :     ///
     142              :     /// For PE file, this function tries to find the **external** PDB using
     143              :     /// the [`crate::pe::debug::CodeViewPDB::filename`] output (if present). One can also
     144              :     /// use [`crate::pdb::load`] or [`crate::pdb::DebugInfo::from`] to get PDB debug
     145              :     /// info.
     146              :     ///
     147              :     /// <div class="warning">
     148              :     /// This function requires LIEF's extended version otherwise it always return `None`
     149              :     /// </div>
     150            0 :     fn debug_info(&self) -> Option<crate::DebugInfo> {
     151            0 :         into_optional(self.as_generic().debug_info())
     152            0 :     }
     153              : 
     154              :     /// Disassemble code starting a the given virtual address and with the given
     155              :     /// size.
     156              :     ///
     157              :     /// ```
     158              :     /// let insts = binary.disassemble(0xacde, 100);
     159              :     /// for inst in insts {
     160              :     ///     println!("{}", inst.to_string());
     161              :     /// }
     162              :     /// ```
     163              :     ///
     164              :     /// See also [`crate::assembly::Instruction`] and [`crate::assembly::Instructions`]
     165            0 :     fn disassemble(&self, address: u64, size: u64) -> InstructionsIt {
     166            0 :         InstructionsIt::new(self.as_generic().disassemble(address, size))
     167            0 :     }
     168              : 
     169              :     /// Disassemble code for the given symbol name
     170              :     ///
     171              :     /// ```
     172              :     /// let insts = binary.disassemble_symbol("__libc_start_main");
     173              :     /// for inst in insts {
     174              :     ///     println!("{}", inst.to_string());
     175              :     /// }
     176              :     /// ```
     177              :     ///
     178              :     /// See also [`crate::assembly::Instruction`] and [`crate::assembly::Instructions`]
     179            0 :     fn disassemble_symbol(&self, name: &str) -> InstructionsIt {
     180            0 :         InstructionsIt::new(self.as_generic().disassemble_function(name.to_string()))
     181            0 :     }
     182              : 
     183              :     /// Disassemble code at the given virtual address
     184              :     ///
     185              :     /// ```
     186              :     /// let insts = binary.disassemble_address(0xacde);
     187              :     /// for inst in insts {
     188              :     ///     println!("{}", inst.to_string());
     189              :     /// }
     190              :     /// ```
     191              :     ///
     192              :     /// See also [`crate::assembly::Instruction`] and [`crate::assembly::Instructions`]
     193            0 :     fn disassemble_address(&self, address: u64) -> InstructionsIt {
     194            0 :         InstructionsIt::new(self.as_generic().disassemble_address(address))
     195            0 :     }
     196              : 
     197              :     /// Disassemble code provided by the given slice at the specified `address` parameter.
     198              :     ///
     199              :     /// See also [`crate::assembly::Instruction`] and [`crate::assembly::Instructions`]
     200            0 :     fn disassemble_slice(&self, slice: &[u8], address: u64) -> InstructionsIt {
     201            0 :         unsafe {
     202            0 :             InstructionsIt::new(self.as_generic().disassemble_buffer(
     203            0 :                     slice.as_ptr(), slice.len().try_into().unwrap(),
     204            0 :                     address))
     205            0 :         }
     206            0 :     }
     207              : 
     208              :     /// Assemble **and patch** the provided assembly code at the specified address.
     209              :     ///
     210              :     /// The generated assembly is returned by the function
     211              :     ///
     212              :     /// ```
     213              :     /// let mut bin = get_binary();
     214              :     ///
     215              :     /// let Vec<u8> bytes = bin.assemble(0x12000440, r#"
     216              :     /// xor rax, rbx;
     217              :     /// mov rcx, rax;
     218              :     /// "#);
     219              :     /// ```
     220            0 :     fn assemble(&mut self, address: u64, asm: &str) -> Vec<u8> {
     221            0 :         Vec::from(self.as_pin_mut_generic().assemble(address, asm).as_slice())
     222            0 :     }
     223              : }
     224              : 
     225              : pub trait DebugInfo {
     226              :     #[doc(hidden)]
     227              :     fn as_generic(&self) -> &ffi::AbstracDebugInfo;
     228              : }
     229              : 
     230            0 : declare_fwd_iterator!(
     231            0 :     InstructionsIt,
     232            0 :     Instructions,
     233            0 :     ffi::asm_Instruction,
     234            0 :     ffi::AbstractBinary,
     235            0 :     ffi::AbstractBinary_it_instructions
     236            0 : );
        

Generated by: LCOV version 2.1-1