1use std::{collections::BTreeMap, fmt};
4
5use rudy_dwarf::{function::SelfType, types::DieTypeDefinition};
6
7#[derive(Clone, Copy, PartialEq, Eq)]
9pub struct ResolvedAddress {
10 pub address: u64,
11}
12
13impl fmt::Debug for ResolvedAddress {
14 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
15 f.debug_struct("ResolvedAddress")
16 .field("address", &format!("{:#x}", self.address))
17 .finish()
18 }
19}
20
21#[derive(Debug, PartialEq, Clone)]
23pub struct ResolvedLocation {
24 pub function: String,
25 pub file: String,
26 pub line: u64,
27}
28
29#[derive(Debug, PartialEq, Eq, Clone)]
31pub struct Variable {
32 pub name: String,
33 pub value: Option<Value>,
34 pub ty: DieTypeDefinition,
35}
36
37#[derive(Debug, Clone)]
39pub struct VariableInfo {
40 pub name: String,
42 pub address: Option<u64>,
44 pub type_def: DieTypeDefinition,
46}
47
48impl VariableInfo {
49 pub fn as_pointer(&self) -> Option<TypedPointer> {
50 self.address.map(|address| TypedPointer {
51 address,
52 type_def: self.type_def.clone(),
53 })
54 }
55}
56
57#[derive(Debug, Clone, PartialEq, Eq)]
59pub struct TypedPointer {
60 pub address: u64,
62 pub type_def: DieTypeDefinition,
64}
65
66#[derive(Debug, PartialEq, Eq, Clone)]
68pub enum Value {
69 Scalar {
70 ty: String,
71 value: String,
72 },
73 Array {
74 ty: String,
75 items: Vec<Value>,
76 },
77 Struct {
78 ty: String,
79 fields: BTreeMap<String, Value>,
80 },
81 Tuple {
82 ty: String,
83 entries: Vec<Value>,
84 },
85 Map {
86 ty: String,
87 entries: Vec<(Value, Value)>,
88 },
89 Pointer(TypedPointer),
90}
91
92impl Value {
93 pub(crate) fn map_type<F>(&self, type_map: F) -> Self
94 where
95 F: Fn(&str) -> String,
96 {
97 match self {
98 Value::Scalar { value, ty } => Value::Scalar {
99 ty: type_map(ty),
100 value: value.clone(),
101 },
102 Value::Array { items, ty } => Value::Array {
103 ty: type_map(ty),
104 items: items.clone(),
105 },
106 Value::Tuple { entries, ty } => Value::Tuple {
107 ty: type_map(ty),
108 entries: entries.clone(),
109 },
110 Value::Struct { fields, ty } => Value::Struct {
111 ty: type_map(ty),
112 fields: fields.clone(),
113 },
114 Value::Map { entries, ty } => Value::Map {
115 ty: type_map(ty),
116 entries: entries.clone(),
117 },
118 Value::Pointer(ptr) => Value::Pointer(TypedPointer {
119 address: ptr.address,
120 type_def: ptr.type_def.clone(),
121 }),
122 }
123 }
124
125 pub(crate) fn prefix_type<T: AsRef<str>>(&self, prefix: T) -> Self {
127 let prefix = prefix.as_ref();
128 self.map_type(|ty| format!("{prefix}{ty}"))
129 }
130 pub(crate) fn wrap_type<T: AsRef<str>>(&self, new_ty: T) -> Self {
132 let new_ty = new_ty.as_ref();
133 self.map_type(|ty| format!("{new_ty}<{ty}>"))
134 }
135}
136
137impl PartialOrd for Value {
138 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
139 Some(self.cmp(other))
140 }
141}
142
143impl Ord for Value {
144 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
145 use std::cmp::Ordering;
146 match (self, other) {
147 (
148 Value::Scalar {
149 ty: ty1,
150 value: val1,
151 },
152 Value::Scalar {
153 ty: ty2,
154 value: val2,
155 },
156 ) => ty1.cmp(ty2).then_with(|| val1.cmp(val2)),
157 (
158 Value::Array {
159 ty: ty1,
160 items: items1,
161 },
162 Value::Array {
163 ty: ty2,
164 items: items2,
165 },
166 ) => ty1.cmp(ty2).then_with(|| items1.cmp(items2)),
167 (
168 Value::Struct {
169 ty: ty1,
170 fields: fields1,
171 },
172 Value::Struct {
173 ty: ty2,
174 fields: fields2,
175 },
176 ) => ty1.cmp(ty2).then_with(|| fields1.cmp(fields2)),
177 (
178 Value::Tuple {
179 ty: ty1,
180 entries: entries1,
181 },
182 Value::Tuple {
183 ty: ty2,
184 entries: entries2,
185 },
186 ) => ty1.cmp(ty2).then_with(|| entries1.cmp(entries2)),
187 (
188 Value::Map {
189 ty: ty1,
190 entries: entries1,
191 },
192 Value::Map {
193 ty: ty2,
194 entries: entries2,
195 },
196 ) => ty1.cmp(ty2).then_with(|| entries1.cmp(entries2)),
197 (Value::Pointer(ptr1), Value::Pointer(ptr2)) => ptr1.address.cmp(&ptr2.address),
198 (Value::Scalar { .. }, _) => Ordering::Less,
200 (Value::Array { .. }, Value::Scalar { .. }) => Ordering::Greater,
201 (Value::Array { .. }, _) => Ordering::Less,
202 (Value::Struct { .. }, Value::Scalar { .. }) => Ordering::Greater,
203 (Value::Struct { .. }, Value::Array { .. }) => Ordering::Greater,
204 (Value::Struct { .. }, _) => Ordering::Less,
205 (Value::Tuple { .. }, Value::Pointer(_)) => Ordering::Less,
206 (Value::Tuple { .. }, Value::Map { .. }) => Ordering::Less,
207 (Value::Tuple { .. }, _) => Ordering::Greater,
208 (Value::Map { .. }, Value::Pointer(_)) => Ordering::Less,
209 (Value::Map { .. }, _) => Ordering::Greater,
210 (Value::Pointer(_), _) => Ordering::Greater,
211 }
212 }
213}
214
215#[derive(Debug, PartialEq, Eq, Clone)]
217pub struct Type {
218 pub name: String,
219}
220
221#[derive(PartialEq, Eq, Clone)]
223pub struct ResolvedFunction {
224 pub name: String,
225 pub address: u64,
226 pub size: u64,
227 pub params: Vec<Variable>,
228}
229
230impl fmt::Debug for ResolvedFunction {
231 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
232 f.debug_struct("ResolvedFunction")
233 .field("name", &self.name)
234 .field("address", &format!("{:#x}", self.address))
235 .field("size", &format!("{:#x}", self.size))
236 .field("params", &self.params)
237 .finish()
238 }
239}
240
241#[derive(Debug, Clone)]
243pub struct DiscoveredMethod {
244 pub name: String,
246 pub full_name: String,
248 pub signature: String,
250 pub address: u64,
252 pub self_type: Option<SelfType>,
254 pub callable: bool,
256 pub is_synthetic: bool,
258 pub return_type: Option<DieTypeDefinition>,
260 pub parameters: Vec<FunctionParameter>,
262}
263
264#[derive(Debug, Clone)]
266pub struct DiscoveredFunction {
267 pub name: String,
269 pub full_name: String,
271 pub signature: String,
273 pub address: u64,
275 pub callable: bool,
277 pub module_path: Vec<String>,
279 pub return_type: Option<DieTypeDefinition>,
281 pub parameters: Vec<FunctionParameter>,
283}
284
285#[derive(Debug, Clone)]
287pub struct FunctionParameter {
288 pub name: Option<String>,
290 pub type_def: DieTypeDefinition,
292}