binaryninja/
low_level_il.rs1use std::borrow::Cow;
16use std::fmt;
17
18use crate::architecture::{Architecture, Flag, RegisterId};
25use crate::architecture::{CoreRegister, Register as ArchReg};
26use crate::function::Location;
27
28pub mod block;
29pub mod expression;
30pub mod function;
31pub mod instruction;
32pub mod lifting;
33pub mod operation;
34
35use self::expression::*;
36use self::function::*;
37use self::instruction::*;
38
39pub type LowLevelILRegularFunction = LowLevelILFunction<Finalized, NonSSA>;
41pub type LowLevelILRegularInstruction<'a> = LowLevelILInstruction<'a, Finalized, NonSSA>;
42pub type LowLevelILRegularInstructionKind<'a> = LowLevelILInstructionKind<'a, Finalized, NonSSA>;
43pub type LowLevelILRegularExpression<'a, ReturnType> =
44 LowLevelILExpression<'a, Finalized, NonSSA, ReturnType>;
45pub type LowLevelILRegularExpressionKind<'a> = LowLevelILExpressionKind<'a, Finalized, NonSSA>;
46
47pub type LowLevelILMutableFunction = LowLevelILFunction<Mutable, NonSSA>;
49pub type LowLevelILMutableExpression<'a, ReturnType> =
50 LowLevelILExpression<'a, Mutable, NonSSA, ReturnType>;
51
52pub type LowLevelILSSAFunction = LowLevelILFunction<Finalized, SSA>;
54
55#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
56pub struct LowLevelILTempRegister {
57 temp_id: RegisterId,
61}
62
63impl LowLevelILTempRegister {
64 pub fn new(temp_id: u32) -> Self {
65 Self {
66 temp_id: RegisterId(temp_id),
67 }
68 }
69
70 pub fn from_id(id: RegisterId) -> Option<Self> {
71 match id.is_temporary() {
72 true => {
73 let temp_id = RegisterId(id.0 & 0x7fff_ffff);
74 Some(Self { temp_id })
75 }
76 false => None,
77 }
78 }
79
80 pub fn id(&self) -> RegisterId {
82 RegisterId(self.temp_id.0 | 0x8000_0000)
83 }
84}
85
86impl fmt::Debug for LowLevelILTempRegister {
87 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
88 write!(f, "temp{}", self.temp_id)
89 }
90}
91
92impl TryFrom<RegisterId> for LowLevelILTempRegister {
93 type Error = ();
94
95 fn try_from(value: RegisterId) -> Result<Self, Self::Error> {
96 Self::from_id(value).ok_or(())
97 }
98}
99
100impl From<u32> for LowLevelILTempRegister {
101 fn from(value: u32) -> Self {
102 Self::new(value)
103 }
104}
105
106#[derive(Copy, Clone, PartialEq, Eq)]
107pub enum LowLevelILRegisterKind<R: ArchReg> {
108 Arch(R),
109 Temp(LowLevelILTempRegister),
110}
111
112impl<R: ArchReg> LowLevelILRegisterKind<R> {
113 pub fn from_raw(arch: &impl Architecture<Register = R>, val: RegisterId) -> Option<Self> {
114 match val.is_temporary() {
115 true => {
116 let temp_reg = LowLevelILTempRegister::from_id(val)?;
117 Some(LowLevelILRegisterKind::Temp(temp_reg))
118 }
119 false => {
120 let arch_reg = arch.register_from_id(val)?;
121 Some(LowLevelILRegisterKind::Arch(arch_reg))
122 }
123 }
124 }
125
126 pub fn from_temp(temp: impl Into<LowLevelILTempRegister>) -> Self {
127 LowLevelILRegisterKind::Temp(temp.into())
128 }
129
130 pub fn id(&self) -> RegisterId {
131 match *self {
132 LowLevelILRegisterKind::Arch(ref r) => r.id(),
133 LowLevelILRegisterKind::Temp(temp) => temp.id(),
134 }
135 }
136
137 pub fn name(&self) -> Cow<'_, str> {
138 match *self {
139 LowLevelILRegisterKind::Arch(ref r) => r.name(),
140 LowLevelILRegisterKind::Temp(temp) => Cow::Owned(format!("temp{}", temp.temp_id)),
141 }
142 }
143}
144
145impl<R: ArchReg> fmt::Debug for LowLevelILRegisterKind<R> {
146 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
147 match *self {
148 LowLevelILRegisterKind::Arch(ref r) => r.fmt(f),
149 LowLevelILRegisterKind::Temp(id) => id.fmt(f),
150 }
151 }
152}
153
154impl From<LowLevelILTempRegister> for LowLevelILRegisterKind<CoreRegister> {
155 fn from(reg: LowLevelILTempRegister) -> Self {
156 LowLevelILRegisterKind::Temp(reg)
157 }
158}
159
160#[derive(Copy, Clone, Debug)]
161pub enum LowLevelILSSARegisterKind<R: ArchReg> {
162 Full {
163 kind: LowLevelILRegisterKind<R>,
164 version: u32,
165 },
166 Partial {
167 full_reg: CoreRegister,
168 partial_reg: CoreRegister,
169 version: u32,
170 },
171}
172
173impl<R: ArchReg> LowLevelILSSARegisterKind<R> {
174 pub fn new_full(kind: LowLevelILRegisterKind<R>, version: u32) -> Self {
175 Self::Full { kind, version }
176 }
177
178 pub fn new_partial(full_reg: CoreRegister, partial_reg: CoreRegister, version: u32) -> Self {
179 Self::Partial {
180 full_reg,
181 partial_reg,
182 version,
183 }
184 }
185
186 pub fn version(&self) -> u32 {
187 match *self {
188 LowLevelILSSARegisterKind::Full { version, .. }
189 | LowLevelILSSARegisterKind::Partial { version, .. } => version,
190 }
191 }
192}
193
194#[derive(Copy, Clone, Debug)]
195pub struct LowLevelILSSAFlag<F: Flag> {
196 pub flag: F,
197 pub version: u32,
198}
199
200impl<F: Flag> LowLevelILSSAFlag<F> {
201 pub fn new(flag: F, version: u32) -> Self {
202 Self { flag, version }
203 }
204}
205
206#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
207pub enum VisitorAction {
208 Descend,
209 Sibling,
210 Halt,
211}