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