Line data Source code
1 : use lief_ffi as ffi;
2 :
3 : use crate::common::{into_optional, FromFFI};
4 : use crate::declare_fwd_iterator;
5 : use crate::dwarf::types::DwarfType;
6 : use crate::to_result;
7 : use std::marker::PhantomData;
8 : use crate::Error;
9 : use super::Type;
10 : use crate::dwarf::Function;
11 :
12 : /// Trait shared by [`Structure`], [`Class`], [`Union`] or [`Packed`]
13 : pub trait ClassLike {
14 : #[doc(hidden)]
15 : fn get_classlike(&self) -> &ffi::DWARF_types_ClassLike;
16 :
17 : /// Return this list of all the attributes defined in this class-like type
18 0 : fn members(&self) -> Members {
19 0 : Members::new(self.get_classlike().members())
20 0 : }
21 :
22 : /// Iterator over the functions defined by the class-like.
23 0 : fn functions(&self) -> Functions {
24 0 : Functions::new(self.get_classlike().functions())
25 0 : }
26 : }
27 :
28 : pub struct Member<'a> {
29 : ptr: cxx::UniquePtr<ffi::DWARF_types_ClassLike_Member>,
30 : _owner: PhantomData<&'a ()>,
31 : }
32 :
33 : impl Member<'_> {
34 : /// Name of the member
35 0 : pub fn name(&self) -> String {
36 0 : self.ptr.name().to_string()
37 0 : }
38 :
39 : /// Offset of the current member in the struct/union/class
40 0 : pub fn offset(&self) -> Result<u64, Error> {
41 0 : to_result!(ffi::DWARF_types_ClassLike_Member::offset, self);
42 0 : }
43 :
44 : /// Offset of the current member in **bits** the struct/union/class
45 : ///
46 : /// This function differs from [`Member::offset`] for aggregates using bit-field
47 : /// declaration:
48 : ///
49 : /// ```cpp
50 : /// struct S {
51 : /// int flag : 4;
52 : /// int opt : 1
53 : /// };
54 : /// ```
55 : ///
56 : /// Usually, `offset() * 8 == bit_offset()`
57 0 : pub fn bit_offset(&self) -> Result<u64, Error> {
58 0 : to_result!(ffi::DWARF_types_ClassLike_Member::bit_offset, self);
59 0 : }
60 :
61 : /// If the current member is a bit-field, this function returns its size in bits
62 0 : pub fn bit_size(&self) -> Result<u64, Error> {
63 0 : to_result!(ffi::DWARF_types_ClassLike_Member::bit_size, self);
64 0 : }
65 :
66 : /// Type of the current member
67 0 : pub fn get_type(&self) -> Option<Type> {
68 0 : into_optional(self.ptr.get_type())
69 0 : }
70 :
71 0 : pub fn is_external(&self) -> bool {
72 0 : self.ptr.is_external()
73 0 : }
74 :
75 0 : pub fn is_declaration(&self) -> bool {
76 0 : self.ptr.is_declaration()
77 0 : }
78 : }
79 :
80 : impl FromFFI<ffi::DWARF_types_ClassLike_Member> for Member<'_> {
81 0 : fn from_ffi(cmd: cxx::UniquePtr<ffi::DWARF_types_ClassLike_Member>) -> Self {
82 0 : Self {
83 0 : ptr: cmd,
84 0 : _owner: PhantomData,
85 0 : }
86 0 : }
87 : }
88 :
89 : /// This structure represents a `DW_TAG_structure_type` DWARF type
90 : pub struct Structure<'a> {
91 : ptr: cxx::UniquePtr<ffi::DWARF_types_Structure>,
92 : _owner: PhantomData<&'a ()>,
93 : }
94 :
95 : impl FromFFI<ffi::DWARF_types_Structure> for Structure<'_> {
96 0 : fn from_ffi(cmd: cxx::UniquePtr<ffi::DWARF_types_Structure>) -> Self {
97 0 : Self {
98 0 : ptr: cmd,
99 0 : _owner: PhantomData,
100 0 : }
101 0 : }
102 : }
103 :
104 : impl DwarfType for Structure<'_> {
105 0 : fn get_base(&self) -> &ffi::DWARF_Type {
106 0 : self.ptr.as_ref().unwrap().as_ref().as_ref()
107 0 : }
108 : }
109 :
110 : impl ClassLike for Structure<'_> {
111 0 : fn get_classlike(&self) -> &ffi::DWARF_types_ClassLike {
112 0 : self.ptr.as_ref().unwrap().as_ref()
113 0 : }
114 : }
115 :
116 : /// This structure represents a `DW_TAG_union_type` DWARF type
117 : pub struct Union<'a> {
118 : ptr: cxx::UniquePtr<ffi::DWARF_types_Union>,
119 : _owner: PhantomData<&'a ()>,
120 : }
121 :
122 : impl FromFFI<ffi::DWARF_types_Union> for Union<'_> {
123 0 : fn from_ffi(cmd: cxx::UniquePtr<ffi::DWARF_types_Union>) -> Self {
124 0 : Self {
125 0 : ptr: cmd,
126 0 : _owner: PhantomData,
127 0 : }
128 0 : }
129 : }
130 :
131 : impl DwarfType for Union<'_> {
132 0 : fn get_base(&self) -> &ffi::DWARF_Type {
133 0 : self.ptr.as_ref().unwrap().as_ref().as_ref()
134 0 : }
135 : }
136 :
137 : impl ClassLike for Union<'_> {
138 0 : fn get_classlike(&self) -> &ffi::DWARF_types_ClassLike {
139 0 : self.ptr.as_ref().unwrap().as_ref()
140 0 : }
141 : }
142 :
143 : /// This structure represents a DWARF `packed` type (`DW_TAG_packed_type`)
144 : pub struct Packed<'a> {
145 : ptr: cxx::UniquePtr<ffi::DWARF_types_Packed>,
146 : _owner: PhantomData<&'a ()>,
147 : }
148 :
149 : impl FromFFI<ffi::DWARF_types_Packed> for Packed<'_> {
150 0 : fn from_ffi(cmd: cxx::UniquePtr<ffi::DWARF_types_Packed>) -> Self {
151 0 : Self {
152 0 : ptr: cmd,
153 0 : _owner: PhantomData,
154 0 : }
155 0 : }
156 : }
157 :
158 : impl DwarfType for Packed<'_> {
159 0 : fn get_base(&self) -> &ffi::DWARF_Type {
160 0 : self.ptr.as_ref().unwrap().as_ref().as_ref()
161 0 : }
162 : }
163 :
164 : impl ClassLike for Packed<'_> {
165 0 : fn get_classlike(&self) -> &ffi::DWARF_types_ClassLike {
166 0 : self.ptr.as_ref().unwrap().as_ref()
167 0 : }
168 : }
169 :
170 : /// This structure represents a `DW_TAG_class_type` DWARF type
171 : pub struct Class<'a> {
172 : ptr: cxx::UniquePtr<ffi::DWARF_types_Class>,
173 : _owner: PhantomData<&'a ()>,
174 : }
175 :
176 : impl FromFFI<ffi::DWARF_types_Class> for Class<'_> {
177 0 : fn from_ffi(cmd: cxx::UniquePtr<ffi::DWARF_types_Class>) -> Self {
178 0 : Self {
179 0 : ptr: cmd,
180 0 : _owner: PhantomData,
181 0 : }
182 0 : }
183 : }
184 :
185 : impl DwarfType for Class<'_> {
186 0 : fn get_base(&self) -> &ffi::DWARF_Type {
187 0 : self.ptr.as_ref().unwrap().as_ref().as_ref()
188 0 : }
189 : }
190 :
191 : impl ClassLike for Class<'_> {
192 0 : fn get_classlike(&self) -> &ffi::DWARF_types_ClassLike {
193 0 : self.ptr.as_ref().unwrap().as_ref()
194 0 : }
195 : }
196 :
197 0 : declare_fwd_iterator!(
198 0 : Members,
199 0 : Member<'a>,
200 0 : ffi::DWARF_types_ClassLike_Member,
201 0 : ffi::DWARF_types_ClassLike,
202 0 : ffi::DWARF_types_ClassLike_it_members
203 0 : );
204 :
205 :
206 0 : declare_fwd_iterator!(
207 0 : Functions,
208 0 : Function<'a>,
209 0 : ffi::DWARF_Function,
210 0 : ffi::DWARF_types_ClassLike,
211 0 : ffi::DWARF_types_ClassLike_it_functions
212 0 : );
|