binaryninja/
external_library.rs1use crate::project::file::ProjectFile;
2use crate::rc::{CoreArrayProvider, CoreArrayProviderInner, Guard, Ref, RefCountable};
3use crate::string::{BnString, IntoCStr};
4use crate::symbol::Symbol;
5use binaryninjacore_sys::*;
6use std::fmt::Debug;
7use std::ptr::NonNull;
8
9#[repr(transparent)]
12pub struct ExternalLibrary {
13 pub(crate) handle: NonNull<BNExternalLibrary>,
14}
15
16impl ExternalLibrary {
17 pub(crate) unsafe fn from_raw(handle: NonNull<BNExternalLibrary>) -> Self {
18 Self { handle }
19 }
20
21 pub(crate) unsafe fn ref_from_raw(handle: NonNull<BNExternalLibrary>) -> Ref<Self> {
22 Ref::new(Self { handle })
23 }
24
25 pub fn name(&self) -> String {
27 let result = unsafe { BNExternalLibraryGetName(self.handle.as_ptr()) };
28 assert!(!result.is_null());
29 unsafe { BnString::into_string(result) }
30 }
31
32 pub fn backing_file(&self) -> Option<Ref<ProjectFile>> {
34 let result = unsafe { BNExternalLibraryGetBackingFile(self.handle.as_ptr()) };
35 let handle = NonNull::new(result)?;
36 Some(unsafe { ProjectFile::ref_from_raw(handle) })
37 }
38
39 pub fn set_backing_file(&self, file: Option<&ProjectFile>) {
41 let file_handle = file
42 .map(|x| x.handle.as_ptr())
43 .unwrap_or(std::ptr::null_mut());
44 unsafe { BNExternalLibrarySetBackingFile(self.handle.as_ptr(), file_handle) }
45 }
46}
47
48impl ToOwned for ExternalLibrary {
49 type Owned = Ref<Self>;
50
51 fn to_owned(&self) -> Self::Owned {
52 unsafe { RefCountable::inc_ref(self) }
53 }
54}
55
56unsafe impl RefCountable for ExternalLibrary {
57 unsafe fn inc_ref(handle: &Self) -> Ref<Self> {
58 Ref::new(Self {
59 handle: NonNull::new(BNNewExternalLibraryReference(handle.handle.as_ptr())).unwrap(),
60 })
61 }
62
63 unsafe fn dec_ref(handle: &Self) {
64 BNFreeExternalLibrary(handle.handle.as_ptr());
65 }
66}
67
68impl Debug for ExternalLibrary {
69 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
70 f.debug_struct("ExternalLibrary")
71 .field("name", &self.name())
72 .field("backing_file", &self.backing_file())
73 .finish()
74 }
75}
76
77impl CoreArrayProvider for ExternalLibrary {
78 type Raw = *mut BNExternalLibrary;
79 type Context = ();
80 type Wrapped<'a> = Guard<'a, ExternalLibrary>;
81}
82
83unsafe impl CoreArrayProviderInner for ExternalLibrary {
84 unsafe fn free(raw: *mut Self::Raw, count: usize, _context: &Self::Context) {
85 BNFreeExternalLibraryList(raw, count)
86 }
87
88 unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, context: &'a Self::Context) -> Self::Wrapped<'a> {
89 let raw_ptr = NonNull::new(*raw).unwrap();
90 Guard::new(Self::from_raw(raw_ptr), context)
91 }
92}
93
94#[repr(transparent)]
97pub struct ExternalLocation {
98 handle: NonNull<BNExternalLocation>,
99}
100
101impl ExternalLocation {
102 pub(crate) unsafe fn from_raw(handle: NonNull<BNExternalLocation>) -> Self {
103 Self { handle }
104 }
105
106 pub(crate) unsafe fn ref_from_raw(handle: NonNull<BNExternalLocation>) -> Ref<Self> {
107 Ref::new(Self { handle })
108 }
109
110 pub fn source_symbol(&self) -> Ref<Symbol> {
112 let result = unsafe { BNExternalLocationGetSourceSymbol(self.handle.as_ptr()) };
113 assert!(!result.is_null());
114 unsafe { Symbol::ref_from_raw(result) }
115 }
116
117 pub fn library(&self) -> Option<Ref<ExternalLibrary>> {
119 let result = unsafe { BNExternalLocationGetExternalLibrary(self.handle.as_ptr()) };
120 let handle = NonNull::new(result)?;
121 Some(unsafe { ExternalLibrary::ref_from_raw(handle) })
122 }
123
124 pub fn set_external_library(&self, lib: Option<&ExternalLibrary>) {
126 let lib_handle = lib
127 .map(|x| x.handle.as_ptr())
128 .unwrap_or(std::ptr::null_mut());
129 unsafe { BNExternalLocationSetExternalLibrary(self.handle.as_ptr(), lib_handle) }
130 }
131
132 pub fn has_target_address(&self) -> bool {
134 unsafe { BNExternalLocationHasTargetAddress(self.handle.as_ptr()) }
135 }
136
137 pub fn has_target_symbol(&self) -> bool {
139 unsafe { BNExternalLocationHasTargetSymbol(self.handle.as_ptr()) }
140 }
141
142 pub fn target_address(&self) -> Option<u64> {
144 self.has_target_address()
145 .then(|| unsafe { BNExternalLocationGetTargetAddress(self.handle.as_ptr()) })
146 }
147
148 pub fn set_target_address(&self, address: Option<u64>) -> bool {
151 match address {
152 Some(mut addr) => unsafe {
153 BNExternalLocationSetTargetAddress(self.handle.as_ptr(), &mut addr)
154 },
155 None => unsafe {
156 BNExternalLocationSetTargetAddress(self.handle.as_ptr(), std::ptr::null_mut())
157 },
158 }
159 }
160
161 pub fn target_symbol(&self) -> Option<BnString> {
163 let result = unsafe { BNExternalLocationGetTargetSymbol(self.handle.as_ptr()) };
164 (!result.is_null()).then(|| unsafe { BnString::from_raw(result) })
165 }
166
167 pub fn set_target_symbol(&self, symbol: Option<&str>) -> bool {
170 match symbol {
171 Some(sym) => {
172 let raw_sym = sym.to_cstr();
173 unsafe { BNExternalLocationSetTargetSymbol(self.handle.as_ptr(), raw_sym.as_ptr()) }
174 }
175 None => unsafe {
176 BNExternalLocationSetTargetSymbol(self.handle.as_ptr(), std::ptr::null())
177 },
178 }
179 }
180}
181
182impl Debug for ExternalLocation {
183 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
184 f.debug_struct("ExternalLocation")
185 .field("source_symbol", &self.source_symbol())
186 .field("library", &self.library())
187 .field("target_address", &self.target_address())
188 .field("target_symbol", &self.target_symbol())
189 .finish()
190 }
191}
192
193impl ToOwned for ExternalLocation {
194 type Owned = Ref<Self>;
195
196 fn to_owned(&self) -> Self::Owned {
197 unsafe { RefCountable::inc_ref(self) }
198 }
199}
200
201unsafe impl RefCountable for ExternalLocation {
202 unsafe fn inc_ref(handle: &Self) -> Ref<Self> {
203 Ref::new(Self {
204 handle: NonNull::new(BNNewExternalLocationReference(handle.handle.as_ptr())).unwrap(),
205 })
206 }
207
208 unsafe fn dec_ref(handle: &Self) {
209 BNFreeExternalLocation(handle.handle.as_ptr());
210 }
211}
212
213impl CoreArrayProvider for ExternalLocation {
214 type Raw = *mut BNExternalLocation;
215 type Context = ();
216 type Wrapped<'a> = Guard<'a, Self>;
217}
218
219unsafe impl CoreArrayProviderInner for ExternalLocation {
220 unsafe fn free(raw: *mut Self::Raw, count: usize, _context: &Self::Context) {
221 BNFreeExternalLocationList(raw, count)
222 }
223
224 unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, context: &'a Self::Context) -> Self::Wrapped<'a> {
225 let raw_ptr = NonNull::new(*raw).unwrap();
226 Guard::new(Self::from_raw(raw_ptr), context)
227 }
228}