1#![allow(unused)]
2
3use crate::architecture::{Architecture, CoreArchitecture, CoreRegister, RegisterId};
4use crate::confidence::Conf;
5use crate::function::{Function, Location};
6use crate::rc::{CoreArrayProvider, CoreArrayProviderInner, Ref};
7use crate::string::{raw_to_string, BnString};
8use crate::types::Type;
9use binaryninjacore_sys::{
10 BNDataVariable, BNDataVariableAndName, BNFreeDataVariables, BNFreeDataVariablesAndName,
11 BNFreeILInstructionList, BNFreeMergedVariableList, BNFreePossibleValueSet,
12 BNFreeStackVariableReferenceList, BNFreeUserVariableValues, BNFreeVariableList,
13 BNFreeVariableNameAndTypeList, BNFromVariableIdentifier, BNLookupTableEntry, BNMergedVariable,
14 BNPossibleValueSet, BNPossibleValueSetAdd, BNPossibleValueSetAnd,
15 BNPossibleValueSetArithShiftRight, BNPossibleValueSetIntersection,
16 BNPossibleValueSetLogicalShiftRight, BNPossibleValueSetMultiply, BNPossibleValueSetNegate,
17 BNPossibleValueSetNot, BNPossibleValueSetOr, BNPossibleValueSetRotateLeft,
18 BNPossibleValueSetRotateRight, BNPossibleValueSetShiftLeft, BNPossibleValueSetSignedDivide,
19 BNPossibleValueSetSignedMod, BNPossibleValueSetSubtract, BNPossibleValueSetUnion,
20 BNPossibleValueSetUnsignedDivide, BNPossibleValueSetUnsignedMod, BNPossibleValueSetXor,
21 BNRegisterValue, BNRegisterValueType, BNStackVariableReference, BNToVariableIdentifier,
22 BNUserVariableValue, BNValueRange, BNVariable, BNVariableNameAndType, BNVariableSourceType,
23};
24use std::collections::HashSet;
25
26pub type VariableSourceType = BNVariableSourceType;
27pub type RegisterValueType = BNRegisterValueType;
28
29#[derive(Debug, Clone, Hash, PartialEq, Eq)]
30pub struct DataVariable {
31 pub address: u64,
32 pub ty: Conf<Ref<Type>>,
33 pub auto_discovered: bool,
34}
35
36impl DataVariable {
37 pub(crate) fn from_raw(value: &BNDataVariable) -> Self {
38 Self {
39 address: value.address,
40 ty: Conf::new(
41 unsafe { Type::from_raw(value.type_).to_owned() },
42 value.typeConfidence,
43 ),
44 auto_discovered: value.autoDiscovered,
45 }
46 }
47
48 pub(crate) fn from_owned_raw(value: BNDataVariable) -> Self {
49 let owned = Self::from_raw(&value);
50 Self::free_raw(value);
51 owned
52 }
53
54 pub(crate) fn into_raw(value: Self) -> BNDataVariable {
55 BNDataVariable {
56 address: value.address,
57 type_: unsafe { Ref::into_raw(value.ty.contents) }.handle,
58 autoDiscovered: value.auto_discovered,
59 typeConfidence: value.ty.confidence,
60 }
61 }
62
63 pub(crate) fn into_owned_raw(value: &Self) -> BNDataVariable {
64 BNDataVariable {
65 address: value.address,
66 type_: value.ty.contents.handle,
67 autoDiscovered: value.auto_discovered,
68 typeConfidence: value.ty.confidence,
69 }
70 }
71
72 pub(crate) fn free_raw(value: BNDataVariable) {
73 let _ = unsafe { Type::ref_from_raw(value.type_) };
74 }
75
76 pub fn new(address: u64, ty: Conf<Ref<Type>>, auto_discovered: bool) -> Self {
77 Self {
78 address,
79 ty,
80 auto_discovered,
81 }
82 }
83}
84
85impl CoreArrayProvider for DataVariable {
86 type Raw = BNDataVariable;
87 type Context = ();
88 type Wrapped<'a> = Self;
89}
90
91unsafe impl CoreArrayProviderInner for DataVariable {
92 unsafe fn free(raw: *mut Self::Raw, count: usize, _context: &Self::Context) {
93 BNFreeDataVariables(raw, count);
94 }
95
96 unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, _context: &'a Self::Context) -> Self::Wrapped<'a> {
97 DataVariable::from_raw(raw)
98 }
99}
100
101#[derive(Debug, Clone, Hash, PartialEq, Eq)]
102pub struct NamedDataVariableWithType {
103 pub address: u64,
104 pub ty: Conf<Ref<Type>>,
105 pub name: String,
106 pub auto_discovered: bool,
107}
108
109impl NamedDataVariableWithType {
110 pub(crate) fn from_raw(value: &BNDataVariableAndName) -> Self {
111 Self {
112 address: value.address,
113 ty: Conf::new(
114 unsafe { Type::from_raw(value.type_).to_owned() },
115 value.typeConfidence,
116 ),
117 name: raw_to_string(value.name as *mut _).unwrap(),
119 auto_discovered: value.autoDiscovered,
120 }
121 }
122
123 pub(crate) fn from_owned_raw(value: BNDataVariableAndName) -> Self {
124 let owned = Self::from_raw(&value);
125 Self::free_raw(value);
126 owned
127 }
128
129 pub(crate) fn into_raw(value: Self) -> BNDataVariableAndName {
130 let bn_name = BnString::new(value.name);
131 BNDataVariableAndName {
132 address: value.address,
133 type_: unsafe { Ref::into_raw(value.ty.contents) }.handle,
134 name: BnString::into_raw(bn_name),
135 autoDiscovered: value.auto_discovered,
136 typeConfidence: value.ty.confidence,
137 }
138 }
139
140 pub(crate) fn free_raw(value: BNDataVariableAndName) {
141 let _ = unsafe { Type::ref_from_raw(value.type_) };
142 let _ = unsafe { BnString::from_raw(value.name) };
143 }
144
145 pub fn new(address: u64, ty: Conf<Ref<Type>>, name: String, auto_discovered: bool) -> Self {
146 Self {
147 address,
148 ty,
149 name,
150 auto_discovered,
151 }
152 }
153}
154
155impl CoreArrayProvider for NamedDataVariableWithType {
156 type Raw = BNDataVariableAndName;
157 type Context = ();
158 type Wrapped<'a> = NamedDataVariableWithType;
159}
160
161unsafe impl CoreArrayProviderInner for NamedDataVariableWithType {
162 unsafe fn free(raw: *mut Self::Raw, count: usize, _context: &Self::Context) {
163 BNFreeDataVariablesAndName(raw, count)
164 }
165
166 unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, _context: &'a Self::Context) -> Self::Wrapped<'a> {
167 Self::from_raw(raw)
168 }
169}
170
171#[derive(Debug, Clone, Hash, PartialEq, Eq)]
172pub struct NamedVariableWithType {
173 pub variable: Variable,
174 pub ty: Conf<Ref<Type>>,
175 pub name: String,
176 pub auto_defined: bool,
177}
178
179impl NamedVariableWithType {
180 pub(crate) fn from_raw(value: &BNVariableNameAndType) -> Self {
181 Self {
182 variable: value.var.into(),
183 ty: Conf::new(
184 unsafe { Type::from_raw(value.type_) }.to_owned(),
185 value.typeConfidence,
186 ),
187 name: raw_to_string(value.name as *mut _).unwrap(),
189 auto_defined: value.autoDefined,
190 }
191 }
192
193 pub(crate) fn from_owned_raw(value: BNVariableNameAndType) -> Self {
194 let owned = Self::from_raw(&value);
195 Self::free_raw(value);
196 owned
197 }
198
199 pub(crate) fn into_raw(value: Self) -> BNVariableNameAndType {
200 let bn_name = BnString::new(value.name);
201 BNVariableNameAndType {
202 var: value.variable.into(),
203 type_: unsafe { Ref::into_raw(value.ty.contents) }.handle,
204 name: BnString::into_raw(bn_name),
205 autoDefined: value.auto_defined,
206 typeConfidence: value.ty.confidence,
207 }
208 }
209
210 pub(crate) fn free_raw(value: BNVariableNameAndType) {
211 let _ = unsafe { Type::ref_from_raw(value.type_) };
212 unsafe { BnString::free_raw(value.name) };
213 }
214
215 pub fn new(variable: Variable, ty: Conf<Ref<Type>>, name: String, auto_defined: bool) -> Self {
216 Self {
217 variable,
218 ty,
219 name,
220 auto_defined,
221 }
222 }
223}
224
225impl CoreArrayProvider for NamedVariableWithType {
226 type Raw = BNVariableNameAndType;
227 type Context = ();
228 type Wrapped<'a> = NamedVariableWithType;
229}
230
231unsafe impl CoreArrayProviderInner for NamedVariableWithType {
232 unsafe fn free(raw: *mut Self::Raw, count: usize, _context: &Self::Context) {
233 BNFreeVariableNameAndTypeList(raw, count)
234 }
235
236 unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, _context: &'a Self::Context) -> Self::Wrapped<'a> {
237 Self::from_raw(raw)
238 }
239}
240
241#[derive(Debug, Clone, PartialEq, Eq)]
242pub struct UserVariableValue {
243 pub variable: Variable,
244 pub def_site: Location,
245 pub after: bool,
246 pub value: PossibleValueSet,
247}
248
249impl UserVariableValue {
250 pub(crate) fn from_raw(value: &BNUserVariableValue) -> Self {
251 Self {
252 variable: value.var.into(),
253 def_site: value.defSite.into(),
254 after: value.after,
255 value: PossibleValueSet::from_raw(&value.value),
256 }
257 }
258
259 pub(crate) fn into_raw(value: Self) -> BNUserVariableValue {
260 BNUserVariableValue {
261 var: value.variable.into(),
262 defSite: value.def_site.into(),
263 after: value.after,
264 value: PossibleValueSet::into_rust_raw(value.value),
267 }
268 }
269}
270
271impl CoreArrayProvider for UserVariableValue {
272 type Raw = BNUserVariableValue;
273 type Context = ();
274 type Wrapped<'a> = Self;
275}
276
277unsafe impl CoreArrayProviderInner for UserVariableValue {
278 unsafe fn free(raw: *mut Self::Raw, _count: usize, _context: &Self::Context) {
279 BNFreeUserVariableValues(raw)
280 }
281
282 unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, _context: &'a Self::Context) -> Self::Wrapped<'a> {
283 UserVariableValue::from_raw(raw)
284 }
285}
286
287#[derive(Debug, Clone, Hash, PartialEq, Eq)]
288pub struct StackVariableReference {
289 source_operand: u32,
290 pub variable_type: Conf<Ref<Type>>,
291 pub name: String,
292 pub variable: Variable,
293 pub offset: i64,
294 pub size: usize,
295}
296
297impl StackVariableReference {
298 pub(crate) fn from_raw(value: &BNStackVariableReference) -> Self {
299 Self {
300 source_operand: value.sourceOperand,
301 variable_type: Conf::new(
302 unsafe { Type::from_raw(value.type_) }.to_owned(),
303 value.typeConfidence,
304 ),
305 name: raw_to_string(value.name).unwrap(),
307 variable: Variable::from_identifier(value.varIdentifier),
309 offset: value.referencedOffset,
310 size: value.size,
311 }
312 }
313
314 pub(crate) fn from_owned_raw(value: BNStackVariableReference) -> Self {
315 let owned = Self::from_raw(&value);
316 Self::free_raw(value);
317 owned
318 }
319
320 pub(crate) fn into_raw(value: Self) -> BNStackVariableReference {
321 let bn_name = BnString::new(value.name);
322 BNStackVariableReference {
323 sourceOperand: value.source_operand,
324 typeConfidence: value.variable_type.confidence,
325 type_: unsafe { Ref::into_raw(value.variable_type.contents) }.handle,
326 name: BnString::into_raw(bn_name),
327 varIdentifier: value.variable.to_identifier(),
328 referencedOffset: value.offset,
329 size: value.size,
330 }
331 }
332
333 pub(crate) fn free_raw(value: BNStackVariableReference) {
334 let _ = unsafe { Type::ref_from_raw(value.type_) };
335 unsafe { BnString::free_raw(value.name) };
336 }
337}
338
339impl CoreArrayProvider for StackVariableReference {
340 type Raw = BNStackVariableReference;
341 type Context = ();
342 type Wrapped<'a> = Self;
343}
344
345unsafe impl CoreArrayProviderInner for StackVariableReference {
346 unsafe fn free(raw: *mut Self::Raw, count: usize, _context: &Self::Context) {
347 BNFreeStackVariableReferenceList(raw, count)
348 }
349
350 unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, _context: &'a Self::Context) -> Self::Wrapped<'a> {
351 StackVariableReference::from_raw(raw)
352 }
353}
354
355#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq)]
356pub struct SSAVariable {
357 pub variable: Variable,
358 pub version: usize,
359}
360
361impl SSAVariable {
362 pub fn new(variable: Variable, version: usize) -> Self {
363 Self { variable, version }
364 }
365}
366
367impl CoreArrayProvider for SSAVariable {
368 type Raw = usize;
369 type Context = Variable;
370 type Wrapped<'a> = Self;
371}
372
373unsafe impl CoreArrayProviderInner for SSAVariable {
374 unsafe fn free(raw: *mut Self::Raw, _count: usize, _context: &Self::Context) {
375 BNFreeILInstructionList(raw)
376 }
377
378 unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, context: &'a Self::Context) -> Self::Wrapped<'a> {
379 SSAVariable::new(*context, *raw)
380 }
381}
382
383#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
388pub struct Variable {
389 pub ty: VariableSourceType,
390 pub index: u32,
392 pub storage: i64,
394}
395
396impl Variable {
397 pub fn new(ty: VariableSourceType, index: u32, storage: i64) -> Self {
398 Self { ty, index, storage }
399 }
400
401 pub fn from_identifier(ident: u64) -> Self {
405 unsafe { BNFromVariableIdentifier(ident) }.into()
406 }
407
408 pub fn to_identifier(&self) -> u64 {
409 let raw = BNVariable::from(*self);
410 unsafe { BNToVariableIdentifier(&raw) }
411 }
412
413 pub fn to_register(&self, arch: CoreArchitecture) -> Option<CoreRegister> {
414 match self.ty {
415 VariableSourceType::RegisterVariableSourceType => {
416 arch.register_from_id(RegisterId(self.storage as u32))
417 }
418 VariableSourceType::StackVariableSourceType => None,
419 VariableSourceType::FlagVariableSourceType => None,
420 }
421 }
422}
423
424impl From<BNVariable> for Variable {
425 fn from(value: BNVariable) -> Self {
426 Self {
427 ty: value.type_,
428 index: value.index,
429 storage: value.storage,
430 }
431 }
432}
433
434impl From<&BNVariable> for Variable {
435 fn from(value: &BNVariable) -> Self {
436 Self::from(*value)
437 }
438}
439
440impl From<Variable> for BNVariable {
441 fn from(value: Variable) -> Self {
442 Self {
443 type_: value.ty,
444 index: value.index,
445 storage: value.storage,
446 }
447 }
448}
449
450impl From<&Variable> for BNVariable {
451 fn from(value: &Variable) -> Self {
452 BNVariable::from(*value)
453 }
454}
455
456impl CoreArrayProvider for Variable {
457 type Raw = BNVariable;
458 type Context = ();
459 type Wrapped<'a> = Self;
460}
461
462unsafe impl CoreArrayProviderInner for Variable {
463 unsafe fn free(raw: *mut Self::Raw, _count: usize, _context: &Self::Context) {
464 BNFreeVariableList(raw)
465 }
466
467 unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, _context: &'a Self::Context) -> Self::Wrapped<'a> {
468 Variable::from(raw)
469 }
470}
471
472#[derive(Debug, Clone, Hash, PartialEq, Eq)]
473pub struct MergedVariable {
474 pub target: Variable,
475 pub sources: Vec<Variable>,
476}
477
478impl MergedVariable {
479 pub(crate) fn from_raw(value: &BNMergedVariable) -> Self {
480 let raw_sources = unsafe { std::slice::from_raw_parts(value.sources, value.sourceCount) };
481 Self {
482 target: value.target.into(),
483 sources: raw_sources.iter().map(Into::into).collect(),
484 }
485 }
486
487 }
489
490impl CoreArrayProvider for MergedVariable {
491 type Raw = BNMergedVariable;
492 type Context = ();
493 type Wrapped<'a> = Self;
494}
495
496unsafe impl CoreArrayProviderInner for MergedVariable {
497 unsafe fn free(raw: *mut Self::Raw, count: usize, _context: &Self::Context) {
498 BNFreeMergedVariableList(raw, count)
499 }
500
501 unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, _context: &'a Self::Context) -> Self::Wrapped<'a> {
502 Self::from_raw(raw)
503 }
504}
505
506#[derive(Clone, Debug, Hash, Eq, PartialEq)]
508pub struct ConstantData {
509 pub function: Ref<Function>,
511 pub value: RegisterValue,
512}
513
514impl ConstantData {
515 pub fn new(function: Ref<Function>, value: RegisterValue) -> Self {
516 Self { function, value }
517 }
518}
519
520#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq)]
521pub struct RegisterValue {
522 pub state: RegisterValueType,
523 pub value: i64,
525 pub offset: i64,
526 pub size: usize,
527}
528
529impl RegisterValue {
530 pub fn new(state: RegisterValueType, value: i64, offset: i64, size: usize) -> Self {
531 Self {
532 state,
533 value,
534 offset,
535 size,
536 }
537 }
538}
539
540impl From<BNRegisterValue> for RegisterValue {
541 fn from(value: BNRegisterValue) -> Self {
542 Self {
543 state: value.state,
544 value: value.value,
545 offset: value.offset,
546 size: value.size,
547 }
548 }
549}
550
551impl From<RegisterValue> for BNRegisterValue {
552 fn from(value: RegisterValue) -> Self {
553 Self {
554 state: value.state,
555 value: value.value,
556 offset: value.offset,
557 size: value.size,
558 }
559 }
560}
561
562#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
563pub struct ValueRange<T> {
564 pub start: T,
565 pub end: T,
566 pub step: u64,
567}
568
569impl From<BNValueRange> for ValueRange<u64> {
570 fn from(value: BNValueRange) -> Self {
571 Self {
572 start: value.start,
573 end: value.end,
574 step: value.step,
575 }
576 }
577}
578
579impl From<ValueRange<u64>> for BNValueRange {
580 fn from(value: ValueRange<u64>) -> Self {
581 Self {
582 start: value.start,
583 end: value.end,
584 step: value.step,
585 }
586 }
587}
588
589impl From<BNValueRange> for ValueRange<i64> {
590 fn from(value: BNValueRange) -> Self {
591 Self {
592 start: value.start as i64,
593 end: value.end as i64,
594 step: value.step,
595 }
596 }
597}
598
599impl From<ValueRange<i64>> for BNValueRange {
600 fn from(value: ValueRange<i64>) -> Self {
601 Self {
602 start: value.start as u64,
603 end: value.end as u64,
604 step: value.step,
605 }
606 }
607}
608
609#[derive(Clone, Debug, Eq, PartialEq)]
612pub struct LookupTableEntry {
613 pub from: HashSet<i64>,
615 pub to: i64,
617}
618
619impl LookupTableEntry {
620 pub(crate) fn from_raw(value: &BNLookupTableEntry) -> Self {
621 let from_values = unsafe { std::slice::from_raw_parts(value.fromValues, value.fromCount) };
622 Self {
623 from: HashSet::from_iter(from_values.iter().copied()),
625 to: value.toValue,
626 }
627 }
628
629 pub(crate) fn from_owned_raw(value: BNLookupTableEntry) -> Self {
630 let owned = Self::from_raw(&value);
631 Self::free_raw(value);
632 owned
633 }
634
635 pub(crate) fn into_raw(value: Self) -> BNLookupTableEntry {
636 let from_values: Box<[i64]> = value.from.into_iter().collect();
637 let from_values_len = from_values.len();
638 BNLookupTableEntry {
639 fromValues: Box::leak(from_values).as_mut_ptr(),
641 fromCount: from_values_len,
642 toValue: value.to,
643 }
644 }
645
646 pub(crate) fn free_raw(value: BNLookupTableEntry) {
647 let raw_from = unsafe { std::slice::from_raw_parts_mut(value.fromValues, value.fromCount) };
648 let boxed_from = unsafe { Box::from_raw(raw_from) };
649 }
650}
651
652#[derive(Debug, Clone, PartialEq, Eq)]
653pub enum PossibleValueSet {
654 UndeterminedValue,
655 EntryValue {
656 reg: i64,
659 },
660 ConstantValue {
661 value: i64,
664 },
665 ConstantPointerValue {
666 value: i64,
668 },
669 ExternalPointerValue {
670 value: i64,
672 offset: i64,
673 },
674 StackFrameOffset {
675 value: i64,
676 },
677 ReturnAddressValue,
678 ImportedAddressValue {
679 value: i64,
680 },
681 SignedRangeValue {
682 value: i64,
683 ranges: Vec<ValueRange<i64>>,
684 },
685 UnsignedRangeValue {
686 value: i64,
687 ranges: Vec<ValueRange<u64>>,
688 },
689 LookupTableValue {
690 table: Vec<LookupTableEntry>,
691 },
692 InSetOfValues {
693 values: HashSet<i64>,
694 },
695 NotInSetOfValues {
696 values: HashSet<i64>,
697 },
698 ConstantDataValue {
700 value: i64,
701 size: usize,
702 },
703 ConstantDataZeroExtendValue {
704 value: i64,
706 size: usize,
707 },
708 ConstantDataSignExtendValue {
709 value: i64,
710 size: usize,
711 },
712 ConstantDataAggregateValue {
713 value: i64,
715 size: usize,
716 },
717}
718
719impl PossibleValueSet {
720 pub(crate) fn from_raw(value: &BNPossibleValueSet) -> Self {
721 match value.state {
722 RegisterValueType::UndeterminedValue => Self::UndeterminedValue,
723 RegisterValueType::EntryValue => Self::EntryValue { reg: value.value },
724 RegisterValueType::ConstantValue => Self::ConstantValue { value: value.value },
725 RegisterValueType::ConstantPointerValue => {
726 Self::ConstantPointerValue { value: value.value }
727 }
728 RegisterValueType::ExternalPointerValue => Self::ExternalPointerValue {
729 value: value.value,
730 offset: value.offset,
731 },
732 RegisterValueType::StackFrameOffset => Self::StackFrameOffset { value: value.value },
733 RegisterValueType::ReturnAddressValue => Self::ReturnAddressValue,
734 RegisterValueType::ImportedAddressValue => {
735 Self::ImportedAddressValue { value: value.value }
736 }
737 RegisterValueType::SignedRangeValue => {
738 let raw_ranges = unsafe { std::slice::from_raw_parts(value.ranges, value.count) };
739 Self::SignedRangeValue {
740 value: value.value,
741 ranges: raw_ranges.iter().map(|&r| r.into()).collect(),
742 }
743 }
744 RegisterValueType::UnsignedRangeValue => {
745 let raw_ranges = unsafe { std::slice::from_raw_parts(value.ranges, value.count) };
746 Self::UnsignedRangeValue {
747 value: value.value,
748 ranges: raw_ranges.iter().map(|&r| r.into()).collect(),
749 }
750 }
751 RegisterValueType::LookupTableValue => {
752 let raw_entries = unsafe { std::slice::from_raw_parts(value.table, value.count) };
753 Self::LookupTableValue {
754 table: raw_entries.iter().map(LookupTableEntry::from_raw).collect(),
755 }
756 }
757 RegisterValueType::InSetOfValues => {
758 let raw_values = unsafe { std::slice::from_raw_parts(value.valueSet, value.count) };
759 Self::InSetOfValues {
760 values: raw_values.iter().copied().collect(),
761 }
762 }
763 RegisterValueType::NotInSetOfValues => {
764 let raw_values = unsafe { std::slice::from_raw_parts(value.valueSet, value.count) };
765 Self::NotInSetOfValues {
766 values: raw_values.iter().copied().collect(),
767 }
768 }
769 RegisterValueType::ConstantDataValue => Self::ConstantDataValue {
770 value: value.value,
771 size: value.size,
772 },
773 RegisterValueType::ConstantDataZeroExtendValue => Self::ConstantDataZeroExtendValue {
774 value: value.value,
775 size: value.size,
776 },
777 RegisterValueType::ConstantDataSignExtendValue => Self::ConstantDataSignExtendValue {
778 value: value.value,
779 size: value.size,
780 },
781 RegisterValueType::ConstantDataAggregateValue => Self::ConstantDataAggregateValue {
782 value: value.value,
783 size: value.size,
784 },
785 }
786 }
787
788 pub(crate) fn from_owned_core_raw(mut value: BNPossibleValueSet) -> Self {
790 let owned = Self::from_raw(&value);
791 Self::free_core_raw(&mut value);
792 owned
793 }
794
795 pub(crate) fn into_rust_raw(value: Self) -> BNPossibleValueSet {
796 let mut raw = BNPossibleValueSet {
797 state: value.value_type(),
798 ..Default::default()
799 };
800 match value {
801 PossibleValueSet::UndeterminedValue => {}
802 PossibleValueSet::EntryValue { reg } => {
803 raw.value = reg;
804 }
805 PossibleValueSet::ConstantValue { value } => {
806 raw.value = value;
807 }
808 PossibleValueSet::ConstantPointerValue { value } => {
809 raw.value = value;
810 }
811 PossibleValueSet::ExternalPointerValue { value, offset } => {
812 raw.value = value;
813 raw.offset = offset;
814 }
815 PossibleValueSet::StackFrameOffset { value } => {
816 raw.value = value;
817 }
818 PossibleValueSet::ReturnAddressValue => {}
819 PossibleValueSet::ImportedAddressValue { value } => {
820 raw.value = value;
821 }
822 PossibleValueSet::SignedRangeValue { value, ranges } => {
823 let boxed_raw_ranges: Box<[BNValueRange]> =
824 ranges.into_iter().map(BNValueRange::from).collect();
825 raw.value = value;
826 raw.count = boxed_raw_ranges.len();
827 raw.ranges = Box::leak(boxed_raw_ranges).as_mut_ptr();
829 }
830 PossibleValueSet::UnsignedRangeValue { value, ranges } => {
831 let boxed_raw_ranges: Box<[BNValueRange]> =
832 ranges.into_iter().map(BNValueRange::from).collect();
833 raw.value = value;
834 raw.count = boxed_raw_ranges.len();
835 raw.ranges = Box::leak(boxed_raw_ranges).as_mut_ptr();
837 }
838 PossibleValueSet::LookupTableValue { table } => {
839 let boxed_raw_entries: Box<[BNLookupTableEntry]> =
840 table.into_iter().map(LookupTableEntry::into_raw).collect();
841 raw.count = boxed_raw_entries.len();
842 raw.table = Box::leak(boxed_raw_entries).as_mut_ptr();
844 }
845 PossibleValueSet::InSetOfValues { values } => {
846 let boxed_raw_values: Box<[i64]> = values.into_iter().collect();
847 raw.count = boxed_raw_values.len();
848 raw.valueSet = Box::leak(boxed_raw_values).as_mut_ptr();
850 }
851 PossibleValueSet::NotInSetOfValues { values } => {
852 let boxed_raw_values: Box<[i64]> = values.into_iter().collect();
853 raw.count = boxed_raw_values.len();
854 raw.valueSet = Box::leak(boxed_raw_values).as_mut_ptr();
856 }
857 PossibleValueSet::ConstantDataValue { value, size } => {
858 raw.value = value;
859 raw.size = size;
860 }
861 PossibleValueSet::ConstantDataZeroExtendValue { value, size } => {
862 raw.value = value;
863 raw.size = size;
864 }
865 PossibleValueSet::ConstantDataSignExtendValue { value, size } => {
866 raw.value = value;
867 raw.size = size;
868 }
869 PossibleValueSet::ConstantDataAggregateValue { value, size } => {
870 raw.value = value;
871 raw.size = size;
872 }
873 };
874 raw
875 }
876
877 pub(crate) fn free_core_raw(value: &mut BNPossibleValueSet) {
879 unsafe { BNFreePossibleValueSet(value) }
880 }
881
882 pub(crate) fn free_rust_raw(value: BNPossibleValueSet) {
884 if !value.ranges.is_null() {
886 let raw_ranges = unsafe { std::slice::from_raw_parts_mut(value.ranges, value.count) };
887 let boxed_ranges = unsafe { Box::from_raw(raw_ranges) };
888 }
889
890 if !value.table.is_null() {
891 unsafe { LookupTableEntry::free_raw(*value.table) };
892 }
893
894 if !value.valueSet.is_null() {
895 let raw_value_set =
896 unsafe { std::slice::from_raw_parts_mut(value.valueSet, value.count) };
897 let boxed_value_set = unsafe { Box::from_raw(raw_value_set) };
898 }
899 }
900
901 pub fn value_type(&self) -> RegisterValueType {
902 match self {
903 PossibleValueSet::UndeterminedValue => RegisterValueType::UndeterminedValue,
904 PossibleValueSet::EntryValue { .. } => RegisterValueType::EntryValue,
905 PossibleValueSet::ConstantValue { .. } => RegisterValueType::ConstantValue,
906 PossibleValueSet::ConstantPointerValue { .. } => {
907 RegisterValueType::ConstantPointerValue
908 }
909 PossibleValueSet::ExternalPointerValue { .. } => {
910 RegisterValueType::ExternalPointerValue
911 }
912 PossibleValueSet::StackFrameOffset { .. } => RegisterValueType::StackFrameOffset,
913 PossibleValueSet::ReturnAddressValue => RegisterValueType::ReturnAddressValue,
914 PossibleValueSet::ImportedAddressValue { .. } => {
915 RegisterValueType::ImportedAddressValue
916 }
917 PossibleValueSet::SignedRangeValue { .. } => RegisterValueType::SignedRangeValue,
918 PossibleValueSet::UnsignedRangeValue { .. } => RegisterValueType::UnsignedRangeValue,
919 PossibleValueSet::LookupTableValue { .. } => RegisterValueType::LookupTableValue,
920 PossibleValueSet::InSetOfValues { .. } => RegisterValueType::InSetOfValues,
921 PossibleValueSet::NotInSetOfValues { .. } => RegisterValueType::NotInSetOfValues,
922 PossibleValueSet::ConstantDataValue { .. } => RegisterValueType::ConstantDataValue,
923 PossibleValueSet::ConstantDataZeroExtendValue { .. } => {
924 RegisterValueType::ConstantDataZeroExtendValue
925 }
926 PossibleValueSet::ConstantDataSignExtendValue { .. } => {
927 RegisterValueType::ConstantDataSignExtendValue
928 }
929 PossibleValueSet::ConstantDataAggregateValue { .. } => {
930 RegisterValueType::ConstantDataAggregateValue
931 }
932 }
933 }
934
935 pub fn add(&self, other: &PossibleValueSet, size: usize) -> PossibleValueSet {
936 let raw_value = PossibleValueSet::into_rust_raw(self.clone());
937 let raw_other = PossibleValueSet::into_rust_raw(other.clone());
938 let result;
939 unsafe { result = BNPossibleValueSetAdd(&raw_value, &raw_other, size) }
940 PossibleValueSet::free_rust_raw(raw_value);
941 PossibleValueSet::free_rust_raw(raw_other);
942 PossibleValueSet::from_owned_core_raw(result)
943 }
944
945 pub fn subtract(&self, other: &PossibleValueSet, size: usize) -> PossibleValueSet {
946 let raw_value = PossibleValueSet::into_rust_raw(self.clone());
947 let raw_other = PossibleValueSet::into_rust_raw(other.clone());
948 let result;
949 unsafe { result = BNPossibleValueSetSubtract(&raw_value, &raw_other, size) }
950 PossibleValueSet::free_rust_raw(raw_value);
951 PossibleValueSet::free_rust_raw(raw_other);
952 PossibleValueSet::from_owned_core_raw(result)
953 }
954
955 pub fn multiply(&self, other: &PossibleValueSet, size: usize) -> PossibleValueSet {
956 let raw_value = PossibleValueSet::into_rust_raw(self.clone());
957 let raw_other = PossibleValueSet::into_rust_raw(other.clone());
958 let result;
959 unsafe { result = BNPossibleValueSetMultiply(&raw_value, &raw_other, size) }
960 PossibleValueSet::free_rust_raw(raw_value);
961 PossibleValueSet::free_rust_raw(raw_other);
962 PossibleValueSet::from_owned_core_raw(result)
963 }
964
965 pub fn signed_divide(&self, other: &PossibleValueSet, size: usize) -> PossibleValueSet {
966 let raw_value = PossibleValueSet::into_rust_raw(self.clone());
967 let raw_other = PossibleValueSet::into_rust_raw(other.clone());
968 let result;
969 unsafe { result = BNPossibleValueSetSignedDivide(&raw_value, &raw_other, size) }
970 PossibleValueSet::free_rust_raw(raw_value);
971 PossibleValueSet::free_rust_raw(raw_other);
972 PossibleValueSet::from_owned_core_raw(result)
973 }
974
975 pub fn unsigned_divide(&self, other: &PossibleValueSet, size: usize) -> PossibleValueSet {
976 let raw_value = PossibleValueSet::into_rust_raw(self.clone());
977 let raw_other = PossibleValueSet::into_rust_raw(other.clone());
978 let result;
979 unsafe { result = BNPossibleValueSetUnsignedDivide(&raw_value, &raw_other, size) }
980 PossibleValueSet::free_rust_raw(raw_value);
981 PossibleValueSet::free_rust_raw(raw_other);
982 PossibleValueSet::from_owned_core_raw(result)
983 }
984
985 pub fn signed_mod(&self, other: &PossibleValueSet, size: usize) -> PossibleValueSet {
986 let raw_value = PossibleValueSet::into_rust_raw(self.clone());
987 let raw_other = PossibleValueSet::into_rust_raw(other.clone());
988 let result;
989 unsafe { result = BNPossibleValueSetSignedMod(&raw_value, &raw_other, size) }
990 PossibleValueSet::free_rust_raw(raw_value);
991 PossibleValueSet::free_rust_raw(raw_other);
992 PossibleValueSet::from_owned_core_raw(result)
993 }
994
995 pub fn unsigned_mod(&self, other: &PossibleValueSet, size: usize) -> PossibleValueSet {
996 let raw_value = PossibleValueSet::into_rust_raw(self.clone());
997 let raw_other = PossibleValueSet::into_rust_raw(other.clone());
998 let result;
999 unsafe { result = BNPossibleValueSetUnsignedMod(&raw_value, &raw_other, size) }
1000 PossibleValueSet::free_rust_raw(raw_value);
1001 PossibleValueSet::free_rust_raw(raw_other);
1002 PossibleValueSet::from_owned_core_raw(result)
1003 }
1004
1005 pub fn and(&self, other: &PossibleValueSet, size: usize) -> PossibleValueSet {
1006 let raw_value = PossibleValueSet::into_rust_raw(self.clone());
1007 let raw_other = PossibleValueSet::into_rust_raw(other.clone());
1008 let result;
1009 unsafe { result = BNPossibleValueSetAnd(&raw_value, &raw_other, size) }
1010 PossibleValueSet::free_rust_raw(raw_value);
1011 PossibleValueSet::free_rust_raw(raw_other);
1012 PossibleValueSet::from_owned_core_raw(result)
1013 }
1014
1015 pub fn or(&self, other: &PossibleValueSet, size: usize) -> PossibleValueSet {
1016 let raw_value = PossibleValueSet::into_rust_raw(self.clone());
1017 let raw_other = PossibleValueSet::into_rust_raw(other.clone());
1018 let result;
1019 unsafe { result = BNPossibleValueSetOr(&raw_value, &raw_other, size) }
1020 PossibleValueSet::free_rust_raw(raw_value);
1021 PossibleValueSet::free_rust_raw(raw_other);
1022 PossibleValueSet::from_owned_core_raw(result)
1023 }
1024
1025 pub fn xor(&self, other: &PossibleValueSet, size: usize) -> PossibleValueSet {
1026 let raw_value = PossibleValueSet::into_rust_raw(self.clone());
1027 let raw_other = PossibleValueSet::into_rust_raw(other.clone());
1028 let result;
1029 unsafe { result = BNPossibleValueSetXor(&raw_value, &raw_other, size) }
1030 PossibleValueSet::free_rust_raw(raw_value);
1031 PossibleValueSet::free_rust_raw(raw_other);
1032 PossibleValueSet::from_owned_core_raw(result)
1033 }
1034
1035 pub fn shift_left(&self, other: &PossibleValueSet, size: usize) -> PossibleValueSet {
1036 let raw_value = PossibleValueSet::into_rust_raw(self.clone());
1037 let raw_other = PossibleValueSet::into_rust_raw(other.clone());
1038 let result;
1039 unsafe { result = BNPossibleValueSetShiftLeft(&raw_value, &raw_other, size) }
1040 PossibleValueSet::free_rust_raw(raw_value);
1041 PossibleValueSet::free_rust_raw(raw_other);
1042 PossibleValueSet::from_owned_core_raw(result)
1043 }
1044
1045 pub fn logical_shift_right(&self, other: &PossibleValueSet, size: usize) -> PossibleValueSet {
1046 let raw_value = PossibleValueSet::into_rust_raw(self.clone());
1047 let raw_other = PossibleValueSet::into_rust_raw(other.clone());
1048 let result;
1049 unsafe { result = BNPossibleValueSetLogicalShiftRight(&raw_value, &raw_other, size) }
1050 PossibleValueSet::free_rust_raw(raw_value);
1051 PossibleValueSet::free_rust_raw(raw_other);
1052 PossibleValueSet::from_owned_core_raw(result)
1053 }
1054
1055 pub fn arith_shift_right(&self, other: &PossibleValueSet, size: usize) -> PossibleValueSet {
1056 let raw_value = PossibleValueSet::into_rust_raw(self.clone());
1057 let raw_other = PossibleValueSet::into_rust_raw(other.clone());
1058 let result;
1059 unsafe { result = BNPossibleValueSetArithShiftRight(&raw_value, &raw_other, size) }
1060 PossibleValueSet::free_rust_raw(raw_value);
1061 PossibleValueSet::free_rust_raw(raw_other);
1062 PossibleValueSet::from_owned_core_raw(result)
1063 }
1064
1065 pub fn rotate_left(&self, other: &PossibleValueSet, size: usize) -> PossibleValueSet {
1066 let raw_value = PossibleValueSet::into_rust_raw(self.clone());
1067 let raw_other = PossibleValueSet::into_rust_raw(other.clone());
1068 let result;
1069 unsafe { result = BNPossibleValueSetRotateLeft(&raw_value, &raw_other, size) }
1070 PossibleValueSet::free_rust_raw(raw_value);
1071 PossibleValueSet::free_rust_raw(raw_other);
1072 PossibleValueSet::from_owned_core_raw(result)
1073 }
1074
1075 pub fn rotate_right(&self, other: &PossibleValueSet, size: usize) -> PossibleValueSet {
1076 let raw_value = PossibleValueSet::into_rust_raw(self.clone());
1077 let raw_other = PossibleValueSet::into_rust_raw(other.clone());
1078 let result;
1079 unsafe { result = BNPossibleValueSetRotateRight(&raw_value, &raw_other, size) }
1080 PossibleValueSet::free_rust_raw(raw_value);
1081 PossibleValueSet::free_rust_raw(raw_other);
1082 PossibleValueSet::from_owned_core_raw(result)
1083 }
1084
1085 pub fn union(&self, other: &PossibleValueSet, size: usize) -> PossibleValueSet {
1086 let raw_value = PossibleValueSet::into_rust_raw(self.clone());
1087 let raw_other = PossibleValueSet::into_rust_raw(other.clone());
1088 let result;
1089 unsafe { result = BNPossibleValueSetUnion(&raw_value, &raw_other, size) }
1090 PossibleValueSet::free_rust_raw(raw_value);
1091 PossibleValueSet::free_rust_raw(raw_other);
1092 PossibleValueSet::from_owned_core_raw(result)
1093 }
1094
1095 pub fn intersection(&self, other: &PossibleValueSet, size: usize) -> PossibleValueSet {
1096 let raw_value = PossibleValueSet::into_rust_raw(self.clone());
1097 let raw_other = PossibleValueSet::into_rust_raw(other.clone());
1098 let result;
1099 unsafe { result = BNPossibleValueSetIntersection(&raw_value, &raw_other, size) }
1100 PossibleValueSet::free_rust_raw(raw_value);
1101 PossibleValueSet::free_rust_raw(raw_other);
1102 PossibleValueSet::from_owned_core_raw(result)
1103 }
1104
1105 pub fn negate(&self, size: usize) -> PossibleValueSet {
1106 let raw_value = PossibleValueSet::into_rust_raw(self.clone());
1107 let result;
1108 unsafe { result = BNPossibleValueSetNegate(&raw_value, size) }
1109 PossibleValueSet::free_rust_raw(raw_value);
1110 PossibleValueSet::from_owned_core_raw(result)
1111 }
1112
1113 pub fn not(&self, size: usize) -> PossibleValueSet {
1114 let raw_value = PossibleValueSet::into_rust_raw(self.clone());
1115 let result;
1116 unsafe { result = BNPossibleValueSetNot(&raw_value, size) }
1117 PossibleValueSet::free_rust_raw(raw_value);
1118 PossibleValueSet::from_owned_core_raw(result)
1119 }
1120}