Line data Source code
1 : use lief_ffi as ffi;
2 :
3 : use crate::{common::FromFFI, to_opt_trait, to_opt_trait_conv};
4 :
5 : use std::marker::PhantomData;
6 : use crate::{declare_fwd_iterator, DeclOpt};
7 :
8 : pub mod simple;
9 : pub mod array;
10 : pub mod bitfield;
11 : pub mod classlike;
12 : pub mod enum_ty;
13 : pub mod function;
14 : pub mod modifier;
15 : pub mod pointer;
16 : pub mod union;
17 : pub mod attribute;
18 : pub mod method;
19 :
20 : #[doc(inline)]
21 : pub use simple::Simple;
22 :
23 : #[doc(inline)]
24 : pub use array::Array;
25 :
26 : #[doc(inline)]
27 : pub use bitfield::BitField;
28 :
29 : #[doc(inline)]
30 : pub use classlike::{Class, Structure, Interface};
31 :
32 : #[doc(inline)]
33 : pub use enum_ty::Enum;
34 :
35 : #[doc(inline)]
36 : pub use function::Function;
37 :
38 : #[doc(inline)]
39 : pub use modifier::Modifier;
40 :
41 : #[doc(inline)]
42 : pub use pointer::Pointer;
43 :
44 : #[doc(inline)]
45 : pub use union::Union;
46 :
47 : #[doc(inline)]
48 : pub use attribute::Attribute;
49 :
50 : #[doc(inline)]
51 : pub use method::Method;
52 :
53 : pub enum Type<'a> {
54 : /// Represent primitive types (int, float, ...)
55 : Simple(Simple<'a>),
56 :
57 : /// Mirror `LF_ARRAY`
58 : Array(Array<'a>),
59 :
60 : /// Mirror `LF_BITFIELD
61 : BitField(BitField<'a>),
62 :
63 : /// Mirror `LF_CLASS
64 : Class(Class<'a>),
65 :
66 : /// Mirror `LF_STRUCTURE
67 : Structure(Structure<'a>),
68 :
69 : /// Mirror `LF_INTERFACE
70 : Interface(Interface<'a>),
71 :
72 : /// Mirror `LF_ENUM
73 : Enum(Enum<'a>),
74 :
75 : /// Mirror `LF_PROCEDURE
76 : Function(Function<'a>),
77 :
78 : /// Mirror `LF_MODIFIER
79 : Modifier(Modifier<'a>),
80 :
81 : /// Mirror `LF_POINTER
82 : Pointer(Pointer<'a>),
83 :
84 : /// Mirror `LF_UNION
85 : Union(Union<'a>),
86 :
87 : Generic(Generic<'a>),
88 : }
89 :
90 : impl FromFFI<ffi::PDB_Type> for Type<'_> {
91 0 : fn from_ffi(ffi_entry: cxx::UniquePtr<ffi::PDB_Type>) -> Self {
92 0 : unsafe {
93 0 : let type_ref = ffi_entry.as_ref().unwrap();
94 0 :
95 0 : if ffi::PDB_types_Simple::classof(type_ref) {
96 0 : let raw = {
97 0 : type From = cxx::UniquePtr<ffi::PDB_Type>;
98 0 : type To = cxx::UniquePtr<ffi::PDB_types_Simple>;
99 0 : std::mem::transmute::<From, To>(ffi_entry)
100 0 : };
101 0 : Type::Simple(Simple::from_ffi(raw))
102 0 : } else if ffi::PDB_types_Array::classof(type_ref) {
103 0 : let raw = {
104 0 : type From = cxx::UniquePtr<ffi::PDB_Type>;
105 0 : type To = cxx::UniquePtr<ffi::PDB_types_Array>;
106 0 : std::mem::transmute::<From, To>(ffi_entry)
107 0 : };
108 0 : Type::Array(Array::from_ffi(raw))
109 0 : } else if ffi::PDB_types_BitField::classof(type_ref) {
110 0 : let raw = {
111 0 : type From = cxx::UniquePtr<ffi::PDB_Type>;
112 0 : type To = cxx::UniquePtr<ffi::PDB_types_BitField>;
113 0 : std::mem::transmute::<From, To>(ffi_entry)
114 0 : };
115 0 : Type::BitField(BitField::from_ffi(raw))
116 0 : } else if ffi::PDB_types_Class::classof(type_ref) {
117 0 : let raw = {
118 0 : type From = cxx::UniquePtr<ffi::PDB_Type>;
119 0 : type To = cxx::UniquePtr<ffi::PDB_types_Class>;
120 0 : std::mem::transmute::<From, To>(ffi_entry)
121 0 : };
122 0 : Type::Class(Class::from_ffi(raw))
123 0 : } else if ffi::PDB_types_Structure::classof(type_ref) {
124 0 : let raw = {
125 0 : type From = cxx::UniquePtr<ffi::PDB_Type>;
126 0 : type To = cxx::UniquePtr<ffi::PDB_types_Structure>;
127 0 : std::mem::transmute::<From, To>(ffi_entry)
128 0 : };
129 0 : Type::Structure(Structure::from_ffi(raw))
130 0 : } else if ffi::PDB_types_Interface::classof(type_ref) {
131 0 : let raw = {
132 0 : type From = cxx::UniquePtr<ffi::PDB_Type>;
133 0 : type To = cxx::UniquePtr<ffi::PDB_types_Interface>;
134 0 : std::mem::transmute::<From, To>(ffi_entry)
135 0 : };
136 0 : Type::Interface(Interface::from_ffi(raw))
137 0 : } else if ffi::PDB_types_Enum::classof(type_ref) {
138 0 : let raw = {
139 0 : type From = cxx::UniquePtr<ffi::PDB_Type>;
140 0 : type To = cxx::UniquePtr<ffi::PDB_types_Enum>;
141 0 : std::mem::transmute::<From, To>(ffi_entry)
142 0 : };
143 0 : Type::Enum(Enum::from_ffi(raw))
144 0 : } else if ffi::PDB_types_Function::classof(type_ref) {
145 0 : let raw = {
146 0 : type From = cxx::UniquePtr<ffi::PDB_Type>;
147 0 : type To = cxx::UniquePtr<ffi::PDB_types_Function>;
148 0 : std::mem::transmute::<From, To>(ffi_entry)
149 0 : };
150 0 : Type::Function(Function::from_ffi(raw))
151 0 : } else if ffi::PDB_types_Modifier::classof(type_ref) {
152 0 : let raw = {
153 0 : type From = cxx::UniquePtr<ffi::PDB_Type>;
154 0 : type To = cxx::UniquePtr<ffi::PDB_types_Modifier>;
155 0 : std::mem::transmute::<From, To>(ffi_entry)
156 0 : };
157 0 : Type::Modifier(Modifier::from_ffi(raw))
158 0 : } else if ffi::PDB_types_Pointer::classof(type_ref) {
159 0 : let raw = {
160 0 : type From = cxx::UniquePtr<ffi::PDB_Type>;
161 0 : type To = cxx::UniquePtr<ffi::PDB_types_Pointer>;
162 0 : std::mem::transmute::<From, To>(ffi_entry)
163 0 : };
164 0 : Type::Pointer(Pointer::from_ffi(raw))
165 0 : } else if ffi::PDB_types_Union::classof(type_ref) {
166 0 : let raw = {
167 0 : type From = cxx::UniquePtr<ffi::PDB_Type>;
168 0 : type To = cxx::UniquePtr<ffi::PDB_types_Union>;
169 0 : std::mem::transmute::<From, To>(ffi_entry)
170 0 : };
171 0 : Type::Union(Union::from_ffi(raw))
172 : } else {
173 0 : Type::Generic(Generic::from_ffi(ffi_entry))
174 : }
175 : }
176 0 : }
177 : }
178 :
179 : pub struct Generic<'a> {
180 : ptr: cxx::UniquePtr<ffi::PDB_Type>,
181 : _owner: PhantomData<&'a ()>,
182 : }
183 :
184 : impl FromFFI<ffi::PDB_Type> for Generic<'_> {
185 0 : fn from_ffi(cmd: cxx::UniquePtr<ffi::PDB_Type>) -> Self {
186 0 : Self {
187 0 : ptr: cmd,
188 0 : _owner: PhantomData,
189 0 : }
190 0 : }
191 : }
192 :
193 : pub trait PdbType {
194 : #[doc(hidden)]
195 : fn get_base(&self) -> &ffi::PDB_Type;
196 :
197 : /// Size of the type. This size should match the value of `sizeof(...)`
198 : /// applied to this type.
199 0 : fn size(&self) -> Option<u64> {
200 0 : to_opt_trait!(
201 0 : &lief_ffi::PDB_Type::size,
202 0 : self.get_base()
203 0 : );
204 0 : }
205 :
206 : /// Type's name (if present)
207 0 : fn name(&self) -> Option<String> {
208 0 : to_opt_trait_conv!(
209 0 : &lief_ffi::PDB_Type::name,
210 0 : self.get_base(),
211 0 : |e: cxx::UniquePtr<cxx::String>| e.to_string()
212 : );
213 0 : }
214 :
215 : /// Generates a C/C++ definition for this type
216 0 : fn to_decl(&self) -> String {
217 0 : self.get_base().to_decl().to_string()
218 0 : }
219 :
220 : /// Generates a C/C++ definition for this type with the given configuration
221 0 : fn to_decl_with_opt(&self, opt: &DeclOpt) -> String {
222 0 : self.get_base().to_decl_with_opt(&opt.to_ffi()).to_string()
223 0 : }
224 : }
225 :
226 : impl PdbType for Type<'_> {
227 0 : fn get_base(&self) -> &ffi::PDB_Type {
228 0 : match &self {
229 0 : Type::Simple(ty) => {
230 0 : ty.get_base()
231 : }
232 0 : Type::Array(ty) => {
233 0 : ty.get_base()
234 : }
235 0 : Type::BitField(ty) => {
236 0 : ty.get_base()
237 : }
238 0 : Type::Class(ty) => {
239 0 : ty.get_base()
240 : }
241 0 : Type::Structure(ty) => {
242 0 : ty.get_base()
243 : }
244 0 : Type::Interface(ty) => {
245 0 : ty.get_base()
246 : }
247 0 : Type::Enum(ty) => {
248 0 : ty.get_base()
249 : }
250 0 : Type::Function(ty) => {
251 0 : ty.get_base()
252 : }
253 0 : Type::Modifier(ty) => {
254 0 : ty.get_base()
255 : }
256 0 : Type::Pointer(ty) => {
257 0 : ty.get_base()
258 : }
259 0 : Type::Union(ty) => {
260 0 : ty.get_base()
261 : }
262 0 : Type::Generic(ty) => {
263 0 : ty.get_base()
264 : }
265 : }
266 0 : }
267 : }
268 :
269 : impl PdbType for Generic<'_> {
270 0 : fn get_base(&self) -> &ffi::PDB_Type {
271 0 : self.ptr.as_ref().unwrap()
272 0 : }
273 : }
274 :
275 0 : declare_fwd_iterator!(
276 0 : Types,
277 0 : Type<'a>,
278 0 : ffi::PDB_Type,
279 0 : ffi::PDB_DebugInfo,
280 0 : ffi::PDB_DebugInfo_it_types
281 0 : );
282 :
|