diff options
Diffstat (limited to 'arch/msp430/src')
| -rw-r--r-- | arch/msp430/src/architecture.rs | 318 | ||||
| -rw-r--r-- | arch/msp430/src/flag.rs | 26 | ||||
| -rw-r--r-- | arch/msp430/src/lib.rs | 22 | ||||
| -rw-r--r-- | arch/msp430/src/lift.rs | 64 | ||||
| -rw-r--r-- | arch/msp430/src/register.rs | 25 |
5 files changed, 226 insertions, 229 deletions
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) } } |
