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-11-30: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        45880 :     pub fn value(&self) -> u16 {
      22        45880 :         self.ptr.value()
      23        45880 :     }
      24              : 
      25              :     /// SymbolVersionAux associated with the current Version if any.
      26        45880 :     pub fn symbol_version_auxiliary(&self) -> Option<SymbolVersionAux> {
      27        45880 :         into_optional(self.ptr.symbol_version_auxiliary())
      28        45880 :     }
      29              : }
      30              : 
      31              : impl fmt::Debug for SymbolVersion<'_> {
      32        45880 :     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
      33        45880 :         f.debug_struct("SymbolVersion")
      34        45880 :             .field("value", &self.value())
      35        45880 :             .field("symbol_version_auxiliary", &self.symbol_version_auxiliary())
      36        45880 :             .finish()
      37        45880 :     }
      38              : }
      39              : 
      40              : impl FromFFI<ffi::ELF_SymbolVersion> for SymbolVersion<'_> {
      41        45880 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::ELF_SymbolVersion>) -> Self {
      42        45880 :         Self {
      43        45880 :             ptr,
      44        45880 :             _owner: PhantomData
      45        45880 :         }
      46        45880 :     }
      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        25410 :     pub fn name(&self) -> String {
      57        25410 :         self.ptr.name().to_string()
      58        25410 :     }
      59              : }
      60              : 
      61              : impl fmt::Debug for SymbolVersionAux<'_> {
      62        25410 :     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
      63        25410 :         f.debug_struct("SymbolVersionAux")
      64        25410 :             .field("name", &self.name())
      65        25410 :             .finish()
      66        25410 :     }
      67              : }
      68              : 
      69              : impl FromFFI<ffi::ELF_SymbolVersionAux> for SymbolVersionAux<'_> {
      70        25410 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::ELF_SymbolVersionAux>) -> Self {
      71        25410 :         Self {
      72        25410 :             ptr,
      73        25410 :             _owner: PhantomData
      74        25410 :         }
      75        25410 :     }
      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          460 :     pub fn hash(&self) -> u32 {
      86          460 :         self.ptr.hash()
      87          460 :     }
      88              :     /// Bitmask of flags
      89          460 :     pub fn flags(&self) -> u16 {
      90          460 :         self.ptr.flags()
      91          460 :     }
      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          460 :     pub fn other(&self) -> u16 {
      98          460 :         self.ptr.other()
      99          460 :     }
     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          460 :     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
     111          460 :         f.debug_struct("SymbolVersionAuxRequirement")
     112          460 :             .field("hash", &self.hash())
     113          460 :             .field("flags", &self.flags())
     114          460 :             .field("other", &self.other())
     115          460 :             .finish()
     116          460 :     }
     117              : }
     118              : 
     119              : impl FromFFI<ffi::ELF_SymbolVersionAuxRequirement> for SymbolVersionAuxRequirement<'_> {
     120          460 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::ELF_SymbolVersionAuxRequirement>) -> Self {
     121          460 :         Self {
     122          460 :             ptr,
     123          460 :             _owner: PhantomData
     124          460 :         }
     125          460 :     }
     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           30 :     pub fn version(&self) -> u16 {
     141           30 :         self.ptr.version()
     142           30 :     }
     143              : 
     144              :     /// Version information
     145           30 :     pub fn flags(&self) -> u16 {
     146           30 :         self.ptr.flags()
     147           30 :     }
     148              : 
     149              :     /// Version index
     150              :     /// Numeric value used as an index in the [`SymbolVersion`] table
     151           30 :     pub fn ndx(&self) -> u16 {
     152           30 :         self.ptr.ndx()
     153           30 :     }
     154              : 
     155              :     /// Hash value of the symbol's name (using ELF hash function)
     156           30 :     pub fn hash(&self) -> u32 {
     157           30 :         self.ptr.hash()
     158           30 :     }
     159              : 
     160              :     /// Iterator over the [`SymbolVersionAux`] associated with this entry
     161           30 :     pub fn auxiliary_symbols(&self) -> DefAuxiliarySymbols {
     162           30 :         DefAuxiliarySymbols::new(self.ptr.sym_aux())
     163           30 :     }
     164              : }
     165              : 
     166              : impl fmt::Debug for SymbolVersionDefinition<'_> {
     167           30 :     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
     168           30 :         f.debug_struct("SymbolVersionDefinition")
     169           30 :             .field("version", &self.version())
     170           30 :             .field("flags", &self.flags())
     171           30 :             .field("ndx", &self.ndx())
     172           30 :             .field("hash", &self.hash())
     173           30 :             .finish()
     174           30 :     }
     175              : }
     176              : 
     177              : impl FromFFI<ffi::ELF_SymbolVersionDefinition> for SymbolVersionDefinition<'_> {
     178           30 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::ELF_SymbolVersionDefinition>) -> Self {
     179           30 :         Self {
     180           30 :             ptr,
     181           30 :             _owner: PhantomData
     182           30 :         }
     183           30 :     }
     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          150 :     pub fn version(&self) -> u16 {
     199          150 :         self.ptr.version()
     200          150 :     }
     201              : 
     202              :     /// Number of auxiliary entries
     203          150 :     pub fn cnt(&self) -> u32 {
     204          150 :         self.ptr.cnt()
     205          150 :     }
     206              : 
     207              :     /// Return the library name associated with this requirement (e.g. `libc.so.6`)
     208          150 :     pub fn name(&self) -> String {
     209          150 :         self.ptr.name().to_string()
     210          150 :     }
     211              : 
     212              :     /// Auxiliary entries as an iterator over [`SymbolVersionAuxRequirement`]
     213          150 :     pub fn auxiliary_symbols(&self) -> AuxiliarySymbols {
     214          150 :         AuxiliarySymbols::new(self.ptr.auxiliary_symbols())
     215          150 :     }
     216              : }
     217              : 
     218              : impl fmt::Debug for SymbolVersionRequirement<'_> {
     219          150 :     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
     220          150 :         f.debug_struct("SymbolVersionRequirement")
     221          150 :             .field("verison", &self.version())
     222          150 :             .field("cnt", &self.cnt())
     223          150 :             .field("name", &self.name())
     224          150 :             .finish()
     225          150 :     }
     226              : }
     227              : 
     228              : impl FromFFI<ffi::ELF_SymbolVersionRequirement> for SymbolVersionRequirement<'_> {
     229          150 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::ELF_SymbolVersionRequirement>) -> Self {
     230          150 :         Self {
     231          150 :             ptr,
     232          150 :             _owner: PhantomData,
     233          150 :         }
     234          150 :     }
     235              : }
     236              : 
     237          460 : declare_iterator!(
     238          460 :     AuxiliarySymbols,
     239          460 :     SymbolVersionAuxRequirement<'a>,
     240          460 :     ffi::ELF_SymbolVersionAuxRequirement,
     241          460 :     ffi::ELF_SymbolVersionRequirement,
     242          460 :     ffi::ELF_SymbolVersionRequirement_it_auxiliary_symbols
     243          460 : );
     244           30 : declare_iterator!(
     245           30 :     DefAuxiliarySymbols,
     246           30 :     SymbolVersionAux<'a>,
     247           30 :     ffi::ELF_SymbolVersionAux,
     248           30 :     ffi::ELF_SymbolVersionDefinition,
     249           30 :     ffi::ELF_SymbolVersionDefinition_it_auxiliary_symbols
     250           30 : );
     251              : 
        

Generated by: LCOV version 2.1-1