Skip to content

Commit 1030bcd

Browse files
committed
[Rust] Add support for LLIL_REG_PHI / LLIL_MEM_PHI / LLIL_FLAG_PHI
1 parent 1431470 commit 1030bcd

File tree

2 files changed

+104
-4
lines changed

2 files changed

+104
-4
lines changed

rust/src/low_level_il/instruction.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,10 @@ where
214214
ForceVersion(Operation<'func, M, F, operation::ForceVersion>),
215215
ForceVersionSsa(Operation<'func, M, F, operation::ForceVersionSsa>),
216216

217+
RegPhi(Operation<'func, M, F, operation::RegPhi>),
218+
FlagPhi(Operation<'func, M, F, operation::FlagPhi>),
219+
MemPhi(Operation<'func, M, F, operation::MemPhi>),
220+
217221
/// The instruction is an expression.
218222
Value(LowLevelILExpression<'func, M, F, ValueExpr>),
219223
}
@@ -317,6 +321,16 @@ where
317321
LLIL_FORCE_VER_SSA => {
318322
LowLevelILInstructionKind::ForceVersionSsa(Operation::new(function, op, expr_index))
319323
}
324+
LLIL_REG_PHI => {
325+
LowLevelILInstructionKind::RegPhi(Operation::new(function, op, expr_index))
326+
}
327+
LLIL_MEM_PHI => {
328+
LowLevelILInstructionKind::MemPhi(Operation::new(function, op, expr_index))
329+
}
330+
LLIL_FLAG_PHI => {
331+
LowLevelILInstructionKind::FlagPhi(Operation::new(function, op, expr_index))
332+
}
333+
320334
_ => LowLevelILInstructionKind::Value(LowLevelILExpression::new(function, expr_index)),
321335
}
322336
}
@@ -370,7 +384,8 @@ where
370384
Value(e) => visit!(e),
371385
// Do not have any sub expressions.
372386
Nop(_) | NoRet(_) | Goto(_) | Syscall(_) | Bp(_) | Trap(_) | Undef(_) | Assert(_)
373-
| AssertSsa(_) | ForceVersion(_) | ForceVersionSsa(_) => {}
387+
| AssertSsa(_) | ForceVersion(_) | ForceVersionSsa(_) | RegPhi(_) | FlagPhi(_)
388+
| MemPhi(_) => {}
374389
}
375390

376391
VisitorAction::Sibling

rust/src/low_level_il/operation.rs

Lines changed: 88 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1475,40 +1475,125 @@ where
14751475

14761476
// LLIL_REG_PHI
14771477
pub struct RegPhi;
1478+
impl<M, F> Operation<'_, M, F, RegPhi>
1479+
where
1480+
M: FunctionMutability,
1481+
F: FunctionForm,
1482+
{
1483+
pub fn dest_reg(&self) -> LowLevelILSSARegisterKind<CoreRegister> {
1484+
let raw_id = RegisterId(self.op.operands[0] as u32);
1485+
let reg_kind = LowLevelILRegisterKind::from_raw(&self.function.arch(), raw_id)
1486+
.expect("Bad register ID");
1487+
let version = self.op.operands[1] as u32;
1488+
LowLevelILSSARegisterKind::new_full(reg_kind, version)
1489+
}
1490+
1491+
pub fn source_regs(&self) -> Vec<LowLevelILSSARegisterKind<CoreRegister>> {
1492+
let operand_list = self.get_operand_list(2);
1493+
let arch = self.function.arch();
1494+
operand_list
1495+
.chunks_exact(2)
1496+
.map(|chunk| {
1497+
let (register, version) = (chunk[0], chunk[1]);
1498+
LowLevelILSSARegisterKind::new_full(
1499+
LowLevelILRegisterKind::from_raw(&arch, RegisterId(register as u32))
1500+
.expect("Bad register ID"),
1501+
version as u32,
1502+
)
1503+
})
1504+
.collect()
1505+
}
1506+
}
14781507

14791508
impl<M, F> Debug for Operation<'_, M, F, RegPhi>
14801509
where
14811510
M: FunctionMutability,
14821511
F: FunctionForm,
14831512
{
14841513
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1485-
f.debug_struct("RegPhi").finish()
1514+
f.debug_struct("RegPhi")
1515+
.field("dest_reg", &self.dest_reg())
1516+
.field("source_regs", &self.source_regs())
1517+
.finish()
14861518
}
14871519
}
14881520

14891521
// LLIL_FLAG_PHI
14901522
pub struct FlagPhi;
14911523

1524+
impl<M, F> Operation<'_, M, F, FlagPhi>
1525+
where
1526+
M: FunctionMutability,
1527+
F: FunctionForm,
1528+
{
1529+
pub fn dest_flag(&self) -> LowLevelILSSAFlag<CoreFlag> {
1530+
let flag = self
1531+
.function
1532+
.arch()
1533+
.flag_from_id(FlagId(self.op.operands[0] as u32))
1534+
.expect("Bad flag ID");
1535+
let version = self.op.operands[1] as u32;
1536+
LowLevelILSSAFlag::new(flag, version)
1537+
}
1538+
1539+
pub fn source_flags(&self) -> Vec<LowLevelILSSAFlag<CoreFlag>> {
1540+
let operand_list = self.get_operand_list(2);
1541+
operand_list
1542+
.chunks_exact(2)
1543+
.map(|chunk| {
1544+
let (flag, version) = (chunk[0], chunk[1]);
1545+
let flag = self
1546+
.function
1547+
.arch()
1548+
.flag_from_id(FlagId(flag as u32))
1549+
.expect("Bad flag ID");
1550+
LowLevelILSSAFlag::new(flag, version as u32)
1551+
})
1552+
.collect()
1553+
}
1554+
}
1555+
14921556
impl<M, F> Debug for Operation<'_, M, F, FlagPhi>
14931557
where
14941558
M: FunctionMutability,
14951559
F: FunctionForm,
14961560
{
14971561
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1498-
f.debug_struct("FlagPhi").finish()
1562+
f.debug_struct("FlagPhi")
1563+
.field("dest_flag", &self.dest_flag())
1564+
.field("source_flags", &self.source_flags())
1565+
.finish()
14991566
}
15001567
}
15011568

15021569
// LLIL_MEM_PHI
15031570
pub struct MemPhi;
15041571

1572+
impl<M, F> Operation<'_, M, F, MemPhi>
1573+
where
1574+
M: FunctionMutability,
1575+
F: FunctionForm,
1576+
{
1577+
pub fn dest_memory_version(&self) -> usize {
1578+
self.op.operands[0] as usize
1579+
}
1580+
1581+
pub fn source_memory_versions(&self) -> Vec<usize> {
1582+
let operand_list = self.get_operand_list(1);
1583+
operand_list.into_iter().map(|op| op as usize).collect()
1584+
}
1585+
}
1586+
15051587
impl<M, F> Debug for Operation<'_, M, F, MemPhi>
15061588
where
15071589
M: FunctionMutability,
15081590
F: FunctionForm,
15091591
{
15101592
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1511-
f.debug_struct("MemPhi").finish()
1593+
f.debug_struct("MemPhi")
1594+
.field("dest_memory_version", &self.dest_memory_version())
1595+
.field("source_memory_versions", &self.source_memory_versions())
1596+
.finish()
15121597
}
15131598
}
15141599

0 commit comments

Comments
 (0)