Line data Source code
1 : //! This module wraps a PDB compilation unit
2 :
3 : use lief_ffi as ffi;
4 :
5 : use std::marker::PhantomData;
6 :
7 : use crate::common::{FromFFI, into_optional};
8 : use crate::declare_fwd_iterator;
9 :
10 : use super::function::Functions;
11 : use super::build_metadata::BuildMetadata;
12 :
13 : /// This structure represents a CompilationUnit (or Module) in a PDB file
14 : pub struct CompilationUnit<'a> {
15 : ptr: cxx::UniquePtr<ffi::PDB_CompilationUnit>,
16 : _owner: PhantomData<&'a ()>,
17 : }
18 :
19 :
20 : impl FromFFI<ffi::PDB_CompilationUnit> for CompilationUnit<'_> {
21 0 : fn from_ffi(ptr: cxx::UniquePtr<ffi::PDB_CompilationUnit>) -> Self {
22 0 : Self {
23 0 : ptr,
24 0 : _owner: PhantomData,
25 0 : }
26 0 : }
27 : }
28 :
29 : impl CompilationUnit<'_> {
30 : /// Name (or path) to the COFF object (`.obj`) associated with this
31 : /// compilation unit (e.g. `e:\obj.amd64fre\minkernel\ntos\hvl\mp\objfre\amd64\hvlp.obj`)
32 0 : pub fn module_name(&self) -> String {
33 0 : self.ptr.module_name().to_string()
34 0 : }
35 :
36 : /// Name of path to the original binary object (COFF, Archive) in which
37 : /// the compilation unit was located before being linked.
38 : /// e.g. `e:\obj.amd64fre\minkernel\ntos\hvl\mp\objfre\amd64\hvl.lib`
39 0 : pub fn object_filename(&self) -> String {
40 0 : self.ptr.object_filename().to_string()
41 0 : }
42 :
43 : /// Return an iterator over the [`crate::pdb::Function`] defined in this compilation unit.
44 : /// If the PDB does not contain or has an empty DBI stream, it returns
45 : /// an empty iterator.
46 0 : pub fn functions(&self) -> Functions {
47 0 : Functions::new(self.ptr.functions())
48 0 : }
49 :
50 : /// Iterator over the sources files (as string) that compose this compilation unit.
51 : /// These files include the **header** (`.h, .hpp`, ...).
52 0 : pub fn sources(&self) -> Sources {
53 0 : Sources::new(self.ptr.sources())
54 0 : }
55 :
56 : /// Return build metadata such as the version of the compiler or
57 : /// the original source language of this compilation unit
58 0 : pub fn build_metadata(&self) -> Option<BuildMetadata> {
59 0 : into_optional(self.ptr.build_metadata())
60 0 : }
61 : }
62 :
63 : impl std::fmt::Display for CompilationUnit<'_> {
64 0 : fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
65 0 : write!(f, "{}", self.ptr.to_string())
66 0 : }
67 : }
68 :
69 0 : declare_fwd_iterator!(
70 0 : CompilationUnits,
71 0 : CompilationUnit<'a>,
72 0 : ffi::PDB_CompilationUnit,
73 0 : ffi::PDB_DebugInfo,
74 0 : ffi::PDB_DebugInfo_it_compilation_units
75 0 : );
76 :
77 :
78 : pub struct Sources<'a> {
79 : #[doc(hidden)]
80 : pub it: cxx::UniquePtr<ffi::PDB_CompilationUnit_it_sources>,
81 : _owner: PhantomData<&'a ffi::PDB_CompilationUnit>,
82 : }
83 :
84 : impl Sources<'_> {
85 : #[doc(hidden)]
86 0 : pub fn new(it: cxx::UniquePtr<ffi::PDB_CompilationUnit_it_sources>) -> Self {
87 0 : Self {
88 0 : it,
89 0 : _owner: PhantomData,
90 0 : }
91 0 : }
92 : }
93 :
94 : impl Iterator for Sources<'_> {
95 : type Item = String;
96 0 : fn next(&mut self) -> Option<Self::Item> {
97 0 : let string = self.it.as_mut().unwrap().next().to_string();
98 0 : // c.f. comment in rust/LIEF/PDB/CompilationUnit.hpp
99 0 : if string == "[LIEF_STOP]" {
100 0 : None
101 : } else {
102 0 : Some(string)
103 : }
104 0 : }
105 : }
|