summaryrefslogtreecommitdiff
path: root/rust
diff options
context:
space:
mode:
authorMason Reed <mason@vector35.com>2025-01-31 13:02:22 -0500
committerMason Reed <mason@vector35.com>2025-01-31 16:17:30 -0500
commitf5b7f5b2779b1b29e14856efd2a2e56a7c3b0113 (patch)
treeb1722f62166390c0d4b245a6695e359652ec6cf5 /rust
parentc00727ed11624018b286f57215a677b1140de2ff (diff)
Add LLIL_REG_STACK_POP and LLIL_REG_STACK_PUSH to Rust API
These were unhandled and x87 register stack LLIL would emit a bunch of warnings
Diffstat (limited to 'rust')
-rw-r--r--rust/src/architecture.rs4
-rw-r--r--rust/src/low_level_il/expression.rs13
-rw-r--r--rust/src/low_level_il/instruction.rs7
-rw-r--r--rust/src/low_level_il/operation.rs86
4 files changed, 106 insertions, 4 deletions
diff --git a/rust/src/architecture.rs b/rust/src/architecture.rs
index 857a6e88..997089f8 100644
--- a/rust/src/architecture.rs
+++ b/rust/src/architecture.rs
@@ -305,7 +305,7 @@ pub trait RegisterStackInfo: Sized {
fn stack_top_reg(&self) -> Self::RegType;
}
-pub trait RegisterStack: Sized + Clone + Copy {
+pub trait RegisterStack: Debug + Sized + Clone + Copy {
type InfoType: RegisterStackInfo<
RegType = Self::RegType,
RegInfoType = Self::RegInfoType,
@@ -641,7 +641,7 @@ pub struct UnusedRegisterStackInfo<R: Register> {
_reg: std::marker::PhantomData<R>,
}
-#[derive(Clone, Copy, PartialEq, Eq, Hash)]
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct UnusedRegisterStack<R: Register> {
_reg: std::marker::PhantomData<R>,
}
diff --git a/rust/src/low_level_il/expression.rs b/rust/src/low_level_il/expression.rs
index 2fc9f93d..7bae22c1 100644
--- a/rust/src/low_level_il/expression.rs
+++ b/rust/src/low_level_il/expression.rs
@@ -236,6 +236,8 @@ where
FlagBit(Operation<'func, A, M, F, operation::FlagBit>),
ExternPtr(Operation<'func, A, M, F, operation::Extern>),
+ RegStackPop(Operation<'func, A, M, F, operation::RegStackPop>),
+
Add(Operation<'func, A, M, F, operation::BinaryOp>),
Adc(Operation<'func, A, M, F, operation::BinaryOpCarry>),
Sub(Operation<'func, A, M, F, operation::BinaryOp>),
@@ -357,6 +359,10 @@ where
}
LLIL_EXTERN_PTR => LowLevelILExpressionKind::ExternPtr(Operation::new(function, op)),
+ LLIL_REG_STACK_POP => {
+ LowLevelILExpressionKind::RegStackPop(Operation::new(function, op))
+ }
+
LLIL_ADD => LowLevelILExpressionKind::Add(Operation::new(function, op)),
LLIL_ADC => LowLevelILExpressionKind::Adc(Operation::new(function, op)),
LLIL_SUB => LowLevelILExpressionKind::Sub(Operation::new(function, op)),
@@ -597,7 +603,8 @@ where
}
// Do not have any sub expressions.
Pop(_) | Reg(_) | RegSplit(_) | Const(_) | ConstPtr(_) | Flag(_) | FlagBit(_)
- | ExternPtr(_) | FlagCond(_) | FlagGroup(_) | Unimpl(_) | Undef(_) => {}
+ | ExternPtr(_) | FlagCond(_) | FlagGroup(_) | Unimpl(_) | Undef(_) | RegStackPop(_) => {
+ }
}
VisitorAction::Sibling
@@ -635,6 +642,8 @@ where
ExternPtr(ref op) => &op.op,
+ RegStackPop(ref op) => &op.op,
+
Adc(ref op) | Sbb(ref op) | Rlc(ref op) | Rrc(ref op) => &op.op,
Add(ref op) | Sub(ref op) | And(ref op) | Or(ref op) | Xor(ref op) | Lsl(ref op)
@@ -692,6 +701,8 @@ where
ExternPtr(ref op) => op.flag_write(),
+ RegStackPop(ref op) => op.flag_write(),
+
Adc(ref op) | Sbb(ref op) | Rlc(ref op) | Rrc(ref op) => op.flag_write(),
Add(ref op) | Sub(ref op) | And(ref op) | Or(ref op) | Xor(ref op) | Lsl(ref op)
diff --git a/rust/src/low_level_il/instruction.rs b/rust/src/low_level_il/instruction.rs
index 5c3010ea..b023ad49 100644
--- a/rust/src/low_level_il/instruction.rs
+++ b/rust/src/low_level_il/instruction.rs
@@ -227,6 +227,8 @@ where
// TODO needs a real op
Push(Operation<'func, A, M, F, operation::UnaryOp>),
+ RegStackPush(Operation<'func, A, M, F, operation::RegStackPush>),
+
Jump(Operation<'func, A, M, F, operation::Jump>),
JumpTo(Operation<'func, A, M, F, operation::JumpTo>),
@@ -278,6 +280,10 @@ where
}
LLIL_PUSH => LowLevelILInstructionKind::Push(Operation::new(function, op)),
+ LLIL_REG_STACK_PUSH => {
+ LowLevelILInstructionKind::RegStackPush(Operation::new(function, op))
+ }
+
LLIL_JUMP => LowLevelILInstructionKind::Jump(Operation::new(function, op)),
LLIL_JUMP_TO => LowLevelILInstructionKind::JumpTo(Operation::new(function, op)),
@@ -330,6 +336,7 @@ where
visit!(&op.source_expr());
}
Push(ref op) => visit!(&op.operand()),
+ RegStackPush(ref op) => visit!(&op.source_expr()),
Jump(ref op) => visit!(&op.target()),
JumpTo(ref op) => visit!(&op.target()),
Call(ref op) | TailCall(ref op) => visit!(&op.target()),
diff --git a/rust/src/low_level_il/operation.rs b/rust/src/low_level_il/operation.rs
index dcc761dd..46d99a97 100644
--- a/rust/src/low_level_il/operation.rs
+++ b/rust/src/low_level_il/operation.rs
@@ -15,7 +15,7 @@
use binaryninjacore_sys::{BNGetLowLevelILByIndex, BNLowLevelILInstruction};
use super::*;
-use crate::architecture::{FlagGroupId, FlagId, FlagWriteId, IntrinsicId};
+use crate::architecture::{FlagGroupId, FlagId, FlagWriteId, IntrinsicId, RegisterStackId};
use std::collections::BTreeMap;
use std::fmt::{Debug, Formatter};
use std::marker::PhantomData;
@@ -537,6 +537,88 @@ where
}
}
+// LLIL_REG_STACK_PUSH
+pub struct RegStackPush;
+
+impl<'func, A, M, F> Operation<'func, A, M, F, RegStackPush>
+where
+ A: Architecture,
+ M: FunctionMutability,
+ F: FunctionForm,
+{
+ pub fn size(&self) -> usize {
+ self.op.size
+ }
+
+ pub fn dest_reg_stack(&self) -> A::RegisterStack {
+ let raw_id = self.op.operands[0] as u32;
+ self.function
+ .arch()
+ .register_stack_from_id(RegisterStackId(raw_id))
+ .expect("Bad register stack ID")
+ }
+
+ pub fn source_expr(&self) -> LowLevelILExpression<'func, A, M, F, ValueExpr> {
+ LowLevelILExpression::new(
+ self.function,
+ LowLevelExpressionIndex(self.op.operands[1] as usize),
+ )
+ }
+}
+
+impl<A, M, F> Debug for Operation<'_, A, M, F, RegStackPush>
+where
+ A: Architecture,
+ M: FunctionMutability,
+ F: FunctionForm,
+{
+ fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
+ f.debug_struct("RegStackPush")
+ .field("address", &self.address())
+ .field("size", &self.size())
+ .field("dest_reg_stack", &self.dest_reg_stack())
+ .field("source_expr", &self.source_expr())
+ .finish()
+ }
+}
+
+// LLIL_REG_STACK_POP
+pub struct RegStackPop;
+
+impl<'func, A, M, F> Operation<'func, A, M, F, RegStackPop>
+where
+ A: Architecture,
+ M: FunctionMutability,
+ F: FunctionForm,
+{
+ pub fn size(&self) -> usize {
+ self.op.size
+ }
+
+ pub fn source_reg_stack(&self) -> A::RegisterStack {
+ let raw_id = self.op.operands[0] as u32;
+ self.function
+ .arch()
+ .register_stack_from_id(RegisterStackId(raw_id))
+ .expect("Bad register stack ID")
+ }
+}
+
+impl<A, M, F> Debug for Operation<'_, A, M, F, RegStackPop>
+where
+ A: Architecture,
+ M: FunctionMutability,
+ F: FunctionForm,
+{
+ fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
+ f.debug_struct("RegStackPop")
+ .field("address", &self.address())
+ .field("size", &self.size())
+ .field("source_reg_stack", &self.source_reg_stack())
+ .finish()
+ }
+}
+
// LLIL_FLAG, LLIL_FLAG_SSA
pub struct Flag;
@@ -1343,6 +1425,8 @@ impl OperationArguments for Load {}
impl OperationArguments for Store {}
impl OperationArguments for Reg {}
impl OperationArguments for RegSplit {}
+impl OperationArguments for RegStackPush {}
+impl OperationArguments for RegStackPop {}
impl OperationArguments for Flag {}
impl OperationArguments for FlagBit {}
impl OperationArguments for Jump {}