binaryninja/
references.rs1#![allow(dead_code)]
2use crate::architecture::CoreArchitecture;
3use crate::function::Function;
4use crate::rc::{CoreArrayProvider, CoreArrayProviderInner, Ref};
5use binaryninjacore_sys::{
6 BNCodeXref, BNDataXref, BNFreeCodeReferences, BNFreeCodeXrefs, BNFreeDataReferences,
7 BNFreeDataXrefs, BNReferenceSource,
8};
9
10#[derive(Debug)]
12pub struct CodeReference {
13 pub arch: Option<CoreArchitecture>,
14 pub func: Option<Ref<Function>>,
15 pub address: u64,
16}
17
18impl CodeReference {
19 pub(crate) fn from_raw(value: &BNReferenceSource) -> Self {
20 Self {
21 func: match value.func.is_null() {
22 false => Some(unsafe { Function::from_raw(value.func) }.to_owned()),
23 true => None,
24 },
25 arch: match value.arch.is_null() {
26 false => Some(unsafe { CoreArchitecture::from_raw(value.arch) }),
27 true => None,
28 },
29 address: value.addr,
30 }
31 }
32
33 pub(crate) fn from_owned_raw(value: BNReferenceSource) -> Self {
34 let owned = Self::from_raw(&value);
35 Self::free_raw(value);
36 owned
37 }
38
39 pub(crate) fn into_raw(value: Self) -> BNReferenceSource {
40 BNReferenceSource {
41 func: match value.func {
42 Some(func) => unsafe { Ref::into_raw(func) }.handle,
43 None => std::ptr::null_mut(),
44 },
45 arch: value.arch.map(|a| a.handle).unwrap_or(std::ptr::null_mut()),
46 addr: value.address,
47 }
48 }
49
50 pub(crate) fn into_owned_raw(value: &Self) -> BNReferenceSource {
51 BNReferenceSource {
52 func: match &value.func {
53 Some(func) => func.handle,
54 None => std::ptr::null_mut(),
55 },
56 arch: value.arch.map(|a| a.handle).unwrap_or(std::ptr::null_mut()),
57 addr: value.address,
58 }
59 }
60
61 pub(crate) fn free_raw(value: BNReferenceSource) {
62 let _ = unsafe { Function::ref_from_raw(value.func) };
63 }
64
65 pub fn new(address: u64, func: Option<Ref<Function>>, arch: Option<CoreArchitecture>) -> Self {
66 Self {
67 func,
68 arch,
69 address,
70 }
71 }
72}
73
74impl CoreArrayProvider for CodeReference {
77 type Raw = BNReferenceSource;
78 type Context = ();
79 type Wrapped<'a> = Self;
80}
81
82unsafe impl CoreArrayProviderInner for CodeReference {
83 unsafe fn free(raw: *mut Self::Raw, count: usize, _context: &Self::Context) {
84 BNFreeCodeReferences(raw, count)
85 }
86
87 unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, _context: &'a Self::Context) -> Self::Wrapped<'a> {
88 CodeReference::from_raw(raw)
89 }
90}
91
92pub struct DataReference {
98 pub address: u64,
99}
100
101impl CoreArrayProvider for DataReference {
102 type Raw = u64;
103 type Context = ();
104 type Wrapped<'a> = DataReference;
105}
106
107unsafe impl CoreArrayProviderInner for DataReference {
108 unsafe fn free(raw: *mut Self::Raw, _count: usize, _context: &Self::Context) {
109 BNFreeDataReferences(raw)
110 }
111
112 unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, _context: &'a Self::Context) -> Self::Wrapped<'a> {
113 DataReference { address: *raw }
114 }
115}
116
117#[derive(Debug)]
119pub struct CodeXref {
120 pub source: CodeReference,
121 pub target: u64,
122}
123
124impl CoreArrayProvider for CodeXref {
125 type Raw = BNCodeXref;
126 type Context = ();
127 type Wrapped<'a> = Self;
128}
129
130unsafe impl CoreArrayProviderInner for CodeXref {
131 unsafe fn free(raw: *mut Self::Raw, count: usize, _context: &Self::Context) {
132 BNFreeCodeXrefs(raw, count)
133 }
134
135 unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, _context: &'a Self::Context) -> Self::Wrapped<'a> {
136 CodeXref {
137 source: CodeReference::from_raw(&raw.source),
138 target: raw.target,
139 }
140 }
141}
142
143#[derive(Debug)]
145pub struct DataXref {
146 pub source: u64,
147 pub target: u64,
148}
149
150impl CoreArrayProvider for DataXref {
151 type Raw = BNDataXref;
152 type Context = ();
153 type Wrapped<'a> = Self;
154}
155
156unsafe impl CoreArrayProviderInner for DataXref {
157 unsafe fn free(raw: *mut Self::Raw, count: usize, _context: &Self::Context) {
158 BNFreeDataXrefs(raw, count)
159 }
160
161 unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, _context: &'a Self::Context) -> Self::Wrapped<'a> {
162 DataXref {
163 source: raw.source,
164 target: raw.target,
165 }
166 }
167}