LCOV - code coverage report
Current view: top level - src/coff - section.rs (source / functions) Coverage Total Hit
Test: lief.lcov Lines: 76.4 % 110 84
Test Date: 2026-04-12:00:00:00 Functions: 80.0 % 25 20

            Line data    Source code
       1              : //! COFF section module
       2              : 
       3              : use super::Relocation;
       4              : use super::Symbol;
       5              : use crate::coff;
       6              : use crate::common::into_optional;
       7              : use crate::common::FromFFI;
       8              : use crate::declare_iterator;
       9              : use crate::generic;
      10              : use crate::pe;
      11              : use std::marker::PhantomData;
      12              : use std::pin::Pin;
      13              : 
      14              : use lief_ffi as ffi;
      15              : 
      16              : pub struct Section<'a> {
      17              :     ptr: cxx::UniquePtr<ffi::COFF_Section>,
      18              :     _owner: PhantomData<&'a ffi::COFF_Binary>,
      19              : }
      20              : 
      21              : impl FromFFI<ffi::COFF_Section> for Section<'_> {
      22        25571 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::COFF_Section>) -> Self {
      23        25571 :         Self {
      24        25571 :             ptr,
      25        25571 :             _owner: PhantomData,
      26        25571 :         }
      27        25571 :     }
      28              : }
      29              : 
      30              : impl Section<'_> {
      31              :     /// Return the size of the data in the section.
      32        13455 :     pub fn sizeof_raw_data(&self) -> u32 {
      33        13455 :         self.ptr.sizeof_raw_data()
      34        13455 :     }
      35              : 
      36              :     /// Return the size of the data when mapped in memory (should be 0)
      37        13455 :     pub fn virtual_size(&self) -> u32 {
      38        13455 :         self.ptr.virtual_size()
      39        13455 :     }
      40              : 
      41              :     /// Offset to the section's content
      42        13455 :     pub fn pointerto_raw_data(&self) -> u32 {
      43        13455 :         self.ptr.pointerto_raw_data()
      44        13455 :     }
      45              : 
      46              :     /// Offset to the relocation table
      47        13455 :     pub fn pointerto_relocation(&self) -> u32 {
      48        13455 :         self.ptr.pointerto_relocation()
      49        13455 :     }
      50              : 
      51              :     /// The file pointer to the beginning of line-number entries for the section.
      52              :     ///
      53              :     /// This is set to zero if there are no COFF line numbers.
      54              :     /// This value should be zero for an image because COFF debugging information
      55              :     /// is deprecated and modern debug information relies on the PDB files.
      56        13455 :     pub fn pointerto_line_numbers(&self) -> u32 {
      57        13455 :         self.ptr.pointerto_line_numbers()
      58        13455 :     }
      59              : 
      60              :     /// Number of relocations.
      61              :     ///
      62              :     /// <div class="warning">
      63              :     /// If the number of relocations is greater than 0xFFFF (maximum value for 16-bits integer),
      64              :     /// then the number of relocations is stored in the virtual address attribute.
      65              :     /// </div>
      66        13455 :     pub fn numberof_relocations(&self) -> u16 {
      67        13455 :         self.ptr.numberof_relocations()
      68        13455 :     }
      69              : 
      70              :     /// Number of line number entries (if any).
      71        13455 :     pub fn numberof_line_numbers(&self) -> u16 {
      72        13455 :         self.ptr.numberof_line_numbers()
      73        13455 :     }
      74              : 
      75              :     /// Characteristics of the section: it provides information about
      76              :     /// the permissions of the section when mapped. It can also provide
      77              :     /// information about the *purpose* of the section (contain code, BSS-like, ...)
      78        13455 :     pub fn characteristics(&self) -> pe::section::Characteristics {
      79        13455 :         pe::section::Characteristics::from(self.ptr.characteristics())
      80        13455 :     }
      81              : 
      82              :     /// True if the section can be discarded as needed.
      83              :     ///
      84              :     /// This is typically the case for debug-related sections
      85            0 :     pub fn is_discardable(&self) -> bool {
      86            0 :         self.ptr.is_discardable()
      87            0 :     }
      88              : 
      89              :     /// Whether there is a large number of relocations whose number need to be stored in the
      90              :     /// virtual address attribute
      91            0 :     pub fn has_extended_relocations(&self) -> bool {
      92            0 :         self.ptr.has_extended_relocations()
      93            0 :     }
      94              : 
      95              :     /// Iterator over the relocations associated with this section
      96         4355 :     pub fn relocations(&self) -> Relocations<'_> {
      97         4355 :         Relocations::new(self.ptr.relocations())
      98         4355 :     }
      99              : 
     100              :     /// Iterator over the symbols associated with this section
     101         4355 :     pub fn symbols(&self) -> Symbols<'_> {
     102         4355 :         Symbols::new(self.ptr.symbols())
     103         4355 :     }
     104              : 
     105              :     /// Return comdat information (only if the section has the
     106              :     /// [`crate::pe::section::Characteristics::LNK_COMDAT`] characteristic)
     107         4355 :     pub fn comdat_info(&self) -> Option<ComdatInfo<'_>> {
     108         4355 :         into_optional(self.ptr.comdat_info())
     109         4355 :     }
     110              : 
     111              :     /// Return the COFF string associated with the section's name (or a None)
     112              :     ///
     113              :     /// This coff string is usually present for long section names whose length
     114              :     /// does not fit in the 8 bytes allocated by the COFF format.
     115            0 :     pub fn coff_string(&self) -> Option<coff::String<'_>> {
     116            0 :         into_optional(self.ptr.coff_string())
     117            0 :     }
     118              : }
     119              : 
     120              : impl generic::Section for Section<'_> {
     121        65936 :     fn as_generic(&self) -> &ffi::AbstractSection {
     122        65936 :         self.ptr.as_ref().unwrap().as_ref()
     123        65936 :     }
     124              : 
     125            0 :     fn as_generic_mut(&mut self) -> Pin<&mut ffi::AbstractSection> {
     126            0 :         unsafe {
     127            0 :             Pin::new_unchecked({
     128            0 :                 (self.ptr.as_ref().unwrap().as_ref() as *const ffi::AbstractSection
     129            0 :                     as *mut ffi::AbstractSection)
     130            0 :                     .as_mut()
     131            0 :                     .unwrap()
     132            0 :             })
     133            0 :         }
     134            0 :     }
     135              : }
     136              : 
     137              : impl std::fmt::Debug for Section<'_> {
     138        13455 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
     139        13455 :         let base = self as &dyn generic::Section;
     140        13455 :         f.debug_struct("Section")
     141        13455 :             .field("base", &base)
     142        13455 :             .field("sizeof_raw_data", &self.sizeof_raw_data())
     143        13455 :             .field("virtual_size", &self.virtual_size())
     144        13455 :             .field("pointerto_raw_data", &self.pointerto_raw_data())
     145        13455 :             .field("pointerto_relocation", &self.pointerto_relocation())
     146        13455 :             .field("pointerto_line_numbers", &self.pointerto_line_numbers())
     147        13455 :             .field("numberof_relocations", &self.numberof_relocations())
     148        13455 :             .field("numberof_line_numbers", &self.numberof_line_numbers())
     149        13455 :             .field("characteristics", &self.characteristics())
     150        13455 :             .finish()
     151        13455 :     }
     152              : }
     153              : 
     154              : impl std::fmt::Display for Section<'_> {
     155        13455 :     fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
     156        13455 :         write!(f, "{}", self.ptr.to_string())
     157        13455 :     }
     158              : }
     159              : 
     160              : /// This structure wraps comdat information which is composed of the symbol
     161              : /// associated with the comdat section and its selection flag
     162              : pub struct ComdatInfo<'a> {
     163              :     ptr: cxx::UniquePtr<ffi::COFF_Section_ComdataInfo>,
     164              :     _owner: PhantomData<&'a ffi::COFF_Binary>,
     165              : }
     166              : 
     167              : impl ComdatInfo<'_> {
     168         2795 :     pub fn symbol(&self) -> Option<Symbol<'_>> {
     169         2795 :         into_optional(self.ptr.symbol())
     170         2795 :     }
     171              : 
     172         2795 :     pub fn kind(&self) -> coff::symbol::ComdatSelection {
     173         2795 :         coff::symbol::ComdatSelection::from(self.ptr.kind())
     174         2795 :     }
     175              : }
     176              : 
     177              : impl FromFFI<ffi::COFF_Section_ComdataInfo> for ComdatInfo<'_> {
     178         2795 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::COFF_Section_ComdataInfo>) -> Self {
     179         2795 :         Self {
     180         2795 :             ptr,
     181         2795 :             _owner: PhantomData,
     182         2795 :         }
     183         2795 :     }
     184              : }
     185              : 
     186              : impl std::fmt::Debug for ComdatInfo<'_> {
     187         2795 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
     188         2795 :         f.debug_struct("ComdatInfo")
     189         2795 :             .field("symbol", &self.symbol())
     190         2795 :             .field("kind", &self.kind())
     191         2795 :             .finish()
     192         2795 :     }
     193              : }
     194              : 
     195            0 : declare_iterator!(
     196            0 :     Relocations,
     197            0 :     Relocation<'a>,
     198            0 :     ffi::COFF_Relocation,
     199            0 :     ffi::COFF_Section,
     200            0 :     ffi::COFF_Section_it_relocations
     201            0 : );
     202              : 
     203         9100 : declare_iterator!(
     204         9100 :     Symbols,
     205         9100 :     Symbol<'a>,
     206         9100 :     ffi::COFF_Symbol,
     207         9100 :     ffi::COFF_Section,
     208         9100 :     ffi::COFF_Section_it_symbols
     209         9100 : );
        

Generated by: LCOV version 2.1-1