LCOV - code coverage report
Current view: top level - src/elf - symbol.rs (source / functions) Coverage Total Hit
Test: lief.lcov Lines: 82.8 % 128 106
Test Date: 2026-04-12:00:00:00 Functions: 56.1 % 41 23

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

Generated by: LCOV version 2.1-1