Line data Source code
1 : use lief_ffi as ffi;
2 :
3 : use std::marker::PhantomData;
4 :
5 : use crate::to_slice;
6 : use crate::common::FromFFI;
7 : use crate::{generic, declare_iterator};
8 :
9 :
10 : #[allow(non_camel_case_types)]
11 335687 : #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
12 : pub enum StorageClass {
13 : INVALID,
14 : END_OF_FUNCTION,
15 : NONE,
16 : AUTOMATIC,
17 : EXTERNAL,
18 : STATIC,
19 : REGISTER,
20 : EXTERNAL_DEF,
21 : LABEL,
22 : UNDEFINED_LABEL,
23 : MEMBER_OF_STRUCT,
24 : ARGUMENT,
25 : STRUCT_TAG,
26 : MEMBER_OF_UNION,
27 : UNION_TAG,
28 : TYPE_DEFINITION,
29 : UNDEFINED_STATIC,
30 : ENUM_TAG,
31 : MEMBER_OF_ENUM,
32 : REGISTER_PARAM,
33 : BIT_FIELD,
34 : BLOCK,
35 : FUNCTION,
36 : END_OF_STRUCT,
37 : FILE,
38 : SECTION,
39 : WEAK_EXTERNAL,
40 : CLR_TOKEN,
41 : UNKNOWN(u32),
42 : }
43 :
44 : impl From<u32> for StorageClass {
45 335687 : fn from(value: u32) -> Self {
46 335687 : match value {
47 0 : 0x000000ff => StorageClass::INVALID,
48 0 : 0xffffffff => StorageClass::END_OF_FUNCTION,
49 0 : 0x00000000 => StorageClass::NONE,
50 0 : 0x00000001 => StorageClass::AUTOMATIC,
51 91179 : 0x00000002 => StorageClass::EXTERNAL,
52 241318 : 0x00000003 => StorageClass::STATIC,
53 0 : 0x00000004 => StorageClass::REGISTER,
54 0 : 0x00000005 => StorageClass::EXTERNAL_DEF,
55 88 : 0x00000006 => StorageClass::LABEL,
56 0 : 0x00000007 => StorageClass::UNDEFINED_LABEL,
57 0 : 0x00000008 => StorageClass::MEMBER_OF_STRUCT,
58 0 : 0x00000009 => StorageClass::ARGUMENT,
59 0 : 0x0000000a => StorageClass::STRUCT_TAG,
60 0 : 0x0000000b => StorageClass::MEMBER_OF_UNION,
61 0 : 0x0000000c => StorageClass::UNION_TAG,
62 0 : 0x0000000d => StorageClass::TYPE_DEFINITION,
63 0 : 0x0000000e => StorageClass::UNDEFINED_STATIC,
64 0 : 0x0000000f => StorageClass::ENUM_TAG,
65 0 : 0x00000010 => StorageClass::MEMBER_OF_ENUM,
66 0 : 0x00000011 => StorageClass::REGISTER_PARAM,
67 0 : 0x00000012 => StorageClass::BIT_FIELD,
68 0 : 0x00000064 => StorageClass::BLOCK,
69 0 : 0x00000065 => StorageClass::FUNCTION,
70 0 : 0x00000066 => StorageClass::END_OF_STRUCT,
71 3014 : 0x00000067 => StorageClass::FILE,
72 0 : 0x00000068 => StorageClass::SECTION,
73 88 : 0x00000069 => StorageClass::WEAK_EXTERNAL,
74 0 : 0x0000006b => StorageClass::CLR_TOKEN,
75 0 : _ => StorageClass::UNKNOWN(value),
76 :
77 : }
78 335687 : }
79 : }
80 : impl From<StorageClass> for u32 {
81 0 : fn from(value: StorageClass) -> u32 {
82 0 : match value {
83 0 : StorageClass::INVALID => 0x000000ff,
84 0 : StorageClass::END_OF_FUNCTION => 0xffffffff,
85 0 : StorageClass::NONE => 0x00000000,
86 0 : StorageClass::AUTOMATIC => 0x00000001,
87 0 : StorageClass::EXTERNAL => 0x00000002,
88 0 : StorageClass::STATIC => 0x00000003,
89 0 : StorageClass::REGISTER => 0x00000004,
90 0 : StorageClass::EXTERNAL_DEF => 0x00000005,
91 0 : StorageClass::LABEL => 0x00000006,
92 0 : StorageClass::UNDEFINED_LABEL => 0x00000007,
93 0 : StorageClass::MEMBER_OF_STRUCT => 0x00000008,
94 0 : StorageClass::ARGUMENT => 0x00000009,
95 0 : StorageClass::STRUCT_TAG => 0x0000000a,
96 0 : StorageClass::MEMBER_OF_UNION => 0x0000000b,
97 0 : StorageClass::UNION_TAG => 0x0000000c,
98 0 : StorageClass::TYPE_DEFINITION => 0x0000000d,
99 0 : StorageClass::UNDEFINED_STATIC => 0x0000000e,
100 0 : StorageClass::ENUM_TAG => 0x0000000f,
101 0 : StorageClass::MEMBER_OF_ENUM => 0x00000010,
102 0 : StorageClass::REGISTER_PARAM => 0x00000011,
103 0 : StorageClass::BIT_FIELD => 0x00000012,
104 0 : StorageClass::BLOCK => 0x00000064,
105 0 : StorageClass::FUNCTION => 0x00000065,
106 0 : StorageClass::END_OF_STRUCT => 0x00000066,
107 0 : StorageClass::FILE => 0x00000067,
108 0 : StorageClass::SECTION => 0x00000068,
109 0 : StorageClass::WEAK_EXTERNAL => 0x00000069,
110 0 : StorageClass::CLR_TOKEN => 0x0000006b,
111 0 : StorageClass::UNKNOWN(value) => value,
112 : }
113 0 : }
114 : }
115 :
116 :
117 : #[allow(non_camel_case_types)]
118 335687 : #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
119 : pub enum BaseType {
120 : TY_NULL,
121 : TY_VOID,
122 : TY_CHAR,
123 : TY_SHORT,
124 : TY_INT,
125 : TY_LONG,
126 : TY_FLOAT,
127 : TY_DOUBLE,
128 : TY_STRUCT,
129 : TY_UNION,
130 : TY_ENUM,
131 : TY_MOE,
132 : TY_BYTE,
133 : TY_WORD,
134 : TY_UINT,
135 : TY_DWORD,
136 : UNKNOWN(u32),
137 : }
138 :
139 : impl From<u32> for BaseType {
140 335687 : fn from(value: u32) -> Self {
141 335687 : match value {
142 335687 : 0x00000000 => BaseType::TY_NULL,
143 0 : 0x00000001 => BaseType::TY_VOID,
144 0 : 0x00000002 => BaseType::TY_CHAR,
145 0 : 0x00000003 => BaseType::TY_SHORT,
146 0 : 0x00000004 => BaseType::TY_INT,
147 0 : 0x00000005 => BaseType::TY_LONG,
148 0 : 0x00000006 => BaseType::TY_FLOAT,
149 0 : 0x00000007 => BaseType::TY_DOUBLE,
150 0 : 0x00000008 => BaseType::TY_STRUCT,
151 0 : 0x00000009 => BaseType::TY_UNION,
152 0 : 0x0000000a => BaseType::TY_ENUM,
153 0 : 0x0000000b => BaseType::TY_MOE,
154 0 : 0x0000000c => BaseType::TY_BYTE,
155 0 : 0x0000000d => BaseType::TY_WORD,
156 0 : 0x0000000e => BaseType::TY_UINT,
157 0 : 0x0000000f => BaseType::TY_DWORD,
158 0 : _ => BaseType::UNKNOWN(value),
159 :
160 : }
161 335687 : }
162 : }
163 : impl From<BaseType> for u32 {
164 0 : fn from(value: BaseType) -> u32 {
165 0 : match value {
166 0 : BaseType::TY_NULL => 0x00000000,
167 0 : BaseType::TY_VOID => 0x00000001,
168 0 : BaseType::TY_CHAR => 0x00000002,
169 0 : BaseType::TY_SHORT => 0x00000003,
170 0 : BaseType::TY_INT => 0x00000004,
171 0 : BaseType::TY_LONG => 0x00000005,
172 0 : BaseType::TY_FLOAT => 0x00000006,
173 0 : BaseType::TY_DOUBLE => 0x00000007,
174 0 : BaseType::TY_STRUCT => 0x00000008,
175 0 : BaseType::TY_UNION => 0x00000009,
176 0 : BaseType::TY_ENUM => 0x0000000a,
177 0 : BaseType::TY_MOE => 0x0000000b,
178 0 : BaseType::TY_BYTE => 0x0000000c,
179 0 : BaseType::TY_WORD => 0x0000000d,
180 0 : BaseType::TY_UINT => 0x0000000e,
181 0 : BaseType::TY_DWORD => 0x0000000f,
182 0 : BaseType::UNKNOWN(value) => value,
183 :
184 : }
185 0 : }
186 : }
187 :
188 :
189 :
190 : #[allow(non_camel_case_types)]
191 335687 : #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
192 : pub enum ComplexType {
193 : TY_NULL,
194 : TY_POINTER,
195 : TY_FUNCTION,
196 : TY_ARRAY,
197 : UNKNOWN(u32),
198 : }
199 :
200 : impl From<u32> for ComplexType {
201 335687 : fn from(value: u32) -> Self {
202 335687 : match value {
203 257774 : 0x00000000 => ComplexType::TY_NULL,
204 0 : 0x00000001 => ComplexType::TY_POINTER,
205 77913 : 0x00000002 => ComplexType::TY_FUNCTION,
206 0 : 0x00000003 => ComplexType::TY_ARRAY,
207 0 : _ => ComplexType::UNKNOWN(value),
208 :
209 : }
210 335687 : }
211 : }
212 : impl From<ComplexType> for u32 {
213 0 : fn from(value: ComplexType) -> u32 {
214 0 : match value {
215 0 : ComplexType::TY_NULL => 0x00000000,
216 0 : ComplexType::TY_POINTER => 0x00000001,
217 0 : ComplexType::TY_FUNCTION => 0x00000002,
218 0 : ComplexType::TY_ARRAY => 0x00000003,
219 0 : ComplexType::UNKNOWN(value) => value,
220 :
221 : }
222 0 : }
223 : }
224 :
225 : /// Structure that represents a PE-COFF symbol.
226 : ///
227 : /// Usually PE debug information (including symbols) are wrapped in a PDB file
228 : /// referenced by the CodeViewPDB object.
229 : ///
230 : /// The PE format allows to define (by COFF inheritance) a symbol table that is
231 : /// different from the regular PDB symbols. This table contains COFF(16) symbols
232 : /// which can reference auxiliary symbols.
233 : ///
234 : /// **Warning:** The [`crate::generic::Symbol::value`] should be interpreted in perspective of
235 : /// the [`Symbol::storage_class`].
236 : ///
237 : /// Reference: <https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#coff-symbol-table>
238 : pub struct Symbol<'a> {
239 : ptr: cxx::UniquePtr<ffi::PE_Symbol>,
240 : _owner: PhantomData<&'a ffi::PE_Binary>
241 : }
242 :
243 : impl FromFFI<ffi::PE_Symbol> for Symbol<'_> {
244 335687 : fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_Symbol>) -> Self {
245 335687 : Self {
246 335687 : ptr,
247 335687 : _owner: PhantomData
248 335687 : }
249 335687 : }
250 : }
251 :
252 : impl std::fmt::Debug for Symbol<'_> {
253 335687 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
254 335687 : let base = self as &dyn generic::Symbol;
255 335687 : f.debug_struct("Symbol")
256 335687 : .field("base", &base)
257 335687 : .field("storage_class", &self.storage_class())
258 335687 : .field("base_type", &self.base_type())
259 335687 : .field("complex_type", &self.complex_type())
260 335687 : .field("section_idx", &self.section_idx())
261 335687 : .finish()
262 335687 : }
263 : }
264 :
265 : impl Symbol<'_> {
266 : /// Auxiliary symbols associated with this symbol.
267 335687 : pub fn auxiliary_symbols(&self) -> ItAuxiliarySymbols {
268 335687 : ItAuxiliarySymbols::new(self.ptr.auxiliary_symbols())
269 335687 : }
270 :
271 : /// Storage class of the symbol which indicates what kind of definition a
272 : /// symbol represents.
273 335687 : pub fn storage_class(&self) -> StorageClass {
274 335687 : StorageClass::from(self.ptr.storage_class())
275 335687 : }
276 :
277 : /// The simple (base) data type
278 335687 : pub fn base_type(&self) -> BaseType {
279 335687 : BaseType::from(self.ptr.base_type())
280 335687 : }
281 :
282 : /// The complex type (if any)
283 335687 : pub fn complex_type(&self) -> ComplexType {
284 335687 : ComplexType::from(self.ptr.complex_type())
285 335687 : }
286 :
287 : /// The signed integer that identifies the section, using a one-based index
288 : /// into the section table. Some values have special meaning:
289 : ///
290 : /// * 0: The symbol record is not yet assigned a section. A value of zero
291 : /// indicates that a reference to an external symbol is defined elsewhere.
292 : /// A value of non-zero is a common symbol with a size that is specified
293 : /// by the value.
294 : /// * -1: The symbol has an absolute (non-relocatable) value and is not an
295 : /// address.
296 : /// * -2: The symbol provides general type or debugging information but does
297 : /// not correspond to a section. Microsoft tools use this setting along
298 : /// with `.file` records
299 335687 : pub fn section_idx(&self) -> i16 {
300 335687 : self.ptr.section_idx()
301 335687 : }
302 :
303 0 : pub fn is_external(&self) -> bool {
304 0 : self.ptr.is_external()
305 0 : }
306 :
307 0 : pub fn is_weak_external(&self) -> bool {
308 0 : self.ptr.is_weak_external()
309 0 : }
310 :
311 0 : pub fn is_undefined(&self) -> bool {
312 0 : self.ptr.is_undefined()
313 0 : }
314 :
315 0 : pub fn is_function_line_info(&self) -> bool {
316 0 : self.ptr.is_function_line_info()
317 0 : }
318 :
319 0 : pub fn is_file_record(&self) -> bool {
320 0 : self.ptr.is_file_record()
321 0 : }
322 : }
323 :
324 : impl generic::Symbol for Symbol<'_> {
325 1007061 : fn as_generic(&self) -> &ffi::AbstractSymbol {
326 1007061 : self.ptr.as_ref().unwrap().as_ref()
327 1007061 : }
328 : }
329 :
330 : /// Class that represents an auxiliary symbols.
331 : ///
332 : /// An auxiliary symbol has the same size as a regular [`Symbol`] (18 bytes) but its content
333 : /// depends on the the parent symbol.
334 220770 : #[derive(Debug)]
335 : pub enum AuxiliarySymbols<'a> {
336 : /// Auxiliary Format 1 from the PE-COFF documentation
337 : FunctionDefinition(AuxiliaryFunctionDefinition<'a>),
338 : /// Auxiliary Format 2: .bf and .ef Symbols from the PE-COFF documentation
339 : BfAndEf(AuxiliaryBfAndEf<'a>),
340 : /// Auxiliary Format 3: Weak Externals from the PE-COFF documentation
341 : WeakExternal(AuxiliaryWeakExternal<'a>),
342 : /// Auxiliary Format 4: Files from the PE-COFF documentation
343 : File(AuxiliaryFile<'a>),
344 : /// Auxiliary Format 5: Section Definitions from the PE-COFF documentation
345 : SectionDefinition(AuxiliarySectionDefinition<'a>),
346 : CLRToken(AuxiliaryCLRToken<'a>),
347 : Unknown(AuxiliarySymbol<'a>),
348 : }
349 :
350 :
351 : impl<'a> FromFFI<ffi::PE_AuxiliarySymbol> for AuxiliarySymbols<'a> {
352 220770 : fn from_ffi(ffi_entry: cxx::UniquePtr<ffi::PE_AuxiliarySymbol>) -> Self {
353 220770 : unsafe {
354 220770 : let aux_ref = ffi_entry.as_ref().unwrap();
355 220770 : if ffi::PE_AuxiliaryFile::classof(aux_ref) {
356 3014 : let raw = {
357 3014 : type From = cxx::UniquePtr<ffi::PE_AuxiliarySymbol>;
358 3014 : type To = cxx::UniquePtr<ffi::PE_AuxiliaryFile>;
359 3014 : std::mem::transmute::<From, To>(ffi_entry)
360 3014 : };
361 3014 : AuxiliarySymbols::File(AuxiliaryFile::from_ffi(raw))
362 217756 : } else if ffi::PE_AuxiliarybfAndefSymbol::classof(aux_ref) {
363 0 : let raw = {
364 0 : type From = cxx::UniquePtr<ffi::PE_AuxiliarySymbol>;
365 0 : type To = cxx::UniquePtr<ffi::PE_AuxiliarybfAndefSymbol>;
366 0 : std::mem::transmute::<From, To>(ffi_entry)
367 0 : };
368 0 : AuxiliarySymbols::BfAndEf(AuxiliaryBfAndEf::from_ffi(raw))
369 217756 : } else if ffi::PE_AuxiliaryCLRToken::classof(aux_ref) {
370 0 : let raw = {
371 0 : type From = cxx::UniquePtr<ffi::PE_AuxiliarySymbol>;
372 0 : type To = cxx::UniquePtr<ffi::PE_AuxiliaryCLRToken>;
373 0 : std::mem::transmute::<From, To>(ffi_entry)
374 0 : };
375 0 : AuxiliarySymbols::CLRToken(AuxiliaryCLRToken::from_ffi(raw))
376 217756 : } else if ffi::PE_AuxiliaryFunctionDefinition::classof(aux_ref) {
377 1771 : let raw = {
378 1771 : type From = cxx::UniquePtr<ffi::PE_AuxiliarySymbol>;
379 1771 : type To = cxx::UniquePtr<ffi::PE_AuxiliaryFunctionDefinition>;
380 1771 : std::mem::transmute::<From, To>(ffi_entry)
381 1771 : };
382 1771 : AuxiliarySymbols::FunctionDefinition(AuxiliaryFunctionDefinition::from_ffi(raw))
383 215985 : } else if ffi::PE_AuxiliaryWeakExternal::classof(aux_ref) {
384 616 : let raw = {
385 616 : type From = cxx::UniquePtr<ffi::PE_AuxiliarySymbol>;
386 616 : type To = cxx::UniquePtr<ffi::PE_AuxiliaryWeakExternal>;
387 616 : std::mem::transmute::<From, To>(ffi_entry)
388 616 : };
389 616 : AuxiliarySymbols::WeakExternal(AuxiliaryWeakExternal::from_ffi(raw))
390 215369 : } else if ffi::PE_AuxiliarySectionDefinition::classof(aux_ref) {
391 215369 : let raw = {
392 215369 : type From = cxx::UniquePtr<ffi::PE_AuxiliarySymbol>;
393 215369 : type To = cxx::UniquePtr<ffi::PE_AuxiliarySectionDefinition>;
394 215369 : std::mem::transmute::<From, To>(ffi_entry)
395 215369 : };
396 215369 : AuxiliarySymbols::SectionDefinition(AuxiliarySectionDefinition::from_ffi(raw))
397 : } else {
398 0 : AuxiliarySymbols::Unknown(AuxiliarySymbol::from_ffi(ffi_entry))
399 : }
400 : }
401 220770 : }
402 : }
403 :
404 : /// This auxiliary symbol represents a filename (auxiliary format 4)
405 : ///
406 : /// The [`crate::generic::Symbol::name`] itself should start with `.file`, and this auxiliary record
407 : /// gives the name of a source-code file.
408 : ///
409 : /// Reference: <https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#auxiliary-format-4-files>
410 : pub struct AuxiliaryFile<'a> {
411 : ptr: cxx::UniquePtr<ffi::PE_AuxiliaryFile>,
412 : _owner: PhantomData<&'a ffi::PE_Symbol>,
413 : }
414 :
415 : impl std::fmt::Debug for AuxiliaryFile<'_> {
416 3014 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
417 3014 : f.debug_struct("AuxiliaryFile")
418 3014 : .field("filename", &self.filename())
419 3014 : .finish()
420 3014 : }
421 : }
422 :
423 : impl<'a> FromFFI<ffi::PE_AuxiliaryFile> for AuxiliaryFile<'a> {
424 3014 : fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_AuxiliaryFile>) -> Self {
425 3014 : Self {
426 3014 : ptr,
427 3014 : _owner: PhantomData,
428 3014 : }
429 3014 : }
430 : }
431 :
432 : impl AuxiliaryFile<'_> {
433 : /// The associated filename
434 3014 : pub fn filename(&self) -> String {
435 3014 : self.ptr.filename().to_string()
436 3014 : }
437 : }
438 :
439 : pub struct AuxiliaryBfAndEf<'a> {
440 : #[allow(dead_code)]
441 : ptr: cxx::UniquePtr<ffi::PE_AuxiliarybfAndefSymbol>,
442 : _owner: PhantomData<&'a ffi::PE_Symbol>,
443 : }
444 :
445 : impl std::fmt::Debug for AuxiliaryBfAndEf<'_> {
446 0 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
447 0 : f.debug_struct("AuxiliaryBfAndEf")
448 0 : .finish()
449 0 : }
450 : }
451 :
452 : impl<'a> FromFFI<ffi::PE_AuxiliarybfAndefSymbol> for AuxiliaryBfAndEf<'a> {
453 0 : fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_AuxiliarybfAndefSymbol>) -> Self {
454 0 : Self {
455 0 : ptr,
456 0 : _owner: PhantomData,
457 0 : }
458 0 : }
459 : }
460 :
461 : pub struct AuxiliaryCLRToken<'a> {
462 : #[allow(dead_code)]
463 : ptr: cxx::UniquePtr<ffi::PE_AuxiliaryCLRToken>,
464 : _owner: PhantomData<&'a ffi::PE_Symbol>,
465 : }
466 :
467 : impl std::fmt::Debug for AuxiliaryCLRToken<'_> {
468 0 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
469 0 : f.debug_struct("AuxiliaryCLRToken")
470 0 : .finish()
471 0 : }
472 : }
473 :
474 : impl<'a> FromFFI<ffi::PE_AuxiliaryCLRToken> for AuxiliaryCLRToken<'a> {
475 0 : fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_AuxiliaryCLRToken>) -> Self {
476 0 : Self {
477 0 : ptr,
478 0 : _owner: PhantomData,
479 0 : }
480 0 : }
481 : }
482 :
483 : /// This auxiliary symbols marks the beginning of a function definition.
484 : ///
485 : /// Reference: <https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#auxiliary-format-1-function-definitions>
486 : pub struct AuxiliaryFunctionDefinition<'a> {
487 : ptr: cxx::UniquePtr<ffi::PE_AuxiliaryFunctionDefinition>,
488 : _owner: PhantomData<&'a ffi::PE_Symbol>,
489 : }
490 :
491 : impl<'a> FromFFI<ffi::PE_AuxiliaryFunctionDefinition> for AuxiliaryFunctionDefinition<'a> {
492 1771 : fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_AuxiliaryFunctionDefinition>) -> Self {
493 1771 : Self {
494 1771 : ptr,
495 1771 : _owner: PhantomData,
496 1771 : }
497 1771 : }
498 : }
499 :
500 : impl std::fmt::Debug for AuxiliaryFunctionDefinition<'_> {
501 1771 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
502 1771 : f.debug_struct("AuxiliaryFunctionDefinition")
503 1771 : .field("tag_index", &self.tag_index())
504 1771 : .field("total_size", &self.total_size())
505 1771 : .field("ptr_to_line_number", &self.ptr_to_line_number())
506 1771 : .field("ptr_to_next_func", &self.ptr_to_next_func())
507 1771 : .field("padding", &self.padding())
508 1771 : .finish()
509 1771 : }
510 : }
511 :
512 : impl AuxiliaryFunctionDefinition<'_> {
513 : /// The symbol-table index of the corresponding `.bf` (begin function)
514 : /// symbol record.
515 1771 : pub fn tag_index(&self) -> u32 {
516 1771 : self.ptr.tag_index()
517 1771 : }
518 :
519 : /// The size of the executable code for the function itself.
520 : ///
521 : /// If the function is in its own section, the `SizeOfRawData` in the section
522 : /// header is greater or equal to this field, depending on alignment considerations.
523 1771 : pub fn total_size(&self) -> u32 {
524 1771 : self.ptr.total_size()
525 1771 : }
526 :
527 : /// The file offset of the first COFF line-number entry for the function,
528 : /// or zero if none exists (deprecated)
529 1771 : pub fn ptr_to_line_number(&self) -> u32 {
530 1771 : self.ptr.ptr_to_line_number()
531 1771 : }
532 :
533 : /// The symbol-table index of the record for the next function. If the function
534 : /// is the last in the symbol table, this field is set to zero.
535 1771 : pub fn ptr_to_next_func(&self) -> u32 {
536 1771 : self.ptr.ptr_to_next_func()
537 1771 : }
538 :
539 : /// Padding value (should be 0)
540 1771 : pub fn padding(&self) -> u16 {
541 1771 : self.ptr.padding()
542 1771 : }
543 :
544 : }
545 :
546 : /// This auxiliary symbol exposes information about the associated section.
547 : ///
548 : /// It **duplicates** some information that are provided in the section header
549 : pub struct AuxiliarySectionDefinition<'a> {
550 : ptr: cxx::UniquePtr<ffi::PE_AuxiliarySectionDefinition>,
551 : _owner: PhantomData<&'a ffi::PE_Symbol>,
552 : }
553 :
554 : impl<'a> FromFFI<ffi::PE_AuxiliarySectionDefinition> for AuxiliarySectionDefinition<'a> {
555 215369 : fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_AuxiliarySectionDefinition>) -> Self {
556 215369 : Self {
557 215369 : ptr,
558 215369 : _owner: PhantomData,
559 215369 : }
560 215369 : }
561 : }
562 :
563 : impl std::fmt::Debug for AuxiliarySectionDefinition<'_> {
564 215369 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
565 215369 : f.debug_struct("AuxiliarySectionDefinition")
566 215369 : .field("length", &self.length())
567 215369 : .field("nb_relocs", &self.nb_relocs())
568 215369 : .field("nb_line_numbers", &self.nb_line_numbers())
569 215369 : .field("checksum", &self.checksum())
570 215369 : .field("section_idx", &self.section_idx())
571 215369 : .field("selection", &self.selection())
572 215369 : .finish()
573 215369 : }
574 : }
575 :
576 : impl AuxiliarySectionDefinition<'_> {
577 : /// The size of section data. The same as `SizeOfRawData` in the section header.
578 215369 : pub fn length(&self) -> u32 {
579 215369 : self.ptr.length()
580 215369 : }
581 :
582 : /// The number of relocation entries for the section.
583 215369 : pub fn nb_relocs(&self) -> u16 {
584 215369 : self.ptr.nb_relocs()
585 215369 : }
586 :
587 : /// The number of line-number entries for the section.
588 215369 : pub fn nb_line_numbers(&self) -> u16 {
589 215369 : self.ptr.nb_line_numbers()
590 215369 : }
591 :
592 : /// The checksum for communal data. It is applicable if the `IMAGE_SCN_LNK_COMDAT` flag is set
593 : /// in the section header.
594 215369 : pub fn checksum(&self) -> u32 {
595 215369 : self.ptr.checksum()
596 215369 : }
597 :
598 : /// One-based index into the section table for the associated section.
599 : /// This is used when the COMDAT selection setting is 5.
600 215369 : pub fn section_idx(&self) -> u16 {
601 215369 : self.ptr.section_idx()
602 215369 : }
603 :
604 : /// The COMDAT selection number. This is applicable if the section is a
605 : /// COMDAT section.
606 215369 : pub fn selection(&self) -> u8 {
607 215369 : self.ptr.selection()
608 215369 : }
609 : }
610 :
611 :
612 : /// "Weak externals" are a mechanism for object files that allows flexibility at
613 : /// link time. A module can contain an unresolved external symbol (`sym1`), but
614 : /// it can also include an auxiliary record that indicates that if `sym1` is not
615 : /// present at link time, another external symbol (`sym2`) is used to resolve
616 : /// references instead.
617 : ///
618 : /// If a definition of `sym1` is linked, then an external reference to the
619 : /// symbol is resolved normally. If a definition of `sym1` is not linked, then all
620 : /// references to the weak external for `sym1` refer to `sym2` instead. The external
621 : /// symbol, `sym2`, must always be linked; typically, it is defined in the module
622 : /// that contains the weak reference to `sym1`.
623 : ///
624 : /// Reference: <https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#auxiliary-format-3-weak-externals>
625 : pub struct AuxiliaryWeakExternal<'a> {
626 : ptr: cxx::UniquePtr<ffi::PE_AuxiliaryWeakExternal>,
627 : _owner: PhantomData<&'a ffi::PE_Symbol>,
628 : }
629 :
630 :
631 : #[allow(non_camel_case_types)]
632 616 : #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
633 : pub enum Characteristics {
634 : SEARCH_NOLIBRARY,
635 : SEARCH_LIBRARY,
636 : SEARCH_ALIAS,
637 : ANTI_DEPENDENCY,
638 : UNKNOWN(u32),
639 : }
640 :
641 : impl From<u32> for Characteristics {
642 616 : fn from(value: u32) -> Self {
643 616 : match value {
644 99 : 0x00000001 => Characteristics::SEARCH_NOLIBRARY,
645 0 : 0x00000002 => Characteristics::SEARCH_LIBRARY,
646 0 : 0x00000003 => Characteristics::SEARCH_ALIAS,
647 0 : 0x00000004 => Characteristics::ANTI_DEPENDENCY,
648 517 : _ => Characteristics::UNKNOWN(value),
649 :
650 : }
651 616 : }
652 : }
653 : impl From<Characteristics> for u32 {
654 0 : fn from(value: Characteristics) -> u32 {
655 0 : match value {
656 0 : Characteristics::SEARCH_NOLIBRARY => 0x00000001,
657 0 : Characteristics::SEARCH_LIBRARY => 0x00000002,
658 0 : Characteristics::SEARCH_ALIAS => 0x00000003,
659 0 : Characteristics::ANTI_DEPENDENCY => 0x00000004,
660 0 : Characteristics::UNKNOWN(value) => value,
661 :
662 : }
663 0 : }
664 : }
665 :
666 : impl<'a> FromFFI<ffi::PE_AuxiliaryWeakExternal> for AuxiliaryWeakExternal<'a> {
667 616 : fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_AuxiliaryWeakExternal>) -> Self {
668 616 : Self {
669 616 : ptr,
670 616 : _owner: PhantomData,
671 616 : }
672 616 : }
673 : }
674 :
675 : impl std::fmt::Debug for AuxiliaryWeakExternal<'_> {
676 616 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
677 616 : f.debug_struct("AuxiliaryWeakExternal")
678 616 : .field("sym_idx", &self.sym_idx())
679 616 : .field("characteristics", &self.characteristics())
680 616 : .finish()
681 616 : }
682 : }
683 :
684 : impl AuxiliaryWeakExternal<'_> {
685 : /// The symbol-table index of `sym2`, the symbol to be linked if `sym1` is not
686 : /// found.
687 616 : pub fn sym_idx(&self) -> u32 {
688 616 : self.ptr.sym_idx()
689 616 : }
690 :
691 616 : pub fn characteristics(&self) -> Characteristics{
692 616 : Characteristics::from(self.ptr.characteristics())
693 616 : }
694 :
695 0 : pub fn padding(&self) -> &[u8] {
696 0 : to_slice!(self.ptr.padding());
697 0 : }
698 : }
699 :
700 :
701 : pub struct AuxiliarySymbol<'a> {
702 : ptr: cxx::UniquePtr<ffi::PE_AuxiliarySymbol>,
703 : _owner: PhantomData<&'a ffi::PE_Symbol>,
704 : }
705 :
706 : impl<'a> FromFFI<ffi::PE_AuxiliarySymbol> for AuxiliarySymbol<'a> {
707 0 : fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_AuxiliarySymbol>) -> Self {
708 0 : Self {
709 0 : ptr,
710 0 : _owner: PhantomData,
711 0 : }
712 0 : }
713 : }
714 :
715 : impl std::fmt::Debug for AuxiliarySymbol<'_> {
716 0 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
717 0 : f.debug_struct("AuxiliarySymbol")
718 0 : .finish()
719 0 : }
720 : }
721 :
722 : impl AuxiliarySymbol<'_> {
723 : /// Return the raw representation of this symbol
724 0 : pub fn payload(&self) -> &[u8] {
725 0 : to_slice!(self.ptr.payload());
726 0 : }
727 : }
728 :
729 220770 : declare_iterator!(
730 220770 : ItAuxiliarySymbols,
731 220770 : AuxiliarySymbols<'a>,
732 220770 : ffi::PE_AuxiliarySymbol,
733 220770 : ffi::PE_Symbol,
734 220770 : ffi::PE_Symbol_it_auxiliary_symbols
735 220770 : );
|