summaryrefslogtreecommitdiff
path: root/rust/src/low_level_il.rs
diff options
context:
space:
mode:
authorMason Reed <mason@vector35.com>2025-04-30 17:38:40 -0400
committerMason Reed <35282038+emesare@users.noreply.github.com>2025-05-12 17:45:24 -0400
commitc3fdda9727f5507818e3f55576ad32215a22b0f9 (patch)
treed522025055eb7253c7f2cb94732402aacf2afbfc /rust/src/low_level_il.rs
parentc3f344a38ca4b027b4e69b0f82d3184622d6da79 (diff)
[Rust] Remove Architecture trait bound on LLIL related structures
Diffstat (limited to 'rust/src/low_level_il.rs')
-rw-r--r--rust/src/low_level_il.rs129
1 files changed, 100 insertions, 29 deletions
diff --git a/rust/src/low_level_il.rs b/rust/src/low_level_il.rs
index d6303c13..453e0546 100644
--- a/rust/src/low_level_il.rs
+++ b/rust/src/low_level_il.rs
@@ -20,8 +20,8 @@ use std::fmt;
// requirements on load/store memory address sizes?
// can reg/set_reg be used with sizes that differ from what is in BNRegisterInfo?
-use crate::architecture::Register as ArchReg;
use crate::architecture::{Architecture, RegisterId};
+use crate::architecture::{CoreRegister, Register as ArchReg};
use crate::function::Location;
pub mod block;
@@ -35,52 +35,123 @@ use self::expression::*;
use self::function::*;
use self::instruction::*;
-pub type MutableLiftedILFunction<Arch> = LowLevelILFunction<Arch, Mutable, NonSSA<LiftedNonSSA>>;
-pub type LiftedILFunction<Arch> = LowLevelILFunction<Arch, Finalized, NonSSA<LiftedNonSSA>>;
-pub type MutableLiftedILExpr<'a, Arch, ReturnType> =
- LowLevelILExpression<'a, Arch, Mutable, NonSSA<LiftedNonSSA>, ReturnType>;
-pub type RegularLowLevelILFunction<Arch> =
- LowLevelILFunction<Arch, Finalized, NonSSA<RegularNonSSA>>;
-pub type RegularLowLevelILInstruction<'a, Arch> =
- LowLevelILInstruction<'a, Arch, Finalized, NonSSA<RegularNonSSA>>;
-pub type RegularLowLevelILInstructionKind<'a, Arch> =
- LowLevelILInstructionKind<'a, Arch, Finalized, NonSSA<RegularNonSSA>>;
-pub type RegularLowLevelILExpression<'a, Arch, ReturnType> =
- LowLevelILExpression<'a, Arch, Finalized, NonSSA<RegularNonSSA>, ReturnType>;
-pub type RegularLowLevelILExpressionKind<'a, Arch> =
- LowLevelILExpressionKind<'a, Arch, Finalized, NonSSA<RegularNonSSA>>;
-pub type LowLevelILSSAFunction<Arch> = LowLevelILFunction<Arch, Finalized, SSA>;
+pub type MutableLiftedILFunction = LowLevelILFunction<Mutable, NonSSA<LiftedNonSSA>>;
+pub type LiftedILFunction = LowLevelILFunction<Finalized, NonSSA<LiftedNonSSA>>;
+pub type MutableLiftedILExpr<'a, ReturnType> =
+ LowLevelILExpression<'a, Mutable, NonSSA<LiftedNonSSA>, ReturnType>;
+pub type RegularLowLevelILFunction = LowLevelILFunction<Finalized, NonSSA<RegularNonSSA>>;
+pub type RegularLowLevelILInstruction<'a> =
+ LowLevelILInstruction<'a, Finalized, NonSSA<RegularNonSSA>>;
+pub type RegularLowLevelILInstructionKind<'a> =
+ LowLevelILInstructionKind<'a, Finalized, NonSSA<RegularNonSSA>>;
+pub type RegularLowLevelILExpression<'a, ReturnType> =
+ LowLevelILExpression<'a, Finalized, NonSSA<RegularNonSSA>, ReturnType>;
+pub type RegularLowLevelILExpressionKind<'a> =
+ LowLevelILExpressionKind<'a, Finalized, NonSSA<RegularNonSSA>>;
+pub type LowLevelILSSAFunction = LowLevelILFunction<Finalized, SSA>;
+
+#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
+pub struct LowLevelILTempRegister {
+ /// The temporary id for the register, this will **NOT** be the referenced id in the core.
+ ///
+ /// Do not attempt to pass this to the core. Use [`LowLevelILTempRegister::id`] instead.
+ 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,
+ }
+ }
+
+ /// The temporary registers core id, with the temporary bit set.
+ 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 LowLevelILRegister<R: ArchReg> {
- ArchReg(R),
- // TODO: Might want to be changed to TempRegisterId.
- // TODO: If we do that then we would need to get rid of `Register::id()`
- Temp(u32),
+pub enum LowLevelILRegisterKind<R: ArchReg> {
+ Arch(R),
+ Temp(LowLevelILTempRegister),
}
-impl<R: ArchReg> LowLevelILRegister<R> {
+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())
+ }
+
fn id(&self) -> RegisterId {
match *self {
- LowLevelILRegister::ArchReg(ref r) => r.id(),
- LowLevelILRegister::Temp(id) => RegisterId(0x8000_0000 | id),
+ LowLevelILRegisterKind::Arch(ref r) => r.id(),
+ LowLevelILRegisterKind::Temp(temp) => temp.id(),
}
}
}
-impl<R: ArchReg> fmt::Debug for LowLevelILRegister<R> {
+impl<R: ArchReg> fmt::Debug for LowLevelILRegisterKind<R> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
- LowLevelILRegister::ArchReg(ref r) => write!(f, "{}", r.name().as_ref()),
- LowLevelILRegister::Temp(id) => write!(f, "temp{}", id),
+ 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 LowLevelILSSARegister<R: ArchReg> {
- Full(LowLevelILRegister<R>, u32), // no such thing as partial access to a temp register, I think
- Partial(R, u32, R), // partial accesses only possible for arch registers, I think
+ Full(LowLevelILRegisterKind<R>, u32), // no such thing as partial access to a temp register, I think
+ Partial(R, u32, R), // partial accesses only possible for arch registers, I think
}
impl<R: ArchReg> LowLevelILSSARegister<R> {