Line data Source code
1 : use lief_ffi as ffi;
2 :
3 : use crate::common::FromFFI;
4 : use super::Type;
5 :
6 : use std::marker::PhantomData;
7 : use crate::common::into_optional;
8 :
9 : pub trait Parameter {
10 : #[doc(hidden)]
11 : fn get_base(&self) -> &ffi::DWARF_Parameter;
12 :
13 : /// The name of the parameter
14 0 : fn name(&self) -> String {
15 0 : self.get_base().name().to_string()
16 0 : }
17 :
18 : /// Return the type of the parameter
19 0 : fn get_type(&self) -> Option<Type> {
20 0 : into_optional(self.get_base().get_type())
21 0 : }
22 :
23 : /// Location of this parameter. For instance it can be a specific register
24 : /// that is not following the calling convention.
25 0 : fn location(&self) -> Option<Location> {
26 0 : into_optional(self.get_base().location())
27 0 : }
28 : }
29 :
30 : pub enum Parameters<'a> {
31 : Formal(Formal<'a>),
32 : TemplateValue(TemplateValue<'a>),
33 : TemplateType(TemplateType<'a>),
34 : }
35 :
36 : impl FromFFI<ffi::DWARF_Parameter> for Parameters<'_> {
37 0 : fn from_ffi(ffi_entry: cxx::UniquePtr<ffi::DWARF_Parameter>) -> Self {
38 0 : unsafe {
39 0 : let param_ref = ffi_entry.as_ref().unwrap();
40 0 :
41 0 : if ffi::DWARF_parameters_Formal::classof(param_ref) {
42 0 : let raw = {
43 0 : type From = cxx::UniquePtr<ffi::DWARF_Parameter>;
44 0 : type To = cxx::UniquePtr<ffi::DWARF_parameters_Formal>;
45 0 : std::mem::transmute::<From, To>(ffi_entry)
46 0 : };
47 0 : Parameters::Formal(Formal::from_ffi(raw))
48 0 : } else if ffi::DWARF_parameters_TemplateValue::classof(param_ref) {
49 0 : let raw = {
50 0 : type From = cxx::UniquePtr<ffi::DWARF_Parameter>;
51 0 : type To = cxx::UniquePtr<ffi::DWARF_parameters_TemplateValue>;
52 0 : std::mem::transmute::<From, To>(ffi_entry)
53 0 : };
54 0 : Parameters::TemplateValue(TemplateValue::from_ffi(raw))
55 0 : } else if ffi::DWARF_parameters_TemplateType::classof(param_ref) {
56 0 : let raw = {
57 0 : type From = cxx::UniquePtr<ffi::DWARF_Parameter>;
58 0 : type To = cxx::UniquePtr<ffi::DWARF_parameters_TemplateType>;
59 0 : std::mem::transmute::<From, To>(ffi_entry)
60 0 : };
61 0 : Parameters::TemplateType(TemplateType::from_ffi(raw))
62 : } else {
63 0 : panic!("Unknown Parameter");
64 : }
65 : }
66 0 : }
67 : }
68 :
69 :
70 : impl Parameter for Parameters<'_> {
71 0 : fn get_base(&self) -> &ffi::DWARF_Parameter {
72 0 : match &self {
73 0 : Parameters::Formal(p) => {
74 0 : p.get_base()
75 : }
76 0 : Parameters::TemplateValue(p) => {
77 0 : p.get_base()
78 : }
79 0 : Parameters::TemplateType(p) => {
80 0 : p.get_base()
81 : }
82 : }
83 0 : }
84 : }
85 :
86 : pub struct Formal<'a> {
87 : ptr: cxx::UniquePtr<ffi::DWARF_parameters_Formal>,
88 : _owner: PhantomData<&'a ()>,
89 : }
90 :
91 : impl FromFFI<ffi::DWARF_parameters_Formal> for Formal<'_> {
92 0 : fn from_ffi(ptr: cxx::UniquePtr<ffi::DWARF_parameters_Formal>) -> Self {
93 0 : Self {
94 0 : ptr,
95 0 : _owner: PhantomData,
96 0 : }
97 0 : }
98 : }
99 :
100 : impl Parameter for Formal<'_> {
101 0 : fn get_base(&self) -> &ffi::DWARF_Parameter {
102 0 : self.ptr.as_ref().unwrap().as_ref()
103 0 : }
104 : }
105 :
106 : pub struct TemplateValue<'a> {
107 : ptr: cxx::UniquePtr<ffi::DWARF_parameters_TemplateValue>,
108 : _owner: PhantomData<&'a ()>,
109 : }
110 :
111 : impl FromFFI<ffi::DWARF_parameters_TemplateValue> for TemplateValue<'_> {
112 0 : fn from_ffi(ptr: cxx::UniquePtr<ffi::DWARF_parameters_TemplateValue>) -> Self {
113 0 : Self {
114 0 : ptr,
115 0 : _owner: PhantomData,
116 0 : }
117 0 : }
118 : }
119 :
120 : impl Parameter for TemplateValue<'_> {
121 0 : fn get_base(&self) -> &ffi::DWARF_Parameter {
122 0 : self.ptr.as_ref().unwrap().as_ref()
123 0 : }
124 : }
125 :
126 : pub struct TemplateType<'a> {
127 : ptr: cxx::UniquePtr<ffi::DWARF_parameters_TemplateType>,
128 : _owner: PhantomData<&'a ()>,
129 : }
130 :
131 : impl FromFFI<ffi::DWARF_parameters_TemplateType> for TemplateType<'_> {
132 0 : fn from_ffi(ptr: cxx::UniquePtr<ffi::DWARF_parameters_TemplateType>) -> Self {
133 0 : Self {
134 0 : ptr,
135 0 : _owner: PhantomData,
136 0 : }
137 0 : }
138 : }
139 :
140 : impl Parameter for TemplateType<'_> {
141 0 : fn get_base(&self) -> &ffi::DWARF_Parameter {
142 0 : self.ptr.as_ref().unwrap().as_ref()
143 0 : }
144 : }
145 :
146 : /// Enum that represents the different type of locations for a parameters
147 : pub enum Location<'a> {
148 : /// Register location (e.g. `r8, x13`)
149 : Register(RegisterLocation<'a>)
150 : }
151 :
152 : impl FromFFI<ffi::DWARF_Parameter_Location> for Location<'_> {
153 0 : fn from_ffi(ffi_entry: cxx::UniquePtr<ffi::DWARF_Parameter_Location>) -> Self {
154 0 : unsafe {
155 0 : let loc_ref = ffi_entry.as_ref().unwrap();
156 0 :
157 0 : if ffi::DWARF_Parameter_RegisterLocation::classof(loc_ref) {
158 0 : let raw = {
159 0 : type From = cxx::UniquePtr<ffi::DWARF_Parameter_Location>;
160 0 : type To = cxx::UniquePtr<ffi::DWARF_Parameter_RegisterLocation>;
161 0 : std::mem::transmute::<From, To>(ffi_entry)
162 0 : };
163 0 : Location::Register(RegisterLocation::from_ffi(raw))
164 : } else {
165 0 : panic!("Unknown Parameter");
166 : }
167 : }
168 0 : }
169 : }
170 :
171 : /// Location as a register
172 : pub struct RegisterLocation<'a> {
173 : ptr: cxx::UniquePtr<ffi::DWARF_Parameter_RegisterLocation>,
174 : _owner: PhantomData<&'a ()>,
175 : }
176 :
177 : impl FromFFI<ffi::DWARF_Parameter_RegisterLocation> for RegisterLocation<'_> {
178 0 : fn from_ffi(ptr: cxx::UniquePtr<ffi::DWARF_Parameter_RegisterLocation>) -> Self {
179 0 : Self {
180 0 : ptr,
181 0 : _owner: PhantomData,
182 0 : }
183 0 : }
184 : }
185 :
186 : impl RegisterLocation<'_> {
187 : /// DWARF id of the register (e.g. `DW_OP_reg0`)
188 0 : pub fn id(&self) -> u64 {
189 0 : self.ptr.id()
190 0 : }
191 : }
|