sleigh_rs/semantic/inner/
varnode.rs1use crate::semantic::meaning::Meaning;
2use crate::semantic::varnode::ContextAttach;
3use crate::semantic::Context as FinalContext;
4use crate::semantic::{
5 syntax, Bitrange, BitrangeId, ContextId, GlobalScope, UserFunction,
6 UserFunctionId, Varnode, VarnodeId,
7};
8use crate::{FieldBits, NumberNonZeroUnsigned, NumberUnsigned, SleighError};
9
10use super::execution::FieldSize;
11use super::{PrintFlags, Sleigh};
12
13#[derive(Debug)]
14pub struct Context {
15 pub name: String,
16 pub bitrange: Bitrange,
17 pub noflow_set: bool,
18 pub print_flags: PrintFlags,
19 pub attach: Option<ContextAttach>,
20}
21
22impl Context {
23 pub fn attach(&mut self, meaning: Meaning) -> Result<(), SleighError> {
24 if self.attach.is_some() {
25 return Err(SleighError::AttachMultiple(
27 self.bitrange.location.clone(),
28 ));
29 }
30 if self.print_flags.signed_set {
31 todo!("Is allowed to attach to signed value?");
32 }
33 if meaning.is_number() && self.print_flags.base.is_some() {
34 todo!("Is allowed to attach varnode/literal if base is set?");
35 }
36 let attach = match meaning {
37 Meaning::NoAttach(_) => unreachable!(),
38 Meaning::Varnode(x) => ContextAttach::Varnode(x),
39 Meaning::Literal(x) => ContextAttach::Literal(x),
40 Meaning::Number(_, _x) => {
41 return Err(SleighError::ContextAttachNumber(
43 self.bitrange.location.clone(),
44 ));
45 }
46 };
47 self.attach = Some(attach);
49 Ok(())
50 }
51
52 pub fn exec_out_value_bits(&self, sleigh: &Sleigh) -> FieldSize {
53 match self.attach {
54 Some(ContextAttach::NoAttach(_)) => unreachable!(),
56 Some(ContextAttach::Literal(_)) | None => FieldSize::default()
57 .set_min(self.bitrange.bits.len())
58 .unwrap(),
59 Some(ContextAttach::Varnode(attach_id)) => {
60 let varnodes = sleigh.attach_varnode(attach_id);
61 varnodes.execution_len(sleigh)
63 }
64 }
65 }
66
67 pub fn convert(self) -> FinalContext {
68 let attach = self
70 .attach
71 .unwrap_or(ContextAttach::NoAttach(self.print_flags.into()));
72 FinalContext {
73 name: self.name.into(),
74 bitrange: self.bitrange,
75 noflow: self.noflow_set,
76 attach,
77 }
78 }
79}
80
81impl Sleigh {
82 pub fn create_memory(
83 &mut self,
84 varnode: syntax::define::Varnode,
85 ) -> Result<(), SleighError> {
86 let space = self
87 .get_global(&varnode.space_name)
88 .ok_or_else(|| {
89 SleighError::SpaceUndefined(varnode.space_span.clone())
90 })?
91 .space()
92 .ok_or_else(|| {
93 SleighError::SpaceInvalid(varnode.space_span.clone())
94 })?;
95 let varnode_bytes = NumberNonZeroUnsigned::new(varnode.value_bytes)
96 .ok_or_else(|| {
97 SleighError::VarnodeInvalidSize(varnode.space_span.clone())
98 })?;
99
100 if varnode.names.is_empty() {
101 todo!("TODO ERROR here")
103 }
104 for (index, (varnode_name, location)) in
105 varnode.names.into_iter().enumerate()
106 {
107 let Some(varnode_name) = varnode_name else {
108 continue;
110 };
111 let address = index as NumberUnsigned * varnode_bytes.get();
112 let location = location.clone();
113 let varnode = Varnode {
114 name: varnode_name.clone().into(),
115 location,
116 address,
117 len_bytes: varnode_bytes,
118 space,
119 };
120 self.varnodes.push(varnode);
121 let varnode_id = VarnodeId(self.varnodes.len() - 1);
122 self.global_scope
123 .insert(varnode_name, GlobalScope::Varnode(varnode_id))
124 .map(|_| Err(SleighError::NameDuplicated))
125 .unwrap_or(Ok(()))?;
126 }
127 Ok(())
128 }
129 pub fn create_bitrange(
130 &mut self,
131 bitrange: syntax::define::BitRangeDef,
132 ) -> Result<(), SleighError> {
133 for field in bitrange.into_iter() {
134 let varnode_id = self
135 .get_global(&field.varnode_name)
136 .ok_or_else(|| {
137 SleighError::VarnodeUndefined(field.src.clone())
138 })?
139 .varnode()
140 .ok_or_else(|| {
141 SleighError::VarnodeInvalid(field.src.clone())
142 })?;
143 let varnode = self.varnode(varnode_id);
144 let bits: FieldBits = field.range.try_into()?;
145
146 let varnode_size = varnode.len_bytes.get() * 8;
150 if bits.field_min_len().get() > varnode_size {
152 return Err(SleighError::VarnodeInvalidSize(field.src.clone()));
153 }
154
155 let bitrange = Bitrange {
156 location: field.src,
157 bits,
158 varnode: varnode_id,
159 };
160
161 self.bitranges.push(bitrange);
162 let bitrange_id = BitrangeId(self.bitranges.len() - 1);
163 self.global_scope
164 .insert(field.name, GlobalScope::Bitrange(bitrange_id))
165 .map(|_| Err(SleighError::NameDuplicated))
166 .unwrap_or(Ok(()))?;
167 }
168 Ok(())
169 }
170 pub fn create_user_function(
171 &mut self,
172 input: syntax::define::UserFunction,
173 ) -> Result<(), SleighError> {
174 let user_function = UserFunction(input.src);
175 self.user_functions.push(user_function);
176 let user_function_id = UserFunctionId(self.user_functions.len() - 1);
177 self.global_scope
178 .insert(input.name, GlobalScope::UserFunction(user_function_id))
179 .map(|_| Err(SleighError::NameDuplicated))
180 .unwrap_or(Ok(()))
181 }
182 pub fn create_context(
183 &mut self,
184 input: syntax::define::Context,
185 ) -> Result<(), SleighError> {
186 let varnode_id = self
187 .get_global(&input.varnode_name)
188 .ok_or_else(|| {
189 SleighError::VarnodeUndefined(input.varnode_span.clone())
190 })?
191 .varnode()
192 .ok_or_else(|| {
193 SleighError::VarnodeInvalid(input.varnode_span.clone())
194 })?;
195 let varnode_len_bits = self.varnode(varnode_id).len_bytes.get() * 8;
196 for field in input.fields.into_iter() {
197 let bits: FieldBits = field.range.try_into()?;
199 if bits.field_min_len().get() > varnode_len_bits {
202 return Err(SleighError::ContextInvalidSize(field.src.clone()));
203 }
204 let print_flags = PrintFlags::from_token_att(
205 &field.src,
206 field.attributes.iter().filter_map(|att| match att {
207 syntax::define::ContextFieldAttribute::Token(att) => {
208 Some(att)
209 }
210 syntax::define::ContextFieldAttribute::Noflow => None,
211 }),
212 )?;
213 let noflow = field
215 .attributes
216 .iter()
217 .filter(|att| {
218 matches!(att, syntax::define::ContextFieldAttribute::Noflow)
219 })
220 .count();
221 let noflow_set = match noflow {
222 0 => false,
223 1 => true,
224 _ => return Err(SleighError::ContextAttDup(field.src.clone())),
225 };
226
227 let context = Context {
229 name: field.name.clone(),
230 bitrange: Bitrange {
231 location: field.src,
232 bits,
233 varnode: varnode_id,
234 },
235 noflow_set,
236 print_flags,
237 attach: None,
238 };
239 self.contexts.push(context);
240 let context_id = ContextId(self.contexts.len() - 1);
241 self.global_scope
242 .insert(field.name, GlobalScope::Context(context_id))
243 .map(|_| Err(SleighError::NameDuplicated))
244 .unwrap_or(Ok(()))?;
245 }
246 Ok(())
247 }
248}