LCOV - code coverage report
Current view: top level - src/elf - symbol_versioning.rs (source / functions) Coverage Total Hit
Test: lief.lcov Lines: 97.6 % 125 122
Test Date: 2024-10-27:00:00:00 Functions: 96.4 % 28 27

            Line data    Source code
       1              : use lief_ffi as ffi;
       2              : use std::fmt;
       3              : use crate::declare_iterator;
       4              : use std::marker::PhantomData;
       5              : use crate::common::{FromFFI, into_optional};
       6              : 
       7              : /// Structure which represents an entry defined in the `DT_VERSYM`
       8              : /// dynamic entry
       9              : pub struct SymbolVersion<'a> {
      10              :     ptr: cxx::UniquePtr<ffi::ELF_SymbolVersion>,
      11              :     _owner: PhantomData<&'a ffi::ELF_Binary>
      12              : }
      13              : 
      14              : impl SymbolVersion<'_> {
      15              :     /// Value associated with the symbol
      16              :     ///
      17              :     /// If the given [`SymbolVersion`] doesn't have [`SymbolVersion::symbol_version_auxiliary`]:
      18              :     ///
      19              :     /// * `0` means **Local**
      20              :     /// * `1` means **Global**
      21        36704 :     pub fn value(&self) -> u16 {
      22        36704 :         self.ptr.value()
      23        36704 :     }
      24              : 
      25              :     /// SymbolVersionAux associated with the current Version if any.
      26        36704 :     pub fn symbol_version_auxiliary(&self) -> Option<SymbolVersionAux> {
      27        36704 :         into_optional(self.ptr.symbol_version_auxiliary())
      28        36704 :     }
      29              : }
      30              : 
      31              : impl fmt::Debug for SymbolVersion<'_> {
      32        36704 :     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
      33        36704 :         f.debug_struct("SymbolVersion")
      34        36704 :             .field("value", &self.value())
      35        36704 :             .field("symbol_version_auxiliary", &self.symbol_version_auxiliary())
      36        36704 :             .finish()
      37        36704 :     }
      38              : }
      39              : 
      40              : impl FromFFI<ffi::ELF_SymbolVersion> for SymbolVersion<'_> {
      41        36704 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::ELF_SymbolVersion>) -> Self {
      42        36704 :         Self {
      43        36704 :             ptr,
      44        36704 :             _owner: PhantomData
      45        36704 :         }
      46        36704 :     }
      47              : }
      48              : 
      49              : pub struct SymbolVersionAux<'a> {
      50              :     ptr: cxx::UniquePtr<ffi::ELF_SymbolVersionAux>,
      51              :     _owner: PhantomData<&'a ()>
      52              : }
      53              : 
      54              : 
      55              : impl SymbolVersionAux<'_> {
      56        20328 :     pub fn name(&self) -> String {
      57        20328 :         self.ptr.name().to_string()
      58        20328 :     }
      59              : }
      60              : 
      61              : impl fmt::Debug for SymbolVersionAux<'_> {
      62        20328 :     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
      63        20328 :         f.debug_struct("SymbolVersionAux")
      64        20328 :             .field("name", &self.name())
      65        20328 :             .finish()
      66        20328 :     }
      67              : }
      68              : 
      69              : impl FromFFI<ffi::ELF_SymbolVersionAux> for SymbolVersionAux<'_> {
      70        20328 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::ELF_SymbolVersionAux>) -> Self {
      71        20328 :         Self {
      72        20328 :             ptr,
      73        20328 :             _owner: PhantomData
      74        20328 :         }
      75        20328 :     }
      76              : }
      77              : 
      78              : pub struct SymbolVersionAuxRequirement<'a> {
      79              :     ptr: cxx::UniquePtr<ffi::ELF_SymbolVersionAuxRequirement>,
      80              :     _owner: PhantomData<&'a ()>
      81              : }
      82              : 
      83              : impl SymbolVersionAuxRequirement<'_> {
      84              :     /// Hash value of the dependency name (use ELF hashing function)
      85          368 :     pub fn hash(&self) -> u32 {
      86          368 :         self.ptr.hash()
      87          368 :     }
      88              :     /// Bitmask of flags
      89          368 :     pub fn flags(&self) -> u16 {
      90          368 :         self.ptr.flags()
      91          368 :     }
      92              : 
      93              :     /// It returns the unique version index for the file which is used in the
      94              :     /// version symbol table. If the highest bit (bit 15) is set this
      95              :     /// is a hidden symbol which cannot be referenced from outside the
      96              :     /// object.
      97          368 :     pub fn other(&self) -> u16 {
      98          368 :         self.ptr.other()
      99          368 :     }
     100              : 
     101              : 
     102              :     /// Symbol's aux name (e.g. ``GLIBC_2.2.5``)
     103            0 :     pub fn name(&self) -> String {
     104            0 :         self.ptr.name().to_string()
     105            0 :     }
     106              : 
     107              : }
     108              : 
     109              : impl fmt::Debug for SymbolVersionAuxRequirement<'_> {
     110          368 :     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
     111          368 :         f.debug_struct("SymbolVersionAuxRequirement")
     112          368 :             .field("hash", &self.hash())
     113          368 :             .field("flags", &self.flags())
     114          368 :             .field("other", &self.other())
     115          368 :             .finish()
     116          368 :     }
     117              : }
     118              : 
     119              : impl FromFFI<ffi::ELF_SymbolVersionAuxRequirement> for SymbolVersionAuxRequirement<'_> {
     120          368 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::ELF_SymbolVersionAuxRequirement>) -> Self {
     121          368 :         Self {
     122          368 :             ptr,
     123          368 :             _owner: PhantomData
     124          368 :         }
     125          368 :     }
     126              : }
     127              : 
     128              : /// Structure which represents an entry defined in `DT_VERDEF` or `.gnu.version_d`
     129              : pub struct SymbolVersionDefinition<'a> {
     130              :     ptr: cxx::UniquePtr<ffi::ELF_SymbolVersionDefinition>,
     131              :     _owner: PhantomData<&'a ()>
     132              : }
     133              : 
     134              : 
     135              : impl SymbolVersionDefinition<'_> {
     136              :     /// Version revision
     137              :     ///
     138              :     /// This field should always have the value `1`. It will be changed
     139              :     /// if the versioning implementation has to be changed in an incompatible way.
     140           24 :     pub fn version(&self) -> u16 {
     141           24 :         self.ptr.version()
     142           24 :     }
     143              : 
     144              :     /// Version information
     145           24 :     pub fn flags(&self) -> u16 {
     146           24 :         self.ptr.flags()
     147           24 :     }
     148              : 
     149              :     /// Version index
     150              :     /// Numeric value used as an index in the [`SymbolVersion`] table
     151           24 :     pub fn ndx(&self) -> u16 {
     152           24 :         self.ptr.ndx()
     153           24 :     }
     154              : 
     155              :     /// Hash value of the symbol's name (using ELF hash function)
     156           24 :     pub fn hash(&self) -> u32 {
     157           24 :         self.ptr.hash()
     158           24 :     }
     159              : 
     160              :     /// Iterator over the [`SymbolVersionAux`] associated with this entry
     161           24 :     pub fn auxiliary_symbols(&self) -> DefAuxiliarySymbols {
     162           24 :         DefAuxiliarySymbols::new(self.ptr.sym_aux())
     163           24 :     }
     164              : }
     165              : 
     166              : impl fmt::Debug for SymbolVersionDefinition<'_> {
     167           24 :     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
     168           24 :         f.debug_struct("SymbolVersionDefinition")
     169           24 :             .field("version", &self.version())
     170           24 :             .field("flags", &self.flags())
     171           24 :             .field("ndx", &self.ndx())
     172           24 :             .field("hash", &self.hash())
     173           24 :             .finish()
     174           24 :     }
     175              : }
     176              : 
     177              : impl FromFFI<ffi::ELF_SymbolVersionDefinition> for SymbolVersionDefinition<'_> {
     178           24 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::ELF_SymbolVersionDefinition>) -> Self {
     179           24 :         Self {
     180           24 :             ptr,
     181           24 :             _owner: PhantomData
     182           24 :         }
     183           24 :     }
     184              : }
     185              : 
     186              : 
     187              : /// Structure which represents an entry in the ``DT_VERNEED`` or ``.gnu.version_r`` table
     188              : pub struct SymbolVersionRequirement<'a> {
     189              :     ptr: cxx::UniquePtr<ffi::ELF_SymbolVersionRequirement>,
     190              :     _owner: PhantomData<&'a ()>
     191              : }
     192              : 
     193              : impl SymbolVersionRequirement<'_> {
     194              :     /// Version revision
     195              :     ///
     196              :     /// This field should always have the value `1`. It will be changed
     197              :     /// if the versioning implementation has to be changed in an incompatible way.
     198          120 :     pub fn version(&self) -> u16 {
     199          120 :         self.ptr.version()
     200          120 :     }
     201              : 
     202              :     /// Number of auxiliary entries
     203          120 :     pub fn cnt(&self) -> u32 {
     204          120 :         self.ptr.cnt()
     205          120 :     }
     206              : 
     207              :     /// Return the library name associated with this requirement (e.g. `libc.so.6`)
     208          120 :     pub fn name(&self) -> String {
     209          120 :         self.ptr.name().to_string()
     210          120 :     }
     211              : 
     212              :     /// Auxiliary entries as an iterator over [`SymbolVersionAuxRequirement`]
     213          120 :     pub fn auxiliary_symbols(&self) -> AuxiliarySymbols {
     214          120 :         AuxiliarySymbols::new(self.ptr.auxiliary_symbols())
     215          120 :     }
     216              : }
     217              : 
     218              : impl fmt::Debug for SymbolVersionRequirement<'_> {
     219          120 :     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
     220          120 :         f.debug_struct("SymbolVersionRequirement")
     221          120 :             .field("verison", &self.version())
     222          120 :             .field("cnt", &self.cnt())
     223          120 :             .field("name", &self.name())
     224          120 :             .finish()
     225          120 :     }
     226              : }
     227              : 
     228              : impl FromFFI<ffi::ELF_SymbolVersionRequirement> for SymbolVersionRequirement<'_> {
     229          120 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::ELF_SymbolVersionRequirement>) -> Self {
     230          120 :         Self {
     231          120 :             ptr,
     232          120 :             _owner: PhantomData,
     233          120 :         }
     234          120 :     }
     235              : }
     236              : 
     237          368 : declare_iterator!(
     238          368 :     AuxiliarySymbols,
     239          368 :     SymbolVersionAuxRequirement<'a>,
     240          368 :     ffi::ELF_SymbolVersionAuxRequirement,
     241          368 :     ffi::ELF_SymbolVersionRequirement,
     242          368 :     ffi::ELF_SymbolVersionRequirement_it_auxiliary_symbols
     243          368 : );
     244           24 : declare_iterator!(
     245           24 :     DefAuxiliarySymbols,
     246           24 :     SymbolVersionAux<'a>,
     247           24 :     ffi::ELF_SymbolVersionAux,
     248           24 :     ffi::ELF_SymbolVersionDefinition,
     249           24 :     ffi::ELF_SymbolVersionDefinition_it_auxiliary_symbols
     250           24 : );
     251              : 
        

Generated by: LCOV version 2.1-1