Skip to content

Commit f5b7f5b

Browse files
committed
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
1 parent c00727e commit f5b7f5b

File tree

4 files changed

+106
-4
lines changed

4 files changed

+106
-4
lines changed

rust/src/architecture.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,7 @@ pub trait RegisterStackInfo: Sized {
305305
fn stack_top_reg(&self) -> Self::RegType;
306306
}
307307

308-
pub trait RegisterStack: Sized + Clone + Copy {
308+
pub trait RegisterStack: Debug + Sized + Clone + Copy {
309309
type InfoType: RegisterStackInfo<
310310
RegType = Self::RegType,
311311
RegInfoType = Self::RegInfoType,
@@ -641,7 +641,7 @@ pub struct UnusedRegisterStackInfo<R: Register> {
641641
_reg: std::marker::PhantomData<R>,
642642
}
643643

644-
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
644+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
645645
pub struct UnusedRegisterStack<R: Register> {
646646
_reg: std::marker::PhantomData<R>,
647647
}

rust/src/low_level_il/expression.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,8 @@ where
236236
FlagBit(Operation<'func, A, M, F, operation::FlagBit>),
237237
ExternPtr(Operation<'func, A, M, F, operation::Extern>),
238238

239+
RegStackPop(Operation<'func, A, M, F, operation::RegStackPop>),
240+
239241
Add(Operation<'func, A, M, F, operation::BinaryOp>),
240242
Adc(Operation<'func, A, M, F, operation::BinaryOpCarry>),
241243
Sub(Operation<'func, A, M, F, operation::BinaryOp>),
@@ -357,6 +359,10 @@ where
357359
}
358360
LLIL_EXTERN_PTR => LowLevelILExpressionKind::ExternPtr(Operation::new(function, op)),
359361

362+
LLIL_REG_STACK_POP => {
363+
LowLevelILExpressionKind::RegStackPop(Operation::new(function, op))
364+
}
365+
360366
LLIL_ADD => LowLevelILExpressionKind::Add(Operation::new(function, op)),
361367
LLIL_ADC => LowLevelILExpressionKind::Adc(Operation::new(function, op)),
362368
LLIL_SUB => LowLevelILExpressionKind::Sub(Operation::new(function, op)),
@@ -597,7 +603,8 @@ where
597603
}
598604
// Do not have any sub expressions.
599605
Pop(_) | Reg(_) | RegSplit(_) | Const(_) | ConstPtr(_) | Flag(_) | FlagBit(_)
600-
| ExternPtr(_) | FlagCond(_) | FlagGroup(_) | Unimpl(_) | Undef(_) => {}
606+
| ExternPtr(_) | FlagCond(_) | FlagGroup(_) | Unimpl(_) | Undef(_) | RegStackPop(_) => {
607+
}
601608
}
602609

603610
VisitorAction::Sibling
@@ -635,6 +642,8 @@ where
635642

636643
ExternPtr(ref op) => &op.op,
637644

645+
RegStackPop(ref op) => &op.op,
646+
638647
Adc(ref op) | Sbb(ref op) | Rlc(ref op) | Rrc(ref op) => &op.op,
639648

640649
Add(ref op) | Sub(ref op) | And(ref op) | Or(ref op) | Xor(ref op) | Lsl(ref op)
@@ -692,6 +701,8 @@ where
692701

693702
ExternPtr(ref op) => op.flag_write(),
694703

704+
RegStackPop(ref op) => op.flag_write(),
705+
695706
Adc(ref op) | Sbb(ref op) | Rlc(ref op) | Rrc(ref op) => op.flag_write(),
696707

697708
Add(ref op) | Sub(ref op) | And(ref op) | Or(ref op) | Xor(ref op) | Lsl(ref op)

rust/src/low_level_il/instruction.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,8 @@ where
227227
// TODO needs a real op
228228
Push(Operation<'func, A, M, F, operation::UnaryOp>),
229229

230+
RegStackPush(Operation<'func, A, M, F, operation::RegStackPush>),
231+
230232
Jump(Operation<'func, A, M, F, operation::Jump>),
231233
JumpTo(Operation<'func, A, M, F, operation::JumpTo>),
232234

@@ -278,6 +280,10 @@ where
278280
}
279281
LLIL_PUSH => LowLevelILInstructionKind::Push(Operation::new(function, op)),
280282

283+
LLIL_REG_STACK_PUSH => {
284+
LowLevelILInstructionKind::RegStackPush(Operation::new(function, op))
285+
}
286+
281287
LLIL_JUMP => LowLevelILInstructionKind::Jump(Operation::new(function, op)),
282288
LLIL_JUMP_TO => LowLevelILInstructionKind::JumpTo(Operation::new(function, op)),
283289

@@ -330,6 +336,7 @@ where
330336
visit!(&op.source_expr());
331337
}
332338
Push(ref op) => visit!(&op.operand()),
339+
RegStackPush(ref op) => visit!(&op.source_expr()),
333340
Jump(ref op) => visit!(&op.target()),
334341
JumpTo(ref op) => visit!(&op.target()),
335342
Call(ref op) | TailCall(ref op) => visit!(&op.target()),

rust/src/low_level_il/operation.rs

Lines changed: 85 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
use binaryninjacore_sys::{BNGetLowLevelILByIndex, BNLowLevelILInstruction};
1616

1717
use super::*;
18-
use crate::architecture::{FlagGroupId, FlagId, FlagWriteId, IntrinsicId};
18+
use crate::architecture::{FlagGroupId, FlagId, FlagWriteId, IntrinsicId, RegisterStackId};
1919
use std::collections::BTreeMap;
2020
use std::fmt::{Debug, Formatter};
2121
use std::marker::PhantomData;
@@ -537,6 +537,88 @@ where
537537
}
538538
}
539539

540+
// LLIL_REG_STACK_PUSH
541+
pub struct RegStackPush;
542+
543+
impl<'func, A, M, F> Operation<'func, A, M, F, RegStackPush>
544+
where
545+
A: Architecture,
546+
M: FunctionMutability,
547+
F: FunctionForm,
548+
{
549+
pub fn size(&self) -> usize {
550+
self.op.size
551+
}
552+
553+
pub fn dest_reg_stack(&self) -> A::RegisterStack {
554+
let raw_id = self.op.operands[0] as u32;
555+
self.function
556+
.arch()
557+
.register_stack_from_id(RegisterStackId(raw_id))
558+
.expect("Bad register stack ID")
559+
}
560+
561+
pub fn source_expr(&self) -> LowLevelILExpression<'func, A, M, F, ValueExpr> {
562+
LowLevelILExpression::new(
563+
self.function,
564+
LowLevelExpressionIndex(self.op.operands[1] as usize),
565+
)
566+
}
567+
}
568+
569+
impl<A, M, F> Debug for Operation<'_, A, M, F, RegStackPush>
570+
where
571+
A: Architecture,
572+
M: FunctionMutability,
573+
F: FunctionForm,
574+
{
575+
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
576+
f.debug_struct("RegStackPush")
577+
.field("address", &self.address())
578+
.field("size", &self.size())
579+
.field("dest_reg_stack", &self.dest_reg_stack())
580+
.field("source_expr", &self.source_expr())
581+
.finish()
582+
}
583+
}
584+
585+
// LLIL_REG_STACK_POP
586+
pub struct RegStackPop;
587+
588+
impl<'func, A, M, F> Operation<'func, A, M, F, RegStackPop>
589+
where
590+
A: Architecture,
591+
M: FunctionMutability,
592+
F: FunctionForm,
593+
{
594+
pub fn size(&self) -> usize {
595+
self.op.size
596+
}
597+
598+
pub fn source_reg_stack(&self) -> A::RegisterStack {
599+
let raw_id = self.op.operands[0] as u32;
600+
self.function
601+
.arch()
602+
.register_stack_from_id(RegisterStackId(raw_id))
603+
.expect("Bad register stack ID")
604+
}
605+
}
606+
607+
impl<A, M, F> Debug for Operation<'_, A, M, F, RegStackPop>
608+
where
609+
A: Architecture,
610+
M: FunctionMutability,
611+
F: FunctionForm,
612+
{
613+
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
614+
f.debug_struct("RegStackPop")
615+
.field("address", &self.address())
616+
.field("size", &self.size())
617+
.field("source_reg_stack", &self.source_reg_stack())
618+
.finish()
619+
}
620+
}
621+
540622
// LLIL_FLAG, LLIL_FLAG_SSA
541623
pub struct Flag;
542624

@@ -1343,6 +1425,8 @@ impl OperationArguments for Load {}
13431425
impl OperationArguments for Store {}
13441426
impl OperationArguments for Reg {}
13451427
impl OperationArguments for RegSplit {}
1428+
impl OperationArguments for RegStackPush {}
1429+
impl OperationArguments for RegStackPop {}
13461430
impl OperationArguments for Flag {}
13471431
impl OperationArguments for FlagBit {}
13481432
impl OperationArguments for Jump {}

0 commit comments

Comments
 (0)