sleigh_rs/semantic/
execution.rs

1use crate::{Number, NumberNonZeroUnsigned, NumberUnsigned, Span};
2
3use super::{
4    disassembly, pcode_macro::PcodeMacroCallId, BitrangeId, ContextId,
5    InstNext, InstStart, SpaceId, TableId, TokenFieldId, UserFunctionId,
6    VarnodeId,
7};
8
9#[derive(Clone, Debug)]
10pub struct Execution {
11    pub(crate) blocks: Box<[Block]>,
12    pub(crate) variables: Box<[Variable]>,
13
14    //entry_block have no name and is not on self.labels
15    pub entry_block: BlockId,
16}
17
18#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
19pub struct BlockId(pub(crate) usize);
20
21#[derive(Clone, Debug)]
22pub struct Block {
23    //None is entry block
24    pub name: Option<Box<str>>,
25    pub next: Option<BlockId>,
26    pub statements: Box<[Statement]>,
27}
28
29#[derive(Clone, Debug)]
30pub enum Statement {
31    Delayslot(NumberUnsigned),
32    Export(Export),
33    CpuBranch(CpuBranch),
34    LocalGoto(LocalGoto),
35    UserCall(UserCall),
36    MacroCall(MacroCall),
37    Build(Build),
38    Declare(VariableId),
39    Assignment(Assignment),
40    MemWrite(MemWrite),
41}
42
43#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
44pub struct VariableId(pub(crate) usize);
45
46#[derive(Clone, Debug)]
47pub struct Variable {
48    pub(crate) name: Box<str>,
49    pub len_bits: NumberNonZeroUnsigned,
50    pub location: Option<Span>,
51}
52
53#[derive(Clone, Debug)]
54pub enum Expr {
55    Value(ExprElement),
56    Op(ExprBinaryOp),
57}
58
59#[derive(Clone, Debug)]
60pub struct ExprBinaryOp {
61    pub location: Span,
62    pub len_bits: NumberNonZeroUnsigned,
63    pub op: Binary,
64    pub left: Box<Expr>,
65    pub right: Box<Expr>,
66}
67
68#[derive(Clone, Debug)]
69pub enum ExprElement {
70    Value(ReadValue),
71    UserCall(UserCall),
72    Reference(Reference),
73    Op(ExprUnaryOp),
74    New(ExprNew),
75    CPool(ExprCPool),
76}
77
78#[derive(Clone, Debug)]
79pub struct Reference {
80    pub location: Span,
81    pub len_bits: NumberNonZeroUnsigned,
82    pub value: ReferencedValue,
83}
84
85#[derive(Clone, Debug)]
86pub struct ExprUnaryOp {
87    pub location: Span,
88    pub output_bits: NumberNonZeroUnsigned,
89    pub op: Unary,
90    pub input: Box<Expr>,
91}
92
93#[derive(Clone, Debug)]
94pub struct ExprNew {
95    pub location: Span,
96    pub first: Box<Expr>,
97    pub second: Option<Box<Expr>>,
98}
99
100#[derive(Clone, Debug)]
101pub struct ExprCPool {
102    pub location: Span,
103    pub params: Box<[Expr]>,
104}
105
106#[derive(Clone, Debug)]
107pub struct UserCall {
108    pub location: Span,
109    pub function: UserFunctionId,
110    pub params: Box<[Expr]>,
111}
112
113#[derive(Clone, Debug)]
114pub enum ReadValue {
115    Int(ExprNumber),
116    TokenField(ExprTokenField),
117    InstStart(ExprInstStart),
118    InstNext(ExprInstNext),
119    Varnode(ExprVarnode),
120    Context(ExprContext),
121    Bitrange(ExprBitrange),
122    Table(ExprTable),
123    DisVar(ExprDisVar),
124    ExeVar(ExprExeVar),
125}
126
127#[derive(Clone, Debug)]
128pub struct ExprNumber {
129    pub location: Span,
130    pub len_bits: NumberNonZeroUnsigned,
131    pub number: Number,
132}
133
134#[derive(Clone, Debug)]
135pub struct ExprTokenField {
136    pub location: Span,
137    pub id: TokenFieldId,
138}
139
140#[derive(Clone, Debug)]
141pub struct ExprInstStart {
142    pub location: Span,
143    pub data: InstStart,
144}
145
146#[derive(Clone, Debug)]
147pub struct ExprInstNext {
148    pub location: Span,
149    pub data: InstNext,
150}
151
152#[derive(Clone, Debug)]
153pub struct ExprVarnode {
154    pub location: Span,
155    pub id: VarnodeId,
156}
157
158#[derive(Clone, Debug)]
159pub struct ExprContext {
160    pub location: Span,
161    pub id: ContextId,
162}
163
164#[derive(Clone, Debug)]
165pub struct ExprBitrange {
166    pub location: Span,
167    pub id: BitrangeId,
168}
169
170#[derive(Clone, Debug)]
171pub struct ExprTable {
172    pub location: Span,
173    pub id: TableId,
174}
175
176#[derive(Clone, Debug)]
177pub struct ExprDisVar {
178    pub location: Span,
179    pub len_bits: NumberNonZeroUnsigned,
180    pub id: disassembly::VariableId,
181}
182
183#[derive(Clone, Debug)]
184pub struct ExprExeVar {
185    pub location: Span,
186    pub id: VariableId,
187}
188
189#[derive(Clone, Debug)]
190pub enum ReferencedValue {
191    //only if translate into varnode
192    TokenField(ExprTokenField),
193    InstStart(ExprInstStart),
194    InstNext(ExprInstNext),
195    Table(ExprTable),
196}
197
198#[derive(Clone, Debug)]
199pub struct CpuBranch {
200    pub cond: Option<Expr>,
201    pub call: BranchCall,
202    pub direct: bool,
203    pub dst: Expr,
204}
205
206#[derive(Clone, Debug, Copy)]
207pub enum BranchCall {
208    Goto,
209    Call,
210    Return,
211}
212
213#[derive(Clone, Debug)]
214pub struct LocalGoto {
215    pub cond: Option<Expr>,
216    pub dst: BlockId,
217}
218
219#[derive(Clone, Debug)]
220pub enum WriteValue {
221    Varnode(ExprVarnode),
222    Bitrange(ExprBitrange),
223    ///only with attach variable
224    TokenField(ExprTokenField),
225    TableExport(ExprTable),
226    Local(ExprExeVar),
227}
228
229#[derive(Clone, Debug)]
230pub struct Assignment {
231    pub location: Span,
232    pub var: WriteValue,
233    pub op: Option<Truncate>,
234    pub right: Expr,
235}
236
237#[derive(Clone, Debug)]
238pub struct MemWrite {
239    pub addr: Expr,
240    pub mem: MemoryLocation,
241    pub right: Expr,
242}
243
244#[derive(Clone, Debug)]
245pub struct WriteAddr {
246    pub space: MemoryLocation,
247    pub expr: Expr,
248}
249
250#[derive(Clone, Debug)]
251pub struct Build {
252    pub table: ExprTable,
253}
254
255#[derive(Clone, Debug)]
256pub struct MacroCall {
257    pub params: Box<[Expr]>,
258    pub function: PcodeMacroCallId,
259}
260
261#[derive(Clone, Debug)]
262pub enum ExportConst {
263    DisVar(disassembly::VariableId),
264    /// Attach values are limited
265    TokenField(TokenFieldId),
266    /// Attach values are limited
267    Context(ContextId),
268    /// only if also export Const
269    Table(TableId),
270    ExeVar(VariableId),
271}
272
273#[derive(Clone, Debug)]
274pub enum Export {
275    /// export a value that is known before the execution step.
276    Const {
277        /// len in bits of the exported value
278        len_bits: NumberNonZeroUnsigned,
279        /// location of the value exported
280        location: Span,
281        /// exported value
282        export: ExportConst,
283    },
284    /// Arbitrarelly values
285    Value(Expr),
286    /// Reference to a memory
287    Reference { addr: Expr, memory: MemoryLocation },
288}
289
290#[derive(Clone, Debug)]
291pub struct MemoryLocation {
292    pub space: SpaceId,
293    pub len_bytes: NumberNonZeroUnsigned,
294}
295
296#[derive(Clone, Copy, Debug)]
297pub struct Truncate {
298    pub lsb: NumberUnsigned,
299    pub len_bits: NumberNonZeroUnsigned,
300}
301
302#[derive(Clone, Debug)]
303pub enum Unary {
304    //NOTE: The ByteRangeMsb, ByteRangeLsb and BitRange from docs are all
305    //Truncate
306    Truncate(Truncate),
307    Dereference(MemoryLocation),
308    //Reference(AddrReference),
309    Negation,
310    BitNegation,
311    Negative,
312    FloatNegative,
313    Popcount,
314    Lzcount,
315    Zext,
316    Sext,
317    FloatNan,
318    FloatAbs,
319    FloatSqrt,
320    Int2Float,
321    Float2Float,
322    SignTrunc,
323    FloatCeil,
324    FloatFloor,
325    FloatRound,
326}
327
328#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
329pub enum Binary {
330    //Binary Arithmetic
331    Mult,
332    Div,
333    SigDiv,
334    Rem,
335    FloatDiv,
336    FloatMult,
337    Add,
338    Sub,
339    FloatAdd,
340    FloatSub,
341    Lsl,
342    Lsr,
343    Asr,
344    BitAnd,
345    BitXor,
346    BitOr,
347    //Binary Logical
348    SigLess,
349    SigGreater,
350    SigRem,
351    SigLessEq,
352    SigGreaterEq,
353    Less,
354    Greater,
355    LessEq,
356    GreaterEq,
357    FloatLess,
358    FloatGreater,
359    FloatLessEq,
360    FloatGreaterEq,
361    And,
362    Xor,
363    Or,
364    Eq,
365    Ne,
366    FloatEq,
367    FloatNe,
368    //call functions
369    Carry,
370    SCarry,
371    SBorrow,
372}
373
374impl Variable {
375    pub fn name(&self) -> &str {
376        &self.name
377    }
378}
379
380impl Execution {
381    pub fn variable(&self, id: VariableId) -> &Variable {
382        &self.variables[id.0]
383    }
384    pub fn block(&self, id: BlockId) -> &Block {
385        &self.blocks[id.0]
386    }
387    pub fn export(&self) -> Option<&Export> {
388        todo!();
389    }
390}