summaryrefslogtreecommitdiff
path: root/arch/riscv
diff options
context:
space:
mode:
Diffstat (limited to 'arch/riscv')
-rw-r--r--arch/riscv/Cargo.lock31
-rw-r--r--arch/riscv/Cargo.toml10
-rw-r--r--arch/riscv/build.rs15
-rw-r--r--arch/riscv/disasm/src/lib.rs29
-rw-r--r--arch/riscv/src/lib.rs494
5 files changed, 312 insertions, 267 deletions
diff --git a/arch/riscv/Cargo.lock b/arch/riscv/Cargo.lock
index de9ca95e..e7c74d5d 100644
--- a/arch/riscv/Cargo.lock
+++ b/arch/riscv/Cargo.lock
@@ -32,7 +32,6 @@ name = "binaryninja"
version = "0.1.0"
dependencies = [
"binaryninjacore-sys",
- "lazy_static",
"log",
"rayon",
]
@@ -157,12 +156,6 @@ dependencies = [
]
[[package]]
-name = "lazy_static"
-version = "1.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
-
-[[package]]
name = "libc"
version = "0.2.151"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -236,9 +229,9 @@ dependencies = [
[[package]]
name = "quote"
-version = "1.0.33"
+version = "1.0.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
+checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc"
dependencies = [
"proc-macro2",
]
@@ -265,9 +258,9 @@ dependencies = [
[[package]]
name = "regex"
-version = "1.10.2"
+version = "1.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343"
+checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191"
dependencies = [
"aho-corasick",
"memchr",
@@ -277,9 +270,9 @@ dependencies = [
[[package]]
name = "regex-automata"
-version = "0.4.3"
+version = "0.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f"
+checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908"
dependencies = [
"aho-corasick",
"memchr",
@@ -288,9 +281,9 @@ dependencies = [
[[package]]
name = "regex-syntax"
-version = "0.8.2"
+version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
+checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
[[package]]
name = "riscv-dis"
@@ -313,9 +306,9 @@ checksum = "a7cee0529a6d40f580e7a5e6c495c8fbfe21b7b52795ed4bb5e62cdf92bc6380"
[[package]]
name = "syn"
-version = "2.0.41"
+version = "2.0.93"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "44c8b28c477cc3bf0e7966561e3460130e1255f7a1cf71931075f1c5e7a7e269"
+checksum = "9c786062daee0d6db1132800e623df74274a0a87322d8e183338e01b3d98d058"
dependencies = [
"proc-macro2",
"quote",
@@ -324,9 +317,9 @@ dependencies = [
[[package]]
name = "unicode-ident"
-version = "1.0.12"
+version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
+checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83"
[[package]]
name = "winapi"
diff --git a/arch/riscv/Cargo.toml b/arch/riscv/Cargo.toml
index 974535b7..1c0979e9 100644
--- a/arch/riscv/Cargo.toml
+++ b/arch/riscv/Cargo.toml
@@ -5,7 +5,8 @@ authors = ["Ryan Snyder <ryan.snyder.or@gmail.com>"]
edition = "2021"
[dependencies]
-binaryninja = { path = "../../rust" }
+binaryninja.workspace = true
+binaryninjacore-sys.workspace = true
riscv-dis = { path = "disasm" }
log = "0.4"
rayon = { version = "1.0", optional = true }
@@ -15,9 +16,4 @@ default = []
liftcheck = ["rayon", "binaryninja/rayon"]
[lib]
-crate-type = ["cdylib"]
-
-[profile.release]
-panic = "abort"
-lto = true
-debug = 1
+crate-type = ["cdylib"] \ No newline at end of file
diff --git a/arch/riscv/build.rs b/arch/riscv/build.rs
new file mode 100644
index 00000000..ed6cec7d
--- /dev/null
+++ b/arch/riscv/build.rs
@@ -0,0 +1,15 @@
+fn main() {
+ let link_path = std::env::var_os("DEP_BINARYNINJACORE_PATH")
+ .expect("DEP_BINARYNINJACORE_PATH not specified");
+
+ println!("cargo::rustc-link-lib=dylib=binaryninjacore");
+ println!("cargo::rustc-link-search={}", link_path.to_str().unwrap());
+
+ #[cfg(not(target_os = "windows"))]
+ {
+ println!(
+ "cargo::rustc-link-arg=-Wl,-rpath,{0},-L{0}",
+ link_path.to_string_lossy()
+ );
+ }
+}
diff --git a/arch/riscv/disasm/src/lib.rs b/arch/riscv/disasm/src/lib.rs
index ad612e7a..a25516a6 100644
--- a/arch/riscv/disasm/src/lib.rs
+++ b/arch/riscv/disasm/src/lib.rs
@@ -4,10 +4,9 @@
// finish transition to from_instr32 from 'new'
// make the various component structs smaller (8 bit IntReg/FloatReg etc.)
-extern crate byteorder;
-
use std::borrow::Cow;
use std::fmt;
+use std::fmt::Debug;
use std::marker::PhantomData;
use std::mem;
@@ -292,7 +291,7 @@ impl FloatRegType for () {}
impl FloatRegType for f32 {}
impl FloatRegType for f64 {}
-pub trait RegFile: Sized + Copy + Clone {
+pub trait RegFile: Debug + Sized + Copy + Clone {
type Int: IntRegType;
type Float: FloatRegType;
@@ -345,21 +344,21 @@ pub enum Operand<D: RiscVDisassembler> {
impl<D: RiscVDisassembler> fmt::Display for Operand<D> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- match self {
- &Operand::R(ref r) => write!(f, "x{}", r.id()),
- &Operand::F(ref r) => write!(f, "f{}", r.id()),
- &Operand::I(i) => match i {
+ match *self {
+ Operand::R(r) => write!(f, "x{}", r.id()),
+ Operand::F(r) => write!(f, "f{}", r.id()),
+ Operand::I(i) => match i {
-0x80000..=-1 => write!(f, "-{:x}", -i),
_ => write!(f, "{:x}", i),
},
- &Operand::M(i, ref r) => {
+ Operand::M(i, r) => {
if i < 0 {
write!(f, "-{:x}(x{})", -i, r.id())
} else {
write!(f, "{:x}(x{})", i, r.id())
}
}
- &Operand::RM(ref r) => write!(f, "{}", r.name()),
+ Operand::RM(r) => write!(f, "{}", r.name()),
}
}
}
@@ -1777,7 +1776,7 @@ pub enum Instr<D: RiscVDisassembler> {
impl<D: RiscVDisassembler> Instr<D> {
pub fn mnem(&self) -> Mnem<D> {
- Mnem(&self)
+ Mnem(self)
}
pub fn operands(&self) -> Vec<Operand<D>> {
@@ -2300,7 +2299,7 @@ impl<'a, D: RiscVDisassembler + 'a> Mnem<'a, D> {
}
}
-impl<'a, D: RiscVDisassembler> fmt::Display for Mnem<'a, D> {
+impl<D: RiscVDisassembler> fmt::Display for Mnem<'_, D> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match (self.mnem(), self.suffix()) {
(m, None) => f.pad(m),
@@ -2332,7 +2331,7 @@ impl StandardExtension for ExtensionSupported {
}
}
-pub trait RiscVDisassembler: Sized + Copy + Clone {
+pub trait RiscVDisassembler: Debug + Sized + Copy + Clone {
type RegFile: RegFile;
type MulDivExtension: StandardExtension;
type AtomicExtension: StandardExtension;
@@ -3141,9 +3140,7 @@ pub trait RiscVDisassembler: Sized + Copy + Clone {
f if (f & 0xfe0) == 0x120 => {
Op::SfenceVma(RTypeIntInst::new(inst)?)
}
- 0x104 => {
- Op::SfenceVm(RTypeIntInst::new(inst)?)
- }
+ 0x104 => Op::SfenceVm(RTypeIntInst::new(inst)?),
0x000 => Op::Ecall,
0x001 => Op::Ebreak,
@@ -3171,7 +3168,7 @@ pub trait RiscVDisassembler: Sized + Copy + Clone {
Ok(Instr::Rv32(decoded))
}
- _ => return Err(TooShort),
+ _ => Err(TooShort),
}
}
}
diff --git a/arch/riscv/src/lib.rs b/arch/riscv/src/lib.rs
index ca2774ca..1abce973 100644
--- a/arch/riscv/src/lib.rs
+++ b/arch/riscv/src/lib.rs
@@ -1,3 +1,4 @@
+#![allow(clippy::unusual_byte_groupings)]
// Option -> Result
// rework operands/instruction text
// helper func for reading/writing to registers
@@ -13,24 +14,19 @@ use binaryninja::{
LlvmServicesRelocMode, Register as Reg, RegisterInfo, UnusedFlag, UnusedRegisterStack,
UnusedRegisterStackInfo,
},
- binaryview::{BinaryView, BinaryViewExt},
- callingconvention::{register_calling_convention, CallingConventionBase, ConventionBuilder},
- custombinaryview::{BinaryViewType, BinaryViewTypeExt},
- disassembly::{InstructionTextToken, InstructionTextTokenContents},
+ binary_view::{BinaryView, BinaryViewExt},
+ calling_convention::{register_calling_convention, CallingConvention, ConventionBuilder},
+ custom_binary_view::{BinaryViewType, BinaryViewTypeExt},
+ disassembly::{InstructionTextToken, InstructionTextTokenKind},
function::Function,
- functionrecognizer::FunctionRecognizer,
- llil,
- llil::{
- ExprInfo, InstrInfo, Label, Liftable, LiftableWithSize, LiftedNonSSA, Lifter, Mutable,
- NonSSA,
- },
+ function_recognizer::FunctionRecognizer,
rc::Ref,
relocation::{
CoreRelocationHandler, CustomRelocationHandlerHandle, RelocationHandler, RelocationInfo,
RelocationType,
},
symbol::{Symbol, SymbolType},
- types::{max_confidence, min_confidence, Conf, NameAndType, Type},
+ types::{NameAndType, Type},
};
use log::LevelFilter;
use std::borrow::Cow;
@@ -38,7 +34,18 @@ use std::fmt;
use std::hash::Hash;
use std::marker::PhantomData;
+use binaryninja::architecture::{BranchKind, IntrinsicId, RegisterId};
+use binaryninja::confidence::{Conf, MAX_CONFIDENCE, MIN_CONFIDENCE};
use binaryninja::logger::Logger;
+use binaryninja::low_level_il::expression::{LowLevelILExpressionKind, ValueExpr};
+use binaryninja::low_level_il::instruction::LowLevelILInstructionKind;
+use binaryninja::low_level_il::lifting::{
+ LiftableLowLevelIL, LiftableLowLevelILWithSize, LowLevelILLabel,
+};
+use binaryninja::low_level_il::{
+ expression::ExpressionHandler, instruction::InstructionHandler, LowLevelILRegister,
+ MutableLiftedILExpr, MutableLiftedILFunction, RegularLowLevelILFunction,
+};
use riscv_dis::{
FloatReg, FloatRegType, Instr, IntRegType, Op, RegFile, Register as RiscVRegister,
RiscVDisassembler, RoundMode,
@@ -82,18 +89,18 @@ enum Intrinsic {
#[derive(Copy, Clone)]
struct Register<D: 'static + RiscVDisassembler> {
- id: u32,
+ id: RegisterId,
_dis: PhantomData<D>,
}
-#[derive(Copy, Clone)]
+#[derive(Debug, Copy, Clone)]
struct RiscVIntrinsic<D: 'static + RiscVDisassembler> {
id: Intrinsic,
_dis: PhantomData<D>,
}
impl<D: 'static + RiscVDisassembler> Register<D> {
- fn new(id: u32) -> Self {
+ fn new(id: RegisterId) -> Self {
Self {
id,
_dis: PhantomData,
@@ -103,10 +110,10 @@ impl<D: 'static + RiscVDisassembler> Register<D> {
fn reg_type(&self) -> RegType {
let int_reg_count = <D::RegFile as RegFile>::int_reg_count();
- if self.id < int_reg_count {
- RegType::Integer(self.id)
+ if self.id.0 < int_reg_count {
+ RegType::Integer(self.id.0)
} else {
- RegType::Float(self.id - int_reg_count)
+ RegType::Float(self.id.0 - int_reg_count)
}
}
}
@@ -114,7 +121,7 @@ impl<D: 'static + RiscVDisassembler> Register<D> {
impl<D: 'static + RiscVDisassembler> From<riscv_dis::IntReg<D>> for Register<D> {
fn from(reg: riscv_dis::IntReg<D>) -> Self {
Self {
- id: reg.id(),
+ id: RegisterId(reg.id()),
_dis: PhantomData,
}
}
@@ -125,15 +132,15 @@ impl<D: 'static + RiscVDisassembler> From<FloatReg<D>> for Register<D> {
let int_reg_count = <D::RegFile as RegFile>::int_reg_count();
Self {
- id: reg.id() + int_reg_count,
+ id: RegisterId(reg.id() + int_reg_count),
_dis: PhantomData,
}
}
}
-impl<D: 'static + RiscVDisassembler> Into<llil::Register<Register<D>>> for Register<D> {
- fn into(self) -> llil::Register<Register<D>> {
- llil::Register::ArchReg(self)
+impl<D: 'static + RiscVDisassembler> From<Register<D>> for LowLevelILRegister<Register<D>> {
+ fn from(reg: Register<D>) -> Self {
+ LowLevelILRegister::ArchReg(reg)
}
}
@@ -192,18 +199,20 @@ impl<D: 'static + RiscVDisassembler> architecture::Register for Register<D> {
*self
}
- fn id(&self) -> u32 {
+ fn id(&self) -> RegisterId {
self.id
}
}
-impl<'a, D: 'static + RiscVDisassembler + Send + Sync> Liftable<'a, RiscVArch<D>> for Register<D> {
- type Result = llil::ValueExpr;
+impl<'a, D: 'static + RiscVDisassembler + Send + Sync> LiftableLowLevelIL<'a, RiscVArch<D>>
+ for Register<D>
+{
+ type Result = ValueExpr;
fn lift(
- il: &'a llil::Lifter<RiscVArch<D>>,
+ il: &'a MutableLiftedILFunction<RiscVArch<D>>,
reg: Self,
- ) -> llil::Expression<'a, RiscVArch<D>, Mutable, NonSSA<LiftedNonSSA>, Self::Result> {
+ ) -> MutableLiftedILExpr<'a, RiscVArch<D>, Self::Result> {
match reg.reg_type() {
RegType::Integer(0) => il.const_int(reg.size(), 0),
RegType::Integer(_) => il.reg(reg.size(), reg),
@@ -212,14 +221,14 @@ impl<'a, D: 'static + RiscVDisassembler + Send + Sync> Liftable<'a, RiscVArch<D>
}
}
-impl<'a, D: 'static + RiscVDisassembler + Send + Sync> LiftableWithSize<'a, RiscVArch<D>>
+impl<'a, D: 'static + RiscVDisassembler + Send + Sync> LiftableLowLevelILWithSize<'a, RiscVArch<D>>
for Register<D>
{
fn lift_with_size(
- il: &'a llil::Lifter<RiscVArch<D>>,
+ il: &'a MutableLiftedILFunction<RiscVArch<D>>,
reg: Self,
size: usize,
- ) -> llil::Expression<'a, RiscVArch<D>, Mutable, NonSSA<LiftedNonSSA>, llil::ValueExpr> {
+ ) -> MutableLiftedILExpr<'a, RiscVArch<D>, ValueExpr> {
#[cfg(debug_assertions)]
{
if reg.size() < size {
@@ -262,14 +271,19 @@ impl<D: 'static + RiscVDisassembler> PartialEq for Register<D> {
impl<D: 'static + RiscVDisassembler> Eq for Register<D> {}
-impl<D: 'static + RiscVDisassembler + Send + Sync> fmt::Debug for Register<D> {
+impl<D: 'static + RiscVDisassembler> fmt::Debug for Register<D> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str(self.name().as_ref())
}
}
impl<D: RiscVDisassembler> RiscVIntrinsic<D> {
- fn id_from_parts(id: u32, sz1: Option<u8>, sz2: Option<u8>, rm: Option<RoundMode>) -> u32 {
+ fn id_from_parts(
+ id: u32,
+ sz1: Option<u8>,
+ sz2: Option<u8>,
+ rm: Option<RoundMode>,
+ ) -> IntrinsicId {
let sz1 = sz1.unwrap_or(0);
let sz2 = sz2.unwrap_or(0);
let rm = match rm {
@@ -285,10 +299,11 @@ impl<D: RiscVDisassembler> RiscVIntrinsic<D> {
id |= sz1 as u32;
id |= (sz2 as u32) << 8;
id |= (rm as u32) << 16;
- id
+ IntrinsicId(id)
}
- fn parts_from_id(id: u32) -> Option<(u32, u8, u8, RoundMode)> {
+ fn parts_from_id(id: IntrinsicId) -> Option<(u32, u8, u8, RoundMode)> {
+ let id = id.0;
let sz1 = (id & 0xff) as u8;
let sz2 = ((id >> 8) & 0xff) as u8;
let rm = match (id >> 16) & 0xf {
@@ -303,7 +318,7 @@ impl<D: RiscVDisassembler> RiscVIntrinsic<D> {
Some(((id >> 20) & 0xfff, sz1, sz2, rm))
}
- fn from_id(id: u32) -> Option<RiscVIntrinsic<D>> {
+ fn from_id(id: IntrinsicId) -> Option<RiscVIntrinsic<D>> {
match Self::parts_from_id(id) {
Some((0, _, _, _)) => Some(Intrinsic::Uret.into()),
Some((1, _, _, _)) => Some(Intrinsic::Sret.into()),
@@ -468,7 +483,7 @@ impl<D: RiscVDisassembler> architecture::Intrinsic for RiscVIntrinsic<D> {
}
}
- fn id(&self) -> u32 {
+ fn id(&self) -> IntrinsicId {
match self.id {
Intrinsic::Uret => Self::id_from_parts(0, None, None, None),
Intrinsic::Sret => Self::id_from_parts(1, None, None, None),
@@ -509,7 +524,7 @@ impl<D: RiscVDisassembler> architecture::Intrinsic for RiscVIntrinsic<D> {
}
}
- fn inputs(&self) -> Vec<Ref<NameAndType>> {
+ fn inputs(&self) -> Vec<NameAndType> {
match self.id {
Intrinsic::Uret | Intrinsic::Sret | Intrinsic::Mret | Intrinsic::Wfi => {
vec![]
@@ -517,17 +532,18 @@ impl<D: RiscVDisassembler> architecture::Intrinsic for RiscVIntrinsic<D> {
Intrinsic::Csrrd => {
vec![NameAndType::new(
"csr",
- &Type::int(4, false),
- max_confidence(),
+ Conf::new(Type::int(4, false), MAX_CONFIDENCE),
)]
}
Intrinsic::Csrrw | Intrinsic::Csrwr | Intrinsic::Csrrs | Intrinsic::Csrrc => {
vec![
- NameAndType::new("csr", &Type::int(4, false), max_confidence()),
+ NameAndType::new("csr", Conf::new(Type::int(4, false), MAX_CONFIDENCE)),
NameAndType::new(
"value",
- &Type::int(<D::RegFile as RegFile>::Int::width(), false),
- min_confidence(),
+ Conf::new(
+ Type::int(<D::RegFile as RegFile>::Int::width(), false),
+ MIN_CONFIDENCE,
+ ),
),
]
}
@@ -541,8 +557,8 @@ impl<D: RiscVDisassembler> architecture::Intrinsic for RiscVIntrinsic<D> {
| Intrinsic::Fmin(size)
| Intrinsic::Fmax(size) => {
vec![
- NameAndType::new("", &Type::float(size as usize), max_confidence()),
- NameAndType::new("", &Type::float(size as usize), max_confidence()),
+ NameAndType::new("", Conf::new(Type::float(size as usize), MAX_CONFIDENCE)),
+ NameAndType::new("", Conf::new(Type::float(size as usize), MAX_CONFIDENCE)),
]
}
Intrinsic::Fsqrt(size, _)
@@ -552,26 +568,26 @@ impl<D: RiscVDisassembler> architecture::Intrinsic for RiscVIntrinsic<D> {
| Intrinsic::FcvtFToU(size, _, _) => {
vec![NameAndType::new(
"",
- &Type::float(size as usize),
- max_confidence(),
+ Conf::new(Type::float(size as usize), MAX_CONFIDENCE),
)]
}
Intrinsic::FcvtIToF(size, _, _) => {
vec![NameAndType::new(
"",
- &Type::int(size as usize, true),
- max_confidence(),
+ Conf::new(Type::int(size as usize, true), MAX_CONFIDENCE),
)]
}
Intrinsic::FcvtUToF(size, _, _) => {
vec![NameAndType::new(
"",
- &Type::int(size as usize, false),
- max_confidence(),
+ Conf::new(Type::int(size as usize, false), MAX_CONFIDENCE),
)]
}
Intrinsic::Fence => {
- vec![NameAndType::new("", &Type::int(4, false), min_confidence())]
+ vec![NameAndType::new(
+ "",
+ Conf::new(Type::int(4, false), MIN_CONFIDENCE),
+ )]
}
}
}
@@ -589,7 +605,7 @@ impl<D: RiscVDisassembler> architecture::Intrinsic for RiscVIntrinsic<D> {
Intrinsic::Csrrw | Intrinsic::Csrrd | Intrinsic::Csrrs | Intrinsic::Csrrc => {
vec![Conf::new(
Type::int(<D::RegFile as RegFile>::Int::width(), false),
- min_confidence(),
+ MIN_CONFIDENCE,
)]
}
Intrinsic::Fadd(size, _)
@@ -605,16 +621,16 @@ impl<D: RiscVDisassembler> architecture::Intrinsic for RiscVIntrinsic<D> {
| Intrinsic::FcvtFToF(_, size, _)
| Intrinsic::FcvtIToF(_, size, _)
| Intrinsic::FcvtUToF(_, size, _) => {
- vec![Conf::new(Type::float(size as usize), max_confidence())]
+ vec![Conf::new(Type::float(size as usize), MAX_CONFIDENCE)]
}
Intrinsic::Fclass(_) => {
- vec![Conf::new(Type::int(4, false), min_confidence())]
+ vec![Conf::new(Type::int(4, false), MIN_CONFIDENCE)]
}
Intrinsic::FcvtFToI(_, size, _) => {
- vec![Conf::new(Type::int(size as usize, true), max_confidence())]
+ vec![Conf::new(Type::int(size as usize, true), MAX_CONFIDENCE)]
}
Intrinsic::FcvtFToU(_, size, _) => {
- vec![Conf::new(Type::int(size as usize, false), max_confidence())]
+ vec![Conf::new(Type::int(size as usize, false), MAX_CONFIDENCE)]
}
}
}
@@ -671,13 +687,11 @@ impl<D: 'static + RiscVDisassembler + Send + Sync> architecture::Architecture fo
self.max_instr_len()
}
- fn associated_arch_by_addr(&self, _addr: &mut u64) -> CoreArchitecture {
+ fn associated_arch_by_addr(&self, _addr: u64) -> CoreArchitecture {
self.handle
}
fn instruction_info(&self, data: &[u8], addr: u64) -> Option<InstructionInfo> {
- use architecture::BranchInfo;
-
let (inst_len, op) = match D::decode(addr, data) {
Ok(Instr::Rv16(op)) => (2, op),
Ok(Instr::Rv32(op)) => (4, op),
@@ -691,23 +705,23 @@ impl<D: 'static + RiscVDisassembler + Send + Sync> architecture::Architecture fo
let target = addr.wrapping_add(j.imm() as i64 as u64);
let branch = if j.rd().id() == 0 {
- BranchInfo::Unconditional(target)
+ BranchKind::Unconditional(target)
} else {
- BranchInfo::Call(target)
+ BranchKind::Call(target)
};
- res.add_branch(branch, None);
+ res.add_branch(branch);
}
Op::Jalr(ref i) => {
// TODO handle the calls with rs1 == 0?
if i.rd().id() == 0 {
let branch_type = if i.rs1().id() == 1 {
- BranchInfo::FunctionReturn
+ BranchKind::FunctionReturn
} else {
- BranchInfo::Unresolved
+ BranchKind::Unresolved
};
- res.add_branch(branch_type, None);
+ res.add_branch(branch_type);
}
}
Op::Beq(ref b)
@@ -716,21 +730,18 @@ impl<D: 'static + RiscVDisassembler + Send + Sync> architecture::Architecture fo
| Op::Bge(ref b)
| Op::BltU(ref b)
| Op::BgeU(ref b) => {
- res.add_branch(BranchInfo::False(addr.wrapping_add(inst_len as u64)), None);
- res.add_branch(
- BranchInfo::True(addr.wrapping_add(b.imm() as i64 as u64)),
- None,
- );
+ res.add_branch(BranchKind::False(addr.wrapping_add(inst_len as u64)));
+ res.add_branch(BranchKind::True(addr.wrapping_add(b.imm() as i64 as u64)));
}
Op::Ecall => {
- res.add_branch(BranchInfo::SystemCall, None);
+ res.add_branch(BranchKind::SystemCall);
}
Op::Ebreak => {
// TODO is this valid, or should lifting handle this?
- res.add_branch(BranchInfo::Unresolved, None);
+ res.add_branch(BranchKind::Unresolved);
}
Op::Uret | Op::Sret | Op::Mret => {
- res.add_branch(BranchInfo::FunctionReturn, None);
+ res.add_branch(BranchKind::FunctionReturn);
}
_ => {}
}
@@ -744,7 +755,7 @@ impl<D: 'static + RiscVDisassembler + Send + Sync> architecture::Architecture fo
addr: u64,
) -> Option<(usize, Vec<InstructionTextToken>)> {
use riscv_dis::Operand;
- use InstructionTextTokenContents::*;
+ use InstructionTextTokenKind::*;
let inst = match D::decode(addr, data) {
Ok(i) => i,
@@ -982,12 +993,12 @@ impl<D: 'static + RiscVDisassembler + Send + Sync> architecture::Architecture fo
Operand::R(r) => {
let reg = self::Register::from(r);
- res.push(InstructionTextToken::new(&reg.name(), Register));
+ res.push(InstructionTextToken::new(reg.name(), Register));
}
Operand::F(r) => {
let reg = self::Register::from(r);
- res.push(InstructionTextToken::new(&reg.name(), Register));
+ res.push(InstructionTextToken::new(reg.name(), Register));
}
Operand::I(i) => {
match op {
@@ -1002,8 +1013,11 @@ impl<D: 'static + RiscVDisassembler + Send + Sync> architecture::Architecture fo
let target = addr.wrapping_add(i as i64 as u64);
res.push(InstructionTextToken::new(
- &format!("0x{:x}", target),
- CodeRelativeAddress(target),
+ format!("0x{:x}", target),
+ CodeRelativeAddress {
+ value: target,
+ size: Some(self.address_size()),
+ },
));
}
_ => {
@@ -1012,7 +1026,10 @@ impl<D: 'static + RiscVDisassembler + Send + Sync> architecture::Architecture fo
-0x8_0000..=-1 => format!("-0x{:x}", -i),
_ => format!("0x{:x}", i),
},
- Integer(i as u64),
+ Integer {
+ value: i as u64,
+ size: None,
+ },
));
}
}
@@ -1027,12 +1044,15 @@ impl<D: 'static + RiscVDisassembler + Send + Sync> architecture::Architecture fo
} else {
format!("0x{:x}", i)
},
- Integer(i as u64),
+ Integer {
+ value: i as u64,
+ size: None,
+ },
));
- res.push(InstructionTextToken::new("(", Brace));
- res.push(InstructionTextToken::new(&reg.name(), Register));
- res.push(InstructionTextToken::new(")", Brace));
+ res.push(InstructionTextToken::new("(", Brace { hash: None }));
+ res.push(InstructionTextToken::new(reg.name(), Register));
+ res.push(InstructionTextToken::new(")", Brace { hash: None }));
res.push(InstructionTextToken::new("", EndMemoryOperand));
}
Operand::RM(r) => {
@@ -1048,7 +1068,7 @@ impl<D: 'static + RiscVDisassembler + Send + Sync> architecture::Architecture fo
&self,
data: &[u8],
addr: u64,
- il: &mut llil::Lifter<Self>,
+ il: &mut MutableLiftedILFunction<Self>,
) -> Option<(usize, bool)> {
let max_width = self.default_integer_size();
@@ -1061,7 +1081,7 @@ impl<D: 'static + RiscVDisassembler + Send + Sync> architecture::Architecture fo
macro_rules! set_reg_or_append_fallback {
($op:ident, $t:expr, $f:expr) => {{
let rd = Register::from($op.rd());
- match rd.id {
+ match rd.id.0 {
0 => $f.append(),
_ => il.set_reg(rd.size(), rd, $t).append(),
}
@@ -1202,7 +1222,7 @@ impl<D: 'static + RiscVDisassembler + Send + Sync> architecture::Architecture fo
let target = addr.wrapping_add(j.imm() as i64 as u64);
match (j.rd().id(), il.label_for_address(target)) {
- (0, Some(l)) => il.goto(l),
+ (0, Some(mut l)) => il.goto(&mut l),
(0, None) => il.jump(il.const_ptr(target)),
(_, _) => il.call(il.const_ptr(target)),
}
@@ -1221,7 +1241,7 @@ impl<D: 'static + RiscVDisassembler + Send + Sync> architecture::Architecture fo
(0, _, _) => il.jump(target).append(), // indirect jump
(rd_id, rs1_id, _) if rd_id == rs1_id => {
// store the target in a temporary register so we don't clobber it when rd == rs1
- let tmp_reg: llil::Register<Register<D>> = llil::Register::Temp(0);
+ let tmp_reg: LowLevelILRegister<Register<D>> = LowLevelILRegister::Temp(0);
il.set_reg(max_width, tmp_reg, target).append();
// indirect jump with storage of next address to non-`ra` register
il.set_reg(
@@ -1259,34 +1279,31 @@ impl<D: 'static + RiscVDisassembler + Send + Sync> architecture::Architecture fo
_ => unreachable!(),
};
- let mut new_false: Option<Label> = None;
- let mut new_true: Option<Label> = None;
+ let mut new_false = false;
+ let mut new_true = false;
let ft = addr.wrapping_add(inst_len);
let tt = addr.wrapping_add(b.imm() as i64 as u64);
- {
- let f = il.label_for_address(ft).unwrap_or_else(|| {
- new_false = Some(Label::new());
- new_false.as_ref().unwrap()
- });
-
- let t = il.label_for_address(tt).unwrap_or_else(|| {
- new_true = Some(Label::new());
- new_true.as_ref().unwrap()
- });
+ let mut f = il.label_for_address(ft).unwrap_or_else(|| {
+ new_false = true;
+ LowLevelILLabel::new()
+ });
- il.if_expr(cond_expr, t, f).append();
- }
+ let mut t = il.label_for_address(tt).unwrap_or_else(|| {
+ new_true = true;
+ LowLevelILLabel::new()
+ });
- if let Some(t) = new_true.as_mut() {
- il.mark_label(t);
+ il.if_expr(cond_expr, &mut t, &mut f).append();
+ if new_true {
+ il.mark_label(&mut t);
il.jump(il.const_ptr(tt)).append();
}
- if let Some(f) = new_false.as_mut() {
- il.mark_label(f);
+ if new_false {
+ il.mark_label(&mut f);
}
}
@@ -1294,41 +1311,41 @@ impl<D: 'static + RiscVDisassembler + Send + Sync> architecture::Architecture fo
Op::Ebreak => il.bp().append(),
Op::Uret => {
il.intrinsic(
- Lifter::<Self>::NO_OUTPUTS,
+ MutableLiftedILFunction::<Self>::NO_OUTPUTS,
Intrinsic::Uret,
- Lifter::<Self>::NO_INPUTS,
+ MutableLiftedILFunction::<Self>::NO_INPUTS,
)
.append();
il.no_ret().append();
}
Op::Sret => {
il.intrinsic(
- Lifter::<Self>::NO_OUTPUTS,
+ MutableLiftedILFunction::<Self>::NO_OUTPUTS,
Intrinsic::Sret,
- Lifter::<Self>::NO_INPUTS,
+ MutableLiftedILFunction::<Self>::NO_INPUTS,
)
.append();
il.no_ret().append();
}
Op::Mret => {
il.intrinsic(
- Lifter::<Self>::NO_OUTPUTS,
+ MutableLiftedILFunction::<Self>::NO_OUTPUTS,
Intrinsic::Mret,
- Lifter::<Self>::NO_INPUTS,
+ MutableLiftedILFunction::<Self>::NO_INPUTS,
)
.append();
il.no_ret().append();
}
Op::Wfi => il
.intrinsic(
- Lifter::<Self>::NO_OUTPUTS,
+ MutableLiftedILFunction::<Self>::NO_OUTPUTS,
Intrinsic::Wfi,
- Lifter::<Self>::NO_INPUTS,
+ MutableLiftedILFunction::<Self>::NO_INPUTS,
)
.append(),
Op::Fence(i) => il
.intrinsic(
- Lifter::<Self>::NO_OUTPUTS,
+ MutableLiftedILFunction::<Self>::NO_OUTPUTS,
Intrinsic::Fence,
[il.const_int(4, i.imm() as u32 as u64)],
)
@@ -1336,19 +1353,23 @@ impl<D: 'static + RiscVDisassembler + Send + Sync> architecture::Architecture fo
Op::Csrrw(i) => {
let rd = Register::from(i.rd());
- let rs1 = Liftable::lift(il, Register::from(i.rs1()));
+ let rs1 = LiftableLowLevelIL::lift(il, Register::from(i.rs1()));
let csr = il.const_int(4, i.csr() as u64);
if i.rd().id() == 0 {
- il.intrinsic(Lifter::<Self>::NO_OUTPUTS, Intrinsic::Csrwr, [csr, rs1])
- .append();
+ il.intrinsic(
+ MutableLiftedILFunction::<Self>::NO_OUTPUTS,
+ Intrinsic::Csrwr,
+ [csr, rs1],
+ )
+ .append();
} else {
il.intrinsic([rd], Intrinsic::Csrrw, [rs1]).append();
}
}
Op::Csrrs(i) => {
let rd = Register::from(i.rd());
- let rs1 = Liftable::lift(il, Register::from(i.rs1()));
+ let rs1 = LiftableLowLevelIL::lift(il, Register::from(i.rs1()));
let csr = il.const_int(4, i.csr() as u64);
if i.rs1().id() == 0 {
@@ -1359,7 +1380,7 @@ impl<D: 'static + RiscVDisassembler + Send + Sync> architecture::Architecture fo
}
Op::Csrrc(i) => {
let rd = Register::from(i.rd());
- let rs1 = Liftable::lift(il, Register::from(i.rs1()));
+ let rs1 = LiftableLowLevelIL::lift(il, Register::from(i.rs1()));
let csr = il.const_int(4, i.csr() as u64);
if i.rs1().id() == 0 {
@@ -1374,8 +1395,12 @@ impl<D: 'static + RiscVDisassembler + Send + Sync> architecture::Architecture fo
let imm = il.const_int(max_width, i.imm() as u64);
if i.rd().id() == 0 {
- il.intrinsic(Lifter::<Self>::NO_OUTPUTS, Intrinsic::Csrwr, [csr, imm])
- .append();
+ il.intrinsic(
+ MutableLiftedILFunction::<Self>::NO_OUTPUTS,
+ Intrinsic::Csrwr,
+ [csr, imm],
+ )
+ .append();
} else {
il.intrinsic([rd], Intrinsic::Csrrw, [csr, imm]).append();
}
@@ -1418,7 +1443,7 @@ impl<D: 'static + RiscVDisassembler + Send + Sync> architecture::Architecture fo
let rd = a.rd();
let dest_reg = match rd.id() {
- 0 => llil::Register::Temp(0),
+ 0 => LowLevelILRegister::Temp(0),
_ => Register::from(rd).into(),
};
@@ -1429,29 +1454,26 @@ impl<D: 'static + RiscVDisassembler + Send + Sync> architecture::Architecture fo
// nature of the store -- dataflow will give up
il.set_reg(max_width, dest_reg, il.unimplemented()).append();
- let mut new_false: Option<Label> = None;
- let mut t = Label::new();
+ let mut new_false = false;
+ let mut t = LowLevelILLabel::new();
- {
- let cond_expr = il.cmp_e(max_width, dest_reg, 0u64);
+ let cond_expr = il.cmp_e(max_width, dest_reg, 0u64);
- let ft = addr.wrapping_add(inst_len);
- let f = il.label_for_address(ft).unwrap_or_else(|| {
- new_false = Some(Label::new());
- new_false.as_ref().unwrap()
- });
+ let ft = addr.wrapping_add(inst_len);
+ let mut f = il.label_for_address(ft).unwrap_or_else(|| {
+ new_false = true;
+ LowLevelILLabel::new()
+ });
- il.if_expr(cond_expr, &t, f).append();
- }
+ il.if_expr(cond_expr, &mut t, &mut f).append();
il.mark_label(&mut t);
-
il.store(size, Register::from(a.rs1()), Register::from(a.rs2()))
.with_source_operand(2)
.append();
- if let Some(f) = new_false.as_mut() {
- il.mark_label(f);
+ if new_false {
+ il.mark_label(&mut f);
}
}
Op::AmoSwap(a)
@@ -1469,14 +1491,14 @@ impl<D: 'static + RiscVDisassembler + Send + Sync> architecture::Architecture fo
let rs2 = a.rs2();
let dest_reg = match rd.id() {
- 0 => llil::Register::Temp(0),
+ 0 => LowLevelILRegister::Temp(0),
_ => Register::from(rd).into(),
};
let mut next_temp_reg = 1;
let mut alloc_reg = |rs: riscv_dis::IntReg<D>| match (rs.id(), rd.id()) {
(id, r) if id != 0 && id == r => {
- let reg = llil::Register::Temp(next_temp_reg);
+ let reg = LowLevelILRegister::Temp(next_temp_reg);
next_temp_reg += 1;
il.set_reg(max_width, reg, Register::from(rs)).append();
@@ -1497,8 +1519,8 @@ impl<D: 'static + RiscVDisassembler + Send + Sync> architecture::Architecture fo
il.set_reg(max_width, dest_reg, load_expr).append();
- let val_expr = LiftableWithSize::lift_with_size(il, reg_with_val, size);
- let dest_reg_val = LiftableWithSize::lift_with_size(il, dest_reg, size);
+ let val_expr = LiftableLowLevelILWithSize::lift_with_size(il, reg_with_val, size);
+ let dest_reg_val = LiftableLowLevelILWithSize::lift_with_size(il, dest_reg, size);
let val_to_store = match op {
Op::AmoSwap(..) => val_expr,
@@ -1556,7 +1578,7 @@ impl<D: 'static + RiscVDisassembler + Send + Sync> architecture::Architecture fo
};
il.set_reg(width, rd, result).append();
} else {
- let product = llil::Register::Temp(0);
+ let product = LowLevelILRegister::Temp(0);
il.intrinsic(
[product],
Intrinsic::Fmul(f.width(), f.rm()),
@@ -1711,7 +1733,7 @@ impl<D: 'static + RiscVDisassembler + Send + Sync> architecture::Architecture fo
}
Op::Fle(f) | Op::Flt(f) | Op::Feq(f) => {
let rd = match f.rd().id() {
- 0 => llil::Register::Temp(0),
+ 0 => LowLevelILRegister::Temp(0),
_ => Register::from(f.rd()).into(),
};
let left = Register::from(f.rs1());
@@ -1745,7 +1767,7 @@ impl<D: 'static + RiscVDisassembler + Send + Sync> architecture::Architecture fo
}
Op::FcvtToInt(f) => {
let rd = match f.rd().id() {
- 0 => llil::Register::Temp(0),
+ 0 => LowLevelILRegister::Temp(0),
_ => Register::from(f.rd()).into(),
};
let rs1 = Register::from(f.rs1());
@@ -1780,7 +1802,7 @@ impl<D: 'static + RiscVDisassembler + Send + Sync> architecture::Architecture fo
let rs1 = Register::from(f.rs1());
let rd_width = f.rd_width() as usize;
let rs1_width = f.rs1_width() as usize;
- let rs1 = LiftableWithSize::lift_with_size(il, rs1, rs1_width);
+ let rs1 = LiftableLowLevelILWithSize::lift_with_size(il, rs1, rs1_width);
if f.zx() {
il.intrinsic(
[rd],
@@ -1802,7 +1824,7 @@ impl<D: 'static + RiscVDisassembler + Send + Sync> architecture::Architecture fo
}
Op::FmvToInt(f) => {
let rd = match f.rd().id() {
- 0 => llil::Register::Temp(0),
+ 0 => LowLevelILRegister::Temp(0),
_ => Register::from(f.rd()).into(),
};
let rs1 = Register::from(f.rs1());
@@ -1818,7 +1840,7 @@ impl<D: 'static + RiscVDisassembler + Send + Sync> architecture::Architecture fo
let rd = Register::from(f.rd());
let rs1 = Register::from(f.rs1());
let width = f.width() as usize;
- let rs1 = LiftableWithSize::lift_with_size(il, rs1, width);
+ let rs1 = LiftableLowLevelILWithSize::lift_with_size(il, rs1, width);
il.set_reg(width, rd, rs1).append();
}
Op::Fclass(f) => {
@@ -1845,7 +1867,7 @@ impl<D: 'static + RiscVDisassembler + Send + Sync> architecture::Architecture fo
let mut res = Vec::with_capacity(reg_count as usize);
for i in 0..reg_count {
- res.push(Register::new(i));
+ res.push(Register::new(RegisterId(i)));
}
res
@@ -1859,28 +1881,28 @@ impl<D: 'static + RiscVDisassembler + Send + Sync> architecture::Architecture fo
let mut regs = Vec::with_capacity(2);
for i in &[3, 4] {
- regs.push(Register::new(*i));
+ regs.push(Register::new(RegisterId(*i)));
}
regs
}
fn stack_pointer_reg(&self) -> Option<Self::Register> {
- Some(Register::new(2))
+ Some(Register::new(RegisterId(2)))
}
fn link_reg(&self) -> Option<Self::Register> {
- Some(Register::new(1))
+ Some(Register::new(RegisterId(1)))
}
- fn register_from_id(&self, id: u32) -> Option<Self::Register> {
+ fn register_from_id(&self, id: RegisterId) -> Option<Self::Register> {
let mut reg_count = <D::RegFile as RegFile>::int_reg_count();
if <D::RegFile as RegFile>::Float::present() {
reg_count += 32;
}
- if id > reg_count {
+ if id.0 > reg_count {
None
} else {
Some(Register::new(id))
@@ -1960,7 +1982,7 @@ impl<D: 'static + RiscVDisassembler + Send + Sync> architecture::Architecture fo
res.iter().map(|i| (*i).into()).collect()
}
- fn intrinsic_from_id(&self, id: u32) -> Option<Self::Intrinsic> {
+ fn intrinsic_from_id(&self, id: IntrinsicId) -> Option<Self::Intrinsic> {
RiscVIntrinsic::from_id(id)
}
@@ -2454,7 +2476,7 @@ impl<D: 'static + RiscVDisassembler + Send + Sync> RelocationHandler
// Actual target symbol is on the associated R_RISCV_PCREL_HI20 relocation, which
// is pointed to by `reloc.target()`.
let target = match bv
- .get_relocations_at(reloc.target())
+ .relocations_at(reloc.target())
.iter()
.find(|r| r.info().native_type == Self::R_RISCV_PCREL_HI20)
{
@@ -2648,10 +2670,8 @@ impl<D: 'static + RiscVDisassembler + Send + Sync> RiscVCC<D> {
}
}
-impl<D: 'static + RiscVDisassembler + Send + Sync> CallingConventionBase for RiscVCC<D> {
- type Arch = RiscVArch<D>;
-
- fn caller_saved_registers(&self) -> Vec<Register<D>> {
+impl<D: 'static + RiscVDisassembler + Send + Sync> CallingConvention for RiscVCC<D> {
+ fn caller_saved_registers(&self) -> Vec<RegisterId> {
let mut regs = Vec::with_capacity(36);
let int_reg_count = <D::RegFile as RegFile>::int_reg_count();
@@ -2659,7 +2679,7 @@ impl<D: 'static + RiscVDisassembler + Send + Sync> CallingConventionBase for Ris
1u32, 5, 6, 7, 10, 11, 12, 13, 14, 15, 16, 17, 28, 29, 30, 31,
] {
if i < &int_reg_count {
- regs.push(Register::new(*i));
+ regs.push(RegisterId(*i));
}
}
@@ -2667,52 +2687,52 @@ impl<D: 'static + RiscVDisassembler + Send + Sync> CallingConventionBase for Ris
for i in &[
0u32, 1, 2, 3, 4, 5, 6, 7, 10, 11, 12, 13, 14, 15, 16, 17, 28, 29, 30, 31,
] {
- regs.push(Register::new(*i + int_reg_count));
+ regs.push(RegisterId(*i + int_reg_count));
}
}
regs
}
- fn callee_saved_registers(&self) -> Vec<Register<D>> {
+ fn callee_saved_registers(&self) -> Vec<RegisterId> {
let mut regs = Vec::with_capacity(24);
let int_reg_count = <D::RegFile as RegFile>::int_reg_count();
for i in &[8u32, 9, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27] {
if i < &int_reg_count {
- regs.push(Register::new(*i));
+ regs.push(RegisterId(*i));
}
}
if <D::RegFile as RegFile>::Float::present() {
for i in &[8u32, 9, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27] {
- regs.push(Register::new(*i + int_reg_count));
+ regs.push(RegisterId(*i + int_reg_count));
}
}
regs
}
- fn int_arg_registers(&self) -> Vec<Register<D>> {
+ fn int_arg_registers(&self) -> Vec<RegisterId> {
let mut regs = Vec::with_capacity(8);
let int_reg_count = <D::RegFile as RegFile>::int_reg_count();
for i in &[10, 11, 12, 13, 14, 15, 16, 17] {
if i < &int_reg_count {
- regs.push(Register::new(*i));
+ regs.push(RegisterId(*i));
}
}
regs
}
- fn float_arg_registers(&self) -> Vec<Register<D>> {
+ fn float_arg_registers(&self) -> Vec<RegisterId> {
let mut regs = Vec::with_capacity(8);
if <D::RegFile as RegFile>::Float::present() {
let int_reg_count = <D::RegFile as RegFile>::int_reg_count();
for i in &[10, 11, 12, 13, 14, 15, 16, 17] {
- regs.push(Register::new(*i + int_reg_count));
+ regs.push(RegisterId(*i + int_reg_count));
}
}
@@ -2735,29 +2755,29 @@ impl<D: 'static + RiscVDisassembler + Send + Sync> CallingConventionBase for Ris
}
// a0 == x10
- fn return_int_reg(&self) -> Option<Register<D>> {
- Some(Register::new(10))
+ fn return_int_reg(&self) -> Option<RegisterId> {
+ Some(RegisterId(10))
}
// a1 == x11
- fn return_hi_int_reg(&self) -> Option<Register<D>> {
- Some(Register::new(11))
+ fn return_hi_int_reg(&self) -> Option<RegisterId> {
+ Some(RegisterId(11))
}
- fn return_float_reg(&self) -> Option<Register<D>> {
+ fn return_float_reg(&self) -> Option<RegisterId> {
if <D::RegFile as RegFile>::Float::present() {
let int_reg_count = <D::RegFile as RegFile>::int_reg_count();
- Some(Register::new(10 + int_reg_count))
+ Some(RegisterId(10 + int_reg_count))
} else {
None
}
}
// gp == x3
- fn global_pointer_reg(&self) -> Option<Register<D>> {
- Some(Register::new(3))
+ fn global_pointer_reg(&self) -> Option<RegisterId> {
+ Some(RegisterId(3))
}
- fn implicitly_defined_registers(&self) -> Vec<Register<D>> {
+ fn implicitly_defined_registers(&self) -> Vec<RegisterId> {
Vec::new()
}
fn are_argument_registers_used_for_var_args(&self) -> bool {
@@ -2772,7 +2792,7 @@ impl FunctionRecognizer for RiscVELFPLTRecognizer {
&self,
bv: &BinaryView,
func: &Function,
- llil: &llil::RegularFunction<CoreArchitecture>,
+ llil: &RegularLowLevelILFunction<CoreArchitecture>,
) -> bool {
// Look for the following code pattern:
// t3 = plt
@@ -2788,11 +2808,13 @@ impl FunctionRecognizer for RiscVELFPLTRecognizer {
let mut next_llil_instr = llil.basic_blocks().iter().next().unwrap().iter();
// Match instruction that fetches PC-relative PLT address range
- let auipc = next_llil_instr.next().unwrap().info();
+ let auipc = next_llil_instr.next().unwrap().kind();
let (auipc_dest, plt_base) = match auipc {
- InstrInfo::SetReg(r) => {
- let value = match r.source_expr().info() {
- ExprInfo::Const(v) | ExprInfo::ConstPtr(v) => v.value(),
+ LowLevelILInstructionKind::SetReg(r) => {
+ let value = match r.source_expr().kind() {
+ LowLevelILExpressionKind::Const(v) | LowLevelILExpressionKind::ConstPtr(v) => {
+ v.value()
+ }
_ => return false,
};
(r.dest_reg(), value)
@@ -2801,34 +2823,46 @@ impl FunctionRecognizer for RiscVELFPLTRecognizer {
};
// Match load instruction that loads the imported address
- let load = next_llil_instr.next().unwrap().info();
+ let load = next_llil_instr.next().unwrap().kind();
let (mut entry, mut target_reg) = match load {
- InstrInfo::SetReg(r) => match r.source_expr().info() {
- ExprInfo::Load(l) => {
+ LowLevelILInstructionKind::SetReg(r) => match r.source_expr().kind() {
+ LowLevelILExpressionKind::Load(l) => {
let target_reg = r.dest_reg();
- let entry = match l.source_mem_expr().info() {
- ExprInfo::Reg(lr) if lr.source_reg() == auipc_dest => plt_base,
- ExprInfo::Add(a) => match (a.left().info(), a.right().info()) {
- (ExprInfo::Reg(a), ExprInfo::Const(b) | ExprInfo::ConstPtr(b))
- if a.source_reg() == auipc_dest =>
- {
- plt_base.wrapping_add(b.value())
- }
- (ExprInfo::Const(b) | ExprInfo::ConstPtr(b), ExprInfo::Reg(a))
- if a.source_reg() == auipc_dest =>
- {
- plt_base.wrapping_add(b.value())
+ let entry = match l.source_mem_expr().kind() {
+ LowLevelILExpressionKind::Reg(lr) if lr.source_reg() == auipc_dest => {
+ plt_base
+ }
+ LowLevelILExpressionKind::Add(a) => {
+ match (a.left().kind(), a.right().kind()) {
+ (
+ LowLevelILExpressionKind::Reg(a),
+ LowLevelILExpressionKind::Const(b)
+ | LowLevelILExpressionKind::ConstPtr(b),
+ ) if a.source_reg() == auipc_dest => {
+ plt_base.wrapping_add(b.value())
+ }
+ (
+ LowLevelILExpressionKind::Const(b)
+ | LowLevelILExpressionKind::ConstPtr(b),
+ LowLevelILExpressionKind::Reg(a),
+ ) if a.source_reg() == auipc_dest => {
+ plt_base.wrapping_add(b.value())
+ }
+ _ => return false,
}
- _ => return false,
- },
- ExprInfo::Sub(a) => match (a.left().info(), a.right().info()) {
- (ExprInfo::Reg(a), ExprInfo::Const(b) | ExprInfo::ConstPtr(b))
- if a.source_reg() == auipc_dest =>
- {
- plt_base.wrapping_sub(b.value())
+ }
+ LowLevelILExpressionKind::Sub(a) => {
+ match (a.left().kind(), a.right().kind()) {
+ (
+ LowLevelILExpressionKind::Reg(a),
+ LowLevelILExpressionKind::Const(b)
+ | LowLevelILExpressionKind::ConstPtr(b),
+ ) if a.source_reg() == auipc_dest => {
+ plt_base.wrapping_sub(b.value())
+ }
+ _ => return false,
}
- _ => return false,
- },
+ }
_ => return false,
};
(entry, target_reg)
@@ -2843,22 +2877,22 @@ impl FunctionRecognizer for RiscVELFPLTRecognizer {
// Ensure that load is pointing at an import address
let sym = match bv.symbol_by_address(entry) {
- Ok(sym) => sym,
- Err(_) => return false,
+ Some(sym) => sym,
+ None => return false,
};
if sym.sym_type() != SymbolType::ImportAddress {
return false;
}
// (OPTIONAL) Check if we are storing in temp0, adjust target reg if so
- let mut temp_reg_inst = next_llil_instr.next().unwrap().info();
+ let mut temp_reg_inst = next_llil_instr.next().unwrap().kind();
match &temp_reg_inst {
- InstrInfo::SetReg(r) if llil.instruction_count() >= 5 => {
- match r.source_expr().info() {
- ExprInfo::Reg(op) if target_reg == op.source_reg() => {
+ LowLevelILInstructionKind::SetReg(r) if llil.instruction_count() >= 5 => {
+ match r.source_expr().kind() {
+ LowLevelILExpressionKind::Reg(op) if target_reg == op.source_reg() => {
// Update the target_reg to the temp reg.
target_reg = r.dest_reg();
- temp_reg_inst = next_llil_instr.next().unwrap().info()
+ temp_reg_inst = next_llil_instr.next().unwrap().kind()
}
_ => {}
}
@@ -2869,9 +2903,11 @@ impl FunctionRecognizer for RiscVELFPLTRecognizer {
// Match instruction that stores the next instruction address into a register
let next_pc_inst = temp_reg_inst;
let (next_pc_dest, next_pc, cur_pc) = match next_pc_inst {
- InstrInfo::SetReg(r) => {
- let value = match r.source_expr().info() {
- ExprInfo::Const(v) | ExprInfo::ConstPtr(v) => v.value(),
+ LowLevelILInstructionKind::SetReg(r) => {
+ let value = match r.source_expr().kind() {
+ LowLevelILExpressionKind::Const(v) | LowLevelILExpressionKind::ConstPtr(v) => {
+ v.value()
+ }
_ => return false,
};
(r.dest_reg(), value, r.address())
@@ -2883,17 +2919,17 @@ impl FunctionRecognizer for RiscVELFPLTRecognizer {
}
// Match tail call at the end and make sure it is going to the import
- let jump = next_llil_instr.next().unwrap().info();
+ let jump = next_llil_instr.next().unwrap().kind();
match jump {
- InstrInfo::TailCall(j) => {
- match j.target().info() {
- ExprInfo::Reg(r) if r.source_reg() == target_reg => (),
+ LowLevelILInstructionKind::TailCall(j) => {
+ match j.target().kind() {
+ LowLevelILExpressionKind::Reg(r) if r.source_reg() == target_reg => (),
_ => return false,
};
}
- InstrInfo::Jump(j) => {
- match j.target().info() {
- ExprInfo::Reg(r) if r.source_reg() == target_reg => (),
+ LowLevelILInstructionKind::Jump(j) => {
+ match j.target().kind() {
+ LowLevelILExpressionKind::Reg(r) if r.source_reg() == target_reg => (),
_ => return false,
};
}
@@ -2907,7 +2943,7 @@ impl FunctionRecognizer for RiscVELFPLTRecognizer {
for ext_sym in &bv.symbols_by_name(func_sym.raw_name()) {
if ext_sym.sym_type() == SymbolType::External {
if let Some(var) = bv.data_variable_at_address(ext_sym.address()) {
- func.apply_imported_types(func_sym.as_ref(), Some(var.t()));
+ func.apply_imported_types(func_sym.as_ref(), Some(&var.ty.contents));
return true;
}
}
@@ -2957,9 +2993,17 @@ pub extern "C" fn CorePluginInit() -> bool {
arch32.register_function_recognizer(RiscVELFPLTRecognizer);
arch64.register_function_recognizer(RiscVELFPLTRecognizer);
- let cc32 = register_calling_convention(arch32, "default", RiscVCC::new());
+ let cc32 = register_calling_convention(
+ arch32,
+ "default",
+ RiscVCC::<RiscVIMACDisassembler<Rv32GRegs>>::new(),
+ );
arch32.set_default_calling_convention(&cc32);
- let cc64 = register_calling_convention(arch64, "default", RiscVCC::new());
+ let cc64 = register_calling_convention(
+ arch64,
+ "default",
+ RiscVCC::<RiscVIMACDisassembler<Rv64GRegs>>::new(),
+ );
arch64.set_default_calling_convention(&cc64);
if let Ok(bvt) = BinaryViewType::by_name("ELF") {