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