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::offset, self);
59 0 : }
60 :
61 : /// Type of the current member
62 0 : pub fn get_type(&self) -> Option<Type> {
63 0 : into_optional(self.ptr.get_type())
64 0 : }
65 :
66 0 : pub fn is_external(&self) -> bool {
67 0 : self.ptr.is_external()
68 0 : }
69 :
70 0 : pub fn is_declaration(&self) -> bool {
71 0 : self.ptr.is_declaration()
72 0 : }
73 : }
74 :
75 : impl FromFFI<ffi::DWARF_types_ClassLike_Member> for Member<'_> {
76 0 : fn from_ffi(cmd: cxx::UniquePtr<ffi::DWARF_types_ClassLike_Member>) -> Self {
77 0 : Self {
78 0 : ptr: cmd,
79 0 : _owner: PhantomData,
80 0 : }
81 0 : }
82 : }
83 :
84 : /// This structure represents a `DW_TAG_structure_type` DWARF type
85 : pub struct Structure<'a> {
86 : ptr: cxx::UniquePtr<ffi::DWARF_types_Structure>,
87 : _owner: PhantomData<&'a ()>,
88 : }
89 :
90 : impl FromFFI<ffi::DWARF_types_Structure> for Structure<'_> {
91 0 : fn from_ffi(cmd: cxx::UniquePtr<ffi::DWARF_types_Structure>) -> Self {
92 0 : Self {
93 0 : ptr: cmd,
94 0 : _owner: PhantomData,
95 0 : }
96 0 : }
97 : }
98 :
99 : impl DwarfType for Structure<'_> {
100 0 : fn get_base(&self) -> &ffi::DWARF_Type {
101 0 : self.ptr.as_ref().unwrap().as_ref().as_ref()
102 0 : }
103 : }
104 :
105 : impl ClassLike for Structure<'_> {
106 0 : fn get_classlike(&self) -> &ffi::DWARF_types_ClassLike {
107 0 : self.ptr.as_ref().unwrap().as_ref()
108 0 : }
109 : }
110 :
111 : /// This structure represents a `DW_TAG_union_type` DWARF type
112 : pub struct Union<'a> {
113 : ptr: cxx::UniquePtr<ffi::DWARF_types_Union>,
114 : _owner: PhantomData<&'a ()>,
115 : }
116 :
117 : impl FromFFI<ffi::DWARF_types_Union> for Union<'_> {
118 0 : fn from_ffi(cmd: cxx::UniquePtr<ffi::DWARF_types_Union>) -> Self {
119 0 : Self {
120 0 : ptr: cmd,
121 0 : _owner: PhantomData,
122 0 : }
123 0 : }
124 : }
125 :
126 : impl DwarfType for Union<'_> {
127 0 : fn get_base(&self) -> &ffi::DWARF_Type {
128 0 : self.ptr.as_ref().unwrap().as_ref().as_ref()
129 0 : }
130 : }
131 :
132 : impl ClassLike for Union<'_> {
133 0 : fn get_classlike(&self) -> &ffi::DWARF_types_ClassLike {
134 0 : self.ptr.as_ref().unwrap().as_ref()
135 0 : }
136 : }
137 :
138 : /// This structure represents a DWARF `packed` type (`DW_TAG_packed_type`)
139 : pub struct Packed<'a> {
140 : ptr: cxx::UniquePtr<ffi::DWARF_types_Packed>,
141 : _owner: PhantomData<&'a ()>,
142 : }
143 :
144 : impl FromFFI<ffi::DWARF_types_Packed> for Packed<'_> {
145 0 : fn from_ffi(cmd: cxx::UniquePtr<ffi::DWARF_types_Packed>) -> Self {
146 0 : Self {
147 0 : ptr: cmd,
148 0 : _owner: PhantomData,
149 0 : }
150 0 : }
151 : }
152 :
153 : impl DwarfType for Packed<'_> {
154 0 : fn get_base(&self) -> &ffi::DWARF_Type {
155 0 : self.ptr.as_ref().unwrap().as_ref().as_ref()
156 0 : }
157 : }
158 :
159 : impl ClassLike for Packed<'_> {
160 0 : fn get_classlike(&self) -> &ffi::DWARF_types_ClassLike {
161 0 : self.ptr.as_ref().unwrap().as_ref()
162 0 : }
163 : }
164 :
165 : /// This structure represents a `DW_TAG_class_type` DWARF type
166 : pub struct Class<'a> {
167 : ptr: cxx::UniquePtr<ffi::DWARF_types_Class>,
168 : _owner: PhantomData<&'a ()>,
169 : }
170 :
171 : impl FromFFI<ffi::DWARF_types_Class> for Class<'_> {
172 0 : fn from_ffi(cmd: cxx::UniquePtr<ffi::DWARF_types_Class>) -> Self {
173 0 : Self {
174 0 : ptr: cmd,
175 0 : _owner: PhantomData,
176 0 : }
177 0 : }
178 : }
179 :
180 : impl DwarfType for Class<'_> {
181 0 : fn get_base(&self) -> &ffi::DWARF_Type {
182 0 : self.ptr.as_ref().unwrap().as_ref().as_ref()
183 0 : }
184 : }
185 :
186 : impl ClassLike for Class<'_> {
187 0 : fn get_classlike(&self) -> &ffi::DWARF_types_ClassLike {
188 0 : self.ptr.as_ref().unwrap().as_ref()
189 0 : }
190 : }
191 :
192 0 : declare_fwd_iterator!(
193 0 : Members,
194 0 : Member<'a>,
195 0 : ffi::DWARF_types_ClassLike_Member,
196 0 : ffi::DWARF_types_ClassLike,
197 0 : ffi::DWARF_types_ClassLike_it_members
198 0 : );
199 :
200 :
201 0 : declare_fwd_iterator!(
202 0 : Functions,
203 0 : Function<'a>,
204 0 : ffi::DWARF_Function,
205 0 : ffi::DWARF_types_ClassLike,
206 0 : ffi::DWARF_types_ClassLike_it_functions
207 0 : );
|