From 6e8116614b43097800f0e7b493260c4aaadd7c29 Mon Sep 17 00:00:00 2001 From: Mark Rowe Date: Tue, 27 May 2025 15:11:43 -0700 Subject: [Rust] Add support for LLIL_REG_PHI / LLIL_MEM_PHI / LLIL_FLAG_PHI --- rust/src/low_level_il/operation.rs | 91 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 88 insertions(+), 3 deletions(-) (limited to 'rust/src/low_level_il/operation.rs') 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 Operation<'_, M, F, RegPhi> +where + M: FunctionMutability, + F: FunctionForm, +{ + pub fn dest_reg(&self) -> LowLevelILSSARegisterKind { + 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> { + 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 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 Operation<'_, M, F, FlagPhi> +where + M: FunctionMutability, + F: FunctionForm, +{ + pub fn dest_flag(&self) -> LowLevelILSSAFlag { + 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> { + 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 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 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 { + let operand_list = self.get_operand_list(1); + operand_list.into_iter().map(|op| op as usize).collect() + } +} + impl 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() } } -- cgit v1.3.1