1#![allow(unused)]
2
3use crate::architecture::{Architecture, CoreArchitecture, CoreRegister, Register, 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 from_register(reg: impl Register) -> Self {
409 Self {
410 ty: VariableSourceType::RegisterVariableSourceType,
411 index: 0,
412 storage: reg.id().0 as i64,
413 }
414 }
415
416 pub fn from_register_id(reg: RegisterId) -> Self {
417 Self {
418 ty: VariableSourceType::RegisterVariableSourceType,
419 index: 0,
420 storage: reg.0 as i64,
421 }
422 }
423
424 pub fn from_stack_offset(offset: i64) -> Self {
425 Self {
426 ty: VariableSourceType::StackVariableSourceType,
427 index: 0,
428 storage: offset,
429 }
430 }
431
432 pub fn to_identifier(&self) -> u64 {
433 let raw = BNVariable::from(*self);
434 unsafe { BNToVariableIdentifier(&raw) }
435 }
436
437 pub fn to_register(&self, arch: CoreArchitecture) -> Option<CoreRegister> {
438 match self.ty {
439 VariableSourceType::RegisterVariableSourceType => {
440 arch.register_from_id(RegisterId(self.storage as u32))
441 }
442 VariableSourceType::StackVariableSourceType => None,
443 VariableSourceType::FlagVariableSourceType => None,
444 VariableSourceType::CompositeReturnValueSourceType => None,
445 VariableSourceType::CompositeParameterSourceType => None,
446 }
447 }
448}
449
450impl From<BNVariable> for Variable {
451 fn from(value: BNVariable) -> Self {
452 Self {
453 ty: value.type_,
454 index: value.index,
455 storage: value.storage,
456 }
457 }
458}
459
460impl From<&BNVariable> for Variable {
461 fn from(value: &BNVariable) -> Self {
462 Self::from(*value)
463 }
464}
465
466impl From<Variable> for BNVariable {
467 fn from(value: Variable) -> Self {
468 Self {
469 type_: value.ty,
470 index: value.index,
471 storage: value.storage,
472 }
473 }
474}
475
476impl From<&Variable> for BNVariable {
477 fn from(value: &Variable) -> Self {
478 BNVariable::from(*value)
479 }
480}
481
482impl CoreArrayProvider for Variable {
483 type Raw = BNVariable;
484 type Context = ();
485 type Wrapped<'a> = Self;
486}
487
488unsafe impl CoreArrayProviderInner for Variable {
489 unsafe fn free(raw: *mut Self::Raw, _count: usize, _context: &Self::Context) {
490 BNFreeVariableList(raw)
491 }
492
493 unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, _context: &'a Self::Context) -> Self::Wrapped<'a> {
494 Variable::from(raw)
495 }
496}
497
498#[derive(Debug, Clone, Hash, PartialEq, Eq)]
499pub struct MergedVariable {
500 pub target: Variable,
501 pub sources: Vec<Variable>,
502}
503
504impl MergedVariable {
505 pub(crate) fn from_raw(value: &BNMergedVariable) -> Self {
506 let raw_sources = unsafe { std::slice::from_raw_parts(value.sources, value.sourceCount) };
507 Self {
508 target: value.target.into(),
509 sources: raw_sources.iter().map(Into::into).collect(),
510 }
511 }
512
513 }
515
516impl CoreArrayProvider for MergedVariable {
517 type Raw = BNMergedVariable;
518 type Context = ();
519 type Wrapped<'a> = Self;
520}
521
522unsafe impl CoreArrayProviderInner for MergedVariable {
523 unsafe fn free(raw: *mut Self::Raw, count: usize, _context: &Self::Context) {
524 BNFreeMergedVariableList(raw, count)
525 }
526
527 unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, _context: &'a Self::Context) -> Self::Wrapped<'a> {
528 Self::from_raw(raw)
529 }
530}
531
532#[derive(Clone, Debug, Hash, Eq, PartialEq)]
534pub struct ConstantData {
535 pub function: Ref<Function>,
537 pub value: RegisterValue,
538}
539
540impl ConstantData {
541 pub fn new(function: Ref<Function>, value: RegisterValue) -> Self {
542 Self { function, value }
543 }
544}
545
546#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq)]
547pub struct RegisterValue {
548 pub state: RegisterValueType,
549 pub value: i64,
551 pub offset: i64,
552 pub size: usize,
553}
554
555impl RegisterValue {
556 pub fn new(state: RegisterValueType, value: i64, offset: i64, size: usize) -> Self {
557 Self {
558 state,
559 value,
560 offset,
561 size,
562 }
563 }
564}
565
566impl From<BNRegisterValue> for RegisterValue {
567 fn from(value: BNRegisterValue) -> Self {
568 Self {
569 state: value.state,
570 value: value.value,
571 offset: value.offset,
572 size: value.size,
573 }
574 }
575}
576
577impl From<RegisterValue> for BNRegisterValue {
578 fn from(value: RegisterValue) -> Self {
579 Self {
580 state: value.state,
581 value: value.value,
582 offset: value.offset,
583 size: value.size,
584 }
585 }
586}
587
588#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
589pub struct ValueRange<T> {
590 pub start: T,
591 pub end: T,
592 pub step: u64,
593}
594
595impl From<BNValueRange> for ValueRange<u64> {
596 fn from(value: BNValueRange) -> Self {
597 Self {
598 start: value.start,
599 end: value.end,
600 step: value.step,
601 }
602 }
603}
604
605impl From<ValueRange<u64>> for BNValueRange {
606 fn from(value: ValueRange<u64>) -> Self {
607 Self {
608 start: value.start,
609 end: value.end,
610 step: value.step,
611 }
612 }
613}
614
615impl From<BNValueRange> for ValueRange<i64> {
616 fn from(value: BNValueRange) -> Self {
617 Self {
618 start: value.start as i64,
619 end: value.end as i64,
620 step: value.step,
621 }
622 }
623}
624
625impl From<ValueRange<i64>> for BNValueRange {
626 fn from(value: ValueRange<i64>) -> Self {
627 Self {
628 start: value.start as u64,
629 end: value.end as u64,
630 step: value.step,
631 }
632 }
633}
634
635#[derive(Clone, Debug, Eq, PartialEq)]
638pub struct LookupTableEntry {
639 pub from: HashSet<i64>,
641 pub to: i64,
643}
644
645impl LookupTableEntry {
646 pub(crate) fn from_raw(value: &BNLookupTableEntry) -> Self {
647 let from_values = unsafe { std::slice::from_raw_parts(value.fromValues, value.fromCount) };
648 Self {
649 from: HashSet::from_iter(from_values.iter().copied()),
651 to: value.toValue,
652 }
653 }
654
655 pub(crate) fn from_owned_raw(value: BNLookupTableEntry) -> Self {
656 let owned = Self::from_raw(&value);
657 Self::free_raw(value);
658 owned
659 }
660
661 pub(crate) fn into_raw(value: Self) -> BNLookupTableEntry {
662 let from_values: Box<[i64]> = value.from.into_iter().collect();
663 let from_values_len = from_values.len();
664 BNLookupTableEntry {
665 fromValues: Box::leak(from_values).as_mut_ptr(),
667 fromCount: from_values_len,
668 toValue: value.to,
669 }
670 }
671
672 pub(crate) fn free_raw(value: BNLookupTableEntry) {
673 let raw_from = unsafe { std::slice::from_raw_parts_mut(value.fromValues, value.fromCount) };
674 let boxed_from = unsafe { Box::from_raw(raw_from) };
675 }
676}
677
678#[derive(Debug, Clone, PartialEq, Eq)]
679pub enum PossibleValueSet {
680 UndeterminedValue,
681 EntryValue {
682 reg: i64,
685 },
686 ConstantValue {
687 value: i64,
690 },
691 ConstantPointerValue {
692 value: i64,
694 },
695 ExternalPointerValue {
696 value: i64,
698 offset: i64,
699 },
700 StackFrameOffset {
701 value: i64,
702 },
703 ResultPointer {
704 offset: i64,
705 },
706 ParameterPointer {
707 index: u64,
708 offset: i64,
709 },
710 ReturnAddressValue,
711 ImportedAddressValue {
712 value: i64,
713 },
714 SignedRangeValue {
715 value: i64,
716 ranges: Vec<ValueRange<i64>>,
717 },
718 UnsignedRangeValue {
719 value: i64,
720 ranges: Vec<ValueRange<u64>>,
721 },
722 LookupTableValue {
723 table: Vec<LookupTableEntry>,
724 },
725 InSetOfValues {
726 values: HashSet<i64>,
727 },
728 NotInSetOfValues {
729 values: HashSet<i64>,
730 },
731 ConstantDataValue {
733 value: i64,
734 size: usize,
735 },
736 ConstantDataZeroExtendValue {
737 value: i64,
739 size: usize,
740 },
741 ConstantDataSignExtendValue {
742 value: i64,
743 size: usize,
744 },
745 ConstantDataAggregateValue {
746 value: i64,
748 size: usize,
749 },
750}
751
752impl PossibleValueSet {
753 pub(crate) fn from_raw(value: &BNPossibleValueSet) -> Self {
754 match value.state {
755 RegisterValueType::UndeterminedValue => Self::UndeterminedValue,
756 RegisterValueType::EntryValue => Self::EntryValue { reg: value.value },
757 RegisterValueType::ConstantValue => Self::ConstantValue { value: value.value },
758 RegisterValueType::ConstantPointerValue => {
759 Self::ConstantPointerValue { value: value.value }
760 }
761 RegisterValueType::ExternalPointerValue => Self::ExternalPointerValue {
762 value: value.value,
763 offset: value.offset,
764 },
765 RegisterValueType::StackFrameOffset => Self::StackFrameOffset { value: value.value },
766 RegisterValueType::ResultPointerValue => Self::ResultPointer {
767 offset: value.value,
768 },
769 RegisterValueType::ParameterPointerValue => Self::ParameterPointer {
770 index: value.value as u64,
771 offset: value.offset,
772 },
773 RegisterValueType::ReturnAddressValue => Self::ReturnAddressValue,
774 RegisterValueType::ImportedAddressValue => {
775 Self::ImportedAddressValue { value: value.value }
776 }
777 RegisterValueType::SignedRangeValue => {
778 let raw_ranges = unsafe { std::slice::from_raw_parts(value.ranges, value.count) };
779 Self::SignedRangeValue {
780 value: value.value,
781 ranges: raw_ranges.iter().map(|&r| r.into()).collect(),
782 }
783 }
784 RegisterValueType::UnsignedRangeValue => {
785 let raw_ranges = unsafe { std::slice::from_raw_parts(value.ranges, value.count) };
786 Self::UnsignedRangeValue {
787 value: value.value,
788 ranges: raw_ranges.iter().map(|&r| r.into()).collect(),
789 }
790 }
791 RegisterValueType::LookupTableValue => {
792 let raw_entries = unsafe { std::slice::from_raw_parts(value.table, value.count) };
793 Self::LookupTableValue {
794 table: raw_entries.iter().map(LookupTableEntry::from_raw).collect(),
795 }
796 }
797 RegisterValueType::InSetOfValues => {
798 let raw_values = unsafe { std::slice::from_raw_parts(value.valueSet, value.count) };
799 Self::InSetOfValues {
800 values: raw_values.iter().copied().collect(),
801 }
802 }
803 RegisterValueType::NotInSetOfValues => {
804 let raw_values = unsafe { std::slice::from_raw_parts(value.valueSet, value.count) };
805 Self::NotInSetOfValues {
806 values: raw_values.iter().copied().collect(),
807 }
808 }
809 RegisterValueType::ConstantDataValue => Self::ConstantDataValue {
810 value: value.value,
811 size: value.size,
812 },
813 RegisterValueType::ConstantDataZeroExtendValue => Self::ConstantDataZeroExtendValue {
814 value: value.value,
815 size: value.size,
816 },
817 RegisterValueType::ConstantDataSignExtendValue => Self::ConstantDataSignExtendValue {
818 value: value.value,
819 size: value.size,
820 },
821 RegisterValueType::ConstantDataAggregateValue => Self::ConstantDataAggregateValue {
822 value: value.value,
823 size: value.size,
824 },
825 }
826 }
827
828 pub(crate) fn from_owned_core_raw(mut value: BNPossibleValueSet) -> Self {
830 let owned = Self::from_raw(&value);
831 Self::free_core_raw(&mut value);
832 owned
833 }
834
835 pub(crate) fn into_rust_raw(value: Self) -> BNPossibleValueSet {
836 let mut raw = BNPossibleValueSet {
837 state: value.value_type(),
838 ..Default::default()
839 };
840 match value {
841 PossibleValueSet::UndeterminedValue => {}
842 PossibleValueSet::EntryValue { reg } => {
843 raw.value = reg;
844 }
845 PossibleValueSet::ConstantValue { value } => {
846 raw.value = value;
847 }
848 PossibleValueSet::ConstantPointerValue { value } => {
849 raw.value = value;
850 }
851 PossibleValueSet::ExternalPointerValue { value, offset } => {
852 raw.value = value;
853 raw.offset = offset;
854 }
855 PossibleValueSet::StackFrameOffset { value } => {
856 raw.value = value;
857 }
858 PossibleValueSet::ResultPointer { offset } => {
859 raw.value = offset;
860 }
861 PossibleValueSet::ParameterPointer { index, offset } => {
862 raw.value = index as i64;
863 raw.offset = offset;
864 }
865 PossibleValueSet::ReturnAddressValue => {}
866 PossibleValueSet::ImportedAddressValue { value } => {
867 raw.value = value;
868 }
869 PossibleValueSet::SignedRangeValue { value, ranges } => {
870 let boxed_raw_ranges: Box<[BNValueRange]> =
871 ranges.into_iter().map(BNValueRange::from).collect();
872 raw.value = value;
873 raw.count = boxed_raw_ranges.len();
874 raw.ranges = Box::leak(boxed_raw_ranges).as_mut_ptr();
876 }
877 PossibleValueSet::UnsignedRangeValue { value, ranges } => {
878 let boxed_raw_ranges: Box<[BNValueRange]> =
879 ranges.into_iter().map(BNValueRange::from).collect();
880 raw.value = value;
881 raw.count = boxed_raw_ranges.len();
882 raw.ranges = Box::leak(boxed_raw_ranges).as_mut_ptr();
884 }
885 PossibleValueSet::LookupTableValue { table } => {
886 let boxed_raw_entries: Box<[BNLookupTableEntry]> =
887 table.into_iter().map(LookupTableEntry::into_raw).collect();
888 raw.count = boxed_raw_entries.len();
889 raw.table = Box::leak(boxed_raw_entries).as_mut_ptr();
891 }
892 PossibleValueSet::InSetOfValues { values } => {
893 let boxed_raw_values: Box<[i64]> = values.into_iter().collect();
894 raw.count = boxed_raw_values.len();
895 raw.valueSet = Box::leak(boxed_raw_values).as_mut_ptr();
897 }
898 PossibleValueSet::NotInSetOfValues { values } => {
899 let boxed_raw_values: Box<[i64]> = values.into_iter().collect();
900 raw.count = boxed_raw_values.len();
901 raw.valueSet = Box::leak(boxed_raw_values).as_mut_ptr();
903 }
904 PossibleValueSet::ConstantDataValue { value, size } => {
905 raw.value = value;
906 raw.size = size;
907 }
908 PossibleValueSet::ConstantDataZeroExtendValue { value, size } => {
909 raw.value = value;
910 raw.size = size;
911 }
912 PossibleValueSet::ConstantDataSignExtendValue { value, size } => {
913 raw.value = value;
914 raw.size = size;
915 }
916 PossibleValueSet::ConstantDataAggregateValue { value, size } => {
917 raw.value = value;
918 raw.size = size;
919 }
920 };
921 raw
922 }
923
924 pub(crate) fn free_core_raw(value: &mut BNPossibleValueSet) {
926 unsafe { BNFreePossibleValueSet(value) }
927 }
928
929 pub(crate) fn free_rust_raw(value: BNPossibleValueSet) {
931 if !value.ranges.is_null() {
933 let raw_ranges = unsafe { std::slice::from_raw_parts_mut(value.ranges, value.count) };
934 let boxed_ranges = unsafe { Box::from_raw(raw_ranges) };
935 }
936
937 if !value.table.is_null() {
938 unsafe { LookupTableEntry::free_raw(*value.table) };
939 }
940
941 if !value.valueSet.is_null() {
942 let raw_value_set =
943 unsafe { std::slice::from_raw_parts_mut(value.valueSet, value.count) };
944 let boxed_value_set = unsafe { Box::from_raw(raw_value_set) };
945 }
946 }
947
948 pub fn value_type(&self) -> RegisterValueType {
949 match self {
950 PossibleValueSet::UndeterminedValue => RegisterValueType::UndeterminedValue,
951 PossibleValueSet::EntryValue { .. } => RegisterValueType::EntryValue,
952 PossibleValueSet::ConstantValue { .. } => RegisterValueType::ConstantValue,
953 PossibleValueSet::ConstantPointerValue { .. } => {
954 RegisterValueType::ConstantPointerValue
955 }
956 PossibleValueSet::ExternalPointerValue { .. } => {
957 RegisterValueType::ExternalPointerValue
958 }
959 PossibleValueSet::StackFrameOffset { .. } => RegisterValueType::StackFrameOffset,
960 PossibleValueSet::ResultPointer { .. } => RegisterValueType::ResultPointerValue,
961 PossibleValueSet::ParameterPointer { .. } => RegisterValueType::ParameterPointerValue,
962 PossibleValueSet::ReturnAddressValue => RegisterValueType::ReturnAddressValue,
963 PossibleValueSet::ImportedAddressValue { .. } => {
964 RegisterValueType::ImportedAddressValue
965 }
966 PossibleValueSet::SignedRangeValue { .. } => RegisterValueType::SignedRangeValue,
967 PossibleValueSet::UnsignedRangeValue { .. } => RegisterValueType::UnsignedRangeValue,
968 PossibleValueSet::LookupTableValue { .. } => RegisterValueType::LookupTableValue,
969 PossibleValueSet::InSetOfValues { .. } => RegisterValueType::InSetOfValues,
970 PossibleValueSet::NotInSetOfValues { .. } => RegisterValueType::NotInSetOfValues,
971 PossibleValueSet::ConstantDataValue { .. } => RegisterValueType::ConstantDataValue,
972 PossibleValueSet::ConstantDataZeroExtendValue { .. } => {
973 RegisterValueType::ConstantDataZeroExtendValue
974 }
975 PossibleValueSet::ConstantDataSignExtendValue { .. } => {
976 RegisterValueType::ConstantDataSignExtendValue
977 }
978 PossibleValueSet::ConstantDataAggregateValue { .. } => {
979 RegisterValueType::ConstantDataAggregateValue
980 }
981 }
982 }
983
984 pub fn add(&self, other: &PossibleValueSet, size: usize) -> PossibleValueSet {
985 let raw_value = PossibleValueSet::into_rust_raw(self.clone());
986 let raw_other = PossibleValueSet::into_rust_raw(other.clone());
987 let result;
988 unsafe { result = BNPossibleValueSetAdd(&raw_value, &raw_other, size) }
989 PossibleValueSet::free_rust_raw(raw_value);
990 PossibleValueSet::free_rust_raw(raw_other);
991 PossibleValueSet::from_owned_core_raw(result)
992 }
993
994 pub fn subtract(&self, other: &PossibleValueSet, size: usize) -> PossibleValueSet {
995 let raw_value = PossibleValueSet::into_rust_raw(self.clone());
996 let raw_other = PossibleValueSet::into_rust_raw(other.clone());
997 let result;
998 unsafe { result = BNPossibleValueSetSubtract(&raw_value, &raw_other, size) }
999 PossibleValueSet::free_rust_raw(raw_value);
1000 PossibleValueSet::free_rust_raw(raw_other);
1001 PossibleValueSet::from_owned_core_raw(result)
1002 }
1003
1004 pub fn multiply(&self, other: &PossibleValueSet, size: usize) -> PossibleValueSet {
1005 let raw_value = PossibleValueSet::into_rust_raw(self.clone());
1006 let raw_other = PossibleValueSet::into_rust_raw(other.clone());
1007 let result;
1008 unsafe { result = BNPossibleValueSetMultiply(&raw_value, &raw_other, size) }
1009 PossibleValueSet::free_rust_raw(raw_value);
1010 PossibleValueSet::free_rust_raw(raw_other);
1011 PossibleValueSet::from_owned_core_raw(result)
1012 }
1013
1014 pub fn signed_divide(&self, other: &PossibleValueSet, size: usize) -> PossibleValueSet {
1015 let raw_value = PossibleValueSet::into_rust_raw(self.clone());
1016 let raw_other = PossibleValueSet::into_rust_raw(other.clone());
1017 let result;
1018 unsafe { result = BNPossibleValueSetSignedDivide(&raw_value, &raw_other, size) }
1019 PossibleValueSet::free_rust_raw(raw_value);
1020 PossibleValueSet::free_rust_raw(raw_other);
1021 PossibleValueSet::from_owned_core_raw(result)
1022 }
1023
1024 pub fn unsigned_divide(&self, other: &PossibleValueSet, size: usize) -> PossibleValueSet {
1025 let raw_value = PossibleValueSet::into_rust_raw(self.clone());
1026 let raw_other = PossibleValueSet::into_rust_raw(other.clone());
1027 let result;
1028 unsafe { result = BNPossibleValueSetUnsignedDivide(&raw_value, &raw_other, size) }
1029 PossibleValueSet::free_rust_raw(raw_value);
1030 PossibleValueSet::free_rust_raw(raw_other);
1031 PossibleValueSet::from_owned_core_raw(result)
1032 }
1033
1034 pub fn signed_mod(&self, other: &PossibleValueSet, size: usize) -> PossibleValueSet {
1035 let raw_value = PossibleValueSet::into_rust_raw(self.clone());
1036 let raw_other = PossibleValueSet::into_rust_raw(other.clone());
1037 let result;
1038 unsafe { result = BNPossibleValueSetSignedMod(&raw_value, &raw_other, size) }
1039 PossibleValueSet::free_rust_raw(raw_value);
1040 PossibleValueSet::free_rust_raw(raw_other);
1041 PossibleValueSet::from_owned_core_raw(result)
1042 }
1043
1044 pub fn unsigned_mod(&self, other: &PossibleValueSet, size: usize) -> PossibleValueSet {
1045 let raw_value = PossibleValueSet::into_rust_raw(self.clone());
1046 let raw_other = PossibleValueSet::into_rust_raw(other.clone());
1047 let result;
1048 unsafe { result = BNPossibleValueSetUnsignedMod(&raw_value, &raw_other, size) }
1049 PossibleValueSet::free_rust_raw(raw_value);
1050 PossibleValueSet::free_rust_raw(raw_other);
1051 PossibleValueSet::from_owned_core_raw(result)
1052 }
1053
1054 pub fn and(&self, other: &PossibleValueSet, size: usize) -> PossibleValueSet {
1055 let raw_value = PossibleValueSet::into_rust_raw(self.clone());
1056 let raw_other = PossibleValueSet::into_rust_raw(other.clone());
1057 let result;
1058 unsafe { result = BNPossibleValueSetAnd(&raw_value, &raw_other, size) }
1059 PossibleValueSet::free_rust_raw(raw_value);
1060 PossibleValueSet::free_rust_raw(raw_other);
1061 PossibleValueSet::from_owned_core_raw(result)
1062 }
1063
1064 pub fn or(&self, other: &PossibleValueSet, size: usize) -> PossibleValueSet {
1065 let raw_value = PossibleValueSet::into_rust_raw(self.clone());
1066 let raw_other = PossibleValueSet::into_rust_raw(other.clone());
1067 let result;
1068 unsafe { result = BNPossibleValueSetOr(&raw_value, &raw_other, size) }
1069 PossibleValueSet::free_rust_raw(raw_value);
1070 PossibleValueSet::free_rust_raw(raw_other);
1071 PossibleValueSet::from_owned_core_raw(result)
1072 }
1073
1074 pub fn xor(&self, other: &PossibleValueSet, size: usize) -> PossibleValueSet {
1075 let raw_value = PossibleValueSet::into_rust_raw(self.clone());
1076 let raw_other = PossibleValueSet::into_rust_raw(other.clone());
1077 let result;
1078 unsafe { result = BNPossibleValueSetXor(&raw_value, &raw_other, size) }
1079 PossibleValueSet::free_rust_raw(raw_value);
1080 PossibleValueSet::free_rust_raw(raw_other);
1081 PossibleValueSet::from_owned_core_raw(result)
1082 }
1083
1084 pub fn shift_left(&self, other: &PossibleValueSet, size: usize) -> PossibleValueSet {
1085 let raw_value = PossibleValueSet::into_rust_raw(self.clone());
1086 let raw_other = PossibleValueSet::into_rust_raw(other.clone());
1087 let result;
1088 unsafe { result = BNPossibleValueSetShiftLeft(&raw_value, &raw_other, size) }
1089 PossibleValueSet::free_rust_raw(raw_value);
1090 PossibleValueSet::free_rust_raw(raw_other);
1091 PossibleValueSet::from_owned_core_raw(result)
1092 }
1093
1094 pub fn logical_shift_right(&self, other: &PossibleValueSet, size: usize) -> PossibleValueSet {
1095 let raw_value = PossibleValueSet::into_rust_raw(self.clone());
1096 let raw_other = PossibleValueSet::into_rust_raw(other.clone());
1097 let result;
1098 unsafe { result = BNPossibleValueSetLogicalShiftRight(&raw_value, &raw_other, size) }
1099 PossibleValueSet::free_rust_raw(raw_value);
1100 PossibleValueSet::free_rust_raw(raw_other);
1101 PossibleValueSet::from_owned_core_raw(result)
1102 }
1103
1104 pub fn arith_shift_right(&self, other: &PossibleValueSet, size: usize) -> PossibleValueSet {
1105 let raw_value = PossibleValueSet::into_rust_raw(self.clone());
1106 let raw_other = PossibleValueSet::into_rust_raw(other.clone());
1107 let result;
1108 unsafe { result = BNPossibleValueSetArithShiftRight(&raw_value, &raw_other, size) }
1109 PossibleValueSet::free_rust_raw(raw_value);
1110 PossibleValueSet::free_rust_raw(raw_other);
1111 PossibleValueSet::from_owned_core_raw(result)
1112 }
1113
1114 pub fn rotate_left(&self, other: &PossibleValueSet, size: usize) -> PossibleValueSet {
1115 let raw_value = PossibleValueSet::into_rust_raw(self.clone());
1116 let raw_other = PossibleValueSet::into_rust_raw(other.clone());
1117 let result;
1118 unsafe { result = BNPossibleValueSetRotateLeft(&raw_value, &raw_other, size) }
1119 PossibleValueSet::free_rust_raw(raw_value);
1120 PossibleValueSet::free_rust_raw(raw_other);
1121 PossibleValueSet::from_owned_core_raw(result)
1122 }
1123
1124 pub fn rotate_right(&self, other: &PossibleValueSet, size: usize) -> PossibleValueSet {
1125 let raw_value = PossibleValueSet::into_rust_raw(self.clone());
1126 let raw_other = PossibleValueSet::into_rust_raw(other.clone());
1127 let result;
1128 unsafe { result = BNPossibleValueSetRotateRight(&raw_value, &raw_other, size) }
1129 PossibleValueSet::free_rust_raw(raw_value);
1130 PossibleValueSet::free_rust_raw(raw_other);
1131 PossibleValueSet::from_owned_core_raw(result)
1132 }
1133
1134 pub fn union(&self, other: &PossibleValueSet, size: usize) -> PossibleValueSet {
1135 let raw_value = PossibleValueSet::into_rust_raw(self.clone());
1136 let raw_other = PossibleValueSet::into_rust_raw(other.clone());
1137 let result;
1138 unsafe { result = BNPossibleValueSetUnion(&raw_value, &raw_other, size) }
1139 PossibleValueSet::free_rust_raw(raw_value);
1140 PossibleValueSet::free_rust_raw(raw_other);
1141 PossibleValueSet::from_owned_core_raw(result)
1142 }
1143
1144 pub fn intersection(&self, other: &PossibleValueSet, size: usize) -> PossibleValueSet {
1145 let raw_value = PossibleValueSet::into_rust_raw(self.clone());
1146 let raw_other = PossibleValueSet::into_rust_raw(other.clone());
1147 let result;
1148 unsafe { result = BNPossibleValueSetIntersection(&raw_value, &raw_other, size) }
1149 PossibleValueSet::free_rust_raw(raw_value);
1150 PossibleValueSet::free_rust_raw(raw_other);
1151 PossibleValueSet::from_owned_core_raw(result)
1152 }
1153
1154 pub fn negate(&self, size: usize) -> PossibleValueSet {
1155 let raw_value = PossibleValueSet::into_rust_raw(self.clone());
1156 let result;
1157 unsafe { result = BNPossibleValueSetNegate(&raw_value, size) }
1158 PossibleValueSet::free_rust_raw(raw_value);
1159 PossibleValueSet::from_owned_core_raw(result)
1160 }
1161
1162 pub fn not(&self, size: usize) -> PossibleValueSet {
1163 let raw_value = PossibleValueSet::into_rust_raw(self.clone());
1164 let result;
1165 unsafe { result = BNPossibleValueSetNot(&raw_value, size) }
1166 PossibleValueSet::free_rust_raw(raw_value);
1167 PossibleValueSet::from_owned_core_raw(result)
1168 }
1169}