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 40 : fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_VolatileMetadata>) -> Self {
18 40 : Self {
19 40 : ptr,
20 40 : _owner: PhantomData,
21 40 : }
22 40 : }
23 : }
24 :
25 : impl VolatileMetadata<'_> {
26 40 : pub fn size(&self) -> u32 {
27 40 : self.ptr.size()
28 40 : }
29 :
30 40 : pub fn min_version(&self) -> u16 {
31 40 : self.ptr.min_version()
32 40 : }
33 :
34 40 : pub fn max_version(&self) -> u16 {
35 40 : self.ptr.max_version()
36 40 : }
37 :
38 40 : pub fn access_table_rva(&self) -> u32 {
39 40 : self.ptr.access_table_rva()
40 40 : }
41 :
42 40 : pub fn access_table_size(&self) -> u32 {
43 40 : self.ptr.access_table_size()
44 40 : }
45 :
46 40 : pub fn info_range_rva(&self) -> u32 {
47 40 : self.ptr.info_range_rva()
48 40 : }
49 :
50 40 : pub fn info_ranges_size(&self) -> u32 {
51 40 : self.ptr.info_ranges_size()
52 40 : }
53 :
54 40 : pub fn info_ranges(&self) -> Ranges {
55 40 : Ranges::new(self.ptr.info_ranges())
56 40 : }
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 40 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
65 40 : f.debug_struct("VolatileMetadata")
66 40 : .field("size", &self.size())
67 40 : .field("min_version", &self.min_version())
68 40 : .field("max_version", &self.max_version())
69 40 : .field("access_table_rva", &self.access_table_rva())
70 40 : .field("access_table_size", &self.access_table_size())
71 40 : .field("info_range_rva", &self.info_range_rva())
72 40 : .field("info_ranges_size", &self.info_ranges_size())
73 40 : .finish()
74 40 : }
75 : }
76 :
77 : impl std::fmt::Display for VolatileMetadata<'_> {
78 40 : fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
79 40 : write!(f, "{}", self.ptr.to_string())
80 40 : }
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 380 : fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_VolatileMetadata_range_t>) -> Self {
90 380 : Self {
91 380 : ptr,
92 380 : _owner: PhantomData,
93 380 : }
94 380 : }
95 : }
96 :
97 : impl Range<'_> {
98 380 : pub fn start(&self) -> u32 {
99 380 : self.ptr.start()
100 380 : }
101 :
102 380 : pub fn end(&self) -> u32 {
103 380 : self.ptr.end()
104 380 : }
105 :
106 380 : pub fn size(&self) -> u32 {
107 380 : self.ptr.size()
108 380 : }
109 : }
110 :
111 : impl std::fmt::Debug for Range<'_> {
112 380 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
113 380 : f.debug_struct("Range")
114 380 : .field("start", &self.start())
115 380 : .field("end", &self.end())
116 380 : .field("size", &self.size())
117 380 : .finish()
118 380 : }
119 : }
120 :
121 380 : declare_iterator!(
122 380 : Ranges,
123 380 : Range<'a>,
124 380 : ffi::PE_Range,
125 380 : ffi::PE_VolatileMetadata,
126 380 : ffi::PE_VolatileMetadata_it_ranges
127 380 : );
128 :
129 :
|