LCOV - code coverage report
Current view: top level - src/elf - symbol.rs (source / functions) Coverage Total Hit
Test: lief.lcov Lines: 93.2 % 88 82
Test Date: 2024-11-30:00:00:00 Functions: 60.5 % 38 23

            Line data    Source code
       1              : use lief_ffi as ffi;
       2              : use std::fmt;
       3              : use std::marker::PhantomData;
       4              : 
       5              : use crate::common::{FromFFI, into_optional};
       6              : use crate::declare_iterator;
       7              : use crate::generic;
       8              : use crate::elf::Section;
       9              : use super::SymbolVersion;
      10              : 
      11              : /// Structure which reprents an ELF symbol
      12              : pub struct Symbol<'a> {
      13              :     ptr: cxx::UniquePtr<ffi::ELF_Symbol>,
      14              :     _owner: PhantomData<&'a ffi::ELF_Binary>
      15              : }
      16              : 
      17              : #[allow(non_camel_case_types)]
      18        32290 : #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
      19              : pub enum Binding {
      20              :     /// Local symbol
      21              :     LOCAL,
      22              :     /// Global symbol
      23              :     GLOBAL,
      24              :     /// Weak symbol
      25              :     WEAK,
      26              :     /// Unique symbol
      27              :     GNU_UNIQUE,
      28              :     UNKNOWN(u32),
      29              : }
      30              : 
      31              : impl Binding {
      32        32290 :     pub fn from_value(value: u32) -> Self {
      33        32290 :         match value {
      34         3770 :             0x00000000 => Binding::LOCAL,
      35        23860 :             0x00000001 => Binding::GLOBAL,
      36         4560 :             0x00000002 => Binding::WEAK,
      37          100 :             0x0000000a => Binding::GNU_UNIQUE,
      38            0 :             _ => Binding::UNKNOWN(value),
      39              : 
      40              :         }
      41        32290 :     }
      42              : }
      43              : 
      44              : 
      45              : #[allow(non_camel_case_types)]
      46        32290 : #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
      47              : /// Type of the symbol. This enum matches the `STT_xxx` values of the ELF
      48              : /// specs
      49              : pub enum Type {
      50              :     /// Symbol's type is not specified
      51              :     NOTYPE,
      52              :     /// Symbol is a data object (variable, array, etc.)
      53              :     OBJECT,
      54              :     /// Symbol is executable code (function, etc.)
      55              :     FUNC,
      56              :     /// Symbol refers to a section
      57              :     SECTION,
      58              :     /// Local, absolute symbol that refers to a file
      59              :     FILE,
      60              :     /// An uninitialized common block
      61              :     COMMON,
      62              :     /// Thread local data object
      63              :     TLS,
      64              :     /// GNU indirect function
      65              :     GNU_IFUNC,
      66              :     UNKNOWN(u32),
      67              : }
      68              : 
      69              : impl Type {
      70        32290 :     pub fn from_value(value: u32) -> Self {
      71        32290 :         match value {
      72         4160 :             0x00000000 => Type::NOTYPE,
      73         7940 :             0x00000001 => Type::OBJECT,
      74        19510 :             0x00000002 => Type::FUNC,
      75          550 :             0x00000003 => Type::SECTION,
      76           70 :             0x00000004 => Type::FILE,
      77            0 :             0x00000005 => Type::COMMON,
      78           60 :             0x00000006 => Type::TLS,
      79            0 :             0x0000000a => Type::GNU_IFUNC,
      80            0 :             _ => Type::UNKNOWN(value),
      81              : 
      82              :         }
      83        32290 :     }
      84              : }
      85              : 
      86              : 
      87              : #[allow(non_camel_case_types)]
      88        32290 : #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
      89              : /// Visibility of the symbol. This enum matches the `STV_xxx` values of the
      90              : /// official ELF specs
      91              : pub enum Visibility {
      92              :     /// Visibility is specified by binding type
      93              :     DEFAULT,
      94              :     /// Defined by processor supplements
      95              :     INTERNAL,
      96              :     /// Not visible to other components
      97              :     HIDDEN,
      98              :     /// Visible in other components but not preemptable
      99              :     PROTECTED,
     100              :     UNKNOWN(u32),
     101              : }
     102              : 
     103              : impl Visibility {
     104        32290 :     pub fn from_value(value: u32) -> Self {
     105        32290 :         match value {
     106        32060 :             0x00000000 => Visibility::DEFAULT,
     107            0 :             0x00000001 => Visibility::INTERNAL,
     108          190 :             0x00000002 => Visibility::HIDDEN,
     109            0 :             0x00000003 => Visibility::PROTECTED,
     110           40 :             _ => Visibility::UNKNOWN(value),
     111              : 
     112              :         }
     113        32290 :     }
     114              : }
     115              : 
     116              : impl Symbol<'_> {
     117              :     /// The symbol's type provides a general classification for the associated entity
     118        32290 :     pub fn get_type(&self) -> Type {
     119        32290 :         Type::from_value(self.ptr.get_type())
     120        32290 :     }
     121              : 
     122              :     /// The symbol's binding determines the linkage visibility and behavior
     123        32290 :     pub fn binding(&self) -> Binding {
     124        32290 :         Binding::from_value(self.ptr.binding())
     125        32290 :     }
     126              : 
     127              :     /// This member specifies the symbol's type and binding attributes.
     128        32290 :     pub fn information(&self) -> u8 {
     129        32290 :         self.ptr.information()
     130        32290 :     }
     131              : 
     132              :     /// Alias for [`Symbol::visibility`]
     133        32290 :     pub fn other(&self) -> u8 {
     134        32290 :         self.ptr.other()
     135        32290 :     }
     136              : 
     137              :     /// ELF Section index associated with the symbol
     138        32290 :     pub fn section_idx(&self) -> u16 {
     139        32290 :         self.ptr.section_idx()
     140        32290 :     }
     141              : 
     142              :     /// Symbol visibility
     143        32290 :     pub fn visibility(&self) -> Visibility {
     144        32290 :         Visibility::from_value(self.ptr.visibility())
     145        32290 :     }
     146              : 
     147              :     /// Section associated with the symbol (if any)
     148        32290 :     pub fn section(&self) -> Option<Section> {
     149        32290 :         into_optional(self.ptr.section())
     150        32290 :     }
     151              : 
     152              :     /// Return the SymbolVersion associated with this symbol (if any)
     153        32290 :     pub fn symbol_version(&self) -> Option<SymbolVersion> {
     154        32290 :         into_optional(self.ptr.symbol_version())
     155        32290 :     }
     156              : 
     157              :     /// Try to demangle the symbol or return an empty string if it is not possible
     158         7770 :     pub fn demangled_name(&self) -> String {
     159         7770 :         self.ptr.demangled_name().to_string()
     160         7770 :     }
     161              : }
     162              : 
     163              : impl fmt::Debug for Symbol<'_> {
     164        32290 :     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
     165        32290 :        let base = self as &dyn generic::Symbol;
     166        32290 :         f.debug_struct("Symbol")
     167        32290 :             .field("base", &base)
     168        32290 :             .field("type", &self.get_type())
     169        32290 :             .field("binding", &self.binding())
     170        32290 :             .field("information", &self.information())
     171        32290 :             .field("other", &self.other())
     172        32290 :             .field("section_idx", &self.section_idx())
     173        32290 :             .field("visibility", &self.visibility())
     174        32290 :             .field("section", &self.section())
     175        32290 :             .field("symbol_version", &self.symbol_version())
     176        32290 :             .finish()
     177        32290 :     }
     178              : }
     179              : 
     180              : impl FromFFI<ffi::ELF_Symbol> for Symbol<'_> {
     181        32310 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::ELF_Symbol>) -> Self {
     182        32310 :         Self {
     183        32310 :             ptr,
     184        32310 :             _owner: PhantomData
     185        32310 :         }
     186        32310 :     }
     187              : }
     188              : 
     189              : impl generic::Symbol for Symbol<'_> {
     190       120180 :     fn as_generic(&self) -> &ffi::AbstractSymbol {
     191       120180 :         self.ptr.as_ref().unwrap().as_ref()
     192       120180 :     }
     193              : }
     194              : 
     195              : impl fmt::Display for Symbol<'_> {
     196         7770 :     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     197         7770 :         write!(f, "{}", self.ptr.to_string())
     198         7770 :     }
     199              : }
     200              : 
     201         7770 : declare_iterator!(DynamicSymbols, Symbol<'a>, ffi::ELF_Symbol, ffi::ELF_Binary, ffi::ELF_Binary_it_dynamic_symbols);
     202         2580 : declare_iterator!(ExportedSymbols, Symbol<'a>, ffi::ELF_Symbol, ffi::ELF_Binary, ffi::ELF_Binary_it_exported_symbols);
     203         4860 : declare_iterator!(ImportedSymbols, Symbol<'a>, ffi::ELF_Symbol, ffi::ELF_Binary, ffi::ELF_Binary_it_imported_symbols);
     204          880 : declare_iterator!(SymtabSymbols, Symbol<'a>, ffi::ELF_Symbol, ffi::ELF_Binary, ffi::ELF_Binary_it_symtab_symbols);
        

Generated by: LCOV version 2.1-1