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, BNFreeDataVariableAndName, BNFreeDataVariables,
11 BNFreeILInstructionList, BNFreeIndirectBranchList, BNFreeMergedVariableList,
12 BNFreePossibleValueSet, BNFreeStackVariableReferenceList, BNFreeUserVariableValues,
13 BNFreeVariableList, BNFreeVariableNameAndTypeList, BNFromVariableIdentifier,
14 BNIndirectBranchInfo, BNLookupTableEntry, BNMergedVariable, BNPossibleValueSet,
15 BNRegisterValue, BNRegisterValueType, BNStackVariableReference, BNToVariableIdentifier,
16 BNTypeWithConfidence, BNUserVariableValue, BNValueRange, BNVariable, BNVariableNameAndType,
17 BNVariableSourceType,
18};
19use std::collections::HashSet;
20
21pub type VariableSourceType = BNVariableSourceType;
22pub type RegisterValueType = BNRegisterValueType;
23
24#[derive(Debug, Clone, Hash, PartialEq, Eq)]
25pub struct DataVariable {
26 pub address: u64,
27 pub ty: Conf<Ref<Type>>,
28 pub auto_discovered: bool,
29}
30
31impl DataVariable {
32 pub(crate) fn from_raw(value: &BNDataVariable) -> Self {
33 Self {
34 address: value.address,
35 ty: Conf::new(
36 unsafe { Type::from_raw(value.type_).to_owned() },
37 value.typeConfidence,
38 ),
39 auto_discovered: value.autoDiscovered,
40 }
41 }
42
43 pub(crate) fn from_owned_raw(value: BNDataVariable) -> Self {
44 let owned = Self::from_raw(&value);
45 Self::free_raw(value);
46 owned
47 }
48
49 pub(crate) fn into_raw(value: Self) -> BNDataVariable {
50 BNDataVariable {
51 address: value.address,
52 type_: unsafe { Ref::into_raw(value.ty.contents) }.handle,
53 autoDiscovered: value.auto_discovered,
54 typeConfidence: value.ty.confidence,
55 }
56 }
57
58 pub(crate) fn into_owned_raw(value: &Self) -> BNDataVariable {
59 BNDataVariable {
60 address: value.address,
61 type_: value.ty.contents.handle,
62 autoDiscovered: value.auto_discovered,
63 typeConfidence: value.ty.confidence,
64 }
65 }
66
67 pub(crate) fn free_raw(value: BNDataVariable) {
68 let _ = unsafe { Type::ref_from_raw(value.type_) };
69 }
70
71 pub fn new(address: u64, ty: Conf<Ref<Type>>, auto_discovered: bool) -> Self {
72 Self {
73 address,
74 ty,
75 auto_discovered,
76 }
77 }
78}
79
80impl CoreArrayProvider for DataVariable {
81 type Raw = BNDataVariable;
82 type Context = ();
83 type Wrapped<'a> = Self;
84}
85
86unsafe impl CoreArrayProviderInner for DataVariable {
87 unsafe fn free(raw: *mut Self::Raw, count: usize, _context: &Self::Context) {
88 BNFreeDataVariables(raw, count);
89 }
90
91 unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, _context: &'a Self::Context) -> Self::Wrapped<'a> {
92 DataVariable::from_raw(raw)
93 }
94}
95
96#[derive(Debug, Clone, Hash, PartialEq, Eq)]
97pub struct NamedDataVariableWithType {
98 pub address: u64,
99 pub ty: Conf<Ref<Type>>,
100 pub name: String,
101 pub auto_discovered: bool,
102}
103
104impl NamedDataVariableWithType {
105 pub(crate) fn from_raw(value: &BNDataVariableAndName) -> Self {
106 Self {
107 address: value.address,
108 ty: Conf::new(
109 unsafe { Type::from_raw(value.type_).to_owned() },
110 value.typeConfidence,
111 ),
112 name: raw_to_string(value.name as *mut _).unwrap(),
114 auto_discovered: value.autoDiscovered,
115 }
116 }
117
118 pub(crate) fn from_owned_raw(value: BNDataVariableAndName) -> Self {
119 let owned = Self::from_raw(&value);
120 Self::free_raw(value);
121 owned
122 }
123
124 pub(crate) fn into_raw(value: Self) -> BNDataVariableAndName {
125 let bn_name = BnString::new(value.name);
126 BNDataVariableAndName {
127 address: value.address,
128 type_: unsafe { Ref::into_raw(value.ty.contents) }.handle,
129 name: BnString::into_raw(bn_name),
130 autoDiscovered: value.auto_discovered,
131 typeConfidence: value.ty.confidence,
132 }
133 }
134
135 pub(crate) fn free_raw(value: BNDataVariableAndName) {
136 let _ = unsafe { Type::ref_from_raw(value.type_) };
137 let _ = unsafe { BnString::from_raw(value.name) };
138 }
139
140 pub fn new(address: u64, ty: Conf<Ref<Type>>, name: String, auto_discovered: bool) -> Self {
141 Self {
142 address,
143 ty,
144 name,
145 auto_discovered,
146 }
147 }
148}
149
150#[derive(Debug, Clone, Hash, PartialEq, Eq)]
151pub struct NamedVariableWithType {
152 pub variable: Variable,
153 pub ty: Conf<Ref<Type>>,
154 pub name: String,
155 pub auto_defined: bool,
156}
157
158impl NamedVariableWithType {
159 pub(crate) fn from_raw(value: &BNVariableNameAndType) -> Self {
160 Self {
161 variable: value.var.into(),
162 ty: Conf::new(
163 unsafe { Type::from_raw(value.type_) }.to_owned(),
164 value.typeConfidence,
165 ),
166 name: raw_to_string(value.name as *mut _).unwrap(),
168 auto_defined: value.autoDefined,
169 }
170 }
171
172 pub(crate) fn from_owned_raw(value: BNVariableNameAndType) -> Self {
173 let owned = Self::from_raw(&value);
174 Self::free_raw(value);
175 owned
176 }
177
178 pub(crate) fn into_raw(value: Self) -> BNVariableNameAndType {
179 let bn_name = BnString::new(value.name);
180 BNVariableNameAndType {
181 var: value.variable.into(),
182 type_: unsafe { Ref::into_raw(value.ty.contents) }.handle,
183 name: BnString::into_raw(bn_name),
184 autoDefined: value.auto_defined,
185 typeConfidence: value.ty.confidence,
186 }
187 }
188
189 pub(crate) fn free_raw(value: BNVariableNameAndType) {
190 let _ = unsafe { Type::ref_from_raw(value.type_) };
191 unsafe { BnString::free_raw(value.name) };
192 }
193
194 pub fn new(variable: Variable, ty: Conf<Ref<Type>>, name: String, auto_defined: bool) -> Self {
195 Self {
196 variable,
197 ty,
198 name,
199 auto_defined,
200 }
201 }
202}
203
204impl CoreArrayProvider for NamedVariableWithType {
205 type Raw = BNVariableNameAndType;
206 type Context = ();
207 type Wrapped<'a> = NamedVariableWithType;
208}
209
210unsafe impl CoreArrayProviderInner for NamedVariableWithType {
211 unsafe fn free(raw: *mut Self::Raw, count: usize, _context: &Self::Context) {
212 BNFreeVariableNameAndTypeList(raw, count)
213 }
214
215 unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, _context: &'a Self::Context) -> Self::Wrapped<'a> {
216 Self::from_raw(raw)
217 }
218}
219
220#[derive(Debug, Clone, PartialEq, Eq)]
221pub struct UserVariableValue {
222 pub variable: Variable,
223 pub def_site: Location,
224 pub after: bool,
225 pub value: PossibleValueSet,
226}
227
228impl UserVariableValue {
229 pub(crate) fn from_raw(value: &BNUserVariableValue) -> Self {
230 Self {
231 variable: value.var.into(),
232 def_site: value.defSite.into(),
233 after: value.after,
234 value: PossibleValueSet::from_raw(&value.value),
235 }
236 }
237
238 pub(crate) fn into_raw(value: Self) -> BNUserVariableValue {
239 BNUserVariableValue {
240 var: value.variable.into(),
241 defSite: value.def_site.into(),
242 after: value.after,
243 value: PossibleValueSet::into_rust_raw(value.value),
246 }
247 }
248}
249
250impl CoreArrayProvider for UserVariableValue {
251 type Raw = BNUserVariableValue;
252 type Context = ();
253 type Wrapped<'a> = Self;
254}
255
256unsafe impl CoreArrayProviderInner for UserVariableValue {
257 unsafe fn free(raw: *mut Self::Raw, _count: usize, _context: &Self::Context) {
258 BNFreeUserVariableValues(raw)
259 }
260
261 unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, _context: &'a Self::Context) -> Self::Wrapped<'a> {
262 UserVariableValue::from_raw(raw)
263 }
264}
265
266#[derive(Debug, Clone, Hash, PartialEq, Eq)]
267pub struct StackVariableReference {
268 source_operand: u32,
269 pub variable_type: Conf<Ref<Type>>,
270 pub name: String,
271 pub variable: Variable,
272 pub offset: i64,
273 pub size: usize,
274}
275
276impl StackVariableReference {
277 pub(crate) fn from_raw(value: &BNStackVariableReference) -> Self {
278 Self {
279 source_operand: value.sourceOperand,
280 variable_type: Conf::new(
281 unsafe { Type::from_raw(value.type_) }.to_owned(),
282 value.typeConfidence,
283 ),
284 name: raw_to_string(value.name).unwrap(),
286 variable: Variable::from_identifier(value.varIdentifier),
288 offset: value.referencedOffset,
289 size: value.size,
290 }
291 }
292
293 pub(crate) fn from_owned_raw(value: BNStackVariableReference) -> Self {
294 let owned = Self::from_raw(&value);
295 Self::free_raw(value);
296 owned
297 }
298
299 pub(crate) fn into_raw(value: Self) -> BNStackVariableReference {
300 let bn_name = BnString::new(value.name);
301 BNStackVariableReference {
302 sourceOperand: value.source_operand,
303 typeConfidence: value.variable_type.confidence,
304 type_: unsafe { Ref::into_raw(value.variable_type.contents) }.handle,
305 name: BnString::into_raw(bn_name),
306 varIdentifier: value.variable.to_identifier(),
307 referencedOffset: value.offset,
308 size: value.size,
309 }
310 }
311
312 pub(crate) fn free_raw(value: BNStackVariableReference) {
313 let _ = unsafe { Type::ref_from_raw(value.type_) };
314 unsafe { BnString::free_raw(value.name) };
315 }
316}
317
318impl CoreArrayProvider for StackVariableReference {
319 type Raw = BNStackVariableReference;
320 type Context = ();
321 type Wrapped<'a> = Self;
322}
323
324unsafe impl CoreArrayProviderInner for StackVariableReference {
325 unsafe fn free(raw: *mut Self::Raw, count: usize, _context: &Self::Context) {
326 BNFreeStackVariableReferenceList(raw, count)
327 }
328
329 unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, _context: &'a Self::Context) -> Self::Wrapped<'a> {
330 StackVariableReference::from_raw(raw)
331 }
332}
333
334#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq)]
335pub struct SSAVariable {
336 pub variable: Variable,
337 pub version: usize,
338}
339
340impl SSAVariable {
341 pub fn new(variable: Variable, version: usize) -> Self {
342 Self { variable, version }
343 }
344}
345
346impl CoreArrayProvider for SSAVariable {
347 type Raw = usize;
348 type Context = Variable;
349 type Wrapped<'a> = Self;
350}
351
352unsafe impl CoreArrayProviderInner for SSAVariable {
353 unsafe fn free(raw: *mut Self::Raw, _count: usize, _context: &Self::Context) {
354 BNFreeILInstructionList(raw)
355 }
356
357 unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, context: &'a Self::Context) -> Self::Wrapped<'a> {
358 SSAVariable::new(*context, *raw)
359 }
360}
361
362#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
367pub struct Variable {
368 pub ty: VariableSourceType,
369 pub index: u32,
371 pub storage: i64,
373}
374
375impl Variable {
376 pub fn new(ty: VariableSourceType, index: u32, storage: i64) -> Self {
377 Self { ty, index, storage }
378 }
379
380 pub fn from_identifier(ident: u64) -> Self {
384 unsafe { BNFromVariableIdentifier(ident) }.into()
385 }
386
387 pub fn to_identifier(&self) -> u64 {
388 let raw = BNVariable::from(*self);
389 unsafe { BNToVariableIdentifier(&raw) }
390 }
391
392 pub fn to_register(&self, arch: CoreArchitecture) -> Option<CoreRegister> {
393 match self.ty {
394 VariableSourceType::RegisterVariableSourceType => {
395 arch.register_from_id(RegisterId(self.storage as u32))
396 }
397 VariableSourceType::StackVariableSourceType => None,
398 VariableSourceType::FlagVariableSourceType => None,
399 }
400 }
401}
402
403impl From<BNVariable> for Variable {
404 fn from(value: BNVariable) -> Self {
405 Self {
406 ty: value.type_,
407 index: value.index,
408 storage: value.storage,
409 }
410 }
411}
412
413impl From<&BNVariable> for Variable {
414 fn from(value: &BNVariable) -> Self {
415 Self::from(*value)
416 }
417}
418
419impl From<Variable> for BNVariable {
420 fn from(value: Variable) -> Self {
421 Self {
422 type_: value.ty,
423 index: value.index,
424 storage: value.storage,
425 }
426 }
427}
428
429impl From<&Variable> for BNVariable {
430 fn from(value: &Variable) -> Self {
431 BNVariable::from(*value)
432 }
433}
434
435impl CoreArrayProvider for Variable {
436 type Raw = BNVariable;
437 type Context = ();
438 type Wrapped<'a> = Self;
439}
440
441unsafe impl CoreArrayProviderInner for Variable {
442 unsafe fn free(raw: *mut Self::Raw, _count: usize, _context: &Self::Context) {
443 BNFreeVariableList(raw)
444 }
445
446 unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, _context: &'a Self::Context) -> Self::Wrapped<'a> {
447 Variable::from(raw)
448 }
449}
450
451#[derive(Debug, Clone, Hash, PartialEq, Eq)]
452pub struct MergedVariable {
453 pub target: Variable,
454 pub sources: Vec<Variable>,
455}
456
457impl MergedVariable {
458 pub(crate) fn from_raw(value: &BNMergedVariable) -> Self {
459 let raw_sources = unsafe { std::slice::from_raw_parts(value.sources, value.sourceCount) };
460 Self {
461 target: value.target.into(),
462 sources: raw_sources.iter().map(Into::into).collect(),
463 }
464 }
465
466 }
468
469impl CoreArrayProvider for MergedVariable {
470 type Raw = BNMergedVariable;
471 type Context = ();
472 type Wrapped<'a> = Self;
473}
474
475unsafe impl CoreArrayProviderInner for MergedVariable {
476 unsafe fn free(raw: *mut Self::Raw, count: usize, _context: &Self::Context) {
477 BNFreeMergedVariableList(raw, count)
478 }
479
480 unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, _context: &'a Self::Context) -> Self::Wrapped<'a> {
481 Self::from_raw(raw)
482 }
483}
484
485#[derive(Clone, Debug, Hash, Eq, PartialEq)]
487pub struct ConstantData {
488 pub function: Ref<Function>,
490 pub value: RegisterValue,
491}
492
493impl ConstantData {
494 pub fn new(function: Ref<Function>, value: RegisterValue) -> Self {
495 Self { function, value }
496 }
497}
498
499#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq)]
500pub struct RegisterValue {
501 pub state: RegisterValueType,
502 pub value: i64,
504 pub offset: i64,
505 pub size: usize,
506}
507
508impl RegisterValue {
509 pub fn new(state: RegisterValueType, value: i64, offset: i64, size: usize) -> Self {
510 Self {
511 state,
512 value,
513 offset,
514 size,
515 }
516 }
517}
518
519impl From<BNRegisterValue> for RegisterValue {
520 fn from(value: BNRegisterValue) -> Self {
521 Self {
522 state: value.state,
523 value: value.value,
524 offset: value.offset,
525 size: value.size,
526 }
527 }
528}
529
530impl From<RegisterValue> for BNRegisterValue {
531 fn from(value: RegisterValue) -> Self {
532 Self {
533 state: value.state,
534 value: value.value,
535 offset: value.offset,
536 size: value.size,
537 }
538 }
539}
540
541#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
542pub struct ValueRange<T> {
543 pub start: T,
544 pub end: T,
545 pub step: u64,
546}
547
548impl From<BNValueRange> for ValueRange<u64> {
549 fn from(value: BNValueRange) -> Self {
550 Self {
551 start: value.start,
552 end: value.end,
553 step: value.step,
554 }
555 }
556}
557
558impl From<ValueRange<u64>> for BNValueRange {
559 fn from(value: ValueRange<u64>) -> Self {
560 Self {
561 start: value.start,
562 end: value.end,
563 step: value.step,
564 }
565 }
566}
567
568impl From<BNValueRange> for ValueRange<i64> {
569 fn from(value: BNValueRange) -> Self {
570 Self {
571 start: value.start as i64,
572 end: value.end as i64,
573 step: value.step,
574 }
575 }
576}
577
578impl From<ValueRange<i64>> for BNValueRange {
579 fn from(value: ValueRange<i64>) -> Self {
580 Self {
581 start: value.start as u64,
582 end: value.end as u64,
583 step: value.step,
584 }
585 }
586}
587
588#[derive(Clone, Debug, Eq, PartialEq)]
591pub struct LookupTableEntry {
592 pub from: HashSet<i64>,
594 pub to: i64,
596}
597
598impl LookupTableEntry {
599 pub(crate) fn from_raw(value: &BNLookupTableEntry) -> Self {
600 let from_values = unsafe { std::slice::from_raw_parts(value.fromValues, value.fromCount) };
601 Self {
602 from: HashSet::from_iter(from_values.iter().copied()),
604 to: value.toValue,
605 }
606 }
607
608 pub(crate) fn from_owned_raw(value: BNLookupTableEntry) -> Self {
609 let owned = Self::from_raw(&value);
610 Self::free_raw(value);
611 owned
612 }
613
614 pub(crate) fn into_raw(value: Self) -> BNLookupTableEntry {
615 let from_values: Box<[i64]> = value.from.into_iter().collect();
616 let from_values_len = from_values.len();
617 BNLookupTableEntry {
618 fromValues: Box::leak(from_values).as_mut_ptr(),
620 fromCount: from_values_len,
621 toValue: value.to,
622 }
623 }
624
625 pub(crate) fn free_raw(value: BNLookupTableEntry) {
626 let raw_from = unsafe { std::slice::from_raw_parts_mut(value.fromValues, value.fromCount) };
627 let boxed_from = unsafe { Box::from_raw(raw_from) };
628 }
629}
630
631#[derive(Debug, Clone, PartialEq, Eq)]
632pub enum PossibleValueSet {
633 UndeterminedValue,
634 EntryValue {
635 reg: i64,
638 },
639 ConstantValue {
640 value: i64,
643 },
644 ConstantPointerValue {
645 value: i64,
647 },
648 ExternalPointerValue {
649 value: i64,
651 offset: i64,
652 },
653 StackFrameOffset {
654 value: i64,
655 },
656 ReturnAddressValue,
657 ImportedAddressValue {
658 value: i64,
659 },
660 SignedRangeValue {
661 value: i64,
662 ranges: Vec<ValueRange<i64>>,
663 },
664 UnsignedRangeValue {
665 value: i64,
666 ranges: Vec<ValueRange<u64>>,
667 },
668 LookupTableValue {
669 table: Vec<LookupTableEntry>,
670 },
671 InSetOfValues {
672 values: HashSet<i64>,
673 },
674 NotInSetOfValues {
675 values: HashSet<i64>,
676 },
677 ConstantDataValue {
679 value: i64,
680 size: usize,
681 },
682 ConstantDataZeroExtendValue {
683 value: i64,
685 size: usize,
686 },
687 ConstantDataSignExtendValue {
688 value: i64,
689 size: usize,
690 },
691 ConstantDataAggregateValue {
692 value: i64,
694 size: usize,
695 },
696}
697
698impl PossibleValueSet {
699 pub(crate) fn from_raw(value: &BNPossibleValueSet) -> Self {
700 match value.state {
701 RegisterValueType::UndeterminedValue => Self::UndeterminedValue,
702 RegisterValueType::EntryValue => Self::EntryValue { reg: value.value },
703 RegisterValueType::ConstantValue => Self::ConstantValue { value: value.value },
704 RegisterValueType::ConstantPointerValue => {
705 Self::ConstantPointerValue { value: value.value }
706 }
707 RegisterValueType::ExternalPointerValue => Self::ExternalPointerValue {
708 value: value.value,
709 offset: value.offset,
710 },
711 RegisterValueType::StackFrameOffset => Self::StackFrameOffset { value: value.value },
712 RegisterValueType::ReturnAddressValue => Self::ReturnAddressValue,
713 RegisterValueType::ImportedAddressValue => {
714 Self::ImportedAddressValue { value: value.value }
715 }
716 RegisterValueType::SignedRangeValue => {
717 let raw_ranges = unsafe { std::slice::from_raw_parts(value.ranges, value.count) };
718 Self::SignedRangeValue {
719 value: value.value,
720 ranges: raw_ranges.iter().map(|&r| r.into()).collect(),
721 }
722 }
723 RegisterValueType::UnsignedRangeValue => {
724 let raw_ranges = unsafe { std::slice::from_raw_parts(value.ranges, value.count) };
725 Self::UnsignedRangeValue {
726 value: value.value,
727 ranges: raw_ranges.iter().map(|&r| r.into()).collect(),
728 }
729 }
730 RegisterValueType::LookupTableValue => {
731 let raw_entries = unsafe { std::slice::from_raw_parts(value.table, value.count) };
732 Self::LookupTableValue {
733 table: raw_entries.iter().map(LookupTableEntry::from_raw).collect(),
734 }
735 }
736 RegisterValueType::InSetOfValues => {
737 let raw_values = unsafe { std::slice::from_raw_parts(value.valueSet, value.count) };
738 Self::InSetOfValues {
739 values: raw_values.iter().copied().collect(),
740 }
741 }
742 RegisterValueType::NotInSetOfValues => {
743 let raw_values = unsafe { std::slice::from_raw_parts(value.valueSet, value.count) };
744 Self::NotInSetOfValues {
745 values: raw_values.iter().copied().collect(),
746 }
747 }
748 RegisterValueType::ConstantDataValue => Self::ConstantDataValue {
749 value: value.value,
750 size: value.size,
751 },
752 RegisterValueType::ConstantDataZeroExtendValue => Self::ConstantDataZeroExtendValue {
753 value: value.value,
754 size: value.size,
755 },
756 RegisterValueType::ConstantDataSignExtendValue => Self::ConstantDataSignExtendValue {
757 value: value.value,
758 size: value.size,
759 },
760 RegisterValueType::ConstantDataAggregateValue => Self::ConstantDataAggregateValue {
761 value: value.value,
762 size: value.size,
763 },
764 }
765 }
766
767 pub(crate) fn from_owned_core_raw(mut value: BNPossibleValueSet) -> Self {
769 let owned = Self::from_raw(&value);
770 Self::free_core_raw(&mut value);
771 owned
772 }
773
774 pub(crate) fn into_rust_raw(value: Self) -> BNPossibleValueSet {
775 let mut raw = BNPossibleValueSet {
776 state: value.value_type(),
777 ..Default::default()
778 };
779 match value {
780 PossibleValueSet::UndeterminedValue => {}
781 PossibleValueSet::EntryValue { reg } => {
782 raw.value = reg;
783 }
784 PossibleValueSet::ConstantValue { value } => {
785 raw.value = value;
786 }
787 PossibleValueSet::ConstantPointerValue { value } => {
788 raw.value = value;
789 }
790 PossibleValueSet::ExternalPointerValue { value, offset } => {
791 raw.value = value;
792 raw.offset = offset;
793 }
794 PossibleValueSet::StackFrameOffset { value } => {
795 raw.value = value;
796 }
797 PossibleValueSet::ReturnAddressValue => {}
798 PossibleValueSet::ImportedAddressValue { value } => {
799 raw.value = value;
800 }
801 PossibleValueSet::SignedRangeValue { value, ranges } => {
802 let boxed_raw_ranges: Box<[BNValueRange]> =
803 ranges.into_iter().map(BNValueRange::from).collect();
804 raw.value = value;
805 raw.count = boxed_raw_ranges.len();
806 raw.ranges = Box::leak(boxed_raw_ranges).as_mut_ptr();
808 }
809 PossibleValueSet::UnsignedRangeValue { value, ranges } => {
810 let boxed_raw_ranges: Box<[BNValueRange]> =
811 ranges.into_iter().map(BNValueRange::from).collect();
812 raw.value = value;
813 raw.count = boxed_raw_ranges.len();
814 raw.ranges = Box::leak(boxed_raw_ranges).as_mut_ptr();
816 }
817 PossibleValueSet::LookupTableValue { table } => {
818 let boxed_raw_entries: Box<[BNLookupTableEntry]> =
819 table.into_iter().map(LookupTableEntry::into_raw).collect();
820 raw.count = boxed_raw_entries.len();
821 raw.table = Box::leak(boxed_raw_entries).as_mut_ptr();
823 }
824 PossibleValueSet::InSetOfValues { values } => {
825 let boxed_raw_values: Box<[i64]> = values.into_iter().collect();
826 raw.count = boxed_raw_values.len();
827 raw.valueSet = Box::leak(boxed_raw_values).as_mut_ptr();
829 }
830 PossibleValueSet::NotInSetOfValues { values } => {
831 let boxed_raw_values: Box<[i64]> = values.into_iter().collect();
832 raw.count = boxed_raw_values.len();
833 raw.valueSet = Box::leak(boxed_raw_values).as_mut_ptr();
835 }
836 PossibleValueSet::ConstantDataValue { value, size } => {
837 raw.value = value;
838 raw.size = size;
839 }
840 PossibleValueSet::ConstantDataZeroExtendValue { value, size } => {
841 raw.value = value;
842 raw.size = size;
843 }
844 PossibleValueSet::ConstantDataSignExtendValue { value, size } => {
845 raw.value = value;
846 raw.size = size;
847 }
848 PossibleValueSet::ConstantDataAggregateValue { value, size } => {
849 raw.value = value;
850 raw.size = size;
851 }
852 };
853 raw
854 }
855
856 pub(crate) fn free_core_raw(value: &mut BNPossibleValueSet) {
858 unsafe { BNFreePossibleValueSet(value) }
859 }
860
861 pub(crate) fn free_rust_raw(value: BNPossibleValueSet) {
863 if !value.ranges.is_null() {
865 let raw_ranges = unsafe { std::slice::from_raw_parts_mut(value.ranges, value.count) };
866 let boxed_ranges = unsafe { Box::from_raw(raw_ranges) };
867 }
868
869 if !value.table.is_null() {
870 unsafe { LookupTableEntry::free_raw(*value.table) };
871 }
872
873 if !value.valueSet.is_null() {
874 let raw_value_set =
875 unsafe { std::slice::from_raw_parts_mut(value.valueSet, value.count) };
876 let boxed_value_set = unsafe { Box::from_raw(raw_value_set) };
877 }
878 }
879
880 pub fn value_type(&self) -> RegisterValueType {
881 match self {
882 PossibleValueSet::UndeterminedValue => RegisterValueType::UndeterminedValue,
883 PossibleValueSet::EntryValue { .. } => RegisterValueType::EntryValue,
884 PossibleValueSet::ConstantValue { .. } => RegisterValueType::ConstantValue,
885 PossibleValueSet::ConstantPointerValue { .. } => {
886 RegisterValueType::ConstantPointerValue
887 }
888 PossibleValueSet::ExternalPointerValue { .. } => {
889 RegisterValueType::ExternalPointerValue
890 }
891 PossibleValueSet::StackFrameOffset { .. } => RegisterValueType::StackFrameOffset,
892 PossibleValueSet::ReturnAddressValue => RegisterValueType::ReturnAddressValue,
893 PossibleValueSet::ImportedAddressValue { .. } => {
894 RegisterValueType::ImportedAddressValue
895 }
896 PossibleValueSet::SignedRangeValue { .. } => RegisterValueType::SignedRangeValue,
897 PossibleValueSet::UnsignedRangeValue { .. } => RegisterValueType::UnsignedRangeValue,
898 PossibleValueSet::LookupTableValue { .. } => RegisterValueType::LookupTableValue,
899 PossibleValueSet::InSetOfValues { .. } => RegisterValueType::InSetOfValues,
900 PossibleValueSet::NotInSetOfValues { .. } => RegisterValueType::NotInSetOfValues,
901 PossibleValueSet::ConstantDataValue { .. } => RegisterValueType::ConstantDataValue,
902 PossibleValueSet::ConstantDataZeroExtendValue { .. } => {
903 RegisterValueType::ConstantDataZeroExtendValue
904 }
905 PossibleValueSet::ConstantDataSignExtendValue { .. } => {
906 RegisterValueType::ConstantDataSignExtendValue
907 }
908 PossibleValueSet::ConstantDataAggregateValue { .. } => {
909 RegisterValueType::ConstantDataAggregateValue
910 }
911 }
912 }
913}
914
915#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
916pub struct IndirectBranchInfo {
917 pub source: Location,
918 pub dest: Location,
919 pub auto_defined: bool,
920}
921
922impl From<BNIndirectBranchInfo> for IndirectBranchInfo {
923 fn from(value: BNIndirectBranchInfo) -> Self {
924 Self {
925 source: Location::from_raw(value.sourceAddr, value.sourceArch),
926 dest: Location::from_raw(value.destAddr, value.destArch),
927 auto_defined: value.autoDefined,
928 }
929 }
930}
931
932impl From<IndirectBranchInfo> for BNIndirectBranchInfo {
933 fn from(value: IndirectBranchInfo) -> Self {
934 let source_arch = value
935 .source
936 .arch
937 .map(|a| a.handle)
938 .unwrap_or(std::ptr::null_mut());
939 let dest_arch = value
940 .source
941 .arch
942 .map(|a| a.handle)
943 .unwrap_or(std::ptr::null_mut());
944 Self {
945 sourceArch: source_arch,
946 sourceAddr: value.source.addr,
947 destArch: dest_arch,
948 destAddr: value.dest.addr,
949 autoDefined: value.auto_defined,
950 }
951 }
952}
953
954impl CoreArrayProvider for IndirectBranchInfo {
955 type Raw = BNIndirectBranchInfo;
956 type Context = ();
957 type Wrapped<'a> = Self;
958}
959
960unsafe impl CoreArrayProviderInner for IndirectBranchInfo {
961 unsafe fn free(raw: *mut Self::Raw, _count: usize, _context: &Self::Context) {
962 BNFreeIndirectBranchList(raw)
963 }
964
965 unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, _context: &'a Self::Context) -> Self::Wrapped<'a> {
966 Self::from(*raw)
967 }
968}