1use std::borrow::Cow;
2
3use serde::{Deserialize, Serialize};
4
5use crate::{
6 symbols::Symbols,
7 types::{BaseRef, Enum, Struct, Type, Types},
8};
9
10#[derive(Debug, Serialize, Deserialize)]
14pub struct Profile<'a> {
15 #[serde(borrow)]
17 architecture: Cow<'a, str>,
18
19 #[serde(borrow)]
21 symbols: Symbols<'a>,
22
23 #[serde(borrow)]
25 types: Types<'a>,
26}
27
28impl<'a> Profile<'a> {
29 pub fn new(architecture: Cow<'a, str>, symbols: Symbols<'a>, types: Types<'a>) -> Self {
31 Self {
32 architecture,
33 symbols,
34 types,
35 }
36 }
37
38 pub fn symbols(&self) -> impl Iterator<Item = (&str, &u64)> {
40 self.symbols
41 .0
42 .iter()
43 .map(|(name, value)| (name.as_ref(), value))
44 }
45
46 pub fn types(&self) -> &Types<'_> {
48 &self.types
49 }
50
51 pub fn type_size(&self, type_: &Type) -> Option<u64> {
53 match type_ {
54 Type::Base(r) => Some(self.base_size(r)),
55 Type::Enum(r) => self.enum_size(&r.name),
56 Type::Struct(r) => self.struct_size(&r.name),
57 Type::Array(r) => self.type_size(&r.subtype),
58 Type::Pointer(_) => Some(self.pointer_size()),
59 Type::Bitfield(r) => self.type_size(&r.subtype),
60 Type::Function => Some(self.pointer_size()),
61 }
62 }
63
64 pub fn base_size(&self, base: &BaseRef) -> u64 {
66 match base {
67 BaseRef::Void => 0,
68 BaseRef::Bool | BaseRef::Char | BaseRef::I8 | BaseRef::U8 | BaseRef::F8 => 1,
69 BaseRef::Wchar | BaseRef::I16 | BaseRef::U16 | BaseRef::F16 => 2,
70 BaseRef::I32 | BaseRef::U32 | BaseRef::F32 => 4,
71 BaseRef::I64 | BaseRef::U64 | BaseRef::F64 => 8,
72 BaseRef::I128 | BaseRef::U128 | BaseRef::F128 => 16,
73 }
74 }
75
76 pub fn enum_size(&self, name: &str) -> Option<u64> {
78 self.type_size(&self.types.enums.get(name)?.subtype)
79 }
80
81 pub fn struct_size(&self, name: &str) -> Option<u64> {
83 self.types.structs.get(name).map(|udt| udt.size)
84 }
85
86 pub fn pointer_size(&self) -> u64 {
88 match self.architecture.as_ref() {
89 "X86" | "Arm" => 4,
90 "Amd64" | "Arm64" => 8,
91 _ => panic!("unsupported architecture"),
92 }
93 }
94
95 pub fn find_symbol(&self, symbol_name: &str) -> Option<u64> {
97 self.symbols.0.get(symbol_name).copied()
98 }
99
100 pub fn find_enum(&self, type_name: &str) -> Option<&Enum<'_>> {
102 self.types.enums.get(type_name)
103 }
104
105 pub fn find_struct(&self, type_name: &str) -> Option<&Struct<'_>> {
107 self.types.structs.get(type_name)
108 }
109}