arch: decouple from IR
This commit is contained in:
parent
fa19fab985
commit
866328ad54
6 changed files with 154 additions and 795 deletions
34
src/arch.rs
34
src/arch.rs
|
|
@ -4,14 +4,10 @@ pub mod arm;
|
|||
|
||||
use crate::{
|
||||
flow::FlowInfo,
|
||||
ir::{Block, FrontendBuilder},
|
||||
ir::Block,
|
||||
};
|
||||
|
||||
/// Flat generic register metadata.
|
||||
///
|
||||
/// This type intentionally stays small.
|
||||
/// Architecture-specific aliasing or overlap semantics belong in the concrete
|
||||
/// architecture module, not here.
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||
pub struct RegisterDesc<R> {
|
||||
/// Architecture-defined register identity.
|
||||
|
|
@ -24,7 +20,7 @@ pub struct RegisterDesc<R> {
|
|||
pub bits: u16,
|
||||
}
|
||||
|
||||
/// Stable architecture protocol.
|
||||
/// Pure ISA protocol: decoding, flow analysis, and disassembly.
|
||||
pub trait Arch {
|
||||
/// Architecture execution mode.
|
||||
type Mode: Copy + Eq;
|
||||
|
|
@ -38,9 +34,6 @@ pub trait Arch {
|
|||
/// Decode-time error.
|
||||
type DecodeError;
|
||||
|
||||
/// Architecture-specific disassembly output.
|
||||
type Disasm;
|
||||
|
||||
/// Stable architecture name.
|
||||
fn name(&self) -> &'static str;
|
||||
|
||||
|
|
@ -66,18 +59,16 @@ pub trait Arch {
|
|||
/// Return instruction-level control-flow facts for one decoded instruction.
|
||||
fn flow_info(&self, inst: &Self::Inst, pc: u64, mode: Self::Mode) -> FlowInfo;
|
||||
|
||||
/// Render one decoded instruction as disassembly.
|
||||
fn disasm(&self, inst: &Self::Inst, pc: u64, mode: Self::Mode) -> Self::Disasm;
|
||||
/// Render one decoded instruction as a disassembly string.
|
||||
fn disasm(&self, inst: &Self::Inst, pc: u64, mode: Self::Mode) -> String;
|
||||
}
|
||||
|
||||
/// Translation-session knowledge available during lifting.
|
||||
pub trait LiftEnv {
|
||||
/// Returns the IR block associated with a statically known target address,
|
||||
/// if the current translation session has created one.
|
||||
/// Returns the IR block associated with a statically known target address.
|
||||
fn block_for_target(&self, addr: u64) -> Option<Block>;
|
||||
|
||||
/// Returns the fallthrough block for the current instruction, if one exists
|
||||
/// in the current translation session.
|
||||
/// Returns the fallthrough block for the current instruction, if one exists.
|
||||
fn fallthrough_block(&self) -> Option<Block>;
|
||||
}
|
||||
|
||||
|
|
@ -87,12 +78,15 @@ pub trait LiftArch: Arch {
|
|||
type LiftError;
|
||||
|
||||
/// Per-lift mutable context.
|
||||
///
|
||||
/// This is where the large mutable lifting state belongs.
|
||||
type LiftCtx<'a>
|
||||
type LiftCtx<'ir, 'fb>
|
||||
where
|
||||
Self: 'a;
|
||||
Self: 'ir,
|
||||
'ir: 'fb;
|
||||
|
||||
/// Lift one decoded instruction into Slonik IR.
|
||||
fn lift(&self, cx: &mut Self::LiftCtx<'_>, inst: &Self::Inst) -> Result<(), Self::LiftError>;
|
||||
fn lift(
|
||||
&self,
|
||||
cx: &mut Self::LiftCtx<'_, '_>,
|
||||
inst: &Self::Inst,
|
||||
) -> Result<(), Self::LiftError>;
|
||||
}
|
||||
|
|
|
|||
882
src/arch/arm.rs
882
src/arch/arm.rs
File diff suppressed because it is too large
Load diff
|
|
@ -3,8 +3,7 @@
|
|||
use cranelift_entity::{EntityRef, ListPool, PrimaryMap};
|
||||
|
||||
use crate::ir::{
|
||||
Block, BlockCall, BlockData, ParamList, Stmt, StmtData, StmtList, Type, Value, ValueData,
|
||||
ValueDef, ValueList,
|
||||
Block, BlockCall, BlockData, Stmt, StmtData, Type, Value, ValueData, ValueDef, ValueList,
|
||||
};
|
||||
|
||||
/// A normalized SSA body.
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
use core::fmt;
|
||||
|
||||
use crate::ir::{Block, Stmt, Type, Value};
|
||||
use crate::ir::{Block, Stmt, Type};
|
||||
|
||||
/// Memory access width in bytes.
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
||||
|
|
|
|||
|
|
@ -4,9 +4,7 @@
|
|||
//! block. This ensures memory order is always explicit in the statement stream
|
||||
//! rather than floating in a sea of pure expressions.
|
||||
|
||||
use crate::ir::{
|
||||
BinaryOp, Block, CastOp, FloatCC, IntCC, MemSize, Stmt, UnaryOp, Value,
|
||||
};
|
||||
use crate::ir::{BinaryOp, Block, CastOp, FloatCC, IntCC, MemSize, UnaryOp, Value};
|
||||
use cranelift_entity::EntityList;
|
||||
|
||||
/// A compact list of SSA values.
|
||||
|
|
|
|||
24
src/main.rs
24
src/main.rs
|
|
@ -9,8 +9,6 @@ use clap::{
|
|||
styling::{AnsiColor, Effects},
|
||||
},
|
||||
};
|
||||
use cranelift_entity::EntityRef;
|
||||
|
||||
use crate::{
|
||||
arch::{
|
||||
Arch, LiftArch,
|
||||
|
|
@ -42,7 +40,6 @@ fn main() {
|
|||
0x1E, 0xFF, 0x2F, 0xE1, // bx lr
|
||||
];
|
||||
|
||||
let arm = crate::arch::arm::Arm::default();
|
||||
let mut body = crate::ir::Body::new();
|
||||
let mut fb_ctx = crate::ir::FrontendBuilderContext::new();
|
||||
let env = DummyEnv;
|
||||
|
|
@ -56,25 +53,12 @@ fn main() {
|
|||
let mut pc = 0x1000u64;
|
||||
let mut rest = bytes;
|
||||
|
||||
let mut cx = crate::arch::arm::ArmLiftCtx::new(
|
||||
&arm,
|
||||
&env,
|
||||
&mut fb,
|
||||
pc,
|
||||
crate::arch::arm::ArmMode::Arm,
|
||||
);
|
||||
let mut cx = ArmLiftCtx::new(&arm, &env, &mut fb, pc, ArmMode::Arm);
|
||||
|
||||
while !rest.is_empty() {
|
||||
let (len, inst) = arm.decode(rest, crate::arch::arm::ArmMode::Arm).unwrap();
|
||||
println!(
|
||||
"{:#x}: {}",
|
||||
pc,
|
||||
arm.disasm(&inst, pc, crate::arch::arm::ArmMode::Arm)
|
||||
);
|
||||
println!(
|
||||
" flow: {:?}",
|
||||
arm.flow_info(&inst, pc, crate::arch::arm::ArmMode::Arm)
|
||||
);
|
||||
let (len, inst) = arm.decode(rest, ArmMode::Arm).unwrap();
|
||||
println!("{:#x}: {}", pc, arm.disasm(&inst, pc, ArmMode::Arm));
|
||||
println!(" flow: {:?}", arm.flow_info(&inst, pc, ArmMode::Arm));
|
||||
|
||||
cx.pc = pc;
|
||||
arm.lift(&mut cx, &inst).unwrap();
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue