Line data Source code
1 : //! PE volatile memory metadata
2 : use std::marker::PhantomData;
3 :
4 : use crate::{common::FromFFI, declare_iterator};
5 : use lief_ffi as ffi;
6 :
7 : /// This class represents volatile metadata which can be enabled at link time
8 : /// with `/volatileMetadata`.
9 : ///
10 : /// This metadata aims to improve performances when running x64 code on ARM64.
11 : pub struct VolatileMetadata<'a> {
12 : ptr: cxx::UniquePtr<ffi::PE_VolatileMetadata>,
13 : _owner: PhantomData<&'a ffi::PE_LoadConfiguration>,
14 : }
15 :
16 : impl<'a> FromFFI<ffi::PE_VolatileMetadata> for VolatileMetadata<'a> {
17 52 : fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_VolatileMetadata>) -> Self {
18 52 : Self {
19 52 : ptr,
20 52 : _owner: PhantomData,
21 52 : }
22 52 : }
23 : }
24 :
25 : impl VolatileMetadata<'_> {
26 52 : pub fn size(&self) -> u32 {
27 52 : self.ptr.size()
28 52 : }
29 :
30 52 : pub fn min_version(&self) -> u16 {
31 52 : self.ptr.min_version()
32 52 : }
33 :
34 52 : pub fn max_version(&self) -> u16 {
35 52 : self.ptr.max_version()
36 52 : }
37 :
38 52 : pub fn access_table_rva(&self) -> u32 {
39 52 : self.ptr.access_table_rva()
40 52 : }
41 :
42 52 : pub fn access_table_size(&self) -> u32 {
43 52 : self.ptr.access_table_size()
44 52 : }
45 :
46 52 : pub fn info_range_rva(&self) -> u32 {
47 52 : self.ptr.info_range_rva()
48 52 : }
49 :
50 52 : pub fn info_ranges_size(&self) -> u32 {
51 52 : self.ptr.info_ranges_size()
52 52 : }
53 :
54 52 : pub fn info_ranges(&self) -> Ranges<'_> {
55 52 : Ranges::new(self.ptr.info_ranges())
56 52 : }
57 :
58 0 : pub fn access_table(&self) -> Vec<u32> {
59 0 : Vec::from(self.ptr.access_table().as_slice())
60 0 : }
61 : }
62 :
63 : impl std::fmt::Debug for VolatileMetadata<'_> {
64 52 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
65 52 : f.debug_struct("VolatileMetadata")
66 52 : .field("size", &self.size())
67 52 : .field("min_version", &self.min_version())
68 52 : .field("max_version", &self.max_version())
69 52 : .field("access_table_rva", &self.access_table_rva())
70 52 : .field("access_table_size", &self.access_table_size())
71 52 : .field("info_range_rva", &self.info_range_rva())
72 52 : .field("info_ranges_size", &self.info_ranges_size())
73 52 : .finish()
74 52 : }
75 : }
76 :
77 : impl std::fmt::Display for VolatileMetadata<'_> {
78 52 : fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
79 52 : write!(f, "{}", self.ptr.to_string())
80 52 : }
81 : }
82 :
83 : pub struct Range<'a> {
84 : ptr: cxx::UniquePtr<ffi::PE_VolatileMetadata_range_t>,
85 : _owner: PhantomData<&'a ffi::PE_VolatileMetadata>,
86 : }
87 :
88 : impl<'a> FromFFI<ffi::PE_VolatileMetadata_range_t> for Range<'a> {
89 494 : fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_VolatileMetadata_range_t>) -> Self {
90 494 : Self {
91 494 : ptr,
92 494 : _owner: PhantomData,
93 494 : }
94 494 : }
95 : }
96 :
97 : impl Range<'_> {
98 494 : pub fn start(&self) -> u32 {
99 494 : self.ptr.start()
100 494 : }
101 :
102 494 : pub fn end(&self) -> u32 {
103 494 : self.ptr.end()
104 494 : }
105 :
106 494 : pub fn size(&self) -> u32 {
107 494 : self.ptr.size()
108 494 : }
109 : }
110 :
111 : impl std::fmt::Debug for Range<'_> {
112 494 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
113 494 : f.debug_struct("Range")
114 494 : .field("start", &self.start())
115 494 : .field("end", &self.end())
116 494 : .field("size", &self.size())
117 494 : .finish()
118 494 : }
119 : }
120 :
121 494 : declare_iterator!(
122 494 : Ranges,
123 494 : Range<'a>,
124 494 : ffi::PE_Range,
125 494 : ffi::PE_VolatileMetadata,
126 494 : ffi::PE_VolatileMetadata_it_ranges
127 494 : );
|