binaryninja/
low_level_il.rsuse std::borrow::Cow;
use std::fmt;
use crate::architecture::{Architecture, Flag, RegisterId};
use crate::architecture::{CoreRegister, Register as ArchReg};
use crate::function::Location;
pub mod block;
pub mod expression;
pub mod function;
pub mod instruction;
pub mod lifting;
pub mod operation;
use self::expression::*;
use self::function::*;
use self::instruction::*;
pub type LowLevelILRegularFunction = LowLevelILFunction<Finalized, NonSSA>;
pub type LowLevelILRegularInstruction<'a> = LowLevelILInstruction<'a, Finalized, NonSSA>;
pub type LowLevelILRegularInstructionKind<'a> = LowLevelILInstructionKind<'a, Finalized, NonSSA>;
pub type LowLevelILRegularExpression<'a, ReturnType> =
LowLevelILExpression<'a, Finalized, NonSSA, ReturnType>;
pub type LowLevelILRegularExpressionKind<'a> = LowLevelILExpressionKind<'a, Finalized, NonSSA>;
pub type LowLevelILMutableFunction = LowLevelILFunction<Mutable, NonSSA>;
pub type LowLevelILMutableExpression<'a, ReturnType> =
LowLevelILExpression<'a, Mutable, NonSSA, ReturnType>;
pub type LowLevelILSSAFunction = LowLevelILFunction<Finalized, SSA>;
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct LowLevelILTempRegister {
temp_id: RegisterId,
}
impl LowLevelILTempRegister {
pub fn new(temp_id: u32) -> Self {
Self {
temp_id: RegisterId(temp_id),
}
}
pub fn from_id(id: RegisterId) -> Option<Self> {
match id.is_temporary() {
true => {
let temp_id = RegisterId(id.0 & 0x7fff_ffff);
Some(Self { temp_id })
}
false => None,
}
}
pub fn id(&self) -> RegisterId {
RegisterId(self.temp_id.0 | 0x8000_0000)
}
}
impl fmt::Debug for LowLevelILTempRegister {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "temp{}", self.temp_id)
}
}
impl TryFrom<RegisterId> for LowLevelILTempRegister {
type Error = ();
fn try_from(value: RegisterId) -> Result<Self, Self::Error> {
Self::from_id(value).ok_or(())
}
}
impl From<u32> for LowLevelILTempRegister {
fn from(value: u32) -> Self {
Self::new(value)
}
}
#[derive(Copy, Clone, PartialEq, Eq)]
pub enum LowLevelILRegisterKind<R: ArchReg> {
Arch(R),
Temp(LowLevelILTempRegister),
}
impl<R: ArchReg> LowLevelILRegisterKind<R> {
pub fn from_raw(arch: &impl Architecture<Register = R>, val: RegisterId) -> Option<Self> {
match val.is_temporary() {
true => {
let temp_reg = LowLevelILTempRegister::from_id(val)?;
Some(LowLevelILRegisterKind::Temp(temp_reg))
}
false => {
let arch_reg = arch.register_from_id(val)?;
Some(LowLevelILRegisterKind::Arch(arch_reg))
}
}
}
pub fn from_temp(temp: impl Into<LowLevelILTempRegister>) -> Self {
LowLevelILRegisterKind::Temp(temp.into())
}
pub fn id(&self) -> RegisterId {
match *self {
LowLevelILRegisterKind::Arch(ref r) => r.id(),
LowLevelILRegisterKind::Temp(temp) => temp.id(),
}
}
pub fn name(&self) -> Cow<str> {
match *self {
LowLevelILRegisterKind::Arch(ref r) => r.name(),
LowLevelILRegisterKind::Temp(temp) => Cow::Owned(format!("temp{}", temp.temp_id)),
}
}
}
impl<R: ArchReg> fmt::Debug for LowLevelILRegisterKind<R> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
LowLevelILRegisterKind::Arch(ref r) => r.fmt(f),
LowLevelILRegisterKind::Temp(id) => id.fmt(f),
}
}
}
impl From<LowLevelILTempRegister> for LowLevelILRegisterKind<CoreRegister> {
fn from(reg: LowLevelILTempRegister) -> Self {
LowLevelILRegisterKind::Temp(reg)
}
}
#[derive(Copy, Clone, Debug)]
pub enum LowLevelILSSARegisterKind<R: ArchReg> {
Full {
kind: LowLevelILRegisterKind<R>,
version: u32,
},
Partial {
full_reg: CoreRegister,
partial_reg: CoreRegister,
version: u32,
},
}
impl<R: ArchReg> LowLevelILSSARegisterKind<R> {
pub fn new_full(kind: LowLevelILRegisterKind<R>, version: u32) -> Self {
Self::Full { kind, version }
}
pub fn new_partial(full_reg: CoreRegister, partial_reg: CoreRegister, version: u32) -> Self {
Self::Partial {
full_reg,
partial_reg,
version,
}
}
pub fn version(&self) -> u32 {
match *self {
LowLevelILSSARegisterKind::Full { version, .. }
| LowLevelILSSARegisterKind::Partial { version, .. } => version,
}
}
}
#[derive(Copy, Clone, Debug)]
pub struct LowLevelILSSAFlag<F: Flag> {
pub flag: F,
pub version: u32,
}
impl<F: Flag> LowLevelILSSAFlag<F> {
pub fn new(flag: F, version: u32) -> Self {
Self { flag, version }
}
}
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
pub enum VisitorAction {
Descend,
Sibling,
Halt,
}