diff options
| author | Mason Reed <mason@vector35.com> | 2025-05-09 14:00:38 -0400 |
|---|---|---|
| committer | Mason Reed <35282038+emesare@users.noreply.github.com> | 2025-05-12 17:45:24 -0400 |
| commit | 2a9beeec15d3f32312a0c4f8ad5ddbcfcbc97a89 (patch) | |
| tree | 5562dd4acafb32f6e9826a4247f910507cec4c8d /rust/src/low_level_il.rs | |
| parent | 6617b0afa09f549d0a5c9c53063f3ad8ab82b7e4 (diff) | |
[Rust] Support SSA form properly in low level IL
Diffstat (limited to 'rust/src/low_level_il.rs')
| -rw-r--r-- | rust/src/low_level_il.rs | 54 |
1 files changed, 47 insertions, 7 deletions
diff --git a/rust/src/low_level_il.rs b/rust/src/low_level_il.rs index 453e0546..4c52e313 100644 --- a/rust/src/low_level_il.rs +++ b/rust/src/low_level_il.rs @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +use std::borrow::Cow; use std::fmt; // TODO : provide some way to forbid emitting register reads for certain registers @@ -20,7 +21,7 @@ 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::{Architecture, RegisterId}; +use crate::architecture::{Architecture, Flag, RegisterId}; use crate::architecture::{CoreRegister, Register as ArchReg}; use crate::function::Location; @@ -125,12 +126,19 @@ impl<R: ArchReg> LowLevelILRegisterKind<R> { LowLevelILRegisterKind::Temp(temp.into()) } - fn id(&self) -> RegisterId { + 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> { @@ -149,19 +157,51 @@ impl From<LowLevelILTempRegister> for LowLevelILRegisterKind<CoreRegister> { } #[derive(Copy, Clone, Debug)] -pub enum LowLevelILSSARegister<R: ArchReg> { - 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 +pub enum LowLevelILSSARegisterKind<R: ArchReg> { + Full { + kind: LowLevelILRegisterKind<R>, + version: u32, + }, + Partial { + full_reg: CoreRegister, + partial_reg: CoreRegister, + version: u32, + }, } -impl<R: ArchReg> LowLevelILSSARegister<R> { +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 { - LowLevelILSSARegister::Full(_, ver) | LowLevelILSSARegister::Partial(_, ver, _) => ver, + 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, |
