diff options
| author | Mark Rowe <mrowe@bdash.net.nz> | 2025-05-27 15:11:43 -0700 |
|---|---|---|
| committer | Mason Reed <mason@vector35.com> | 2025-05-30 19:17:10 -0400 |
| commit | 6e8116614b43097800f0e7b493260c4aaadd7c29 (patch) | |
| tree | fe4e8252604362b702aadb285d076f8316f1304f /rust/src | |
| parent | abc355d98467bc1fce4368d4a7e1aff0e12cc3c3 (diff) | |
[Rust] Add support for LLIL_REG_PHI / LLIL_MEM_PHI / LLIL_FLAG_PHI
Diffstat (limited to 'rust/src')
| -rw-r--r-- | rust/src/low_level_il/instruction.rs | 17 | ||||
| -rw-r--r-- | rust/src/low_level_il/operation.rs | 91 |
2 files changed, 104 insertions, 4 deletions
diff --git a/rust/src/low_level_il/instruction.rs b/rust/src/low_level_il/instruction.rs index 652706ea..04a1d2d5 100644 --- a/rust/src/low_level_il/instruction.rs +++ b/rust/src/low_level_il/instruction.rs @@ -254,6 +254,10 @@ where ForceVersion(Operation<'func, M, F, operation::ForceVersion>), ForceVersionSsa(Operation<'func, M, F, operation::ForceVersionSsa>), + RegPhi(Operation<'func, M, F, operation::RegPhi>), + FlagPhi(Operation<'func, M, F, operation::FlagPhi>), + MemPhi(Operation<'func, M, F, operation::MemPhi>), + /// The instruction is an expression. Value(LowLevelILExpression<'func, M, F, ValueExpr>), } @@ -357,6 +361,16 @@ where LLIL_FORCE_VER_SSA => { LowLevelILInstructionKind::ForceVersionSsa(Operation::new(function, op, expr_index)) } + LLIL_REG_PHI => { + LowLevelILInstructionKind::RegPhi(Operation::new(function, op, expr_index)) + } + LLIL_MEM_PHI => { + LowLevelILInstructionKind::MemPhi(Operation::new(function, op, expr_index)) + } + LLIL_FLAG_PHI => { + LowLevelILInstructionKind::FlagPhi(Operation::new(function, op, expr_index)) + } + _ => LowLevelILInstructionKind::Value(LowLevelILExpression::new(function, expr_index)), } } @@ -410,7 +424,8 @@ where Value(e) => visit!(e), // Do not have any sub expressions. Nop(_) | NoRet(_) | Goto(_) | Syscall(_) | Bp(_) | Trap(_) | Undef(_) | Assert(_) - | AssertSsa(_) | ForceVersion(_) | ForceVersionSsa(_) => {} + | AssertSsa(_) | ForceVersion(_) | ForceVersionSsa(_) | RegPhi(_) | FlagPhi(_) + | MemPhi(_) => {} } VisitorAction::Sibling diff --git a/rust/src/low_level_il/operation.rs b/rust/src/low_level_il/operation.rs index 6e0dda91..382b4927 100644 --- a/rust/src/low_level_il/operation.rs +++ b/rust/src/low_level_il/operation.rs @@ -1475,6 +1475,35 @@ where // LLIL_REG_PHI pub struct RegPhi; +impl<M, F> Operation<'_, M, F, RegPhi> +where + M: FunctionMutability, + F: FunctionForm, +{ + pub fn dest_reg(&self) -> LowLevelILSSARegisterKind<CoreRegister> { + let raw_id = RegisterId(self.op.operands[0] as u32); + let reg_kind = LowLevelILRegisterKind::from_raw(&self.function.arch(), raw_id) + .expect("Bad register ID"); + let version = self.op.operands[1] as u32; + LowLevelILSSARegisterKind::new_full(reg_kind, version) + } + + pub fn source_regs(&self) -> Vec<LowLevelILSSARegisterKind<CoreRegister>> { + let operand_list = self.get_operand_list(2); + let arch = self.function.arch(); + operand_list + .chunks_exact(2) + .map(|chunk| { + let (register, version) = (chunk[0], chunk[1]); + LowLevelILSSARegisterKind::new_full( + LowLevelILRegisterKind::from_raw(&arch, RegisterId(register as u32)) + .expect("Bad register ID"), + version as u32, + ) + }) + .collect() + } +} impl<M, F> Debug for Operation<'_, M, F, RegPhi> where @@ -1482,33 +1511,89 @@ where F: FunctionForm, { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - f.debug_struct("RegPhi").finish() + f.debug_struct("RegPhi") + .field("dest_reg", &self.dest_reg()) + .field("source_regs", &self.source_regs()) + .finish() } } // LLIL_FLAG_PHI pub struct FlagPhi; +impl<M, F> Operation<'_, M, F, FlagPhi> +where + M: FunctionMutability, + F: FunctionForm, +{ + pub fn dest_flag(&self) -> LowLevelILSSAFlag<CoreFlag> { + let flag = self + .function + .arch() + .flag_from_id(FlagId(self.op.operands[0] as u32)) + .expect("Bad flag ID"); + let version = self.op.operands[1] as u32; + LowLevelILSSAFlag::new(flag, version) + } + + pub fn source_flags(&self) -> Vec<LowLevelILSSAFlag<CoreFlag>> { + let operand_list = self.get_operand_list(2); + operand_list + .chunks_exact(2) + .map(|chunk| { + let (flag, version) = (chunk[0], chunk[1]); + let flag = self + .function + .arch() + .flag_from_id(FlagId(flag as u32)) + .expect("Bad flag ID"); + LowLevelILSSAFlag::new(flag, version as u32) + }) + .collect() + } +} + impl<M, F> Debug for Operation<'_, M, F, FlagPhi> where M: FunctionMutability, F: FunctionForm, { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - f.debug_struct("FlagPhi").finish() + f.debug_struct("FlagPhi") + .field("dest_flag", &self.dest_flag()) + .field("source_flags", &self.source_flags()) + .finish() } } // LLIL_MEM_PHI pub struct MemPhi; +impl<M, F> Operation<'_, M, F, MemPhi> +where + M: FunctionMutability, + F: FunctionForm, +{ + pub fn dest_memory_version(&self) -> usize { + self.op.operands[0] as usize + } + + pub fn source_memory_versions(&self) -> Vec<usize> { + let operand_list = self.get_operand_list(1); + operand_list.into_iter().map(|op| op as usize).collect() + } +} + impl<M, F> Debug for Operation<'_, M, F, MemPhi> where M: FunctionMutability, F: FunctionForm, { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - f.debug_struct("MemPhi").finish() + f.debug_struct("MemPhi") + .field("dest_memory_version", &self.dest_memory_version()) + .field("source_memory_versions", &self.source_memory_versions()) + .finish() } } |
