Line data Source code
1 : use lief_ffi as ffi;
2 :
3 : use super::Type;
4 : use crate::common::FromFFI;
5 :
6 : use crate::common::into_optional;
7 : use std::marker::PhantomData;
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 : impl Parameter for Parameters<'_> {
70 0 : fn get_base(&self) -> &ffi::DWARF_Parameter {
71 0 : match &self {
72 0 : Parameters::Formal(p) => p.get_base(),
73 0 : Parameters::TemplateValue(p) => p.get_base(),
74 0 : Parameters::TemplateType(p) => p.get_base(),
75 : }
76 0 : }
77 : }
78 :
79 : pub struct Formal<'a> {
80 : ptr: cxx::UniquePtr<ffi::DWARF_parameters_Formal>,
81 : _owner: PhantomData<&'a ()>,
82 : }
83 :
84 : impl FromFFI<ffi::DWARF_parameters_Formal> for Formal<'_> {
85 0 : fn from_ffi(ptr: cxx::UniquePtr<ffi::DWARF_parameters_Formal>) -> Self {
86 0 : Self {
87 0 : ptr,
88 0 : _owner: PhantomData,
89 0 : }
90 0 : }
91 : }
92 :
93 : impl Parameter for Formal<'_> {
94 0 : fn get_base(&self) -> &ffi::DWARF_Parameter {
95 0 : self.ptr.as_ref().unwrap().as_ref()
96 0 : }
97 : }
98 :
99 : pub struct TemplateValue<'a> {
100 : ptr: cxx::UniquePtr<ffi::DWARF_parameters_TemplateValue>,
101 : _owner: PhantomData<&'a ()>,
102 : }
103 :
104 : impl FromFFI<ffi::DWARF_parameters_TemplateValue> for TemplateValue<'_> {
105 0 : fn from_ffi(ptr: cxx::UniquePtr<ffi::DWARF_parameters_TemplateValue>) -> Self {
106 0 : Self {
107 0 : ptr,
108 0 : _owner: PhantomData,
109 0 : }
110 0 : }
111 : }
112 :
113 : impl Parameter for TemplateValue<'_> {
114 0 : fn get_base(&self) -> &ffi::DWARF_Parameter {
115 0 : self.ptr.as_ref().unwrap().as_ref()
116 0 : }
117 : }
118 :
119 : pub struct TemplateType<'a> {
120 : ptr: cxx::UniquePtr<ffi::DWARF_parameters_TemplateType>,
121 : _owner: PhantomData<&'a ()>,
122 : }
123 :
124 : impl FromFFI<ffi::DWARF_parameters_TemplateType> for TemplateType<'_> {
125 0 : fn from_ffi(ptr: cxx::UniquePtr<ffi::DWARF_parameters_TemplateType>) -> Self {
126 0 : Self {
127 0 : ptr,
128 0 : _owner: PhantomData,
129 0 : }
130 0 : }
131 : }
132 :
133 : impl Parameter for TemplateType<'_> {
134 0 : fn get_base(&self) -> &ffi::DWARF_Parameter {
135 0 : self.ptr.as_ref().unwrap().as_ref()
136 0 : }
137 : }
138 :
139 : /// Enum that represents the different type of locations for a parameters
140 : pub enum Location<'a> {
141 : /// Register location (e.g. `r8, x13`)
142 : Register(RegisterLocation<'a>),
143 : }
144 :
145 : impl FromFFI<ffi::DWARF_Parameter_Location> for Location<'_> {
146 0 : fn from_ffi(ffi_entry: cxx::UniquePtr<ffi::DWARF_Parameter_Location>) -> Self {
147 0 : unsafe {
148 0 : let loc_ref = ffi_entry.as_ref().unwrap();
149 0 :
150 0 : if ffi::DWARF_Parameter_RegisterLocation::classof(loc_ref) {
151 0 : let raw = {
152 0 : type From = cxx::UniquePtr<ffi::DWARF_Parameter_Location>;
153 0 : type To = cxx::UniquePtr<ffi::DWARF_Parameter_RegisterLocation>;
154 0 : std::mem::transmute::<From, To>(ffi_entry)
155 0 : };
156 0 : Location::Register(RegisterLocation::from_ffi(raw))
157 : } else {
158 0 : panic!("Unknown Parameter");
159 : }
160 : }
161 0 : }
162 : }
163 :
164 : /// Location as a register
165 : pub struct RegisterLocation<'a> {
166 : ptr: cxx::UniquePtr<ffi::DWARF_Parameter_RegisterLocation>,
167 : _owner: PhantomData<&'a ()>,
168 : }
169 :
170 : impl FromFFI<ffi::DWARF_Parameter_RegisterLocation> for RegisterLocation<'_> {
171 0 : fn from_ffi(ptr: cxx::UniquePtr<ffi::DWARF_Parameter_RegisterLocation>) -> Self {
172 0 : Self {
173 0 : ptr,
174 0 : _owner: PhantomData,
175 0 : }
176 0 : }
177 : }
178 :
179 : impl RegisterLocation<'_> {
180 : /// DWARF id of the register (e.g. `DW_OP_reg0`)
181 0 : pub fn id(&self) -> u64 {
182 0 : self.ptr.id()
183 0 : }
184 : }
|