forked from Vector35/binaryninja-api
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathreferences.rs
86 lines (75 loc) · 2.86 KB
/
references.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
use crate::architecture::CoreArchitecture;
use crate::function::Function;
use crate::rc::{CoreArrayProvider, CoreArrayProviderInner, Guard, Ref};
use binaryninjacore_sys::{BNFreeCodeReferences, BNFreeDataReferences, BNReferenceSource};
use std::mem::ManuallyDrop;
/// A struct representing a single code cross-reference.
/// Taking a cue from [`crate::linearview::LinearDisassemblyLine`], this struct uses [ManuallyDrop] to
/// prevent destructors from being run on the [`Function`] object allocated by
/// the core in `BNGetCodeReferences` (et al). The reference is cleaned up on [Drop] of
/// the enclosing array object.
#[derive(Debug)]
pub struct CodeReference {
arch: CoreArchitecture,
func: ManuallyDrop<Ref<Function>>,
pub address: u64,
}
/// A struct representing a single data cross-reference.
/// Data references have no associated metadata, so this object has only
/// a single [`DataReference::address`] attribute.
pub struct DataReference {
pub address: u64,
}
impl CodeReference {
pub(crate) unsafe fn new(handle: &BNReferenceSource) -> Self {
let func = ManuallyDrop::new(Function::from_raw(handle.func));
let arch = CoreArchitecture::from_raw(handle.arch);
let address = handle.addr;
Self {
func,
arch,
address,
}
}
}
impl<'a> CodeReference {
/// A handle to the referenced function bound by the [CodeReference] object's lifetime.
/// A user can call `.to_owned()` to promote this into its own ref-counted struct
/// and use it after the lifetime of the [CodeReference].
pub fn function(&'a self) -> &'a Function {
self.func.as_ref()
}
/// A handle to the [CodeReference]'s [CoreArchitecture]. This type is [Copy] so reference
/// shenanigans are not needed here.
pub fn architecture(&self) -> CoreArchitecture {
self.arch
}
}
// Code Reference Array<T> boilerplate
impl CoreArrayProvider for CodeReference {
type Raw = BNReferenceSource;
type Context = ();
type Wrapped<'a> = Guard<'a, CodeReference>;
}
unsafe impl CoreArrayProviderInner for CodeReference {
unsafe fn free(raw: *mut Self::Raw, count: usize, _context: &Self::Context) {
BNFreeCodeReferences(raw, count)
}
unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, _context: &'a Self::Context) -> Self::Wrapped<'a> {
Guard::new(CodeReference::new(raw), &())
}
}
// Data Reference Array<T> boilerplate
impl CoreArrayProvider for DataReference {
type Raw = u64;
type Context = ();
type Wrapped<'a> = DataReference;
}
unsafe impl CoreArrayProviderInner for DataReference {
unsafe fn free(raw: *mut Self::Raw, _count: usize, _context: &Self::Context) {
BNFreeDataReferences(raw)
}
unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, _context: &'a Self::Context) -> Self::Wrapped<'a> {
DataReference { address: *raw }
}
}