binaryninja/architecture/
branches.rs1use crate::architecture::CoreArchitecture;
2use crate::function::Location;
3use crate::rc::{CoreArrayProvider, CoreArrayProviderInner};
4use binaryninjacore_sys::*;
5
6pub use binaryninjacore_sys::BNBranchType as BranchType;
7
8#[derive(Default, Copy, Clone, PartialEq, Eq, Hash, Debug)]
9pub enum BranchKind {
10 #[default]
11 Unresolved,
12 Unconditional(u64),
13 False(u64),
14 True(u64),
15 Call(u64),
16 FunctionReturn,
17 SystemCall,
18 Indirect,
19 Exception,
20 UserDefined,
21}
22
23#[derive(Default, Copy, Clone, PartialEq, Eq, Hash, Debug)]
24pub struct BranchInfo {
25 pub arch: Option<CoreArchitecture>,
27 pub kind: BranchKind,
28}
29
30impl BranchInfo {
31 pub fn new(kind: BranchKind) -> Self {
33 Self { arch: None, kind }
34 }
35
36 pub fn new_with_arch(kind: BranchKind, arch: CoreArchitecture) -> Self {
40 Self {
41 arch: Some(arch),
42 kind,
43 }
44 }
45
46 pub fn target(&self) -> Option<u64> {
47 match self.kind {
48 BranchKind::Unconditional(target) => Some(target),
49 BranchKind::False(target) => Some(target),
50 BranchKind::True(target) => Some(target),
51 BranchKind::Call(target) => Some(target),
52 _ => None,
53 }
54 }
55}
56
57impl From<BranchInfo> for BNBranchType {
58 fn from(value: BranchInfo) -> Self {
59 match value.kind {
60 BranchKind::Unresolved => BNBranchType::UnresolvedBranch,
61 BranchKind::Unconditional(_) => BNBranchType::UnconditionalBranch,
62 BranchKind::False(_) => BNBranchType::FalseBranch,
63 BranchKind::True(_) => BNBranchType::TrueBranch,
64 BranchKind::Call(_) => BNBranchType::CallDestination,
65 BranchKind::FunctionReturn => BNBranchType::FunctionReturn,
66 BranchKind::SystemCall => BNBranchType::SystemCall,
67 BranchKind::Indirect => BNBranchType::IndirectBranch,
68 BranchKind::Exception => BNBranchType::ExceptionBranch,
69 BranchKind::UserDefined => BNBranchType::UserDefinedBranch,
70 }
71 }
72}
73
74impl From<BranchKind> for BranchInfo {
75 fn from(value: BranchKind) -> Self {
76 Self {
77 arch: None,
78 kind: value,
79 }
80 }
81}
82
83impl From<BranchKind> for BranchType {
84 fn from(value: BranchKind) -> Self {
85 match value {
86 BranchKind::Unresolved => BranchType::UnresolvedBranch,
87 BranchKind::Unconditional(_) => BranchType::UnconditionalBranch,
88 BranchKind::True(_) => BranchType::TrueBranch,
89 BranchKind::False(_) => BranchType::FalseBranch,
90 BranchKind::Call(_) => BranchType::CallDestination,
91 BranchKind::FunctionReturn => BranchType::FunctionReturn,
92 BranchKind::SystemCall => BranchType::SystemCall,
93 BranchKind::Indirect => BranchType::IndirectBranch,
94 BranchKind::Exception => BranchType::ExceptionBranch,
95 BranchKind::UserDefined => BranchType::UserDefinedBranch,
96 }
97 }
98}
99
100#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
101pub struct IndirectBranchInfo {
102 pub source: Location,
103 pub dest: Location,
104 pub auto_defined: bool,
105}
106
107impl From<BNIndirectBranchInfo> for IndirectBranchInfo {
108 fn from(value: BNIndirectBranchInfo) -> Self {
109 Self {
110 source: Location::from_raw(value.sourceAddr, value.sourceArch),
111 dest: Location::from_raw(value.destAddr, value.destArch),
112 auto_defined: value.autoDefined,
113 }
114 }
115}
116
117impl From<IndirectBranchInfo> for BNIndirectBranchInfo {
118 fn from(value: IndirectBranchInfo) -> Self {
119 let source_arch = value
120 .source
121 .arch
122 .map(|a| a.handle)
123 .unwrap_or(std::ptr::null_mut());
124 let dest_arch = value
125 .source
126 .arch
127 .map(|a| a.handle)
128 .unwrap_or(std::ptr::null_mut());
129 Self {
130 sourceArch: source_arch,
131 sourceAddr: value.source.addr,
132 destArch: dest_arch,
133 destAddr: value.dest.addr,
134 autoDefined: value.auto_defined,
135 }
136 }
137}
138
139impl From<&BNIndirectBranchInfo> for IndirectBranchInfo {
140 fn from(value: &BNIndirectBranchInfo) -> Self {
141 Self::from(*value)
142 }
143}
144
145impl CoreArrayProvider for IndirectBranchInfo {
146 type Raw = BNIndirectBranchInfo;
147 type Context = ();
148 type Wrapped<'a> = Self;
149}
150
151unsafe impl CoreArrayProviderInner for IndirectBranchInfo {
152 unsafe fn free(raw: *mut Self::Raw, _count: usize, _context: &Self::Context) {
153 BNFreeIndirectBranchList(raw)
154 }
155
156 unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, _context: &'a Self::Context) -> Self::Wrapped<'a> {
157 Self::from(*raw)
158 }
159}