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-10-27: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        25832 : #[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        25832 :     pub fn from_value(value: u32) -> Self {
      33        25832 :         match value {
      34         3016 :             0x00000000 => Binding::LOCAL,
      35        19088 :             0x00000001 => Binding::GLOBAL,
      36         3648 :             0x00000002 => Binding::WEAK,
      37           80 :             0x0000000a => Binding::GNU_UNIQUE,
      38            0 :             _ => Binding::UNKNOWN(value),
      39              : 
      40              :         }
      41        25832 :     }
      42              : }
      43              : 
      44              : 
      45              : #[allow(non_camel_case_types)]
      46        25832 : #[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        25832 :     pub fn from_value(value: u32) -> Self {
      71        25832 :         match value {
      72         3328 :             0x00000000 => Type::NOTYPE,
      73         6352 :             0x00000001 => Type::OBJECT,
      74        15608 :             0x00000002 => Type::FUNC,
      75          440 :             0x00000003 => Type::SECTION,
      76           56 :             0x00000004 => Type::FILE,
      77            0 :             0x00000005 => Type::COMMON,
      78           48 :             0x00000006 => Type::TLS,
      79            0 :             0x0000000a => Type::GNU_IFUNC,
      80            0 :             _ => Type::UNKNOWN(value),
      81              : 
      82              :         }
      83        25832 :     }
      84              : }
      85              : 
      86              : 
      87              : #[allow(non_camel_case_types)]
      88        25832 : #[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        25832 :     pub fn from_value(value: u32) -> Self {
     105        25832 :         match value {
     106        25648 :             0x00000000 => Visibility::DEFAULT,
     107            0 :             0x00000001 => Visibility::INTERNAL,
     108          152 :             0x00000002 => Visibility::HIDDEN,
     109            0 :             0x00000003 => Visibility::PROTECTED,
     110           32 :             _ => Visibility::UNKNOWN(value),
     111              : 
     112              :         }
     113        25832 :     }
     114              : }
     115              : 
     116              : impl Symbol<'_> {
     117              :     /// The symbol's type provides a general classification for the associated entity
     118        25832 :     pub fn get_type(&self) -> Type {
     119        25832 :         Type::from_value(self.ptr.get_type())
     120        25832 :     }
     121              : 
     122              :     /// The symbol's binding determines the linkage visibility and behavior
     123        25832 :     pub fn binding(&self) -> Binding {
     124        25832 :         Binding::from_value(self.ptr.binding())
     125        25832 :     }
     126              : 
     127              :     /// This member specifies the symbol's type and binding attributes.
     128        25832 :     pub fn information(&self) -> u8 {
     129        25832 :         self.ptr.information()
     130        25832 :     }
     131              : 
     132              :     /// Alias for [`Symbol::visibility`]
     133        25832 :     pub fn other(&self) -> u8 {
     134        25832 :         self.ptr.other()
     135        25832 :     }
     136              : 
     137              :     /// ELF Section index associated with the symbol
     138        25832 :     pub fn section_idx(&self) -> u16 {
     139        25832 :         self.ptr.section_idx()
     140        25832 :     }
     141              : 
     142              :     /// Symbol visibility
     143        25832 :     pub fn visibility(&self) -> Visibility {
     144        25832 :         Visibility::from_value(self.ptr.visibility())
     145        25832 :     }
     146              : 
     147              :     /// Section associated with the symbol (if any)
     148        25832 :     pub fn section(&self) -> Option<Section> {
     149        25832 :         into_optional(self.ptr.section())
     150        25832 :     }
     151              : 
     152              :     /// Return the SymbolVersion associated with this symbol (if any)
     153        25832 :     pub fn symbol_version(&self) -> Option<SymbolVersion> {
     154        25832 :         into_optional(self.ptr.symbol_version())
     155        25832 :     }
     156              : 
     157              :     /// Try to demangle the symbol or return an empty string if it is not possible
     158         6216 :     pub fn demangled_name(&self) -> String {
     159         6216 :         self.ptr.demangled_name().to_string()
     160         6216 :     }
     161              : }
     162              : 
     163              : impl fmt::Debug for Symbol<'_> {
     164        25832 :     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
     165        25832 :        let base = self as &dyn generic::Symbol;
     166        25832 :         f.debug_struct("Symbol")
     167        25832 :             .field("base", &base)
     168        25832 :             .field("type", &self.get_type())
     169        25832 :             .field("binding", &self.binding())
     170        25832 :             .field("information", &self.information())
     171        25832 :             .field("other", &self.other())
     172        25832 :             .field("section_idx", &self.section_idx())
     173        25832 :             .field("visibility", &self.visibility())
     174        25832 :             .field("section", &self.section())
     175        25832 :             .field("symbol_version", &self.symbol_version())
     176        25832 :             .finish()
     177        25832 :     }
     178              : }
     179              : 
     180              : impl FromFFI<ffi::ELF_Symbol> for Symbol<'_> {
     181        25848 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::ELF_Symbol>) -> Self {
     182        25848 :         Self {
     183        25848 :             ptr,
     184        25848 :             _owner: PhantomData
     185        25848 :         }
     186        25848 :     }
     187              : }
     188              : 
     189              : impl generic::Symbol for Symbol<'_> {
     190        96144 :     fn as_generic(&self) -> &ffi::AbstractSymbol {
     191        96144 :         self.ptr.as_ref().unwrap().as_ref()
     192        96144 :     }
     193              : }
     194              : 
     195              : impl fmt::Display for Symbol<'_> {
     196         6216 :     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     197         6216 :         write!(f, "{}", self.ptr.to_string())
     198         6216 :     }
     199              : }
     200              : 
     201         6216 : declare_iterator!(DynamicSymbols, Symbol<'a>, ffi::ELF_Symbol, ffi::ELF_Binary, ffi::ELF_Binary_it_dynamic_symbols);
     202         2064 : declare_iterator!(ExportedSymbols, Symbol<'a>, ffi::ELF_Symbol, ffi::ELF_Binary, ffi::ELF_Binary_it_exported_symbols);
     203         3888 : declare_iterator!(ImportedSymbols, Symbol<'a>, ffi::ELF_Symbol, ffi::ELF_Binary, ffi::ELF_Binary_it_imported_symbols);
     204          704 : declare_iterator!(SymtabSymbols, Symbol<'a>, ffi::ELF_Symbol, ffi::ELF_Binary, ffi::ELF_Binary_it_symtab_symbols);
        

Generated by: LCOV version 2.1-1