1use binaryninjacore_sys::*;
18use std::fmt::{Debug, Formatter};
19
20use crate::architecture::CoreArchitecture;
21use crate::binary_view::BinaryView;
22
23use crate::function::Function;
24use crate::rc::*;
25use crate::string::*;
26
27pub type TagTypeType = BNTagTypeType;
28pub type TagReferenceType = BNTagReferenceType;
29
30pub struct Tag {
31 pub(crate) handle: *mut BNTag,
32}
33
34impl Tag {
35 pub(crate) unsafe fn from_raw(handle: *mut BNTag) -> Self {
36 debug_assert!(!handle.is_null());
37 Self { handle }
38 }
39
40 pub(crate) unsafe fn ref_from_raw(handle: *mut BNTag) -> Ref<Self> {
41 debug_assert!(!handle.is_null());
42 Ref::new(Self { handle })
43 }
44
45 pub fn new(t: &TagType, data: &str) -> Ref<Self> {
46 let data = data.to_cstr();
47 unsafe { Self::ref_from_raw(BNCreateTag(t.handle, data.as_ptr())) }
48 }
49
50 pub fn id(&self) -> String {
51 unsafe { BnString::into_string(BNTagGetId(self.handle)) }
52 }
53
54 pub fn data(&self) -> String {
55 unsafe { BnString::into_string(BNTagGetData(self.handle)) }
56 }
57
58 pub fn ty(&self) -> Ref<TagType> {
59 unsafe { TagType::ref_from_raw(BNTagGetType(self.handle)) }
60 }
61
62 pub fn set_data(&self, data: &str) {
63 let data = data.to_cstr();
64 unsafe {
65 BNTagSetData(self.handle, data.as_ptr());
66 }
67 }
68}
69
70impl Debug for Tag {
71 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
72 f.debug_struct("Tag")
73 .field("id", &self.id())
74 .field("data", &self.data())
75 .field("type", &self.ty())
76 .finish()
77 }
78}
79
80impl PartialEq for Tag {
81 fn eq(&self, other: &Self) -> bool {
82 self.id() == other.id()
83 }
84}
85
86impl Eq for Tag {}
87
88unsafe impl RefCountable for Tag {
89 unsafe fn inc_ref(handle: &Self) -> Ref<Self> {
90 Ref::new(Self {
91 handle: BNNewTagReference(handle.handle),
92 })
93 }
94
95 unsafe fn dec_ref(handle: &Self) {
96 BNFreeTag(handle.handle);
97 }
98}
99
100impl ToOwned for Tag {
101 type Owned = Ref<Self>;
102
103 fn to_owned(&self) -> Self::Owned {
104 unsafe { RefCountable::inc_ref(self) }
105 }
106}
107
108impl CoreArrayProvider for Tag {
109 type Raw = *mut BNTag;
110 type Context = ();
111 type Wrapped<'a> = Guard<'a, Tag>;
112}
113
114unsafe impl CoreArrayProviderInner for Tag {
115 unsafe fn free(raw: *mut Self::Raw, count: usize, _context: &Self::Context) {
116 BNFreeTagList(raw, count)
117 }
118
119 unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, context: &'a Self::Context) -> Self::Wrapped<'a> {
120 Guard::new(Self { handle: *raw }, &context)
121 }
122}
123
124unsafe impl Send for Tag {}
125unsafe impl Sync for Tag {}
126
127pub struct TagType {
128 pub(crate) handle: *mut BNTagType,
129}
130
131impl TagType {
132 pub(crate) unsafe fn ref_from_raw(handle: *mut BNTagType) -> Ref<Self> {
133 debug_assert!(!handle.is_null());
134 Ref::new(Self { handle })
135 }
136
137 pub fn create(view: &BinaryView, name: &str, icon: &str) -> Ref<Self> {
138 let tag_type = unsafe { Self::ref_from_raw(BNCreateTagType(view.handle)) };
139 tag_type.set_name(name);
140 tag_type.set_icon(icon);
141 tag_type.set_type(TagTypeType::UserTagType);
142 tag_type
143 }
144
145 pub fn id(&self) -> String {
146 unsafe { BnString::into_string(BNTagTypeGetId(self.handle)) }
147 }
148
149 pub fn icon(&self) -> String {
150 unsafe { BnString::into_string(BNTagTypeGetIcon(self.handle)) }
151 }
152
153 pub fn set_icon(&self, icon: &str) {
154 let icon = icon.to_cstr();
155 unsafe {
156 BNTagTypeSetIcon(self.handle, icon.as_ptr());
157 }
158 }
159
160 pub fn name(&self) -> String {
161 unsafe { BnString::into_string(BNTagTypeGetName(self.handle)) }
162 }
163
164 pub fn set_name(&self, name: &str) {
165 let name = name.to_cstr();
166 unsafe {
167 BNTagTypeSetName(self.handle, name.as_ptr());
168 }
169 }
170
171 pub fn visible(&self) -> bool {
172 unsafe { BNTagTypeGetVisible(self.handle) }
173 }
174
175 pub fn set_visible(&self, visible: bool) {
176 unsafe { BNTagTypeSetVisible(self.handle, visible) }
177 }
178
179 pub fn ty(&self) -> TagTypeType {
180 unsafe { BNTagTypeGetType(self.handle) }
181 }
182
183 pub fn set_type(&self, ty: TagTypeType) {
184 unsafe {
185 BNTagTypeSetType(self.handle, ty);
186 }
187 }
188
189 pub fn view(&self) -> Ref<BinaryView> {
190 unsafe { BinaryView::ref_from_raw(BNTagTypeGetView(self.handle)) }
191 }
192}
193
194impl Debug for TagType {
195 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
196 f.debug_struct("TagType")
197 .field("id", &self.id())
198 .field("name", &self.name())
199 .field("icon", &self.icon())
200 .field("visible", &self.visible())
201 .field("type", &self.ty())
202 .finish()
203 }
204}
205
206impl PartialEq for TagType {
207 fn eq(&self, other: &Self) -> bool {
208 self.id() == other.id()
209 }
210}
211
212impl Eq for TagType {}
213
214unsafe impl RefCountable for TagType {
215 unsafe fn inc_ref(handle: &Self) -> Ref<Self> {
216 Ref::new(Self {
217 handle: BNNewTagTypeReference(handle.handle),
218 })
219 }
220
221 unsafe fn dec_ref(handle: &Self) {
222 BNFreeTagType(handle.handle);
223 }
224}
225
226impl ToOwned for TagType {
227 type Owned = Ref<Self>;
228
229 fn to_owned(&self) -> Self::Owned {
230 unsafe { RefCountable::inc_ref(self) }
231 }
232}
233
234unsafe impl Send for TagType {}
235unsafe impl Sync for TagType {}
236
237#[derive(Clone, PartialEq)]
238pub struct TagReference {
239 pub arch: CoreArchitecture,
240 pub func: Ref<Function>,
241 pub addr: u64,
242 pub auto_defined: bool,
243 pub reference_type: TagReferenceType,
244 pub tag: Ref<Tag>,
245}
246
247impl From<&BNTagReference> for TagReference {
248 fn from(value: &BNTagReference) -> Self {
249 Self {
250 reference_type: value.refType,
251 auto_defined: value.autoDefined,
252 tag: unsafe { Tag::from_raw(value.tag).to_owned() },
253 arch: unsafe { CoreArchitecture::from_raw(value.arch) },
254 func: unsafe { Function::from_raw(value.func).to_owned() },
255 addr: value.addr,
256 }
257 }
258}
259
260impl Debug for TagReference {
261 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
262 f.debug_struct("TagReference")
263 .field("addr", &self.addr)
264 .field("auto_defined", &self.auto_defined)
265 .field("reference_type", &self.reference_type)
266 .field("tag", &self.tag)
267 .finish()
268 }
269}
270
271impl CoreArrayProvider for TagReference {
272 type Raw = BNTagReference;
273 type Context = ();
274 type Wrapped<'a> = Self;
275}
276
277unsafe impl CoreArrayProviderInner for TagReference {
278 unsafe fn free(raw: *mut Self::Raw, count: usize, _context: &Self::Context) {
279 BNFreeTagReferences(raw, count)
280 }
281
282 unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, _context: &'a Self::Context) -> Self::Wrapped<'a> {
283 raw.into()
284 }
285}