LCOV - code coverage report
Current view: top level - src/dwarf - compilation_unit.rs (source / functions) Coverage Total Hit
Test: lief.lcov Lines: 0.0 % 83 0
Test Date: 2024-10-27:00:00:00 Functions: 0.0 % 25 0

            Line data    Source code
       1              : //! This module wraps DWARF compilation unit
       2              : 
       3              : use lief_ffi as ffi;
       4              : 
       5              : use std::marker::PhantomData;
       6              : 
       7              : use crate::common::{into_optional, into_ranges, FromFFI};
       8              : use crate::declare_fwd_iterator;
       9              : use crate::Range;
      10              : 
      11              : use super::{Function, Variable};
      12              : use crate::dwarf::variable::CompilationUnitVariables;
      13              : use crate::dwarf::function::Functions;
      14              : use crate::dwarf::types::Types;
      15              : 
      16              : /// A DWARF compilation unit
      17              : pub struct CompilationUnit<'a> {
      18              :     ptr: cxx::UniquePtr<ffi::DWARF_CompilationUnit>,
      19              :     _owner: PhantomData<&'a ()>,
      20              : }
      21              : 
      22              : 
      23              : #[allow(non_camel_case_types)]
      24            0 : #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
      25              : pub enum Langs {
      26              :     C,
      27              :     CPP,
      28              :     RUST,
      29              :     DART,
      30              :     UNKNOWN(u32),
      31              : }
      32              : 
      33              : impl From<u32> for Langs {
      34            0 :     fn from(value: u32) -> Self {
      35            0 :         match value {
      36            0 :             0x00000001 => Langs::C,
      37            0 :             0x00000002 => Langs::CPP,
      38            0 :             0x00000003 => Langs::RUST,
      39            0 :             0x00000004 => Langs::DART,
      40            0 :             _ => Langs::UNKNOWN(value),
      41              : 
      42              :         }
      43            0 :     }
      44              : }
      45              : impl From<Langs> for u32 {
      46            0 :     fn from(value: Langs) -> u32 {
      47            0 :         match value {
      48            0 :             Langs::C => 0x00000001,
      49            0 :             Langs::CPP => 0x00000002,
      50            0 :             Langs::RUST => 0x00000003,
      51            0 :             Langs::DART => 0x00000004,
      52            0 :             Langs::UNKNOWN(_) => 0,
      53              :         }
      54            0 :     }
      55              : }
      56              : 
      57              : /// Languages supported by the DWARF (v5) format.
      58              : /// See: <https://dwarfstd.org/languages.html>
      59              : ///
      60              : /// Some languages (like C++11, C++17, ..) have a version (11, 17, ...) which
      61              : /// is stored in a dedicated attribute: #version
      62            0 : #[derive(Debug)]
      63              : pub struct Language {
      64              :     /// The language itself
      65              :     pub lang: Langs,
      66              : 
      67              :     /// Version of the language (e.g. 17 for C++17)
      68              :     pub version: u32,
      69              : }
      70              : 
      71              : impl FromFFI<ffi::DWARF_CompilationUnit_Language> for Language {
      72            0 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::DWARF_CompilationUnit_Language>) -> Self {
      73            0 :         let lang_ref = ptr.as_ref().unwrap();
      74            0 :         Self {
      75            0 :             lang: Langs::from(lang_ref.lang),
      76            0 :             version: lang_ref.version,
      77            0 :         }
      78            0 :     }
      79              : }
      80              : 
      81              : impl FromFFI<ffi::DWARF_CompilationUnit> for CompilationUnit<'_> {
      82            0 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::DWARF_CompilationUnit>) -> Self {
      83            0 :         Self {
      84            0 :             ptr,
      85            0 :             _owner: PhantomData,
      86            0 :         }
      87            0 :     }
      88              : }
      89              : 
      90              : impl CompilationUnit<'_> {
      91              :     /// Name of the file associated with this compilation unit (e.g. `test.cpp`)
      92              :     /// Return an **empty** string if the name is not found or can't be resolved
      93              :     ///
      94              :     /// This value matches the `DW_AT_name` attribute
      95            0 :     pub fn name(&self) -> String {
      96            0 :         self.ptr.name().to_string()
      97            0 :     }
      98              : 
      99              :     /// Information about the program (or library) that generated this compilation
     100              :     /// unit. For instance, it can output: `Debian clang version 17.0.6`.
     101              :     ///
     102              :     /// It returns an **empty** string if the producer is not present or can't be
     103              :     /// resolved
     104              :     ///
     105              :     /// This value matches the `DW_AT_producer` attribute
     106            0 :     pub fn producer(&self) -> String {
     107            0 :         self.ptr.producer().to_string()
     108            0 :     }
     109              : 
     110              :     /// Return the path to the directory in which the compilation took place for
     111              :     /// compiling this compilation unit (e.g. `/workdir/build`)
     112              :     ///
     113              :     /// It returns an **empty** string if the entry is not present or can't be
     114              :     /// resolved
     115              :     ///
     116              :     /// This value matches the `DW_AT_comp_dir` attributeducer` attribute
     117            0 :     pub fn compilation_dir(&self) -> String {
     118            0 :         self.ptr.compilation_dir().to_string()
     119            0 :     }
     120              : 
     121              :     /// Original Language of this compilation unit.
     122              :     ///
     123              :     /// This value matches the `DW_AT_language` attribute
     124            0 :     pub fn language(&self) -> Language {
     125            0 :         Language::from_ffi(self.ptr.language())
     126            0 :     }
     127              : 
     128              :     /// Return the lowest virtual address owned by this compilation unit.
     129            0 :     pub fn low_address(&self) -> u64 {
     130            0 :         self.ptr.low_address()
     131            0 :     }
     132              : 
     133              :     /// Return the highest virtual address owned by this compilation unit.
     134            0 :     pub fn high_address(&self) -> u64 {
     135            0 :         self.ptr.high_address()
     136            0 :     }
     137              : 
     138              :     /// Return the size of the compilation unit according to its range of address.
     139              :     ///
     140              :     /// If the compilation is fragmented (i.e. there are some address ranges
     141              :     /// between the lowest address and the highest that are not owned by the CU),
     142              :     /// then it returns the sum of **all** the address ranges owned by this CU.
     143              :     ///
     144              :     /// If the compilation unit is **not** fragmented, then is basically returns
     145              :     /// `high_address - low_address`.
     146            0 :     pub fn size(&self) -> u64 {
     147            0 :         self.ptr.size()
     148            0 :     }
     149              : 
     150              :     /// Return a list of address ranges owned by this compilation unit.
     151              :     ///
     152              :     /// If the compilation unit owns a contiguous range, it should return
     153              :     /// **a single** range.
     154            0 :     pub fn ranges(&self) -> Vec<Range> {
     155            0 :         into_ranges(self.ptr.ranges())
     156            0 :     }
     157              : 
     158              :     /// Return an iterator over the functions [`Function`] implemented in this compilation
     159              :     /// unit.
     160              :     ///
     161              :     /// Note that this iterator only iterates over the functions that have a
     162              :     /// **concrete** implementation in the compilation unit.
     163              :     ///
     164              :     /// For instance with this code:
     165              :     ///
     166              :     /// ```cpp
     167              :     /// inline const char* get_secret_env() {
     168              :     ///   return getenv("MY_SECRET_ENV");
     169              :     /// }
     170              :     ///
     171              :     /// int main() {
     172              :     ///   printf("%s", get_secret_env());
     173              :     ///   return 0;
     174              :     /// }
     175              :     /// ```
     176              :     ///
     177              :     /// The iterator will only return **one function** for `main` since
     178              :     /// `get_secret_env` is inlined and thus, its implementation is located in
     179              :     /// `main`.
     180            0 :     pub fn functions(&self) -> Functions {
     181            0 :         Functions::new(self.ptr.functions())
     182            0 :     }
     183              : 
     184              :     /// Return an iterator over the variables defined in the **global** scope
     185              :     /// of this compilation unit:
     186              :     ///
     187              :     /// ```cpp
     188              :     /// static int A = 1; // Returned by the iterator
     189              :     /// static const char* B = "Hello"; // Returned by the iterator
     190              :     ///
     191              :     /// int get() {
     192              :     ///   static int C = 2; // Returned by the iterator
     193              :     ///   return C;
     194              :     /// }
     195              :     /// ```
     196            0 :     pub fn variables(&self) -> CompilationUnitVariables {
     197            0 :         CompilationUnitVariables::new(self.ptr.variables())
     198            0 :     }
     199              : 
     200            0 :     pub fn types(&self) -> Types {
     201            0 :         Types::new(self.ptr.types())
     202            0 :     }
     203              : 
     204              :     /// Try to find the function whose name is given in parameter.
     205              :     ///
     206              :     /// The provided name can be demangled.
     207            0 :     pub fn function_by_name(&self, name: &str) -> Option<Function> {
     208            0 :         into_optional(self.ptr.function_by_name(name))
     209            0 :     }
     210              : 
     211              :     /// Try to find the function at the given address
     212            0 :     pub fn function_by_addr(&self, address: u64) -> Option<Function> {
     213            0 :         into_optional(self.ptr.function_by_address(address))
     214            0 :     }
     215              : 
     216              :     /// Try to find the variable whose name is given in parameter.
     217            0 :     pub fn variable_by_name(&self, name: &str) -> Option<Variable> {
     218            0 :         into_optional(self.ptr.variable_by_name(name))
     219            0 :     }
     220              : 
     221              :     /// Try to find the variable at the given address
     222            0 :     pub fn variable_by_addr(&self, address: u64) -> Option<Variable> {
     223            0 :         into_optional(self.ptr.variable_by_address(address))
     224            0 :     }
     225              : }
     226              : 
     227            0 : declare_fwd_iterator!(
     228            0 :     CompilationUnits,
     229            0 :     CompilationUnit<'a>,
     230            0 :     ffi::DWARF_CompilationUnit,
     231            0 :     ffi::DWARF_DebugInfo,
     232            0 :     ffi::DWARF_DebugInfo_it_compilation_units
     233            0 : );
        

Generated by: LCOV version 2.1-1