Skip to content

Commit d0b25ef

Browse files
committed
Support SSA form properly in low level IL Rust API
1 parent cb782ec commit d0b25ef

File tree

7 files changed

+1053
-171
lines changed

7 files changed

+1053
-171
lines changed

arch/riscv/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2884,7 +2884,7 @@ impl FunctionRecognizer for RiscVELFPLTRecognizer {
28842884
LowLevelILInstructionKind::SetReg(r) => match r.source_expr().kind() {
28852885
LowLevelILExpressionKind::Load(l) => {
28862886
let target_reg = r.dest_reg();
2887-
let entry = match l.source_mem_expr().kind() {
2887+
let entry = match l.source_expr().kind() {
28882888
LowLevelILExpressionKind::Reg(lr) if lr.source_reg() == auipc_dest => {
28892889
plt_base
28902890
}

rust/src/low_level_il.rs

Lines changed: 47 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15+
use std::borrow::Cow;
1516
use std::fmt;
1617

1718
// TODO : provide some way to forbid emitting register reads for certain registers
@@ -20,7 +21,7 @@ use std::fmt;
2021
// requirements on load/store memory address sizes?
2122
// can reg/set_reg be used with sizes that differ from what is in BNRegisterInfo?
2223

23-
use crate::architecture::{Architecture, RegisterId};
24+
use crate::architecture::{Architecture, Flag, RegisterId};
2425
use crate::architecture::{CoreRegister, Register as ArchReg};
2526
use crate::function::Location;
2627

@@ -125,12 +126,19 @@ impl<R: ArchReg> LowLevelILRegisterKind<R> {
125126
LowLevelILRegisterKind::Temp(temp.into())
126127
}
127128

128-
fn id(&self) -> RegisterId {
129+
pub fn id(&self) -> RegisterId {
129130
match *self {
130131
LowLevelILRegisterKind::Arch(ref r) => r.id(),
131132
LowLevelILRegisterKind::Temp(temp) => temp.id(),
132133
}
133134
}
135+
136+
pub fn name(&self) -> Cow<str> {
137+
match *self {
138+
LowLevelILRegisterKind::Arch(ref r) => r.name(),
139+
LowLevelILRegisterKind::Temp(temp) => Cow::Owned(format!("temp{}", temp.temp_id)),
140+
}
141+
}
134142
}
135143

136144
impl<R: ArchReg> fmt::Debug for LowLevelILRegisterKind<R> {
@@ -149,19 +157,51 @@ impl From<LowLevelILTempRegister> for LowLevelILRegisterKind<CoreRegister> {
149157
}
150158

151159
#[derive(Copy, Clone, Debug)]
152-
pub enum LowLevelILSSARegister<R: ArchReg> {
153-
Full(LowLevelILRegisterKind<R>, u32), // no such thing as partial access to a temp register, I think
154-
Partial(R, u32, R), // partial accesses only possible for arch registers, I think
160+
pub enum LowLevelILSSARegisterKind<R: ArchReg> {
161+
Full {
162+
kind: LowLevelILRegisterKind<R>,
163+
version: u32,
164+
},
165+
Partial {
166+
full_reg: CoreRegister,
167+
partial_reg: CoreRegister,
168+
version: u32,
169+
},
155170
}
156171

157-
impl<R: ArchReg> LowLevelILSSARegister<R> {
172+
impl<R: ArchReg> LowLevelILSSARegisterKind<R> {
173+
pub fn new_full(kind: LowLevelILRegisterKind<R>, version: u32) -> Self {
174+
Self::Full { kind, version }
175+
}
176+
177+
pub fn new_partial(full_reg: CoreRegister, partial_reg: CoreRegister, version: u32) -> Self {
178+
Self::Partial {
179+
full_reg,
180+
partial_reg,
181+
version,
182+
}
183+
}
184+
158185
pub fn version(&self) -> u32 {
159186
match *self {
160-
LowLevelILSSARegister::Full(_, ver) | LowLevelILSSARegister::Partial(_, ver, _) => ver,
187+
LowLevelILSSARegisterKind::Full { version, .. }
188+
| LowLevelILSSARegisterKind::Partial { version, .. } => version,
161189
}
162190
}
163191
}
164192

193+
#[derive(Copy, Clone, Debug)]
194+
pub struct LowLevelILSSAFlag<F: Flag> {
195+
pub flag: F,
196+
pub version: u32,
197+
}
198+
199+
impl<F: Flag> LowLevelILSSAFlag<F> {
200+
pub fn new(flag: F, version: u32) -> Self {
201+
Self { flag, version }
202+
}
203+
}
204+
165205
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
166206
pub enum VisitorAction {
167207
Descend,

0 commit comments

Comments
 (0)