diff options
| author | Mason Reed <mason@vector35.com> | 2025-04-30 17:38:40 -0400 |
|---|---|---|
| committer | Mason Reed <35282038+emesare@users.noreply.github.com> | 2025-05-12 17:45:24 -0400 |
| commit | c3fdda9727f5507818e3f55576ad32215a22b0f9 (patch) | |
| tree | d522025055eb7253c7f2cb94732402aacf2afbfc /rust/src/low_level_il.rs | |
| parent | c3f344a38ca4b027b4e69b0f82d3184622d6da79 (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.rs | 129 |
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> { |
