summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/msp430/Cargo.lock19
-rw-r--r--arch/msp430/Cargo.toml8
-rw-r--r--arch/msp430/build.rs15
-rw-r--r--arch/msp430/src/architecture.rs318
-rw-r--r--arch/msp430/src/flag.rs26
-rw-r--r--arch/msp430/src/lib.rs22
-rw-r--r--arch/msp430/src/lift.rs64
-rw-r--r--arch/msp430/src/register.rs25
-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
13 files changed, 561 insertions, 515 deletions
diff --git a/arch/msp430/Cargo.lock b/arch/msp430/Cargo.lock
index 515b6ccf..22f7d7a3 100644
--- a/arch/msp430/Cargo.lock
+++ b/arch/msp430/Cargo.lock
@@ -25,7 +25,6 @@ name = "binaryninja"
version = "0.1.0"
dependencies = [
"binaryninjacore-sys",
- "lazy_static",
"log",
]
@@ -111,12 +110,6 @@ dependencies = [
]
[[package]]
-name = "lazy_static"
-version = "1.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
-
-[[package]]
name = "libc"
version = "0.2.158"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -187,9 +180,9 @@ dependencies = [
[[package]]
name = "quote"
-version = "1.0.36"
+version = "1.0.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7"
+checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc"
dependencies = [
"proc-macro2",
]
@@ -237,9 +230,9 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
[[package]]
name = "syn"
-version = "2.0.75"
+version = "2.0.93"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f6af063034fc1935ede7be0122941bafa9bacb949334d090b77ca98b5817c7d9"
+checksum = "9c786062daee0d6db1132800e623df74274a0a87322d8e183338e01b3d98d058"
dependencies = [
"proc-macro2",
"quote",
@@ -248,9 +241,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 = "windows-targets"
diff --git a/arch/msp430/Cargo.toml b/arch/msp430/Cargo.toml
index d97b8fc8..ddc442e8 100644
--- a/arch/msp430/Cargo.toml
+++ b/arch/msp430/Cargo.toml
@@ -5,14 +5,10 @@ authors = ["jrozner"]
edition = "2021"
[dependencies]
-binaryninja = { path = "../../rust" }
+binaryninja.workspace = true
+binaryninjacore-sys.workspace = true
log = "0.4"
msp430-asm = "^0.2"
[lib]
crate-type = ["cdylib"]
-
-[profile.release]
-panic = "abort"
-lto = true
-debug = 1
diff --git a/arch/msp430/build.rs b/arch/msp430/build.rs
new file mode 100644
index 00000000..ed6cec7d
--- /dev/null
+++ b/arch/msp430/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/msp430/src/architecture.rs b/arch/msp430/src/architecture.rs
index c37358ea..938e9ec5 100644
--- a/arch/msp430/src/architecture.rs
+++ b/arch/msp430/src/architecture.rs
@@ -4,11 +4,10 @@ use crate::register::Register;
use binaryninja::{
architecture::{
- Architecture, BranchInfo, CoreArchitecture, CustomArchitectureHandle, FlagCondition,
- InstructionInfo, UnusedIntrinsic, UnusedRegisterStack, UnusedRegisterStackInfo,
+ Architecture, CoreArchitecture, CustomArchitectureHandle, FlagCondition, InstructionInfo,
+ UnusedIntrinsic, UnusedRegisterStack, UnusedRegisterStackInfo,
},
- disassembly::{InstructionTextToken, InstructionTextTokenContents},
- llil::{LiftedExpr, Lifter},
+ disassembly::{InstructionTextToken, InstructionTextTokenKind},
Endianness,
};
@@ -17,6 +16,11 @@ use msp430_asm::{
single_operand::SingleOperand, two_operand::TwoOperand,
};
+use binaryninja::architecture::{
+ BranchKind, FlagClassId, FlagGroupId, FlagId, FlagWriteId, RegisterId,
+};
+use binaryninja::low_level_il::expression::ValueExpr;
+use binaryninja::low_level_il::{MutableLiftedILExpr, MutableLiftedILFunction};
use log::error;
const MIN_MNEMONIC: usize = 9;
@@ -71,7 +75,7 @@ impl Architecture for Msp430 {
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
}
@@ -82,137 +86,81 @@ impl Architecture for Msp430 {
match inst {
Instruction::Jnz(inst) => {
- info.add_branch(
- BranchInfo::True(offset_to_absolute(addr, inst.offset())),
- Some(self.handle),
- );
- info.add_branch(
- BranchInfo::False(addr + inst.size() as u64),
- Some(self.handle),
- );
+ info.add_branch(BranchKind::True(offset_to_absolute(addr, inst.offset())));
+ info.add_branch(BranchKind::False(addr + inst.size() as u64));
}
Instruction::Jz(inst) => {
- info.add_branch(
- BranchInfo::True(offset_to_absolute(addr, inst.offset())),
- Some(self.handle),
- );
- info.add_branch(
- BranchInfo::False(addr + inst.size() as u64),
- Some(self.handle),
- );
+ info.add_branch(BranchKind::True(offset_to_absolute(addr, inst.offset())));
+ info.add_branch(BranchKind::False(addr + inst.size() as u64));
}
Instruction::Jlo(inst) => {
- info.add_branch(
- BranchInfo::True(offset_to_absolute(addr, inst.offset())),
- Some(self.handle),
- );
- info.add_branch(
- BranchInfo::False(addr + inst.size() as u64),
- Some(self.handle),
- );
+ info.add_branch(BranchKind::True(offset_to_absolute(addr, inst.offset())));
+ info.add_branch(BranchKind::False(addr + inst.size() as u64));
}
Instruction::Jc(inst) => {
- info.add_branch(
- BranchInfo::True(offset_to_absolute(addr, inst.offset())),
- Some(self.handle),
- );
- info.add_branch(
- BranchInfo::False(addr + inst.size() as u64),
- Some(self.handle),
- );
+ info.add_branch(BranchKind::True(offset_to_absolute(addr, inst.offset())));
+ info.add_branch(BranchKind::False(addr + inst.size() as u64));
}
Instruction::Jn(inst) => {
- info.add_branch(
- BranchInfo::True(offset_to_absolute(addr, inst.offset())),
- Some(self.handle),
- );
- info.add_branch(
- BranchInfo::False(addr + inst.size() as u64),
- Some(self.handle),
- );
+ info.add_branch(BranchKind::True(offset_to_absolute(addr, inst.offset())));
+ info.add_branch(BranchKind::False(addr + inst.size() as u64));
}
Instruction::Jge(inst) => {
- info.add_branch(
- BranchInfo::True(offset_to_absolute(addr, inst.offset())),
- Some(self.handle),
- );
- info.add_branch(
- BranchInfo::False(addr + inst.size() as u64),
- Some(self.handle),
- );
+ info.add_branch(BranchKind::True(offset_to_absolute(addr, inst.offset())));
+ info.add_branch(BranchKind::False(addr + inst.size() as u64));
}
Instruction::Jl(inst) => {
- info.add_branch(
- BranchInfo::True(offset_to_absolute(addr, inst.offset())),
- Some(self.handle),
- );
- info.add_branch(
- BranchInfo::False(addr + inst.size() as u64),
- Some(self.handle),
- );
+ info.add_branch(BranchKind::True(offset_to_absolute(addr, inst.offset())));
+ info.add_branch(BranchKind::False(addr + inst.size() as u64));
}
Instruction::Jmp(inst) => {
- info.add_branch(
- BranchInfo::Unconditional(offset_to_absolute(addr, inst.offset())),
- Some(self.handle),
- );
+ info.add_branch(BranchKind::Unconditional(offset_to_absolute(
+ addr,
+ inst.offset(),
+ )));
}
Instruction::Br(inst) => match inst.destination() {
- Some(Operand::RegisterDirect(_)) => {
- info.add_branch(BranchInfo::Indirect, Some(self.handle))
- }
- Some(Operand::Indexed(_)) => {
- info.add_branch(BranchInfo::Indirect, Some(self.handle))
+ Some(Operand::RegisterDirect(_)) => info.add_branch(BranchKind::Indirect),
+ Some(Operand::Indexed(_)) => info.add_branch(BranchKind::Indirect),
+ Some(Operand::Absolute(value)) => {
+ info.add_branch(BranchKind::Unconditional(*value as u64))
}
- Some(Operand::Absolute(value)) => info.add_branch(
- BranchInfo::Unconditional(*value as u64),
- Some(self.handle),
- ),
Some(Operand::Symbolic(offset)) => info.add_branch(
- BranchInfo::Unconditional((addr as i64 + *offset as i64) as u64),
- Some(self.handle),
+ BranchKind::Unconditional((addr as i64 + *offset as i64) as u64),
),
- Some(Operand::Immediate(addr)) => info
- .add_branch(BranchInfo::Unconditional(*addr as u64), Some(self.handle)),
+ Some(Operand::Immediate(addr)) => {
+ info.add_branch(BranchKind::Unconditional(*addr as u64))
+ }
Some(Operand::Constant(_)) => {
- info.add_branch(BranchInfo::Unconditional(addr), Some(self.handle))
+ info.add_branch(BranchKind::Unconditional(addr))
}
Some(Operand::RegisterIndirect(_))
| Some(Operand::RegisterIndirectAutoIncrement(_)) => {
- info.add_branch(BranchInfo::Indirect, Some(self.handle))
+ info.add_branch(BranchKind::Indirect)
}
None => {}
},
Instruction::Call(inst) => match inst.source() {
- Operand::RegisterDirect(_) => {
- info.add_branch(BranchInfo::Indirect, Some(self.handle))
- }
- Operand::Indexed(_) => {
- info.add_branch(BranchInfo::Indirect, Some(self.handle))
- }
+ Operand::RegisterDirect(_) => info.add_branch(BranchKind::Indirect),
+ Operand::Indexed(_) => info.add_branch(BranchKind::Indirect),
Operand::Absolute(value) => {
- info.add_branch(BranchInfo::Call(*value as u64), Some(self.handle))
- }
- Operand::Symbolic(offset) => info.add_branch(
- BranchInfo::Call((addr as i64 + *offset as i64) as u64),
- Some(self.handle),
- ),
- Operand::Immediate(addr) => {
- info.add_branch(BranchInfo::Call(*addr as u64), Some(self.handle))
+ info.add_branch(BranchKind::Call(*value as u64))
}
- Operand::Constant(_) => {
- info.add_branch(BranchInfo::Call(addr), Some(self.handle))
+ Operand::Symbolic(offset) => {
+ info.add_branch(BranchKind::Call((addr as i64 + *offset as i64) as u64))
}
+ Operand::Immediate(addr) => info.add_branch(BranchKind::Call(*addr as u64)),
+ Operand::Constant(_) => info.add_branch(BranchKind::Call(addr)),
Operand::RegisterIndirect(_)
| Operand::RegisterIndirectAutoIncrement(_) => {
- info.add_branch(BranchInfo::Indirect, Some(self.handle))
+ info.add_branch(BranchKind::Indirect)
}
},
Instruction::Reti(_) => {
- info.add_branch(BranchInfo::FunctionReturn, Some(self.handle));
+ info.add_branch(BranchKind::FunctionReturn);
}
Instruction::Ret(_) => {
- info.add_branch(BranchInfo::FunctionReturn, Some(self.handle));
+ info.add_branch(BranchKind::FunctionReturn);
}
_ => {}
}
@@ -245,7 +193,7 @@ impl Architecture for Msp430 {
&self,
data: &[u8],
addr: u64,
- il: &mut Lifter<Self>,
+ il: &mut MutableLiftedILFunction<Self>,
) -> Option<(usize, bool)> {
match msp430_asm::decode(data) {
Ok(inst) => {
@@ -277,8 +225,8 @@ impl Architecture for Msp430 {
fn flag_group_llil<'a>(
&self,
_group: Self::FlagGroup,
- _il: &'a mut Lifter<Self>,
- ) -> Option<LiftedExpr<'a, Self>> {
+ _il: &'a mut MutableLiftedILFunction<Self>,
+ ) -> Option<MutableLiftedILExpr<'a, Self, ValueExpr>> {
None
}
@@ -361,14 +309,14 @@ impl Architecture for Msp430 {
None
}
- fn register_from_id(&self, id: u32) -> Option<Self::Register> {
+ fn register_from_id(&self, id: RegisterId) -> Option<Self::Register> {
match id.try_into() {
Ok(register) => Some(register),
Err(_) => None,
}
}
- fn flag_from_id(&self, id: u32) -> Option<Self::Flag> {
+ fn flag_from_id(&self, id: FlagId) -> Option<Self::Flag> {
match id.try_into() {
Ok(flag) => Some(flag),
Err(_) => {
@@ -378,7 +326,7 @@ impl Architecture for Msp430 {
}
}
- fn flag_write_from_id(&self, id: u32) -> Option<Self::FlagWrite> {
+ fn flag_write_from_id(&self, id: FlagWriteId) -> Option<Self::FlagWrite> {
match id.try_into() {
Ok(flag_write) => Some(flag_write),
Err(_) => {
@@ -388,11 +336,11 @@ impl Architecture for Msp430 {
}
}
- fn flag_class_from_id(&self, _: u32) -> Option<Self::FlagClass> {
+ fn flag_class_from_id(&self, _: FlagClassId) -> Option<Self::FlagClass> {
None
}
- fn flag_group_from_id(&self, _: u32) -> Option<Self::FlagGroup> {
+ fn flag_group_from_id(&self, _: FlagGroupId) -> Option<Self::FlagGroup> {
None
}
@@ -417,7 +365,7 @@ fn generate_tokens(inst: &Instruction, addr: u64) -> Vec<InstructionTextToken> {
Instruction::Call(inst) => generate_single_operand_tokens(inst, addr, true),
Instruction::Reti(_) => vec![InstructionTextToken::new(
"reti",
- InstructionTextTokenContents::Instruction,
+ InstructionTextTokenKind::Instruction,
)],
// Jxx instructions
@@ -479,14 +427,14 @@ fn generate_single_operand_tokens(
) -> Vec<InstructionTextToken> {
let mut res = vec![InstructionTextToken::new(
inst.mnemonic(),
- InstructionTextTokenContents::Instruction,
+ InstructionTextTokenKind::Instruction,
)];
if inst.mnemonic().len() < MIN_MNEMONIC {
let padding = " ".repeat(MIN_MNEMONIC - inst.mnemonic().len());
res.push(InstructionTextToken::new(
- &padding,
- InstructionTextTokenContents::Text,
+ padding,
+ InstructionTextTokenKind::Text,
))
}
@@ -500,20 +448,23 @@ fn generate_jxx_tokens(inst: &impl Jxx, addr: u64) -> Vec<InstructionTextToken>
let mut res = vec![InstructionTextToken::new(
inst.mnemonic(),
- InstructionTextTokenContents::Instruction,
+ InstructionTextTokenKind::Instruction,
)];
if inst.mnemonic().len() < MIN_MNEMONIC {
let padding = " ".repeat(MIN_MNEMONIC - inst.mnemonic().len());
res.push(InstructionTextToken::new(
- &padding,
- InstructionTextTokenContents::Text,
+ padding,
+ InstructionTextTokenKind::Text,
))
}
res.push(InstructionTextToken::new(
- &format!("0x{fixed_addr:4x}"),
- InstructionTextTokenContents::CodeRelativeAddress(fixed_addr),
+ format!("0x{fixed_addr:4x}"),
+ InstructionTextTokenKind::CodeRelativeAddress {
+ value: fixed_addr,
+ size: None,
+ },
));
res
@@ -522,21 +473,21 @@ fn generate_jxx_tokens(inst: &impl Jxx, addr: u64) -> Vec<InstructionTextToken>
fn generate_two_operand_tokens(inst: &impl TwoOperand, addr: u64) -> Vec<InstructionTextToken> {
let mut res = vec![InstructionTextToken::new(
inst.mnemonic(),
- InstructionTextTokenContents::Instruction,
+ InstructionTextTokenKind::Instruction,
)];
if inst.mnemonic().len() < MIN_MNEMONIC {
let padding = " ".repeat(MIN_MNEMONIC - inst.mnemonic().len());
res.push(InstructionTextToken::new(
- &padding,
- InstructionTextTokenContents::Text,
+ padding,
+ InstructionTextTokenKind::Text,
))
}
res.extend_from_slice(&generate_operand_tokens(inst.source(), addr, false));
res.push(InstructionTextToken::new(
", ",
- InstructionTextTokenContents::OperandSeparator,
+ InstructionTextTokenKind::OperandSeparator,
));
res.extend_from_slice(&generate_operand_tokens(inst.destination(), addr, false));
@@ -550,14 +501,14 @@ fn generate_emulated_tokens(
) -> Vec<InstructionTextToken> {
let mut res = vec![InstructionTextToken::new(
inst.mnemonic(),
- InstructionTextTokenContents::Instruction,
+ InstructionTextTokenKind::Instruction,
)];
if inst.mnemonic().len() < MIN_MNEMONIC {
let padding = " ".repeat(MIN_MNEMONIC - inst.mnemonic().len());
res.push(InstructionTextToken::new(
&padding,
- InstructionTextTokenContents::Text,
+ InstructionTextTokenKind::Text,
))
}
@@ -577,23 +528,23 @@ fn generate_operand_tokens(source: &Operand, addr: u64, call: bool) -> Vec<Instr
Operand::RegisterDirect(r) => match r {
0 => vec![InstructionTextToken::new(
"pc",
- InstructionTextTokenContents::Register,
+ InstructionTextTokenKind::Register,
)],
1 => vec![InstructionTextToken::new(
"sp",
- InstructionTextTokenContents::Register,
+ InstructionTextTokenKind::Register,
)],
2 => vec![InstructionTextToken::new(
"sr",
- InstructionTextTokenContents::Register,
+ InstructionTextTokenKind::Register,
)],
3 => vec![InstructionTextToken::new(
"cg",
- InstructionTextTokenContents::Register,
+ InstructionTextTokenKind::Register,
)],
_ => vec![InstructionTextToken::new(
- &format!("r{r}"),
- InstructionTextTokenContents::Register,
+ format!("r{r}"),
+ InstructionTextTokenKind::Register,
)],
},
Operand::Indexed((r, i)) => match r {
@@ -606,11 +557,14 @@ fn generate_operand_tokens(source: &Operand, addr: u64, call: bool) -> Vec<Instr
vec![
InstructionTextToken::new(
&num_text,
- InstructionTextTokenContents::Integer(*i as u64),
+ InstructionTextTokenKind::Integer {
+ value: *i as u64,
+ size: None,
+ },
),
- InstructionTextToken::new("(", InstructionTextTokenContents::Text),
- InstructionTextToken::new("pc", InstructionTextTokenContents::Register),
- InstructionTextToken::new(")", InstructionTextTokenContents::Text),
+ InstructionTextToken::new("(", InstructionTextTokenKind::Text),
+ InstructionTextToken::new("pc", InstructionTextTokenKind::Register),
+ InstructionTextToken::new(")", InstructionTextTokenKind::Text),
]
}
1 => {
@@ -622,11 +576,14 @@ fn generate_operand_tokens(source: &Operand, addr: u64, call: bool) -> Vec<Instr
vec![
InstructionTextToken::new(
&num_text,
- InstructionTextTokenContents::Integer(*i as u64),
+ InstructionTextTokenKind::Integer {
+ value: *i as u64,
+ size: None,
+ },
),
- InstructionTextToken::new("(", InstructionTextTokenContents::Text),
- InstructionTextToken::new("sp", InstructionTextTokenContents::Register),
- InstructionTextToken::new(")", InstructionTextTokenContents::Text),
+ InstructionTextToken::new("(", InstructionTextTokenKind::Text),
+ InstructionTextToken::new("sp", InstructionTextTokenKind::Register),
+ InstructionTextToken::new(")", InstructionTextTokenKind::Text),
]
}
2 => {
@@ -638,11 +595,14 @@ fn generate_operand_tokens(source: &Operand, addr: u64, call: bool) -> Vec<Instr
vec![
InstructionTextToken::new(
&num_text,
- InstructionTextTokenContents::Integer(*i as u64),
+ InstructionTextTokenKind::Integer {
+ value: *i as u64,
+ size: None,
+ },
),
- InstructionTextToken::new("(", InstructionTextTokenContents::Text),
- InstructionTextToken::new("sr", InstructionTextTokenContents::Register),
- InstructionTextToken::new(")", InstructionTextTokenContents::Text),
+ InstructionTextToken::new("(", InstructionTextTokenKind::Text),
+ InstructionTextToken::new("sr", InstructionTextTokenKind::Register),
+ InstructionTextToken::new(")", InstructionTextTokenKind::Text),
]
}
3 => {
@@ -654,11 +614,14 @@ fn generate_operand_tokens(source: &Operand, addr: u64, call: bool) -> Vec<Instr
vec![
InstructionTextToken::new(
&num_text,
- InstructionTextTokenContents::Integer(*i as u64),
+ InstructionTextTokenKind::Integer {
+ value: *i as u64,
+ size: None,
+ },
),
- InstructionTextToken::new("(", InstructionTextTokenContents::Text),
- InstructionTextToken::new("cg", InstructionTextTokenContents::Register),
- InstructionTextToken::new(")", InstructionTextTokenContents::Text),
+ InstructionTextToken::new("(", InstructionTextTokenKind::Text),
+ InstructionTextToken::new("cg", InstructionTextTokenKind::Register),
+ InstructionTextToken::new(")", InstructionTextTokenKind::Text),
]
}
_ => {
@@ -670,14 +633,14 @@ fn generate_operand_tokens(source: &Operand, addr: u64, call: bool) -> Vec<Instr
vec![
InstructionTextToken::new(
&num_text,
- InstructionTextTokenContents::Integer(*i as u64),
+ InstructionTextTokenKind::Integer {
+ value: *i as u64,
+ size: None,
+ },
),
- InstructionTextToken::new("(", InstructionTextTokenContents::Text),
- InstructionTextToken::new(
- &format!("r{r}"),
- InstructionTextTokenContents::Register,
- ),
- InstructionTextToken::new(")", InstructionTextTokenContents::Text),
+ InstructionTextToken::new("(", InstructionTextTokenKind::Text),
+ InstructionTextToken::new(format!("r{r}"), InstructionTextTokenKind::Register),
+ InstructionTextToken::new(")", InstructionTextTokenKind::Text),
]
}
},
@@ -689,8 +652,8 @@ fn generate_operand_tokens(source: &Operand, addr: u64, call: bool) -> Vec<Instr
};
vec![
- InstructionTextToken::new("@", InstructionTextTokenContents::Text),
- InstructionTextToken::new(&r_text, InstructionTextTokenContents::Register),
+ InstructionTextToken::new("@", InstructionTextTokenKind::Text),
+ InstructionTextToken::new(r_text, InstructionTextTokenKind::Register),
]
}
Operand::RegisterIndirectAutoIncrement(r) => {
@@ -701,41 +664,53 @@ fn generate_operand_tokens(source: &Operand, addr: u64, call: bool) -> Vec<Instr
};
vec![
- InstructionTextToken::new("@", InstructionTextTokenContents::Text),
- InstructionTextToken::new(&r_text, InstructionTextTokenContents::Register),
- InstructionTextToken::new("+", InstructionTextTokenContents::Text),
+ InstructionTextToken::new("@", InstructionTextTokenKind::Text),
+ InstructionTextToken::new(r_text, InstructionTextTokenKind::Register),
+ InstructionTextToken::new("+", InstructionTextTokenKind::Text),
]
}
Operand::Symbolic(i) => {
- let val = (addr as i64 + *i as i64) as u64;
+ let value = (addr as i64 + *i as i64) as u64;
vec![InstructionTextToken::new(
- &format!("{val:#x}"),
- InstructionTextTokenContents::CodeRelativeAddress(val),
+ format!("{value:#x}"),
+ InstructionTextTokenKind::CodeRelativeAddress { value, size: None },
)]
}
Operand::Immediate(i) => {
if call {
vec![InstructionTextToken::new(
- &format!("{i:#x}"),
- InstructionTextTokenContents::CodeRelativeAddress(*i as u64),
+ format!("{i:#x}"),
+ InstructionTextTokenKind::CodeRelativeAddress {
+ value: *i as u64,
+ size: None,
+ },
)]
} else {
vec![InstructionTextToken::new(
- &format!("{i:#x}"),
- InstructionTextTokenContents::PossibleAddress(*i as u64),
+ format!("{i:#x}"),
+ InstructionTextTokenKind::PossibleAddress {
+ value: *i as u64,
+ size: None,
+ },
)]
}
}
Operand::Absolute(a) => {
if call {
vec![InstructionTextToken::new(
- &format!("{a:#x}"),
- InstructionTextTokenContents::CodeRelativeAddress(*a as u64),
+ format!("{a:#x}"),
+ InstructionTextTokenKind::CodeRelativeAddress {
+ value: *a as u64,
+ size: None,
+ },
)]
} else {
vec![InstructionTextToken::new(
- &format!("{a:#x}"),
- InstructionTextTokenContents::PossibleAddress(*a as u64),
+ format!("{a:#x}"),
+ InstructionTextTokenKind::PossibleAddress {
+ value: *a as u64,
+ size: None,
+ },
)]
}
}
@@ -747,10 +722,13 @@ fn generate_operand_tokens(source: &Operand, addr: u64, call: bool) -> Vec<Instr
};
vec![
- InstructionTextToken::new("#", InstructionTextTokenContents::Text),
+ InstructionTextToken::new("#", InstructionTextTokenKind::Text),
InstructionTextToken::new(
- &num_text,
- InstructionTextTokenContents::Integer(*i as u64),
+ num_text,
+ InstructionTextTokenKind::Integer {
+ value: *i as u64,
+ size: None,
+ },
),
]
}
diff --git a/arch/msp430/src/flag.rs b/arch/msp430/src/flag.rs
index 115fe866..5baca412 100644
--- a/arch/msp430/src/flag.rs
+++ b/arch/msp430/src/flag.rs
@@ -1,5 +1,5 @@
use binaryninja::architecture;
-use binaryninja::architecture::FlagRole;
+use binaryninja::architecture::{FlagClassId, FlagGroupId, FlagId, FlagRole, FlagWriteId};
use std::borrow::Cow;
use std::collections::HashMap;
@@ -25,7 +25,7 @@ impl architecture::Flag for Flag {
}
}
- fn role(&self, _class: Option<Self::FlagClass>) -> architecture::FlagRole {
+ fn role(&self, _class: Option<Self::FlagClass>) -> FlagRole {
match self {
Self::C => FlagRole::CarryFlagRole,
Self::Z => FlagRole::ZeroFlagRole,
@@ -34,20 +34,21 @@ impl architecture::Flag for Flag {
}
}
- fn id(&self) -> u32 {
+ fn id(&self) -> FlagId {
match self {
Self::C => 0,
Self::Z => 1,
Self::N => 2,
Self::V => 8,
}
+ .into()
}
}
-impl TryFrom<u32> for Flag {
+impl TryFrom<FlagId> for Flag {
type Error = ();
- fn try_from(flag: u32) -> Result<Self, Self::Error> {
- match flag {
+ fn try_from(flag: FlagId) -> Result<Self, Self::Error> {
+ match flag.0 {
0 => Ok(Self::C),
1 => Ok(Self::Z),
2 => Ok(Self::N),
@@ -65,7 +66,7 @@ impl architecture::FlagClass for FlagClass {
unimplemented!()
}
- fn id(&self) -> u32 {
+ fn id(&self) -> FlagClassId {
unimplemented!()
}
}
@@ -81,7 +82,7 @@ impl architecture::FlagGroup for FlagGroup {
unimplemented!()
}
- fn id(&self) -> u32 {
+ fn id(&self) -> FlagGroupId {
unimplemented!()
}
@@ -119,13 +120,14 @@ impl architecture::FlagWrite for FlagWrite {
None
}
- fn id(&self) -> u32 {
+ fn id(&self) -> FlagWriteId {
match self {
Self::All => 1,
Self::Nz => 2,
Self::Nvz => 3,
Self::Cnz => 4,
}
+ .into()
}
fn flags_written(&self) -> Vec<Self::FlagType> {
@@ -138,11 +140,11 @@ impl architecture::FlagWrite for FlagWrite {
}
}
-impl TryFrom<u32> for FlagWrite {
+impl TryFrom<FlagWriteId> for FlagWrite {
type Error = ();
- fn try_from(value: u32) -> Result<Self, Self::Error> {
- match value {
+ fn try_from(value: FlagWriteId) -> Result<Self, Self::Error> {
+ match value.0 {
1 => Ok(Self::All),
2 => Ok(Self::Nz),
3 => Ok(Self::Nvz),
diff --git a/arch/msp430/src/lib.rs b/arch/msp430/src/lib.rs
index 7654b33c..b5465554 100644
--- a/arch/msp430/src/lib.rs
+++ b/arch/msp430/src/lib.rs
@@ -2,8 +2,14 @@ extern crate binaryninja;
extern crate log;
extern crate msp430_asm;
+use binaryninja::{
+ add_optional_plugin_dependency,
+ architecture::ArchitectureExt,
+ calling_convention,
+ custom_binary_view::{BinaryViewType, BinaryViewTypeExt},
+ Endianness,
+};
use log::LevelFilter;
-use binaryninja::{add_optional_plugin_dependency, architecture::ArchitectureExt, callingconvention, custombinaryview::{BinaryViewType, BinaryViewTypeExt}, Endianness};
mod architecture;
mod flag;
@@ -17,10 +23,10 @@ use binaryninja::logger::Logger;
#[allow(non_snake_case)]
pub extern "C" fn CorePluginInit() -> bool {
Logger::new("MSP430").with_level(LevelFilter::Info).init();
- let arch = binaryninja::architecture::register_architecture(
- "msp430",
- |custom_handle, handle| Msp430::new(handle, custom_handle),
- );
+ let arch =
+ binaryninja::architecture::register_architecture("msp430", |custom_handle, handle| {
+ Msp430::new(handle, custom_handle)
+ });
// we may need to introduce additional calling conventions here to
// support additional ABIs. MSPGCC's calling convention (what
@@ -30,13 +36,13 @@ pub extern "C" fn CorePluginInit() -> bool {
// https://www.ti.com/lit/an/slaa664/slaa664.pdf?ts=1613210655081. MSPGCC
// appears to be a legacy calling convention while EABI is the newer
// standardized one that is compatible with TI's compiler
- let default = callingconvention::ConventionBuilder::new(arch)
+ let default = calling_convention::ConventionBuilder::new(arch)
.is_eligible_for_heuristics(true)
.int_arg_registers(&["r15", "r14", "r13", "r12"])
.return_int_reg("r15")
.return_hi_int_reg("r14")
.register("default");
- callingconvention::ConventionBuilder::new(arch)
+ calling_convention::ConventionBuilder::new(arch)
.is_eligible_for_heuristics(true)
.return_int_reg("r15")
.return_hi_int_reg("r14")
@@ -55,4 +61,4 @@ pub extern "C" fn CorePluginInit() -> bool {
#[allow(non_snake_case)]
pub extern "C" fn CorePluginDependencies() {
add_optional_plugin_dependency("view_elf");
-} \ No newline at end of file
+}
diff --git a/arch/msp430/src/lift.rs b/arch/msp430/src/lift.rs
index feb8ce35..6ad7b67b 100644
--- a/arch/msp430/src/lift.rs
+++ b/arch/msp430/src/lift.rs
@@ -3,10 +3,7 @@ use crate::flag::{Flag, FlagWrite};
use crate::register::Register;
use crate::Msp430;
-use binaryninja::{
- architecture::FlagCondition,
- llil::{Label, LiftedNonSSA, Lifter, Mutable, NonSSA},
-};
+use binaryninja::{architecture::FlagCondition, low_level_il::lifting::LowLevelILLabel};
use msp430_asm::emulate::Emulated;
use msp430_asm::instruction::Instruction;
@@ -15,6 +12,8 @@ use msp430_asm::operand::{Operand, OperandWidth};
use msp430_asm::single_operand::SingleOperand;
use msp430_asm::two_operand::TwoOperand;
+use binaryninja::low_level_il::expression::ValueExpr;
+use binaryninja::low_level_il::{MutableLiftedILExpr, MutableLiftedILFunction};
use log::info;
macro_rules! auto_increment {
@@ -138,31 +137,38 @@ macro_rules! conditional_jump {
($addr:ident, $inst:ident, $cond:ident, $il:ident) => {
let true_addr = offset_to_absolute($addr, $inst.offset());
let false_addr = $addr + $inst.size() as u64;
- let mut new_true = Label::new();
- let mut new_false = Label::new();
+ let mut new_true = true;
+ let mut new_false = false;
- let true_label = $il.label_for_address(true_addr);
- let false_label = $il.label_for_address(false_addr);
+ let mut true_label = $il.label_for_address(true_addr).unwrap_or_else(|| {
+ new_true = true;
+ LowLevelILLabel::new()
+ });
- $il.if_expr(
- $cond,
- true_label.unwrap_or_else(|| &new_true),
- false_label.unwrap_or_else(|| &new_false),
- )
- .append();
-
- if true_label.is_none() {
- $il.mark_label(&mut new_true);
+ let mut false_label = $il.label_for_address(false_addr).unwrap_or_else(|| {
+ new_false = true;
+ LowLevelILLabel::new()
+ });
+
+ $il.if_expr($cond, &mut true_label, &mut false_label)
+ .append();
+
+ if new_true {
+ $il.mark_label(&mut true_label);
$il.jump($il.const_ptr(true_addr)).append();
}
- if false_label.is_none() {
- $il.mark_label(&mut new_false);
+ if new_false {
+ $il.mark_label(&mut false_label);
}
};
}
-pub(crate) fn lift_instruction(inst: &Instruction, addr: u64, il: &Lifter<Msp430>) {
+pub(crate) fn lift_instruction(
+ inst: &Instruction,
+ addr: u64,
+ il: &MutableLiftedILFunction<Msp430>,
+) {
match inst {
Instruction::Rrc(inst) => {
let size = match inst.operand_width() {
@@ -277,8 +283,8 @@ pub(crate) fn lift_instruction(inst: &Instruction, addr: u64, il: &Lifter<Msp430
let fixed_addr = offset_to_absolute(addr, inst.offset());
let label = il.label_for_address(fixed_addr);
match label {
- Some(label) => {
- il.goto(label).append();
+ Some(mut label) => {
+ il.goto(&mut label).append();
}
None => {
il.jump(il.const_ptr(fixed_addr)).append();
@@ -411,8 +417,8 @@ pub(crate) fn lift_instruction(inst: &Instruction, addr: u64, il: &Lifter<Msp430
}
Instruction::Br(inst) => {
let dest = if let Some(Operand::Immediate(dest)) = inst.destination() {
- if let Some(label) = il.label_for_address(*dest as u64) {
- il.goto(label).append();
+ if let Some(mut label) = il.label_for_address(*dest as u64) {
+ il.goto(&mut label).append();
return;
} else {
il.const_ptr(*dest as u64)
@@ -622,14 +628,8 @@ pub(crate) fn lift_instruction(inst: &Instruction, addr: u64, il: &Lifter<Msp430
fn lift_source_operand<'a>(
operand: &Operand,
size: usize,
- il: &'a Lifter<Msp430>,
-) -> binaryninja::llil::Expression<
- 'a,
- Msp430,
- Mutable,
- NonSSA<LiftedNonSSA>,
- binaryninja::llil::ValueExpr,
-> {
+ il: &'a MutableLiftedILFunction<Msp430>,
+) -> MutableLiftedILExpr<'a, Msp430, ValueExpr> {
match operand {
Operand::RegisterDirect(r) => il.reg(size, Register::try_from(*r as u32).unwrap()),
Operand::Indexed((r, offset)) => il
diff --git a/arch/msp430/src/register.rs b/arch/msp430/src/register.rs
index 20a5dff8..0886e537 100644
--- a/arch/msp430/src/register.rs
+++ b/arch/msp430/src/register.rs
@@ -1,6 +1,7 @@
use binaryninja::architecture;
-use binaryninja::architecture::ImplicitRegisterExtend;
+use binaryninja::architecture::{ImplicitRegisterExtend, RegisterId};
+use binaryninja::low_level_il::LowLevelILRegister;
use std::borrow::Cow;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@@ -23,15 +24,15 @@ pub enum Register {
R15,
}
-impl TryFrom<u32> for Register {
+impl TryFrom<RegisterId> for Register {
type Error = ();
- fn try_from(id: u32) -> Result<Self, Self::Error> {
+ fn try_from(id: RegisterId) -> Result<Self, Self::Error> {
// TODO: we should return separate errors if the id is between 0x7fff_ffff and 0xffff_ffff
// vs outside of that range. Temporary registers have have the high bit set which we
// shouldn't get, unless there is a bug in core. An id that isn't within that range but we
// don't handle is a bug in the architecture.
- match id {
+ match id.0 {
0 => Ok(Self::Pc),
1 => Ok(Self::Sp),
2 => Ok(Self::Sr),
@@ -53,6 +54,15 @@ impl TryFrom<u32> for Register {
}
}
+// TODO: Get rid of this and lift all u32 vals to a proper register id.
+impl TryFrom<u32> for Register {
+ type Error = ();
+
+ fn try_from(id: u32) -> Result<Self, Self::Error> {
+ Register::try_from(RegisterId(id))
+ }
+}
+
impl architecture::Register for Register {
type InfoType = Self;
@@ -81,7 +91,7 @@ impl architecture::Register for Register {
*self
}
- fn id(&self) -> u32 {
+ fn id(&self) -> RegisterId {
match self {
Self::Pc => 0,
Self::Sp => 1,
@@ -100,6 +110,7 @@ impl architecture::Register for Register {
Self::R14 => 14,
Self::R15 => 15,
}
+ .into()
}
}
@@ -123,8 +134,8 @@ impl architecture::RegisterInfo for Register {
}
}
-impl From<Register> for binaryninja::llil::Register<Register> {
+impl From<Register> for LowLevelILRegister<Register> {
fn from(register: Register) -> Self {
- binaryninja::llil::Register::ArchReg(register)
+ LowLevelILRegister::ArchReg(register)
}
}
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") {