1use std::borrow::Cow;
16use std::fmt;
17use std::fmt::{Debug, Display};
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 Debug for LowLevelILTempRegister {
87 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
88 write!(f, "temp{}", self.temp_id)
89 }
90}
91
92impl Display for LowLevelILTempRegister {
93 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
94 Debug::fmt(self, f)
95 }
96}
97
98impl TryFrom<RegisterId> for LowLevelILTempRegister {
99 type Error = ();
100
101 fn try_from(value: RegisterId) -> Result<Self, Self::Error> {
102 Self::from_id(value).ok_or(())
103 }
104}
105
106impl From<u32> for LowLevelILTempRegister {
107 fn from(value: u32) -> Self {
108 Self::new(value)
109 }
110}
111
112#[derive(Copy, Clone, PartialEq, Eq)]
113pub enum LowLevelILRegisterKind<R: ArchReg> {
114 Arch(R),
115 Temp(LowLevelILTempRegister),
116}
117
118impl<R: ArchReg> LowLevelILRegisterKind<R> {
119 pub fn from_raw(arch: &impl Architecture<Register = R>, val: RegisterId) -> Option<Self> {
120 match val.is_temporary() {
121 true => {
122 let temp_reg = LowLevelILTempRegister::from_id(val)?;
123 Some(LowLevelILRegisterKind::Temp(temp_reg))
124 }
125 false => {
126 let arch_reg = arch.register_from_id(val)?;
127 Some(LowLevelILRegisterKind::Arch(arch_reg))
128 }
129 }
130 }
131
132 pub fn from_temp(temp: impl Into<LowLevelILTempRegister>) -> Self {
133 LowLevelILRegisterKind::Temp(temp.into())
134 }
135
136 pub fn id(&self) -> RegisterId {
137 match *self {
138 LowLevelILRegisterKind::Arch(ref r) => r.id(),
139 LowLevelILRegisterKind::Temp(temp) => temp.id(),
140 }
141 }
142
143 pub fn name(&self) -> Cow<'_, str> {
144 match *self {
145 LowLevelILRegisterKind::Arch(ref r) => r.name(),
146 LowLevelILRegisterKind::Temp(temp) => Cow::Owned(format!("temp{}", temp.temp_id)),
147 }
148 }
149}
150
151impl<R: ArchReg> Debug for LowLevelILRegisterKind<R> {
152 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
153 match *self {
154 LowLevelILRegisterKind::Arch(ref r) => r.fmt(f),
155 LowLevelILRegisterKind::Temp(ref id) => Debug::fmt(id, f),
156 }
157 }
158}
159
160impl<R: ArchReg> Display for LowLevelILRegisterKind<R> {
161 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
162 match *self {
163 LowLevelILRegisterKind::Arch(ref r) => write!(f, "{}", r.name()),
164 LowLevelILRegisterKind::Temp(ref id) => Display::fmt(id, f),
165 }
166 }
167}
168
169impl From<LowLevelILTempRegister> for LowLevelILRegisterKind<CoreRegister> {
170 fn from(reg: LowLevelILTempRegister) -> Self {
171 LowLevelILRegisterKind::Temp(reg)
172 }
173}
174
175#[derive(Copy, Clone, Debug)]
176pub struct LowLevelILSSARegister<R: ArchReg> {
177 pub reg: LowLevelILRegisterKind<R>,
178 pub version: u32,
180}
181
182impl<R: ArchReg> LowLevelILSSARegister<R> {
183 pub fn new(reg: LowLevelILRegisterKind<R>, version: u32) -> Self {
184 Self { reg, version }
185 }
186
187 pub fn name(&self) -> Cow<'_, str> {
188 self.reg.name()
189 }
190
191 pub fn id(&self) -> RegisterId {
192 self.reg.id()
193 }
194}
195
196impl<R: ArchReg> Display for LowLevelILSSARegister<R> {
197 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
198 write!(f, "{}#{}", self.reg, self.version)
199 }
200}
201
202#[derive(Copy, Clone, Debug)]
213pub enum LowLevelILSSARegisterKind<R: ArchReg> {
214 Full(LowLevelILSSARegister<R>),
216 Partial {
217 full_reg: LowLevelILSSARegister<R>,
225 partial_reg: CoreRegister,
230 },
231}
232
233impl<R: ArchReg> LowLevelILSSARegisterKind<R> {
234 pub fn new_full(kind: LowLevelILRegisterKind<R>, version: u32) -> Self {
235 Self::Full(LowLevelILSSARegister::new(kind, version))
236 }
237
238 pub fn new_partial(
239 full_reg: LowLevelILRegisterKind<R>,
240 version: u32,
241 partial_reg: CoreRegister,
242 ) -> Self {
243 Self::Partial {
244 full_reg: LowLevelILSSARegister::new(full_reg, version),
245 partial_reg,
246 }
247 }
248
249 pub fn physical_reg(&self) -> LowLevelILSSARegister<R> {
256 match *self {
257 LowLevelILSSARegisterKind::Full(reg) => reg,
258 LowLevelILSSARegisterKind::Partial { full_reg, .. } => full_reg,
259 }
260 }
261
262 pub fn name(&self) -> Cow<'_, str> {
268 match *self {
269 LowLevelILSSARegisterKind::Full(ref reg) => reg.reg.name(),
270 LowLevelILSSARegisterKind::Partial {
271 ref partial_reg, ..
272 } => partial_reg.name(),
273 }
274 }
275}
276
277impl<R: ArchReg> AsRef<LowLevelILSSARegister<R>> for LowLevelILSSARegisterKind<R> {
278 fn as_ref(&self) -> &LowLevelILSSARegister<R> {
279 match self {
280 LowLevelILSSARegisterKind::Full(reg) => reg,
281 LowLevelILSSARegisterKind::Partial { full_reg, .. } => full_reg,
282 }
283 }
284}
285
286impl<R: ArchReg> From<LowLevelILSSARegister<R>> for LowLevelILSSARegisterKind<R> {
287 fn from(value: LowLevelILSSARegister<R>) -> Self {
288 LowLevelILSSARegisterKind::Full(value)
289 }
290}
291
292impl<R: ArchReg> From<LowLevelILSSARegisterKind<R>> for LowLevelILSSARegister<R> {
293 fn from(value: LowLevelILSSARegisterKind<R>) -> Self {
294 match value {
295 LowLevelILSSARegisterKind::Full(reg) => reg,
296 LowLevelILSSARegisterKind::Partial { full_reg, .. } => full_reg,
297 }
298 }
299}
300
301#[derive(Copy, Clone, Debug)]
302pub struct LowLevelILSSAFlag<F: Flag> {
303 pub flag: F,
304 pub version: u32,
305}
306
307impl<F: Flag> LowLevelILSSAFlag<F> {
308 pub fn new(flag: F, version: u32) -> Self {
309 Self { flag, version }
310 }
311}
312
313#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
314pub enum VisitorAction {
315 Descend,
316 Sibling,
317 Halt,
318}