LCOV - code coverage report
Current view: top level - src/pe - tls.rs (source / functions) Coverage Total Hit
Test: lief.lcov Lines: 84.8 % 46 39
Test Date: 2024-10-27:00:00:00 Functions: 81.8 % 11 9

            Line data    Source code
       1              : //! This module represents the PE's Thread Local Storage (TLS)
       2              : 
       3              : use lief_ffi as ffi;
       4              : 
       5              : use crate::common::{FromFFI, into_optional};
       6              : use crate::to_slice;
       7              : use std::marker::PhantomData;
       8              : 
       9              : use crate::pe::Section;
      10              : use crate::pe::DataDirectory;
      11              : 
      12              : pub struct TLS<'a> {
      13              :     ptr: cxx::UniquePtr<ffi::PE_TLS>,
      14              :     _owner: PhantomData<&'a ffi::PE_Binary>,
      15              : }
      16              : 
      17              : impl std::fmt::Debug for TLS<'_> {
      18           40 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
      19           40 :         f.debug_struct("TLS")
      20           40 :             .field("callbacks", &self.callbacks())
      21           40 :             .field("addressof_index", &self.addressof_index())
      22           40 :             .field("addressof_callbacks", &self.addressof_callbacks())
      23           40 :             .field("sizeof_zero_fill", &self.sizeof_zero_fill())
      24           40 :             .field("characteristics", &self.characteristics())
      25           40 :             .finish()
      26           40 :     }
      27              : }
      28              : 
      29              : impl TLS<'_> {
      30              :     /// List of callbacks associated with the current TLS
      31              :     ///
      32              :     /// These functions are called before any other functions.
      33           40 :     pub fn callbacks(&self) -> Vec<u64> {
      34           40 :         Vec::from(self.ptr.callbacks().as_slice())
      35           40 :     }
      36              :     /// The location to receive the TLS index assigned by the loader
      37           40 :     pub fn addressof_index(&self) -> u64 {
      38           40 :         self.ptr.addressof_index()
      39           40 :     }
      40              : 
      41              :     /// Pointer to an array of TLS callback functions.
      42              :     ///
      43              :     /// The array is null-terminated, so if there is no callback function this field points to 4
      44              :     /// bytes set to zero.
      45              :     ///
      46              :     /// See [`TLS::callbacks`]
      47           40 :     pub fn addressof_callbacks(&self) -> u64 {
      48           40 :         self.ptr.addressof_callbacks()
      49           40 :     }
      50              : 
      51              :     /// Size in bytes of the zero to be *padded* after the data specified by [`TLS::data_template`]
      52           40 :     pub fn sizeof_zero_fill(&self) -> u64 {
      53           40 :         self.ptr.sizeof_zero_fill()
      54           40 :     }
      55              : 
      56              :     /// The four bits `[23:20]` describe alignment info.
      57              :     ///
      58              :     /// Possible values are those defined as `IMAGE_SCN_ALIGN_*`, which are also used to describe
      59              :     /// alignment of section in object files.
      60              :     ///
      61              :     /// The other 28 bits are reserved for future use.
      62           40 :     pub fn characteristics(&self) -> u64 {
      63           40 :         self.ptr.characteristics()
      64           40 :     }
      65              : 
      66              :     /// The initial content used to initialize TLS data.
      67           40 :     pub fn data_template(&self) -> &[u8] {
      68           40 :         to_slice!(self.ptr.data_template());
      69           40 :     }
      70              : 
      71              :     /// Range of addresses where the [`TLS::data_template`] is located.
      72           40 :     pub fn addressof_raw_data(&self) -> (u64, u64) {
      73           40 :         let vec = Vec::from(self.ptr.addressof_raw_data().as_slice());
      74           40 :         if vec.len() != 2 {
      75            0 :             return (0, 0);
      76           40 :         }
      77           40 :         (vec[0], vec[1])
      78           40 :     }
      79              : 
      80              :     /// The section where the TLS structure is located
      81            0 :     pub fn section(&self) -> Option<Section> {
      82            0 :         into_optional(self.ptr.section())
      83            0 :     }
      84              : 
      85              :     /// The data directory describing the TLS
      86            0 :     pub fn directory(&self) -> Option<DataDirectory> {
      87            0 :         into_optional(self.ptr.data_directory())
      88            0 :     }
      89              : }
      90              : 
      91              : impl<'a> FromFFI<ffi::PE_TLS> for TLS<'a> {
      92           40 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_TLS>) -> Self {
      93           40 :         TLS {
      94           40 :             ptr,
      95           40 :             _owner: PhantomData,
      96           40 :         }
      97           40 :     }
      98              : }
        

Generated by: LCOV version 2.1-1