1use binaryninjacore_sys::*;
2use std::fmt;
3use std::fmt::{Debug, Display, Formatter};
4
5use super::operation::*;
6use super::{HighLevelILFunction, HighLevelILLiftedInstruction, HighLevelILLiftedInstructionKind};
7use crate::architecture::{CoreIntrinsic, IntrinsicId};
8use crate::confidence::Conf;
9use crate::disassembly::DisassemblyTextLine;
10use crate::rc::{Array, CoreArrayProvider, CoreArrayProviderInner, Ref};
11use crate::types::Type;
12use crate::variable::{ConstantData, RegisterValue, SSAVariable, Variable};
13
14#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
15pub struct HighLevelInstructionIndex(pub usize);
16
17impl HighLevelInstructionIndex {
18 pub fn next(&self) -> Self {
19 Self(self.0 + 1)
20 }
21}
22
23impl From<usize> for HighLevelInstructionIndex {
24 fn from(index: usize) -> Self {
25 Self(index)
26 }
27}
28
29impl From<u64> for HighLevelInstructionIndex {
30 fn from(index: u64) -> Self {
31 Self(index as usize)
32 }
33}
34
35impl Display for HighLevelInstructionIndex {
36 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
37 f.write_fmt(format_args!("{}", self.0))
38 }
39}
40
41#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
42pub struct HighLevelExpressionIndex(pub usize);
43
44impl HighLevelExpressionIndex {
45 pub fn next(&self) -> Self {
46 Self(self.0 + 1)
47 }
48}
49
50impl From<usize> for HighLevelExpressionIndex {
51 fn from(index: usize) -> Self {
52 Self(index)
53 }
54}
55
56impl From<u64> for HighLevelExpressionIndex {
57 fn from(index: u64) -> Self {
58 Self(index as usize)
59 }
60}
61
62impl Display for HighLevelExpressionIndex {
63 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
64 f.write_fmt(format_args!("{}", self.0))
65 }
66}
67
68#[derive(Clone)]
69pub struct HighLevelILInstruction {
70 pub function: Ref<HighLevelILFunction>,
71 pub address: u64,
72 pub instr_index: HighLevelInstructionIndex,
73 pub expr_index: HighLevelExpressionIndex,
74 pub size: usize,
75 pub kind: HighLevelILInstructionKind,
76}
77
78impl HighLevelILInstruction {
79 pub(crate) fn from_instr_index(
80 function: Ref<HighLevelILFunction>,
81 instr_index: HighLevelInstructionIndex,
82 ) -> Self {
83 let expr_index_raw =
85 unsafe { BNGetHighLevelILIndexForInstruction(function.handle, instr_index.0) };
86 Self::new(
87 function,
88 instr_index,
89 HighLevelExpressionIndex(expr_index_raw),
90 )
91 }
92
93 pub(crate) fn from_expr_index(
94 function: Ref<HighLevelILFunction>,
95 expr_index: HighLevelExpressionIndex,
96 ) -> Self {
97 let instr_index_raw =
99 unsafe { BNGetHighLevelILInstructionForExpr(function.handle, expr_index.0) };
100 Self::new(
101 function,
102 HighLevelInstructionIndex(instr_index_raw),
103 expr_index,
104 )
105 }
106
107 pub(crate) fn new(
108 function: Ref<HighLevelILFunction>,
109 instr_index: HighLevelInstructionIndex,
110 expr_index: HighLevelExpressionIndex,
111 ) -> Self {
112 let op =
113 unsafe { BNGetHighLevelILByIndex(function.handle, expr_index.0, function.full_ast) };
114 use BNHighLevelILOperation::*;
115 use HighLevelILInstructionKind as Op;
116 let kind = match op.operation {
117 HLIL_NOP => Op::Nop,
118 HLIL_BREAK => Op::Break,
119 HLIL_CONTINUE => Op::Continue,
120 HLIL_NORET => Op::Noret,
121 HLIL_UNREACHABLE => Op::Unreachable,
122 HLIL_BP => Op::Bp,
123 HLIL_UNDEF => Op::Undef,
124 HLIL_FORCE_VER | HLIL_FORCE_VER_SSA | HLIL_ASSERT | HLIL_ASSERT_SSA => Op::Undef,
125 HLIL_UNIMPL => Op::Unimpl,
126 HLIL_ADC => Op::Adc(BinaryOpCarry {
127 left: HighLevelExpressionIndex::from(op.operands[0]),
128 right: HighLevelExpressionIndex::from(op.operands[1]),
129 carry: HighLevelExpressionIndex::from(op.operands[2]),
130 }),
131 HLIL_SBB => Op::Sbb(BinaryOpCarry {
132 left: HighLevelExpressionIndex::from(op.operands[0]),
133 right: HighLevelExpressionIndex::from(op.operands[1]),
134 carry: HighLevelExpressionIndex::from(op.operands[2]),
135 }),
136 HLIL_RLC => Op::Rlc(BinaryOpCarry {
137 left: HighLevelExpressionIndex::from(op.operands[0]),
138 right: HighLevelExpressionIndex::from(op.operands[1]),
139 carry: HighLevelExpressionIndex::from(op.operands[2]),
140 }),
141 HLIL_RRC => Op::Rrc(BinaryOpCarry {
142 left: HighLevelExpressionIndex::from(op.operands[0]),
143 right: HighLevelExpressionIndex::from(op.operands[1]),
144 carry: HighLevelExpressionIndex::from(op.operands[2]),
145 }),
146 HLIL_ADD => Op::Add(BinaryOp {
147 left: HighLevelExpressionIndex::from(op.operands[0]),
148 right: HighLevelExpressionIndex::from(op.operands[1]),
149 }),
150 HLIL_SUB => Op::Sub(BinaryOp {
151 left: HighLevelExpressionIndex::from(op.operands[0]),
152 right: HighLevelExpressionIndex::from(op.operands[1]),
153 }),
154 HLIL_AND => Op::And(BinaryOp {
155 left: HighLevelExpressionIndex::from(op.operands[0]),
156 right: HighLevelExpressionIndex::from(op.operands[1]),
157 }),
158 HLIL_OR => Op::Or(BinaryOp {
159 left: HighLevelExpressionIndex::from(op.operands[0]),
160 right: HighLevelExpressionIndex::from(op.operands[1]),
161 }),
162 HLIL_XOR => Op::Xor(BinaryOp {
163 left: HighLevelExpressionIndex::from(op.operands[0]),
164 right: HighLevelExpressionIndex::from(op.operands[1]),
165 }),
166 HLIL_LSL => Op::Lsl(BinaryOp {
167 left: HighLevelExpressionIndex::from(op.operands[0]),
168 right: HighLevelExpressionIndex::from(op.operands[1]),
169 }),
170 HLIL_LSR => Op::Lsr(BinaryOp {
171 left: HighLevelExpressionIndex::from(op.operands[0]),
172 right: HighLevelExpressionIndex::from(op.operands[1]),
173 }),
174 HLIL_ASR => Op::Asr(BinaryOp {
175 left: HighLevelExpressionIndex::from(op.operands[0]),
176 right: HighLevelExpressionIndex::from(op.operands[1]),
177 }),
178 HLIL_ROL => Op::Rol(BinaryOp {
179 left: HighLevelExpressionIndex::from(op.operands[0]),
180 right: HighLevelExpressionIndex::from(op.operands[1]),
181 }),
182 HLIL_ROR => Op::Ror(BinaryOp {
183 left: HighLevelExpressionIndex::from(op.operands[0]),
184 right: HighLevelExpressionIndex::from(op.operands[1]),
185 }),
186 HLIL_MUL => Op::Mul(BinaryOp {
187 left: HighLevelExpressionIndex::from(op.operands[0]),
188 right: HighLevelExpressionIndex::from(op.operands[1]),
189 }),
190 HLIL_MULU_DP => Op::MuluDp(BinaryOp {
191 left: HighLevelExpressionIndex::from(op.operands[0]),
192 right: HighLevelExpressionIndex::from(op.operands[1]),
193 }),
194 HLIL_MULS_DP => Op::MulsDp(BinaryOp {
195 left: HighLevelExpressionIndex::from(op.operands[0]),
196 right: HighLevelExpressionIndex::from(op.operands[1]),
197 }),
198 HLIL_DIVU => Op::Divu(BinaryOp {
199 left: HighLevelExpressionIndex::from(op.operands[0]),
200 right: HighLevelExpressionIndex::from(op.operands[1]),
201 }),
202 HLIL_DIVU_DP => Op::DivuDp(BinaryOp {
203 left: HighLevelExpressionIndex::from(op.operands[0]),
204 right: HighLevelExpressionIndex::from(op.operands[1]),
205 }),
206 HLIL_DIVS => Op::Divs(BinaryOp {
207 left: HighLevelExpressionIndex::from(op.operands[0]),
208 right: HighLevelExpressionIndex::from(op.operands[1]),
209 }),
210 HLIL_DIVS_DP => Op::DivsDp(BinaryOp {
211 left: HighLevelExpressionIndex::from(op.operands[0]),
212 right: HighLevelExpressionIndex::from(op.operands[1]),
213 }),
214 HLIL_MODU => Op::Modu(BinaryOp {
215 left: HighLevelExpressionIndex::from(op.operands[0]),
216 right: HighLevelExpressionIndex::from(op.operands[1]),
217 }),
218 HLIL_MODU_DP => Op::ModuDp(BinaryOp {
219 left: HighLevelExpressionIndex::from(op.operands[0]),
220 right: HighLevelExpressionIndex::from(op.operands[1]),
221 }),
222 HLIL_MODS => Op::Mods(BinaryOp {
223 left: HighLevelExpressionIndex::from(op.operands[0]),
224 right: HighLevelExpressionIndex::from(op.operands[1]),
225 }),
226 HLIL_MODS_DP => Op::ModsDp(BinaryOp {
227 left: HighLevelExpressionIndex::from(op.operands[0]),
228 right: HighLevelExpressionIndex::from(op.operands[1]),
229 }),
230 HLIL_CMP_E => Op::CmpE(BinaryOp {
231 left: HighLevelExpressionIndex::from(op.operands[0]),
232 right: HighLevelExpressionIndex::from(op.operands[1]),
233 }),
234 HLIL_CMP_NE => Op::CmpNe(BinaryOp {
235 left: HighLevelExpressionIndex::from(op.operands[0]),
236 right: HighLevelExpressionIndex::from(op.operands[1]),
237 }),
238 HLIL_CMP_SLT => Op::CmpSlt(BinaryOp {
239 left: HighLevelExpressionIndex::from(op.operands[0]),
240 right: HighLevelExpressionIndex::from(op.operands[1]),
241 }),
242 HLIL_CMP_ULT => Op::CmpUlt(BinaryOp {
243 left: HighLevelExpressionIndex::from(op.operands[0]),
244 right: HighLevelExpressionIndex::from(op.operands[1]),
245 }),
246 HLIL_CMP_SLE => Op::CmpSle(BinaryOp {
247 left: HighLevelExpressionIndex::from(op.operands[0]),
248 right: HighLevelExpressionIndex::from(op.operands[1]),
249 }),
250 HLIL_CMP_ULE => Op::CmpUle(BinaryOp {
251 left: HighLevelExpressionIndex::from(op.operands[0]),
252 right: HighLevelExpressionIndex::from(op.operands[1]),
253 }),
254 HLIL_CMP_SGE => Op::CmpSge(BinaryOp {
255 left: HighLevelExpressionIndex::from(op.operands[0]),
256 right: HighLevelExpressionIndex::from(op.operands[1]),
257 }),
258 HLIL_CMP_UGE => Op::CmpUge(BinaryOp {
259 left: HighLevelExpressionIndex::from(op.operands[0]),
260 right: HighLevelExpressionIndex::from(op.operands[1]),
261 }),
262 HLIL_CMP_SGT => Op::CmpSgt(BinaryOp {
263 left: HighLevelExpressionIndex::from(op.operands[0]),
264 right: HighLevelExpressionIndex::from(op.operands[1]),
265 }),
266 HLIL_CMP_UGT => Op::CmpUgt(BinaryOp {
267 left: HighLevelExpressionIndex::from(op.operands[0]),
268 right: HighLevelExpressionIndex::from(op.operands[1]),
269 }),
270 HLIL_TEST_BIT => Op::TestBit(BinaryOp {
271 left: HighLevelExpressionIndex::from(op.operands[0]),
272 right: HighLevelExpressionIndex::from(op.operands[1]),
273 }),
274 HLIL_ADD_OVERFLOW => Op::AddOverflow(BinaryOp {
275 left: HighLevelExpressionIndex::from(op.operands[0]),
276 right: HighLevelExpressionIndex::from(op.operands[1]),
277 }),
278 HLIL_FADD => Op::Fadd(BinaryOp {
279 left: HighLevelExpressionIndex::from(op.operands[0]),
280 right: HighLevelExpressionIndex::from(op.operands[1]),
281 }),
282 HLIL_FSUB => Op::Fsub(BinaryOp {
283 left: HighLevelExpressionIndex::from(op.operands[0]),
284 right: HighLevelExpressionIndex::from(op.operands[1]),
285 }),
286 HLIL_FMUL => Op::Fmul(BinaryOp {
287 left: HighLevelExpressionIndex::from(op.operands[0]),
288 right: HighLevelExpressionIndex::from(op.operands[1]),
289 }),
290 HLIL_FDIV => Op::Fdiv(BinaryOp {
291 left: HighLevelExpressionIndex::from(op.operands[0]),
292 right: HighLevelExpressionIndex::from(op.operands[1]),
293 }),
294 HLIL_FCMP_E => Op::FcmpE(BinaryOp {
295 left: HighLevelExpressionIndex::from(op.operands[0]),
296 right: HighLevelExpressionIndex::from(op.operands[1]),
297 }),
298 HLIL_FCMP_NE => Op::FcmpNe(BinaryOp {
299 left: HighLevelExpressionIndex::from(op.operands[0]),
300 right: HighLevelExpressionIndex::from(op.operands[1]),
301 }),
302 HLIL_FCMP_LT => Op::FcmpLt(BinaryOp {
303 left: HighLevelExpressionIndex::from(op.operands[0]),
304 right: HighLevelExpressionIndex::from(op.operands[1]),
305 }),
306 HLIL_FCMP_LE => Op::FcmpLe(BinaryOp {
307 left: HighLevelExpressionIndex::from(op.operands[0]),
308 right: HighLevelExpressionIndex::from(op.operands[1]),
309 }),
310 HLIL_FCMP_GE => Op::FcmpGe(BinaryOp {
311 left: HighLevelExpressionIndex::from(op.operands[0]),
312 right: HighLevelExpressionIndex::from(op.operands[1]),
313 }),
314 HLIL_FCMP_GT => Op::FcmpGt(BinaryOp {
315 left: HighLevelExpressionIndex::from(op.operands[0]),
316 right: HighLevelExpressionIndex::from(op.operands[1]),
317 }),
318 HLIL_FCMP_O => Op::FcmpO(BinaryOp {
319 left: HighLevelExpressionIndex::from(op.operands[0]),
320 right: HighLevelExpressionIndex::from(op.operands[1]),
321 }),
322 HLIL_FCMP_UO => Op::FcmpUo(BinaryOp {
323 left: HighLevelExpressionIndex::from(op.operands[0]),
324 right: HighLevelExpressionIndex::from(op.operands[1]),
325 }),
326 HLIL_ARRAY_INDEX => Op::ArrayIndex(ArrayIndex {
327 src: HighLevelExpressionIndex::from(op.operands[0]),
328 index: HighLevelExpressionIndex::from(op.operands[1]),
329 }),
330 HLIL_ARRAY_INDEX_SSA => Op::ArrayIndexSsa(ArrayIndexSsa {
331 src: HighLevelExpressionIndex::from(op.operands[0]),
332 src_memory: op.operands[1],
333 index: HighLevelExpressionIndex::from(op.operands[2]),
334 }),
335 HLIL_ASSIGN => Op::Assign(Assign {
336 dest: HighLevelExpressionIndex::from(op.operands[0]),
337 src: HighLevelExpressionIndex::from(op.operands[1]),
338 }),
339 HLIL_ASSIGN_MEM_SSA => Op::AssignMemSsa(AssignMemSsa {
340 dest: HighLevelExpressionIndex::from(op.operands[0]),
341 dest_memory: op.operands[1],
342 src: HighLevelExpressionIndex::from(op.operands[2]),
343 src_memory: op.operands[3],
344 }),
345 HLIL_ASSIGN_UNPACK => Op::AssignUnpack(AssignUnpack {
346 num_dests: op.operands[0] as usize,
347 first_dest: op.operands[1] as usize,
348 src: HighLevelExpressionIndex::from(op.operands[2]),
349 }),
350 HLIL_ASSIGN_UNPACK_MEM_SSA => Op::AssignUnpackMemSsa(AssignUnpackMemSsa {
351 num_dests: op.operands[0] as usize,
352 first_dest: op.operands[1] as usize,
353 dest_memory: op.operands[2],
354 src: HighLevelExpressionIndex::from(op.operands[3]),
355 src_memory: op.operands[4],
356 }),
357 HLIL_BLOCK => Op::Block(Block {
358 num_params: op.operands[0] as usize,
359 first_param: op.operands[1] as usize,
360 }),
361 HLIL_CALL => Op::Call(Call {
362 dest: HighLevelExpressionIndex::from(op.operands[0]),
363 num_params: op.operands[1] as usize,
364 first_param: op.operands[2] as usize,
365 }),
366 HLIL_TAILCALL => Op::Tailcall(Call {
367 dest: HighLevelExpressionIndex::from(op.operands[0]),
368 num_params: op.operands[1] as usize,
369 first_param: op.operands[2] as usize,
370 }),
371 HLIL_CALL_SSA => Op::CallSsa(CallSsa {
372 dest: HighLevelExpressionIndex::from(op.operands[0]),
373 num_params: op.operands[1] as usize,
374 first_param: op.operands[2] as usize,
375 dest_memory: op.operands[3],
376 src_memory: op.operands[4],
377 }),
378 HLIL_CASE => Op::Case(Case {
379 num_values: op.operands[0] as usize,
380 first_value: op.operands[1] as usize,
381 body: HighLevelExpressionIndex::from(op.operands[2]),
382 }),
383 HLIL_CONST => Op::Const(Const {
384 constant: op.operands[0],
385 }),
386 HLIL_CONST_PTR => Op::ConstPtr(Const {
387 constant: op.operands[0],
388 }),
389 HLIL_IMPORT => Op::Import(Const {
390 constant: op.operands[0],
391 }),
392 HLIL_CONST_DATA => Op::ConstData(ConstData {
393 constant_data_kind: op.operands[0] as u32,
394 constant_data_value: op.operands[1] as i64,
395 size: op.size,
396 }),
397 HLIL_DEREF => Op::Deref(UnaryOp {
398 src: HighLevelExpressionIndex::from(op.operands[0]),
399 }),
400 HLIL_ADDRESS_OF => Op::AddressOf(UnaryOp {
401 src: HighLevelExpressionIndex::from(op.operands[0]),
402 }),
403 HLIL_NEG => Op::Neg(UnaryOp {
404 src: HighLevelExpressionIndex::from(op.operands[0]),
405 }),
406 HLIL_NOT => Op::Not(UnaryOp {
407 src: HighLevelExpressionIndex::from(op.operands[0]),
408 }),
409 HLIL_SX => Op::Sx(UnaryOp {
410 src: HighLevelExpressionIndex::from(op.operands[0]),
411 }),
412 HLIL_ZX => Op::Zx(UnaryOp {
413 src: HighLevelExpressionIndex::from(op.operands[0]),
414 }),
415 HLIL_LOW_PART => Op::LowPart(UnaryOp {
416 src: HighLevelExpressionIndex::from(op.operands[0]),
417 }),
418 HLIL_BOOL_TO_INT => Op::BoolToInt(UnaryOp {
419 src: HighLevelExpressionIndex::from(op.operands[0]),
420 }),
421 HLIL_UNIMPL_MEM => Op::UnimplMem(UnaryOp {
422 src: HighLevelExpressionIndex::from(op.operands[0]),
423 }),
424 HLIL_FSQRT => Op::Fsqrt(UnaryOp {
425 src: HighLevelExpressionIndex::from(op.operands[0]),
426 }),
427 HLIL_FNEG => Op::Fneg(UnaryOp {
428 src: HighLevelExpressionIndex::from(op.operands[0]),
429 }),
430 HLIL_FABS => Op::Fabs(UnaryOp {
431 src: HighLevelExpressionIndex::from(op.operands[0]),
432 }),
433 HLIL_FLOAT_TO_INT => Op::FloatToInt(UnaryOp {
434 src: HighLevelExpressionIndex::from(op.operands[0]),
435 }),
436 HLIL_INT_TO_FLOAT => Op::IntToFloat(UnaryOp {
437 src: HighLevelExpressionIndex::from(op.operands[0]),
438 }),
439 HLIL_FLOAT_CONV => Op::FloatConv(UnaryOp {
440 src: HighLevelExpressionIndex::from(op.operands[0]),
441 }),
442 HLIL_ROUND_TO_INT => Op::RoundToInt(UnaryOp {
443 src: HighLevelExpressionIndex::from(op.operands[0]),
444 }),
445 HLIL_FLOOR => Op::Floor(UnaryOp {
446 src: HighLevelExpressionIndex::from(op.operands[0]),
447 }),
448 HLIL_CEIL => Op::Ceil(UnaryOp {
449 src: HighLevelExpressionIndex::from(op.operands[0]),
450 }),
451 HLIL_FTRUNC => Op::Ftrunc(UnaryOp {
452 src: HighLevelExpressionIndex::from(op.operands[0]),
453 }),
454 HLIL_DEREF_FIELD_SSA => Op::DerefFieldSsa(DerefFieldSsa {
455 src: HighLevelExpressionIndex::from(op.operands[0]),
456 src_memory: op.operands[1],
457 offset: op.operands[2],
458 member_index: get_member_index(op.operands[3]),
459 }),
460 HLIL_DEREF_SSA => Op::DerefSsa(DerefSsa {
461 src: HighLevelExpressionIndex::from(op.operands[0]),
462 src_memory: op.operands[1],
463 }),
464 HLIL_EXTERN_PTR => Op::ExternPtr(ExternPtr {
465 constant: op.operands[0],
466 offset: op.operands[1],
467 }),
468 HLIL_FLOAT_CONST => Op::FloatConst(FloatConst {
469 constant: get_float(op.operands[0], op.size),
470 }),
471 HLIL_FOR => Op::For(ForLoop {
472 init: HighLevelExpressionIndex::from(op.operands[0]),
473 condition: HighLevelExpressionIndex::from(op.operands[1]),
474 update: HighLevelExpressionIndex::from(op.operands[2]),
475 body: HighLevelExpressionIndex::from(op.operands[3]),
476 }),
477 HLIL_FOR_SSA => Op::ForSsa(ForLoopSsa {
478 init: HighLevelExpressionIndex::from(op.operands[0]),
479 condition_phi: HighLevelExpressionIndex::from(op.operands[1]),
480 condition: HighLevelExpressionIndex::from(op.operands[2]),
481 update: HighLevelExpressionIndex::from(op.operands[3]),
482 body: HighLevelExpressionIndex::from(op.operands[4]),
483 }),
484 HLIL_GOTO => Op::Goto(Label {
485 target: op.operands[0],
486 }),
487 HLIL_LABEL => Op::Label(Label {
488 target: op.operands[0],
489 }),
490 HLIL_IF => Op::If(If {
491 condition: HighLevelExpressionIndex::from(op.operands[0]),
492 cond_true: HighLevelExpressionIndex::from(op.operands[1]),
493 cond_false: HighLevelExpressionIndex::from(op.operands[2]),
494 }),
495 HLIL_INTRINSIC => Op::Intrinsic(Intrinsic {
496 intrinsic: op.operands[0] as u32,
497 num_params: op.operands[1] as usize,
498 first_param: op.operands[2] as usize,
499 }),
500 HLIL_INTRINSIC_SSA => Op::IntrinsicSsa(IntrinsicSsa {
501 intrinsic: op.operands[0] as u32,
502 num_params: op.operands[1] as usize,
503 first_param: op.operands[2] as usize,
504 dest_memory: op.operands[3],
505 src_memory: op.operands[4],
506 }),
507 HLIL_JUMP => Op::Jump(Jump {
508 dest: HighLevelExpressionIndex::from(op.operands[0]),
509 }),
510 HLIL_MEM_PHI => Op::MemPhi(MemPhi {
511 dest: op.operands[0],
512 num_srcs: op.operands[1] as usize,
513 first_src: op.operands[2] as usize,
514 }),
515 HLIL_RET => Op::Ret(Ret {
516 num_srcs: op.operands[0] as usize,
517 first_src: op.operands[1] as usize,
518 }),
519 HLIL_SPLIT => Op::Split(Split {
520 high: HighLevelExpressionIndex::from(op.operands[0]),
521 low: HighLevelExpressionIndex::from(op.operands[1]),
522 }),
523 HLIL_STRUCT_FIELD => Op::StructField(StructField {
524 src: HighLevelExpressionIndex::from(op.operands[0]),
525 offset: op.operands[1],
526 member_index: get_member_index(op.operands[2]),
527 }),
528 HLIL_DEREF_FIELD => Op::DerefField(StructField {
529 src: HighLevelExpressionIndex::from(op.operands[0]),
530 offset: op.operands[1],
531 member_index: get_member_index(op.operands[2]),
532 }),
533 HLIL_SWITCH => Op::Switch(Switch {
534 condition: HighLevelExpressionIndex::from(op.operands[0]),
535 default: HighLevelExpressionIndex::from(op.operands[1]),
536 num_cases: op.operands[2] as usize,
537 first_case: op.operands[3] as usize,
538 }),
539 HLIL_SYSCALL => Op::Syscall(Syscall {
540 num_params: op.operands[0] as usize,
541 first_param: op.operands[1] as usize,
542 }),
543 HLIL_SYSCALL_SSA => Op::SyscallSsa(SyscallSsa {
544 num_params: op.operands[0] as usize,
545 first_param: op.operands[1] as usize,
546 dest_memory: op.operands[2],
547 src_memory: op.operands[3],
548 }),
549 HLIL_TRAP => Op::Trap(Trap {
550 vector: op.operands[0],
551 }),
552 HLIL_VAR_DECLARE => Op::VarDeclare(Var {
553 var: get_var(op.operands[0]),
554 }),
555 HLIL_VAR => Op::Var(Var {
556 var: get_var(op.operands[0]),
557 }),
558 HLIL_VAR_INIT => Op::VarInit(VarInit {
559 dest: get_var(op.operands[0]),
560 src: HighLevelExpressionIndex::from(op.operands[1]),
561 }),
562 HLIL_VAR_INIT_SSA => Op::VarInitSsa(VarInitSsa {
563 dest: get_var_ssa((op.operands[0], op.operands[1] as usize)),
564 src: HighLevelExpressionIndex::from(op.operands[2]),
565 }),
566 HLIL_VAR_PHI => Op::VarPhi(VarPhi {
567 dest: get_var_ssa((op.operands[0], op.operands[1] as usize)),
568 num_srcs: op.operands[2] as usize,
569 first_src: op.operands[3] as usize,
570 }),
571 HLIL_VAR_SSA => Op::VarSsa(VarSsa {
572 var: get_var_ssa((op.operands[0], op.operands[1] as usize)),
573 }),
574 HLIL_WHILE => Op::While(While {
575 condition: HighLevelExpressionIndex::from(op.operands[0]),
576 body: HighLevelExpressionIndex::from(op.operands[1]),
577 }),
578 HLIL_DO_WHILE => Op::DoWhile(While {
579 body: HighLevelExpressionIndex::from(op.operands[0]),
580 condition: HighLevelExpressionIndex::from(op.operands[1]),
581 }),
582 HLIL_WHILE_SSA => Op::WhileSsa(WhileSsa {
583 condition_phi: HighLevelExpressionIndex::from(op.operands[0]),
584 condition: HighLevelExpressionIndex::from(op.operands[1]),
585 body: HighLevelExpressionIndex::from(op.operands[2]),
586 }),
587 HLIL_DO_WHILE_SSA => Op::DoWhileSsa(WhileSsa {
588 condition_phi: HighLevelExpressionIndex::from(op.operands[0]),
589 condition: HighLevelExpressionIndex::from(op.operands[1]),
590 body: HighLevelExpressionIndex::from(op.operands[2]),
591 }),
592 };
593 Self {
594 function,
595 address: op.address,
596 instr_index,
597 expr_index,
598 size: op.size,
599 kind,
600 }
601 }
602
603 fn get_operand_list(&self, operand_idx: usize) -> Vec<u64> {
604 let mut count = 0;
605 let raw_list_ptr = unsafe {
606 BNHighLevelILGetOperandList(
607 self.function.handle,
608 self.expr_index.0,
609 operand_idx,
610 &mut count,
611 )
612 };
613 assert!(!raw_list_ptr.is_null());
614 let list = unsafe { std::slice::from_raw_parts(raw_list_ptr, count).to_vec() };
615 unsafe { BNHighLevelILFreeOperandList(raw_list_ptr) };
616 list
617 }
618
619 fn get_ssa_var_list(&self, operand_idx: usize) -> Vec<SSAVariable> {
620 self.get_operand_list(operand_idx)
621 .chunks(2)
622 .map(|chunk| (Variable::from_identifier(chunk[0]), chunk[1] as usize))
623 .map(|(var, version)| SSAVariable::new(var, version))
624 .collect()
625 }
626
627 fn get_expr_list(&self, operand_idx: usize) -> Vec<HighLevelILInstruction> {
628 self.get_operand_list(operand_idx)
629 .into_iter()
630 .map(|val| HighLevelExpressionIndex(val as usize))
631 .filter_map(|idx| self.function.instruction_from_expr_index(idx))
632 .collect()
633 }
634
635 pub fn lift(&self) -> HighLevelILLiftedInstruction {
636 use HighLevelILInstructionKind::*;
637 use HighLevelILLiftedInstructionKind as Lifted;
638 let kind = match self.kind {
639 Nop => Lifted::Nop,
640 Break => Lifted::Break,
641 Continue => Lifted::Continue,
642 Noret => Lifted::Noret,
643 Unreachable => Lifted::Unreachable,
644 Bp => Lifted::Bp,
645 Undef => Lifted::Undef,
646 Unimpl => Lifted::Unimpl,
647
648 Adc(op) => Lifted::Adc(self.lift_binary_op_carry(op)),
649 Sbb(op) => Lifted::Sbb(self.lift_binary_op_carry(op)),
650 Rlc(op) => Lifted::Rlc(self.lift_binary_op_carry(op)),
651 Rrc(op) => Lifted::Rrc(self.lift_binary_op_carry(op)),
652
653 Add(op) => Lifted::Add(self.lift_binary_op(op)),
654 Sub(op) => Lifted::Sub(self.lift_binary_op(op)),
655 And(op) => Lifted::And(self.lift_binary_op(op)),
656 Or(op) => Lifted::Or(self.lift_binary_op(op)),
657 Xor(op) => Lifted::Xor(self.lift_binary_op(op)),
658 Lsl(op) => Lifted::Lsl(self.lift_binary_op(op)),
659 Lsr(op) => Lifted::Lsr(self.lift_binary_op(op)),
660 Asr(op) => Lifted::Asr(self.lift_binary_op(op)),
661 Rol(op) => Lifted::Rol(self.lift_binary_op(op)),
662 Ror(op) => Lifted::Ror(self.lift_binary_op(op)),
663 Mul(op) => Lifted::Mul(self.lift_binary_op(op)),
664 MuluDp(op) => Lifted::MuluDp(self.lift_binary_op(op)),
665 MulsDp(op) => Lifted::MulsDp(self.lift_binary_op(op)),
666 Divu(op) => Lifted::Divu(self.lift_binary_op(op)),
667 DivuDp(op) => Lifted::DivuDp(self.lift_binary_op(op)),
668 Divs(op) => Lifted::Divs(self.lift_binary_op(op)),
669 DivsDp(op) => Lifted::DivsDp(self.lift_binary_op(op)),
670 Modu(op) => Lifted::Modu(self.lift_binary_op(op)),
671 ModuDp(op) => Lifted::ModuDp(self.lift_binary_op(op)),
672 Mods(op) => Lifted::Mods(self.lift_binary_op(op)),
673 ModsDp(op) => Lifted::ModsDp(self.lift_binary_op(op)),
674 CmpE(op) => Lifted::CmpE(self.lift_binary_op(op)),
675 CmpNe(op) => Lifted::CmpNe(self.lift_binary_op(op)),
676 CmpSlt(op) => Lifted::CmpSlt(self.lift_binary_op(op)),
677 CmpUlt(op) => Lifted::CmpUlt(self.lift_binary_op(op)),
678 CmpSle(op) => Lifted::CmpSle(self.lift_binary_op(op)),
679 CmpUle(op) => Lifted::CmpUle(self.lift_binary_op(op)),
680 CmpSge(op) => Lifted::CmpSge(self.lift_binary_op(op)),
681 CmpUge(op) => Lifted::CmpUge(self.lift_binary_op(op)),
682 CmpSgt(op) => Lifted::CmpSgt(self.lift_binary_op(op)),
683 CmpUgt(op) => Lifted::CmpUgt(self.lift_binary_op(op)),
684 TestBit(op) => Lifted::TestBit(self.lift_binary_op(op)),
685 AddOverflow(op) => Lifted::AddOverflow(self.lift_binary_op(op)),
686 Fadd(op) => Lifted::Fadd(self.lift_binary_op(op)),
687 Fsub(op) => Lifted::Fsub(self.lift_binary_op(op)),
688 Fmul(op) => Lifted::Fmul(self.lift_binary_op(op)),
689 Fdiv(op) => Lifted::Fdiv(self.lift_binary_op(op)),
690 FcmpE(op) => Lifted::FcmpE(self.lift_binary_op(op)),
691 FcmpNe(op) => Lifted::FcmpNe(self.lift_binary_op(op)),
692 FcmpLt(op) => Lifted::FcmpLt(self.lift_binary_op(op)),
693 FcmpLe(op) => Lifted::FcmpLe(self.lift_binary_op(op)),
694 FcmpGe(op) => Lifted::FcmpGe(self.lift_binary_op(op)),
695 FcmpGt(op) => Lifted::FcmpGt(self.lift_binary_op(op)),
696 FcmpO(op) => Lifted::FcmpO(self.lift_binary_op(op)),
697 FcmpUo(op) => Lifted::FcmpUo(self.lift_binary_op(op)),
698
699 ArrayIndex(op) => Lifted::ArrayIndex(LiftedArrayIndex {
700 src: self.lift_operand(op.src),
701 index: self.lift_operand(op.index),
702 }),
703 ArrayIndexSsa(op) => Lifted::ArrayIndexSsa(LiftedArrayIndexSsa {
704 src: self.lift_operand(op.src),
705 src_memory: op.src_memory,
706 index: self.lift_operand(op.index),
707 }),
708 Assign(op) => Lifted::Assign(LiftedAssign {
709 dest: self.lift_operand(op.dest),
710 src: self.lift_operand(op.src),
711 }),
712 AssignUnpack(op) => Lifted::AssignUnpack(LiftedAssignUnpack {
713 dest: self
714 .get_expr_list(0)
715 .iter()
716 .map(|expr| expr.lift())
717 .collect(),
718 src: self.lift_operand(op.src),
719 }),
720 AssignMemSsa(op) => Lifted::AssignMemSsa(LiftedAssignMemSsa {
721 dest: self.lift_operand(op.dest),
722 dest_memory: op.dest_memory,
723 src: self.lift_operand(op.src),
724 src_memory: op.src_memory,
725 }),
726 AssignUnpackMemSsa(op) => Lifted::AssignUnpackMemSsa(LiftedAssignUnpackMemSsa {
727 dest: self
728 .get_expr_list(0)
729 .iter()
730 .map(|expr| expr.lift())
731 .collect(),
732 dest_memory: op.dest_memory,
733 src: self.lift_operand(op.src),
734 src_memory: op.src_memory,
735 }),
736 Block(_op) => Lifted::Block(LiftedBlock {
737 body: self
738 .get_expr_list(0)
739 .iter()
740 .map(|expr| expr.lift())
741 .collect(),
742 }),
743
744 Call(op) => Lifted::Call(self.lift_call(op)),
745 Tailcall(op) => Lifted::Tailcall(self.lift_call(op)),
746 CallSsa(op) => Lifted::CallSsa(LiftedCallSsa {
747 dest: self.lift_operand(op.dest),
748 params: self
749 .get_expr_list(1)
750 .iter()
751 .map(|expr| expr.lift())
752 .collect(),
753 dest_memory: op.dest_memory,
754 src_memory: op.src_memory,
755 }),
756
757 Case(op) => Lifted::Case(LiftedCase {
758 values: self
759 .get_expr_list(0)
760 .iter()
761 .map(|expr| expr.lift())
762 .collect(),
763 body: self.lift_operand(op.body),
764 }),
765 Const(op) => Lifted::Const(op),
766 ConstPtr(op) => Lifted::ConstPtr(op),
767 Import(op) => Lifted::Import(op),
768 ConstData(op) => Lifted::ConstData(LiftedConstData {
769 constant_data: ConstantData::new(
770 self.function.function(),
771 RegisterValue {
772 state: unsafe {
776 std::mem::transmute::<u32, BNRegisterValueType>(op.constant_data_kind)
777 },
778 value: op.constant_data_value,
779 offset: 0,
780 size: op.size,
781 },
782 ),
783 }),
784
785 Deref(op) => Lifted::Deref(self.lift_unary_op(op)),
786 AddressOf(op) => Lifted::AddressOf(self.lift_unary_op(op)),
787 Neg(op) => Lifted::Neg(self.lift_unary_op(op)),
788 Not(op) => Lifted::Not(self.lift_unary_op(op)),
789 Sx(op) => Lifted::Sx(self.lift_unary_op(op)),
790 Zx(op) => Lifted::Zx(self.lift_unary_op(op)),
791 LowPart(op) => Lifted::LowPart(self.lift_unary_op(op)),
792 BoolToInt(op) => Lifted::BoolToInt(self.lift_unary_op(op)),
793 UnimplMem(op) => Lifted::UnimplMem(self.lift_unary_op(op)),
794 Fsqrt(op) => Lifted::Fsqrt(self.lift_unary_op(op)),
795 Fneg(op) => Lifted::Fneg(self.lift_unary_op(op)),
796 Fabs(op) => Lifted::Fabs(self.lift_unary_op(op)),
797 FloatToInt(op) => Lifted::FloatToInt(self.lift_unary_op(op)),
798 IntToFloat(op) => Lifted::IntToFloat(self.lift_unary_op(op)),
799 FloatConv(op) => Lifted::FloatConv(self.lift_unary_op(op)),
800 RoundToInt(op) => Lifted::RoundToInt(self.lift_unary_op(op)),
801 Floor(op) => Lifted::Floor(self.lift_unary_op(op)),
802 Ceil(op) => Lifted::Ceil(self.lift_unary_op(op)),
803 Ftrunc(op) => Lifted::Ftrunc(self.lift_unary_op(op)),
804
805 DerefFieldSsa(op) => Lifted::DerefFieldSsa(LiftedDerefFieldSsa {
806 src: self.lift_operand(op.src),
807 src_memory: op.src_memory,
808 offset: op.offset,
809 member_index: op.member_index,
810 }),
811 DerefSsa(op) => Lifted::DerefSsa(LiftedDerefSsa {
812 src: self.lift_operand(op.src),
813 src_memory: op.src_memory,
814 }),
815 ExternPtr(op) => Lifted::ExternPtr(op),
816 FloatConst(op) => Lifted::FloatConst(op),
817 For(op) => Lifted::For(LiftedForLoop {
818 init: self.lift_operand(op.init),
819 condition: self.lift_operand(op.condition),
820 update: self.lift_operand(op.update),
821 body: self.lift_operand(op.body),
822 }),
823 Goto(op) => Lifted::Goto(self.lift_label(op)),
824 Label(op) => Lifted::Label(self.lift_label(op)),
825 ForSsa(op) => Lifted::ForSsa(LiftedForLoopSsa {
826 init: self.lift_operand(op.init),
827 condition_phi: self.lift_operand(op.condition_phi),
828 condition: self.lift_operand(op.condition),
829 update: self.lift_operand(op.update),
830 body: self.lift_operand(op.body),
831 }),
832 If(op) => Lifted::If(LiftedIf {
833 condition: self.lift_operand(op.condition),
834 cond_true: self.lift_operand(op.cond_true),
835 cond_false: self.lift_operand(op.cond_false),
836 }),
837 Intrinsic(op) => Lifted::Intrinsic(LiftedIntrinsic {
838 intrinsic: CoreIntrinsic::new(
839 self.function.function().arch(),
840 IntrinsicId(op.intrinsic),
841 )
842 .expect("Invalid intrinsic"),
843 params: self
844 .get_expr_list(1)
845 .iter()
846 .map(|expr| expr.lift())
847 .collect(),
848 }),
849 IntrinsicSsa(op) => Lifted::IntrinsicSsa(LiftedIntrinsicSsa {
850 intrinsic: CoreIntrinsic::new(
851 self.function.function().arch(),
852 IntrinsicId(op.intrinsic),
853 )
854 .expect("Invalid intrinsic"),
855 params: self
856 .get_expr_list(1)
857 .iter()
858 .map(|expr| expr.lift())
859 .collect(),
860 dest_memory: op.dest_memory,
861 src_memory: op.src_memory,
862 }),
863 Jump(op) => Lifted::Jump(LiftedJump {
864 dest: self.lift_operand(op.dest),
865 }),
866 MemPhi(op) => Lifted::MemPhi(LiftedMemPhi {
867 dest: op.dest,
868 src: self.get_operand_list(1),
869 }),
870 Ret(_op) => Lifted::Ret(LiftedRet {
871 src: self
872 .get_expr_list(0)
873 .iter()
874 .map(|expr| expr.lift())
875 .collect(),
876 }),
877 Split(op) => Lifted::Split(LiftedSplit {
878 high: self.lift_operand(op.high),
879 low: self.lift_operand(op.low),
880 }),
881 StructField(op) => Lifted::StructField(self.lift_struct_field(op)),
882 DerefField(op) => Lifted::DerefField(self.lift_struct_field(op)),
883 Switch(op) => Lifted::Switch(LiftedSwitch {
884 condition: self.lift_operand(op.condition),
885 default: self.lift_operand(op.default),
886 cases: self
887 .get_expr_list(2)
888 .iter()
889 .map(|expr| expr.lift())
890 .collect(),
891 }),
892 Syscall(_op) => Lifted::Syscall(LiftedSyscall {
893 params: self
894 .get_expr_list(0)
895 .iter()
896 .map(|expr| expr.lift())
897 .collect(),
898 }),
899 SyscallSsa(op) => Lifted::SyscallSsa(LiftedSyscallSsa {
900 params: self
901 .get_expr_list(0)
902 .iter()
903 .map(|expr| expr.lift())
904 .collect(),
905 dest_memory: op.dest_memory,
906 src_memory: op.src_memory,
907 }),
908 Trap(op) => Lifted::Trap(op),
909 VarDeclare(op) => Lifted::VarDeclare(op),
910 Var(op) => Lifted::Var(op),
911 VarInit(op) => Lifted::VarInit(LiftedVarInit {
912 dest: op.dest,
913 src: self.lift_operand(op.src),
914 }),
915 VarInitSsa(op) => Lifted::VarInitSsa(LiftedVarInitSsa {
916 dest: op.dest,
917 src: self.lift_operand(op.src),
918 }),
919 VarPhi(op) => Lifted::VarPhi(LiftedVarPhi {
920 dest: op.dest,
921 src: self.get_ssa_var_list(2),
922 }),
923 VarSsa(op) => Lifted::VarSsa(op),
924
925 While(op) => Lifted::While(self.lift_while(op)),
926 DoWhile(op) => Lifted::DoWhile(self.lift_while(op)),
927
928 WhileSsa(op) => Lifted::WhileSsa(self.lift_while_ssa(op)),
929 DoWhileSsa(op) => Lifted::DoWhileSsa(self.lift_while_ssa(op)),
930 };
931 HighLevelILLiftedInstruction {
932 function: self.function.clone(),
933 address: self.address,
934 instr_index: self.instr_index,
935 expr_index: self.expr_index,
936 size: self.size,
937 kind,
938 }
939 }
940
941 pub fn lines(&self) -> Array<DisassemblyTextLine> {
943 let mut count = 0;
944 let lines = unsafe {
945 BNGetHighLevelILExprText(
946 self.function.handle,
947 self.expr_index.0,
948 self.function.full_ast,
949 &mut count,
950 core::ptr::null_mut(),
951 )
952 };
953 unsafe { Array::new(lines, count, ()) }
954 }
955
956 pub fn expr_type(&self) -> Option<Conf<Ref<Type>>> {
958 let result = unsafe { BNGetHighLevelILExprType(self.function.handle, self.expr_index.0) };
959 (!result.type_.is_null()).then(|| {
960 Conf::new(
961 unsafe { Type::ref_from_raw(result.type_) },
962 result.confidence,
963 )
964 })
965 }
966
967 pub fn ssa_memory_version(&self) -> usize {
969 unsafe {
970 BNGetHighLevelILSSAMemoryVersionAtILInstruction(self.function.handle, self.expr_index.0)
971 }
972 }
973
974 pub fn ssa_variable_version(&self, variable: Variable) -> SSAVariable {
975 let version = unsafe {
976 BNGetHighLevelILSSAVarVersionAtILInstruction(
977 self.function.handle,
978 &variable.into(),
979 self.expr_index.0,
980 )
981 };
982 SSAVariable::new(variable, version)
983 }
984
985 fn lift_operand(
986 &self,
987 expr_idx: HighLevelExpressionIndex,
988 ) -> Box<HighLevelILLiftedInstruction> {
989 let operand_instr = self.function.instruction_from_expr_index(expr_idx).unwrap();
990 Box::new(operand_instr.lift())
991 }
992
993 fn lift_binary_op(&self, op: BinaryOp) -> LiftedBinaryOp {
994 LiftedBinaryOp {
995 left: self.lift_operand(op.left),
996 right: self.lift_operand(op.right),
997 }
998 }
999
1000 fn lift_binary_op_carry(&self, op: BinaryOpCarry) -> LiftedBinaryOpCarry {
1001 LiftedBinaryOpCarry {
1002 left: self.lift_operand(op.left),
1003 right: self.lift_operand(op.right),
1004 carry: self.lift_operand(op.carry),
1005 }
1006 }
1007
1008 fn lift_unary_op(&self, op: UnaryOp) -> LiftedUnaryOp {
1009 LiftedUnaryOp {
1010 src: self.lift_operand(op.src),
1011 }
1012 }
1013
1014 fn lift_label(&self, op: Label) -> LiftedLabel {
1015 LiftedLabel {
1016 target: GotoLabel {
1017 function: self.function.function(),
1018 target: op.target,
1019 },
1020 }
1021 }
1022
1023 fn lift_call(&self, op: Call) -> LiftedCall {
1024 LiftedCall {
1025 dest: self.lift_operand(op.dest),
1026 params: self
1027 .get_expr_list(1)
1028 .iter()
1029 .map(|expr| expr.lift())
1030 .collect(),
1031 }
1032 }
1033
1034 fn lift_while(&self, op: While) -> LiftedWhile {
1035 LiftedWhile {
1036 condition: self.lift_operand(op.condition),
1037 body: self.lift_operand(op.body),
1038 }
1039 }
1040
1041 fn lift_while_ssa(&self, op: WhileSsa) -> LiftedWhileSsa {
1042 LiftedWhileSsa {
1043 condition_phi: self.lift_operand(op.condition_phi),
1044 condition: self.lift_operand(op.condition),
1045 body: self.lift_operand(op.body),
1046 }
1047 }
1048
1049 fn lift_struct_field(&self, op: StructField) -> LiftedStructField {
1050 LiftedStructField {
1051 src: self.lift_operand(op.src),
1052 offset: op.offset,
1053 member_index: op.member_index,
1054 }
1055 }
1056}
1057
1058impl CoreArrayProvider for HighLevelILInstruction {
1059 type Raw = usize;
1060 type Context = Ref<HighLevelILFunction>;
1061 type Wrapped<'a> = Self;
1062}
1063
1064unsafe impl CoreArrayProviderInner for HighLevelILInstruction {
1065 unsafe fn free(raw: *mut Self::Raw, _count: usize, _context: &Self::Context) {
1066 unsafe { BNFreeILInstructionList(raw) }
1067 }
1068
1069 unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, context: &'a Self::Context) -> Self::Wrapped<'a> {
1070 context
1071 .instruction_from_expr_index(HighLevelExpressionIndex(*raw))
1072 .unwrap()
1073 }
1074}
1075
1076impl Debug for HighLevelILInstruction {
1077 fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
1078 write!(
1080 f,
1081 "<{} at 0x{:08}>",
1082 core::any::type_name::<Self>(),
1083 self.address,
1084 )
1085 }
1086}
1087
1088#[derive(Debug, Copy, Clone)]
1089pub enum HighLevelILInstructionKind {
1090 Nop,
1091 Break,
1092 Continue,
1093 Noret,
1094 Unreachable,
1095 Bp,
1096 Undef,
1097 Unimpl,
1098 Adc(BinaryOpCarry),
1099 Sbb(BinaryOpCarry),
1100 Rlc(BinaryOpCarry),
1101 Rrc(BinaryOpCarry),
1102 Add(BinaryOp),
1103 Sub(BinaryOp),
1104 And(BinaryOp),
1105 Or(BinaryOp),
1106 Xor(BinaryOp),
1107 Lsl(BinaryOp),
1108 Lsr(BinaryOp),
1109 Asr(BinaryOp),
1110 Rol(BinaryOp),
1111 Ror(BinaryOp),
1112 Mul(BinaryOp),
1113 MuluDp(BinaryOp),
1114 MulsDp(BinaryOp),
1115 Divu(BinaryOp),
1116 DivuDp(BinaryOp),
1117 Divs(BinaryOp),
1118 DivsDp(BinaryOp),
1119 Modu(BinaryOp),
1120 ModuDp(BinaryOp),
1121 Mods(BinaryOp),
1122 ModsDp(BinaryOp),
1123 CmpE(BinaryOp),
1124 CmpNe(BinaryOp),
1125 CmpSlt(BinaryOp),
1126 CmpUlt(BinaryOp),
1127 CmpSle(BinaryOp),
1128 CmpUle(BinaryOp),
1129 CmpSge(BinaryOp),
1130 CmpUge(BinaryOp),
1131 CmpSgt(BinaryOp),
1132 CmpUgt(BinaryOp),
1133 TestBit(BinaryOp),
1134 AddOverflow(BinaryOp),
1135 Fadd(BinaryOp),
1136 Fsub(BinaryOp),
1137 Fmul(BinaryOp),
1138 Fdiv(BinaryOp),
1139 FcmpE(BinaryOp),
1140 FcmpNe(BinaryOp),
1141 FcmpLt(BinaryOp),
1142 FcmpLe(BinaryOp),
1143 FcmpGe(BinaryOp),
1144 FcmpGt(BinaryOp),
1145 FcmpO(BinaryOp),
1146 FcmpUo(BinaryOp),
1147 ArrayIndex(ArrayIndex),
1148 ArrayIndexSsa(ArrayIndexSsa),
1149 Assign(Assign),
1150 AssignMemSsa(AssignMemSsa),
1151 AssignUnpack(AssignUnpack),
1152 AssignUnpackMemSsa(AssignUnpackMemSsa),
1153 Block(Block),
1154 Call(Call),
1155 Tailcall(Call),
1156 CallSsa(CallSsa),
1157 Case(Case),
1158 Const(Const),
1159 ConstPtr(Const),
1160 Import(Const),
1161 ConstData(ConstData),
1162 Deref(UnaryOp),
1163 AddressOf(UnaryOp),
1164 Neg(UnaryOp),
1165 Not(UnaryOp),
1166 Sx(UnaryOp),
1167 Zx(UnaryOp),
1168 LowPart(UnaryOp),
1169 BoolToInt(UnaryOp),
1170 UnimplMem(UnaryOp),
1171 Fsqrt(UnaryOp),
1172 Fneg(UnaryOp),
1173 Fabs(UnaryOp),
1174 FloatToInt(UnaryOp),
1175 IntToFloat(UnaryOp),
1176 FloatConv(UnaryOp),
1177 RoundToInt(UnaryOp),
1178 Floor(UnaryOp),
1179 Ceil(UnaryOp),
1180 Ftrunc(UnaryOp),
1181 DerefFieldSsa(DerefFieldSsa),
1182 DerefSsa(DerefSsa),
1183 ExternPtr(ExternPtr),
1184 FloatConst(FloatConst),
1185 For(ForLoop),
1186 ForSsa(ForLoopSsa),
1187 Goto(Label),
1188 Label(Label),
1189 If(If),
1190 Intrinsic(Intrinsic),
1191 IntrinsicSsa(IntrinsicSsa),
1192 Jump(Jump),
1193 MemPhi(MemPhi),
1194 Ret(Ret),
1195 Split(Split),
1196 StructField(StructField),
1197 DerefField(StructField),
1198 Switch(Switch),
1199 Syscall(Syscall),
1200 SyscallSsa(SyscallSsa),
1201 Trap(Trap),
1202 VarDeclare(Var),
1203 Var(Var),
1204 VarInit(VarInit),
1205 VarInitSsa(VarInitSsa),
1206 VarPhi(VarPhi),
1207 VarSsa(VarSsa),
1208 While(While),
1209 DoWhile(While),
1210 WhileSsa(WhileSsa),
1211 DoWhileSsa(WhileSsa),
1212}
1213
1214fn get_float(value: u64, size: usize) -> f64 {
1215 match size {
1216 4 => f32::from_bits(value as u32) as f64,
1217 8 => f64::from_bits(value),
1218 size => todo!("float size {}", size),
1220 }
1221}
1222
1223fn get_var(id: u64) -> Variable {
1224 Variable::from_identifier(id)
1225}
1226
1227fn get_member_index(idx: u64) -> Option<usize> {
1228 (idx as i64 > 0).then_some(idx as usize)
1229}
1230
1231fn get_var_ssa(input: (u64, usize)) -> SSAVariable {
1232 SSAVariable::new(get_var(input.0), input.1)
1233}