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