1use super::operation::*;
2use super::{HighLevelExpressionIndex, HighLevelILFunction, HighLevelInstructionIndex};
3use std::fmt::{Debug, Formatter};
4
5use crate::architecture::CoreIntrinsic;
6use crate::rc::Ref;
7use crate::variable::{ConstantData, SSAVariable, Variable};
8
9#[derive(Clone, Debug)]
10pub enum HighLevelILLiftedOperand {
11 ConstantData(ConstantData),
12 Expr(HighLevelILLiftedInstruction),
13 ExprList(Vec<HighLevelILLiftedInstruction>),
14 Float(f64),
15 Int(u64),
16 IntList(Vec<u64>),
17 Intrinsic(CoreIntrinsic),
18 Label(GotoLabel),
19 MemberIndex(Option<usize>),
20 Var(Variable),
21 VarSsa(SSAVariable),
22 VarSsaList(Vec<SSAVariable>),
23}
24
25#[derive(Clone, PartialEq)]
30pub struct HighLevelILLiftedInstruction {
31 pub function: Ref<HighLevelILFunction>,
32 pub address: u64,
33 pub instr_index: HighLevelInstructionIndex,
34 pub expr_index: HighLevelExpressionIndex,
35 pub size: usize,
36 pub kind: HighLevelILLiftedInstructionKind,
37}
38
39#[derive(Clone, Debug, PartialEq)]
40pub enum HighLevelILLiftedInstructionKind {
41 Nop,
42 Break,
43 Continue,
44 Noret,
45 Unreachable,
46 Bp,
47 Undef,
48 Unimpl,
49 Adc(LiftedBinaryOpCarry),
50 Sbb(LiftedBinaryOpCarry),
51 Rlc(LiftedBinaryOpCarry),
52 Rrc(LiftedBinaryOpCarry),
53 Add(LiftedBinaryOp),
54 Sub(LiftedBinaryOp),
55 And(LiftedBinaryOp),
56 Or(LiftedBinaryOp),
57 Xor(LiftedBinaryOp),
58 Lsl(LiftedBinaryOp),
59 Lsr(LiftedBinaryOp),
60 Asr(LiftedBinaryOp),
61 Rol(LiftedBinaryOp),
62 Ror(LiftedBinaryOp),
63 Mul(LiftedBinaryOp),
64 MuluDp(LiftedBinaryOp),
65 MulsDp(LiftedBinaryOp),
66 Divu(LiftedBinaryOp),
67 DivuDp(LiftedBinaryOp),
68 Divs(LiftedBinaryOp),
69 DivsDp(LiftedBinaryOp),
70 Modu(LiftedBinaryOp),
71 ModuDp(LiftedBinaryOp),
72 Mods(LiftedBinaryOp),
73 ModsDp(LiftedBinaryOp),
74 CmpE(LiftedBinaryOp),
75 CmpNe(LiftedBinaryOp),
76 CmpSlt(LiftedBinaryOp),
77 CmpUlt(LiftedBinaryOp),
78 CmpSle(LiftedBinaryOp),
79 CmpUle(LiftedBinaryOp),
80 CmpSge(LiftedBinaryOp),
81 CmpUge(LiftedBinaryOp),
82 CmpSgt(LiftedBinaryOp),
83 CmpUgt(LiftedBinaryOp),
84 TestBit(LiftedBinaryOp),
85 AddOverflow(LiftedBinaryOp),
86 Fadd(LiftedBinaryOp),
87 Fsub(LiftedBinaryOp),
88 Fmul(LiftedBinaryOp),
89 Fdiv(LiftedBinaryOp),
90 FcmpE(LiftedBinaryOp),
91 FcmpNe(LiftedBinaryOp),
92 FcmpLt(LiftedBinaryOp),
93 FcmpLe(LiftedBinaryOp),
94 FcmpGe(LiftedBinaryOp),
95 FcmpGt(LiftedBinaryOp),
96 FcmpO(LiftedBinaryOp),
97 FcmpUo(LiftedBinaryOp),
98 ArrayIndex(LiftedArrayIndex),
99 ArrayIndexSsa(LiftedArrayIndexSsa),
100 Assign(LiftedAssign),
101 AssignMemSsa(LiftedAssignMemSsa),
102 AssignUnpack(LiftedAssignUnpack),
103 AssignUnpackMemSsa(LiftedAssignUnpackMemSsa),
104 Block(LiftedBlock),
105 Call(LiftedCall),
106 Tailcall(LiftedCall),
107 CallSsa(LiftedCallSsa),
108 Case(LiftedCase),
109 Const(Const),
110 ConstPtr(Const),
111 Import(Const),
112 ConstData(LiftedConstData),
113 Deref(LiftedUnaryOp),
114 AddressOf(LiftedUnaryOp),
115 Neg(LiftedUnaryOp),
116 Not(LiftedUnaryOp),
117 Sx(LiftedUnaryOp),
118 Zx(LiftedUnaryOp),
119 LowPart(LiftedUnaryOp),
120 BoolToInt(LiftedUnaryOp),
121 UnimplMem(LiftedUnaryOp),
122 Fsqrt(LiftedUnaryOp),
123 Fneg(LiftedUnaryOp),
124 Fabs(LiftedUnaryOp),
125 FloatToInt(LiftedUnaryOp),
126 IntToFloat(LiftedUnaryOp),
127 FloatConv(LiftedUnaryOp),
128 RoundToInt(LiftedUnaryOp),
129 Floor(LiftedUnaryOp),
130 Ceil(LiftedUnaryOp),
131 Ftrunc(LiftedUnaryOp),
132 DerefFieldSsa(LiftedDerefFieldSsa),
133 DerefSsa(LiftedDerefSsa),
134 ExternPtr(ExternPtr),
135 FloatConst(FloatConst),
136 For(LiftedForLoop),
137 ForSsa(LiftedForLoopSsa),
138 Goto(LiftedLabel),
139 Label(LiftedLabel),
140 If(LiftedIf),
141 Intrinsic(LiftedIntrinsic),
142 IntrinsicSsa(LiftedIntrinsicSsa),
143 Jump(LiftedJump),
144 MemPhi(LiftedMemPhi),
145 Ret(LiftedRet),
146 Split(LiftedSplit),
147 StructField(LiftedStructField),
148 DerefField(LiftedStructField),
149 Switch(LiftedSwitch),
150 Syscall(LiftedSyscall),
151 SyscallSsa(LiftedSyscallSsa),
152 Trap(Trap),
153 VarDeclare(Var),
154 Var(Var),
155 VarInit(LiftedVarInit),
156 VarInitSsa(LiftedVarInitSsa),
157 VarPhi(LiftedVarPhi),
158 VarSsa(VarSsa),
159 While(LiftedWhile),
160 DoWhile(LiftedWhile),
161 WhileSsa(LiftedWhileSsa),
162 DoWhileSsa(LiftedWhileSsa),
163}
164
165impl HighLevelILLiftedInstruction {
166 pub fn name(&self) -> &'static str {
167 use HighLevelILLiftedInstructionKind::*;
168 match self.kind {
169 Nop => "Nop",
170 Break => "Break",
171 Continue => "Continue",
172 Noret => "Noret",
173 Unreachable => "Unreachable",
174 Bp => "Bp",
175 Undef => "Undef",
176 Unimpl => "Unimpl",
177 Adc(_) => "Adc",
178 Sbb(_) => "Sbb",
179 Rlc(_) => "Rlc",
180 Rrc(_) => "Rrc",
181 Add(_) => "Add",
182 Sub(_) => "Sub",
183 And(_) => "And",
184 Or(_) => "Or",
185 Xor(_) => "Xor",
186 Lsl(_) => "Lsl",
187 Lsr(_) => "Lsr",
188 Asr(_) => "Asr",
189 Rol(_) => "Rol",
190 Ror(_) => "Ror",
191 Mul(_) => "Mul",
192 MuluDp(_) => "MuluDp",
193 MulsDp(_) => "MulsDp",
194 Divu(_) => "Divu",
195 DivuDp(_) => "DivuDp",
196 Divs(_) => "Divs",
197 DivsDp(_) => "DivsDp",
198 Modu(_) => "Modu",
199 ModuDp(_) => "ModuDp",
200 Mods(_) => "Mods",
201 ModsDp(_) => "ModsDp",
202 CmpE(_) => "CmpE",
203 CmpNe(_) => "CmpNe",
204 CmpSlt(_) => "CmpSlt",
205 CmpUlt(_) => "CmpUlt",
206 CmpSle(_) => "CmpSle",
207 CmpUle(_) => "CmpUle",
208 CmpSge(_) => "CmpSge",
209 CmpUge(_) => "CmpUge",
210 CmpSgt(_) => "CmpSgt",
211 CmpUgt(_) => "CmpUgt",
212 TestBit(_) => "TestBit",
213 AddOverflow(_) => "AddOverflow",
214 Fadd(_) => "Fadd",
215 Fsub(_) => "Fsub",
216 Fmul(_) => "Fmul",
217 Fdiv(_) => "Fdiv",
218 FcmpE(_) => "FcmpE",
219 FcmpNe(_) => "FcmpNe",
220 FcmpLt(_) => "FcmpLt",
221 FcmpLe(_) => "FcmpLe",
222 FcmpGe(_) => "FcmpGe",
223 FcmpGt(_) => "FcmpGt",
224 FcmpO(_) => "FcmpO",
225 FcmpUo(_) => "FcmpUo",
226 ArrayIndex(_) => "ArrayIndex",
227 ArrayIndexSsa(_) => "ArrayIndexSsa",
228 Assign(_) => "Assign",
229 AssignMemSsa(_) => "AssignMemSsa",
230 AssignUnpack(_) => "AssignUnpack",
231 AssignUnpackMemSsa(_) => "AssignUnpackMemSsa",
232 Block(_) => "Block",
233 Call(_) => "Call",
234 Tailcall(_) => "Tailcall",
235 CallSsa(_) => "CallSsa",
236 Case(_) => "Case",
237 Const(_) => "Const",
238 ConstPtr(_) => "ConstPtr",
239 Import(_) => "Import",
240 ConstData(_) => "ConstData",
241 Deref(_) => "Deref",
242 AddressOf(_) => "AddressOf",
243 Neg(_) => "Neg",
244 Not(_) => "Not",
245 Sx(_) => "Sx",
246 Zx(_) => "Zx",
247 LowPart(_) => "LowPart",
248 BoolToInt(_) => "BoolToInt",
249 UnimplMem(_) => "UnimplMem",
250 Fsqrt(_) => "Fsqrt",
251 Fneg(_) => "Fneg",
252 Fabs(_) => "Fabs",
253 FloatToInt(_) => "FloatToInt",
254 IntToFloat(_) => "IntToFloat",
255 FloatConv(_) => "FloatConv",
256 RoundToInt(_) => "RoundToInt",
257 Floor(_) => "Floor",
258 Ceil(_) => "Ceil",
259 Ftrunc(_) => "Ftrunc",
260 DerefFieldSsa(_) => "DerefFieldSsa",
261 DerefSsa(_) => "DerefSsa",
262 ExternPtr(_) => "ExternPtr",
263 FloatConst(_) => "FloatConst",
264 For(_) => "For",
265 ForSsa(_) => "ForSsa",
266 Goto(_) => "Goto",
267 Label(_) => "Label",
268 If(_) => "If",
269 Intrinsic(_) => "Intrinsic",
270 IntrinsicSsa(_) => "IntrinsicSsa",
271 Jump(_) => "Jump",
272 MemPhi(_) => "MemPhi",
273 Ret(_) => "Ret",
274 Split(_) => "Split",
275 StructField(_) => "StructField",
276 DerefField(_) => "DerefField",
277 Switch(_) => "Switch",
278 Syscall(_) => "Syscall",
279 SyscallSsa(_) => "SyscallSsa",
280 Trap(_) => "Trap",
281 VarDeclare(_) => "VarDeclare",
282 Var(_) => "Var",
283 VarInit(_) => "VarInit",
284 VarInitSsa(_) => "VarInitSsa",
285 VarPhi(_) => "VarPhi",
286 VarSsa(_) => "VarSsa",
287 While(_) => "While",
288 DoWhile(_) => "DoWhile",
289 WhileSsa(_) => "WhileSsa",
290 DoWhileSsa(_) => "DoWhileSsa",
291 }
292 }
293
294 pub fn operands(&self) -> Vec<(&'static str, HighLevelILLiftedOperand)> {
295 use HighLevelILLiftedInstructionKind::*;
296 use HighLevelILLiftedOperand as Operand;
297 match &self.kind {
298 Nop | Break | Continue | Noret | Unreachable | Bp | Undef | Unimpl => vec![],
299 Adc(op) | Sbb(op) | Rlc(op) | Rrc(op) => vec![
300 ("left", Operand::Expr(*op.left.clone())),
301 ("right", Operand::Expr(*op.right.clone())),
302 ("carry", Operand::Expr(*op.carry.clone())),
303 ],
304 Add(op) | Sub(op) | And(op) | Or(op) | Xor(op) | Lsl(op) | Lsr(op) | Asr(op)
305 | Rol(op) | Ror(op) | Mul(op) | MuluDp(op) | MulsDp(op) | Divu(op) | DivuDp(op)
306 | Divs(op) | DivsDp(op) | Modu(op) | ModuDp(op) | Mods(op) | ModsDp(op) | CmpE(op)
307 | CmpNe(op) | CmpSlt(op) | CmpUlt(op) | CmpSle(op) | CmpUle(op) | CmpSge(op)
308 | CmpUge(op) | CmpSgt(op) | CmpUgt(op) | TestBit(op) | AddOverflow(op) | Fadd(op)
309 | Fsub(op) | Fmul(op) | Fdiv(op) | FcmpE(op) | FcmpNe(op) | FcmpLt(op) | FcmpLe(op)
310 | FcmpGe(op) | FcmpGt(op) | FcmpO(op) | FcmpUo(op) => vec![
311 ("left", Operand::Expr(*op.left.clone())),
312 ("right", Operand::Expr(*op.right.clone())),
313 ],
314 ArrayIndex(op) => vec![
315 ("src", Operand::Expr(*op.src.clone())),
316 ("index", Operand::Expr(*op.index.clone())),
317 ],
318 ArrayIndexSsa(op) => vec![
319 ("src", Operand::Expr(*op.src.clone())),
320 ("src_memory", Operand::Int(op.src_memory)),
321 ("index", Operand::Expr(*op.index.clone())),
322 ],
323 Assign(op) => vec![
324 ("dest", Operand::Expr(*op.dest.clone())),
325 ("src", Operand::Expr(*op.src.clone())),
326 ],
327 AssignMemSsa(op) => vec![
328 ("dest", Operand::Expr(*op.dest.clone())),
329 ("dest_memory", Operand::Int(op.dest_memory)),
330 ("src", Operand::Expr(*op.src.clone())),
331 ("src_memory", Operand::Int(op.src_memory)),
332 ],
333 AssignUnpack(op) => vec![
334 ("dest", Operand::ExprList(op.dest.clone())),
335 ("src", Operand::Expr(*op.src.clone())),
336 ],
337 AssignUnpackMemSsa(op) => vec![
338 ("dest", Operand::ExprList(op.dest.clone())),
339 ("dest_memory", Operand::Int(op.dest_memory)),
340 ("src", Operand::Expr(*op.src.clone())),
341 ("src_memory", Operand::Int(op.src_memory)),
342 ],
343 Block(op) => vec![("body", Operand::ExprList(op.body.clone()))],
344 Call(op) | Tailcall(op) => vec![
345 ("dest", Operand::Expr(*op.dest.clone())),
346 ("params", Operand::ExprList(op.params.clone())),
347 ],
348 CallSsa(op) => vec![
349 ("dest", Operand::Expr(*op.dest.clone())),
350 ("params", Operand::ExprList(op.params.clone())),
351 ("dest_memory", Operand::Int(op.dest_memory)),
352 ("src_memory", Operand::Int(op.src_memory)),
353 ],
354 Case(op) => vec![
355 ("values", Operand::ExprList(op.values.clone())),
356 ("body", Operand::Expr(*op.body.clone())),
357 ],
358 Const(op) | ConstPtr(op) | Import(op) => vec![("constant", Operand::Int(op.constant))],
359 ConstData(op) => vec![(
360 "constant_data",
361 Operand::ConstantData(op.constant_data.clone()),
362 )],
363 Deref(op) | AddressOf(op) | Neg(op) | Not(op) | Sx(op) | Zx(op) | LowPart(op)
364 | BoolToInt(op) | UnimplMem(op) | Fsqrt(op) | Fneg(op) | Fabs(op) | FloatToInt(op)
365 | IntToFloat(op) | FloatConv(op) | RoundToInt(op) | Floor(op) | Ceil(op)
366 | Ftrunc(op) => vec![("src", Operand::Expr(*op.src.clone()))],
367 DerefFieldSsa(op) => vec![
368 ("src", Operand::Expr(*op.src.clone())),
369 ("src_memory", Operand::Int(op.src_memory)),
370 ("offset", Operand::Int(op.offset)),
371 ("member_index", Operand::MemberIndex(op.member_index)),
372 ],
373 DerefSsa(op) => vec![
374 ("src", Operand::Expr(*op.src.clone())),
375 ("src_memory", Operand::Int(op.src_memory)),
376 ],
377 ExternPtr(op) => vec![
378 ("constant", Operand::Int(op.constant)),
379 ("offset", Operand::Int(op.offset)),
380 ],
381 FloatConst(op) => vec![("constant", Operand::Float(op.constant))],
382 For(op) => vec![
383 ("init", Operand::Expr(*op.init.clone())),
384 ("condition", Operand::Expr(*op.condition.clone())),
385 ("update", Operand::Expr(*op.update.clone())),
386 ("body", Operand::Expr(*op.body.clone())),
387 ],
388 ForSsa(op) => vec![
389 ("init", Operand::Expr(*op.init.clone())),
390 ("condition_phi", Operand::Expr(*op.condition_phi.clone())),
391 ("condition", Operand::Expr(*op.condition.clone())),
392 ("update", Operand::Expr(*op.update.clone())),
393 ("body", Operand::Expr(*op.body.clone())),
394 ],
395 Goto(op) | Label(op) => vec![("target", Operand::Label(op.target.clone()))],
396 If(op) => vec![
397 ("condition", Operand::Expr(*op.condition.clone())),
398 ("cond_true", Operand::Expr(*op.cond_true.clone())),
399 ("cond_false", Operand::Expr(*op.cond_false.clone())),
400 ],
401 Intrinsic(op) => vec![
402 ("intrinsic", Operand::Intrinsic(op.intrinsic)),
403 ("params", Operand::ExprList(op.params.clone())),
404 ],
405 IntrinsicSsa(op) => vec![
406 ("intrinsic", Operand::Intrinsic(op.intrinsic)),
407 ("params", Operand::ExprList(op.params.clone())),
408 ("dest_memory", Operand::Int(op.dest_memory)),
409 ("src_memory", Operand::Int(op.src_memory)),
410 ],
411 Jump(op) => vec![("dest", Operand::Expr(*op.dest.clone()))],
412 MemPhi(op) => vec![
413 ("dest", Operand::Int(op.dest)),
414 ("src", Operand::IntList(op.src.clone())),
415 ],
416 Ret(op) => vec![("src", Operand::ExprList(op.src.clone()))],
417 Split(op) => vec![
418 ("high", Operand::Expr(*op.high.clone())),
419 ("low", Operand::Expr(*op.low.clone())),
420 ],
421 StructField(op) | DerefField(op) => vec![
422 ("src", Operand::Expr(*op.src.clone())),
423 ("offset", Operand::Int(op.offset)),
424 ("member_index", Operand::MemberIndex(op.member_index)),
425 ],
426 Switch(op) => vec![
427 ("condition", Operand::Expr(*op.condition.clone())),
428 ("default", Operand::Expr(*op.default.clone())),
429 ("cases", Operand::ExprList(op.cases.clone())),
430 ],
431 Syscall(op) => vec![("params", Operand::ExprList(op.params.clone()))],
432 SyscallSsa(op) => vec![
433 ("params", Operand::ExprList(op.params.clone())),
434 ("dest_memory", Operand::Int(op.dest_memory)),
435 ("src_memory", Operand::Int(op.src_memory)),
436 ],
437 Trap(op) => vec![("vector", Operand::Int(op.vector))],
438 VarDeclare(op) | Var(op) => vec![("var", Operand::Var(op.var))],
439 VarInit(op) => vec![
440 ("dest", Operand::Var(op.dest)),
441 ("src", Operand::Expr(*op.src.clone())),
442 ],
443 VarInitSsa(op) => vec![
444 ("dest", Operand::VarSsa(op.dest)),
445 ("src", Operand::Expr(*op.src.clone())),
446 ],
447 VarPhi(op) => vec![
448 ("dest", Operand::VarSsa(op.dest)),
449 ("src", Operand::VarSsaList(op.src.clone())),
450 ],
451 VarSsa(op) => vec![("var", Operand::VarSsa(op.var))],
452 While(op) | DoWhile(op) => vec![
453 ("condition", Operand::Expr(*op.condition.clone())),
454 ("body", Operand::Expr(*op.body.clone())),
455 ],
456 WhileSsa(op) | DoWhileSsa(op) => vec![
457 ("condition_phi", Operand::Expr(*op.condition_phi.clone())),
458 ("condition", Operand::Expr(*op.condition.clone())),
459 ("body", Operand::Expr(*op.body.clone())),
460 ],
461 }
462 }
463}
464
465impl Debug for HighLevelILLiftedInstruction {
466 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
467 f.debug_struct("HighLevelILLiftedInstruction")
468 .field("address", &self.address)
469 .field("expr_index", &self.expr_index)
470 .field("size", &self.size)
471 .field("kind", &self.kind)
472 .finish()
473 }
474}