1#![allow(unused)]
15
16use binaryninjacore_sys::*;
17
18use crate::architecture::Architecture;
19use crate::architecture::CoreArchitecture;
20use crate::basic_block::BasicBlock;
21use crate::function::{Location, NativeBlock};
22use crate::high_level_il as hlil;
23use crate::low_level_il as llil;
24use crate::medium_level_il as mlil;
25use crate::string::IntoCStr;
26use crate::string::{raw_to_string, strings_to_string_list, BnString};
27
28use crate::rc::*;
29
30use crate::confidence::MAX_CONFIDENCE;
31use crate::function::{Function, HighlightColor};
32use crate::tags::Tag;
33use crate::types::Type;
34use crate::variable::StackVariableReference;
35
36use crate::binary_view::StringType;
37use crate::high_level_il::HighLevelILFunction;
38use crate::low_level_il::function::{FunctionForm, FunctionMutability, LowLevelILFunction};
39use crate::medium_level_il::MediumLevelILFunction;
40use crate::project::Project;
41use std::convert::From;
42use std::ffi;
43use std::fmt::{Display, Formatter};
44use std::ptr;
45use std::ptr::NonNull;
46
47pub type DisassemblyOption = BNDisassemblyOption;
48pub type InstructionTextTokenType = BNInstructionTextTokenType;
49
50#[derive(Clone, PartialEq, Debug, Default, Eq)]
51pub struct DisassemblyTextLine {
52 pub address: u64,
53 pub instruction_index: usize,
55 pub tokens: Vec<InstructionTextToken>,
56 pub highlight: HighlightColor,
57 pub tags: Vec<Ref<Tag>>,
58 pub type_info: DisassemblyTextLineTypeInfo,
59}
60
61impl DisassemblyTextLine {
62 pub(crate) fn from_raw(value: &BNDisassemblyTextLine) -> Self {
63 let raw_tokens = unsafe { std::slice::from_raw_parts(value.tokens, value.count) };
64 let tokens: Vec<_> = raw_tokens
65 .iter()
66 .map(InstructionTextToken::from_raw)
67 .collect();
68 let raw_tags = unsafe { std::slice::from_raw_parts(value.tags, value.tagCount) };
70 let tags: Vec<_> = raw_tags
71 .iter()
72 .map(|&t| unsafe { Tag::from_raw(t) }.to_owned())
73 .collect();
74 Self {
75 address: value.addr,
76 instruction_index: value.instrIndex,
77 tokens,
78 highlight: value.highlight.into(),
79 tags,
80 type_info: DisassemblyTextLineTypeInfo::from_raw(&value.typeInfo),
81 }
82 }
83
84 pub(crate) fn into_raw(value: Self) -> BNDisassemblyTextLine {
88 let tokens: Box<[BNInstructionTextToken]> = value
90 .tokens
91 .into_iter()
92 .map(InstructionTextToken::into_raw)
93 .collect();
94 let tags: Box<[*mut BNTag]> = value
95 .tags
96 .into_iter()
97 .map(|t| {
98 unsafe { Ref::into_raw(t) }.handle
101 })
102 .collect();
103 BNDisassemblyTextLine {
104 addr: value.address,
105 instrIndex: value.instruction_index,
106 count: tokens.len(),
107 tokens: Box::leak(tokens).as_mut_ptr(),
109 highlight: value.highlight.into(),
110 tagCount: tags.len(),
111 tags: Box::leak(tags).as_mut_ptr(),
113 typeInfo: DisassemblyTextLineTypeInfo::into_raw(value.type_info),
114 }
115 }
116
117 pub(crate) fn free_raw(value: BNDisassemblyTextLine) {
121 let raw_tokens = unsafe { std::slice::from_raw_parts_mut(value.tokens, value.count) };
123 let boxed_tokens = unsafe { Box::from_raw(raw_tokens) };
124 for token in boxed_tokens {
125 InstructionTextToken::free_raw(token);
127 }
128 let raw_tags = unsafe { std::slice::from_raw_parts_mut(value.tags, value.tagCount) };
130 let boxed_tags = unsafe { Box::from_raw(raw_tags) };
131 for tag in boxed_tags {
132 let _ = unsafe { Tag::ref_from_raw(tag) };
134 }
135 DisassemblyTextLineTypeInfo::free_raw(value.typeInfo);
137 }
138
139 pub fn new(tokens: Vec<InstructionTextToken>) -> Self {
140 Self {
141 tokens,
142 ..Default::default()
143 }
144 }
145
146 pub fn new_with_addr(tokens: Vec<InstructionTextToken>, addr: u64) -> Self {
147 Self {
148 address: addr,
149 tokens,
150 ..Default::default()
151 }
152 }
153}
154
155impl From<&str> for DisassemblyTextLine {
156 fn from(value: &str) -> Self {
157 Self::new(vec![InstructionTextToken::new(
158 value,
159 InstructionTextTokenKind::Text,
160 )])
161 }
162}
163
164impl From<String> for DisassemblyTextLine {
165 fn from(value: String) -> Self {
166 Self::new(vec![InstructionTextToken::new(
167 value,
168 InstructionTextTokenKind::Text,
169 )])
170 }
171}
172
173impl Display for DisassemblyTextLine {
174 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
175 for token in &self.tokens {
176 write!(f, "{}", token)?;
177 }
178 Ok(())
179 }
180}
181
182impl CoreArrayProvider for DisassemblyTextLine {
183 type Raw = BNDisassemblyTextLine;
184 type Context = ();
185 type Wrapped<'a> = Self;
186}
187
188unsafe impl CoreArrayProviderInner for DisassemblyTextLine {
189 unsafe fn free(raw: *mut Self::Raw, count: usize, _context: &Self::Context) {
190 BNFreeDisassemblyTextLines(raw, count)
191 }
192
193 unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, _context: &'a Self::Context) -> Self::Wrapped<'a> {
194 Self::from_raw(raw)
195 }
196}
197
198#[derive(Default, Clone, PartialEq, Eq, Debug, Hash)]
199pub struct DisassemblyTextLineTypeInfo {
200 pub has_type_info: bool,
201 pub parent_type: Option<Ref<Type>>,
202 pub field_index: usize,
203 pub offset: u64,
204}
205
206impl DisassemblyTextLineTypeInfo {
207 pub(crate) fn from_raw(value: &BNDisassemblyTextLineTypeInfo) -> Self {
208 Self {
209 has_type_info: value.hasTypeInfo,
210 parent_type: match value.parentType.is_null() {
211 false => Some(unsafe { Type::from_raw(value.parentType).to_owned() }),
212 true => None,
213 },
214 field_index: value.fieldIndex,
215 offset: value.offset,
216 }
217 }
218
219 pub(crate) fn from_owned_raw(value: BNDisassemblyTextLineTypeInfo) -> Self {
220 Self {
221 has_type_info: value.hasTypeInfo,
222 parent_type: match value.parentType.is_null() {
223 false => Some(unsafe { Type::ref_from_raw(value.parentType) }),
224 true => None,
225 },
226 field_index: value.fieldIndex,
227 offset: value.offset,
228 }
229 }
230
231 pub(crate) fn into_raw(value: Self) -> BNDisassemblyTextLineTypeInfo {
232 BNDisassemblyTextLineTypeInfo {
233 hasTypeInfo: value.has_type_info,
234 parentType: value
235 .parent_type
236 .map(|t| unsafe { Ref::into_raw(t) }.handle)
237 .unwrap_or(std::ptr::null_mut()),
238 fieldIndex: value.field_index,
239 offset: value.offset,
240 }
241 }
242
243 pub(crate) fn into_owned_raw(value: &Self) -> BNDisassemblyTextLineTypeInfo {
244 BNDisassemblyTextLineTypeInfo {
245 hasTypeInfo: value.has_type_info,
246 parentType: value
247 .parent_type
248 .as_ref()
249 .map(|t| t.handle)
250 .unwrap_or(std::ptr::null_mut()),
251 fieldIndex: value.field_index,
252 offset: value.offset,
253 }
254 }
255
256 pub(crate) fn free_raw(value: BNDisassemblyTextLineTypeInfo) {
257 if !value.parentType.is_null() {
258 let _ = unsafe { Type::ref_from_raw(value.parentType) };
259 }
260 }
261}
262
263#[derive(Debug, Clone, PartialEq, Eq)]
264pub struct InstructionTextToken {
265 pub address: u64,
266 pub text: String,
267 pub confidence: u8,
268 pub context: InstructionTextTokenContext,
269 pub expr_index: usize,
271 pub kind: InstructionTextTokenKind,
272}
273
274impl InstructionTextToken {
275 pub(crate) fn from_raw(value: &BNInstructionTextToken) -> Self {
276 Self {
277 address: value.address,
278 text: raw_to_string(value.text).unwrap(),
279 confidence: value.confidence,
280 context: value.context.into(),
281 expr_index: value.exprIndex,
282 kind: InstructionTextTokenKind::from_raw(value),
283 }
284 }
285
286 pub(crate) fn into_raw(value: Self) -> BNInstructionTextToken {
287 let bn_text = BnString::new(value.text);
288 let kind_value = value.kind.try_value().unwrap_or(0);
290 let operand = value.kind.try_operand().unwrap_or(0);
291 let size = value.kind.try_size().unwrap_or(0);
292 let type_names = value.kind.try_type_names().unwrap_or_default();
293 BNInstructionTextToken {
294 type_: value.kind.into(),
295 text: BnString::into_raw(bn_text),
297 value: kind_value,
298 width: 0,
300 size,
301 operand,
302 context: value.context.into(),
303 confidence: value.confidence,
304 address: value.address,
305 typeNames: strings_to_string_list(&type_names),
307 namesCount: type_names.len(),
308 exprIndex: value.expr_index,
309 }
310 }
311
312 pub(crate) fn free_raw(value: BNInstructionTextToken) {
313 unsafe { BnString::free_raw(value.text) };
314 if !value.typeNames.is_null() {
315 unsafe { BNFreeStringList(value.typeNames, value.namesCount) };
316 }
317 }
318
319 pub fn new(text: impl Into<String>, kind: InstructionTextTokenKind) -> Self {
324 Self {
325 address: 0,
326 text: text.into(),
327 confidence: MAX_CONFIDENCE,
328 context: InstructionTextTokenContext::Normal,
329 expr_index: 0,
330 kind,
331 }
332 }
333
334 pub fn new_with_address(
335 address: u64,
336 text: impl Into<String>,
337 kind: InstructionTextTokenKind,
338 ) -> Self {
339 Self {
340 address,
341 text: text.into(),
342 confidence: MAX_CONFIDENCE,
343 context: InstructionTextTokenContext::Normal,
344 expr_index: 0,
345 kind,
346 }
347 }
348}
349
350impl Display for InstructionTextToken {
351 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
352 self.text.fmt(f)
353 }
354}
355
356impl CoreArrayProvider for InstructionTextToken {
357 type Raw = BNInstructionTextToken;
358 type Context = ();
359 type Wrapped<'a> = Self;
360}
361
362unsafe impl CoreArrayProviderInner for InstructionTextToken {
363 unsafe fn free(raw: *mut Self::Raw, count: usize, _context: &Self::Context) {
364 BNFreeInstructionText(raw, count)
366 }
367
368 unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, _context: &'a Self::Context) -> Self::Wrapped<'a> {
369 Self::from_raw(raw)
370 }
371}
372
373impl CoreArrayProvider for Array<InstructionTextToken> {
374 type Raw = BNInstructionTextLine;
375 type Context = ();
376 type Wrapped<'a> = std::mem::ManuallyDrop<Self>;
377}
378
379unsafe impl CoreArrayProviderInner for Array<InstructionTextToken> {
380 unsafe fn free(raw: *mut Self::Raw, count: usize, _context: &Self::Context) {
381 BNFreeInstructionTextLines(raw, count)
383 }
384
385 unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, _context: &'a Self::Context) -> Self::Wrapped<'a> {
386 std::mem::ManuallyDrop::new(Self::new(raw.tokens, raw.count, ()))
388 }
389}
390
391#[derive(Clone, PartialEq, Debug)]
392pub enum InstructionTextTokenKind {
393 Text,
394 Instruction,
395 OperandSeparator,
396 Register,
397 Integer {
398 value: u64,
399 size: Option<usize>,
401 },
402 PossibleAddress {
403 value: u64,
404 size: Option<usize>,
406 },
407 BeginMemoryOperand,
408 EndMemoryOperand,
409 FloatingPoint {
410 value: f64,
411 size: Option<usize>,
413 },
414 Annotation,
415 CodeRelativeAddress {
416 value: u64,
417 size: Option<usize>,
418 },
419 ArgumentName {
420 value: u64,
422 },
423 HexDumpByteValue {
424 value: u8,
425 },
426 HexDumpSkippedByte,
427 HexDumpInvalidByte,
428 HexDumpText {
429 width: u64,
431 },
432 Opcode,
433 String {
434 value: u64,
437 },
438 StringContent {
442 ty: StringType,
443 },
444 CharacterConstant,
445 Keyword {
446 value: u64,
448 },
449 TypeName,
450 FieldName {
451 offset: u64,
453 type_names: Vec<String>,
458 },
459 NameSpace,
460 NameSpaceSeparator,
461 Tag,
462 StructOffset {
463 offset: u64,
465 type_names: Vec<String>,
468 },
469 StructOffsetByteValue,
471 StructureHexDumpText {
473 width: u64,
475 },
476 GotoLabel {
477 target: u64,
478 },
479 Comment {
480 target: u64,
481 },
482 PossibleValue {
483 value: u64,
484 },
485 PossibleValueType,
487 ArrayIndex {
488 index: u64,
489 },
490 Indentation,
491 UnknownMemory,
492 EnumerationMember {
493 value: u64,
494 type_id: Option<String>,
498 },
499 Operation,
501 BaseStructureName,
502 BaseStructureSeparator,
503 Brace {
504 hash: Option<u64>,
506 },
507 CodeSymbol {
508 value: u64,
510 size: usize, },
513 DataSymbol {
514 value: u64,
516 size: usize, },
519 LocalVariable {
520 variable_id: u64,
524 ssa_version: usize,
526 },
527 Import {
528 target: u64,
530 },
531 AddressDisplay {
532 address: u64,
533 },
534 IndirectImport {
536 target: u64,
540 size: usize,
542 source_operand: usize,
544 },
545 ExternalSymbol {
546 value: u64,
548 },
549 StackVariable {
550 variable_id: u64,
553 },
554 AddressSeparator,
555 CollapsedInformation,
556 CollapseStateIndicator {
557 hash: Option<u64>,
559 },
560 NewLine {
561 value: u64,
563 },
564}
565
566impl InstructionTextTokenKind {
567 pub(crate) fn from_raw(value: &BNInstructionTextToken) -> Self {
568 match value.type_ {
569 BNInstructionTextTokenType::TextToken => Self::Text,
570 BNInstructionTextTokenType::InstructionToken => Self::Instruction,
571 BNInstructionTextTokenType::OperandSeparatorToken => Self::OperandSeparator,
572 BNInstructionTextTokenType::RegisterToken => Self::Register,
573 BNInstructionTextTokenType::IntegerToken => Self::Integer {
574 value: value.value,
575 size: match value.size {
576 0 => None,
577 size => Some(size),
578 },
579 },
580 BNInstructionTextTokenType::PossibleAddressToken => Self::PossibleAddress {
581 value: value.value,
582 size: match value.size {
583 0 => None,
584 size => Some(size),
585 },
586 },
587 BNInstructionTextTokenType::BeginMemoryOperandToken => Self::BeginMemoryOperand,
588 BNInstructionTextTokenType::EndMemoryOperandToken => Self::EndMemoryOperand,
589 BNInstructionTextTokenType::FloatingPointToken => Self::FloatingPoint {
590 value: value.value as f64,
591 size: match value.size {
592 0 => None,
593 size => Some(size),
594 },
595 },
596 BNInstructionTextTokenType::AnnotationToken => Self::Annotation,
597 BNInstructionTextTokenType::CodeRelativeAddressToken => Self::CodeRelativeAddress {
598 value: value.value,
599 size: match value.size {
600 0 => None,
601 size => Some(size),
602 },
603 },
604 BNInstructionTextTokenType::ArgumentNameToken => {
605 Self::ArgumentName { value: value.value }
606 }
607 BNInstructionTextTokenType::HexDumpByteValueToken => Self::HexDumpByteValue {
608 value: value.value as u8,
609 },
610 BNInstructionTextTokenType::HexDumpSkippedByteToken => Self::HexDumpSkippedByte,
611 BNInstructionTextTokenType::HexDumpInvalidByteToken => Self::HexDumpInvalidByte,
612 BNInstructionTextTokenType::HexDumpTextToken => {
613 Self::HexDumpText { width: value.value }
614 }
615 BNInstructionTextTokenType::OpcodeToken => Self::Opcode,
616 BNInstructionTextTokenType::StringToken => match value.context {
617 BNInstructionTextTokenContext::StringReferenceTokenContext
618 | BNInstructionTextTokenContext::StringDisplayTokenContext => {
619 match value.value {
620 0 => Self::StringContent {
621 ty: StringType::AsciiString,
622 },
623 1 => Self::StringContent {
624 ty: StringType::Utf8String,
625 },
626 2 => Self::StringContent {
627 ty: StringType::Utf16String,
628 },
629 3 => Self::StringContent {
630 ty: StringType::Utf32String,
631 },
632 value => Self::String { value },
636 }
637 }
638 _ => Self::String { value: value.value },
639 },
640 BNInstructionTextTokenType::CharacterConstantToken => Self::CharacterConstant,
641 BNInstructionTextTokenType::KeywordToken => Self::Keyword { value: value.value },
642 BNInstructionTextTokenType::TypeNameToken => Self::TypeName,
643 BNInstructionTextTokenType::FieldNameToken => Self::FieldName {
644 offset: value.value,
645 type_names: {
646 let raw_names =
648 unsafe { std::slice::from_raw_parts(value.typeNames, value.namesCount) };
649 raw_names.iter().filter_map(|&r| raw_to_string(r)).collect()
650 },
651 },
652 BNInstructionTextTokenType::NameSpaceToken => Self::NameSpace,
653 BNInstructionTextTokenType::NameSpaceSeparatorToken => Self::NameSpaceSeparator,
654 BNInstructionTextTokenType::TagToken => Self::Tag,
655 BNInstructionTextTokenType::StructOffsetToken => Self::StructOffset {
656 offset: value.value,
657 type_names: {
658 let raw_names =
660 unsafe { std::slice::from_raw_parts(value.typeNames, value.namesCount) };
661 raw_names.iter().filter_map(|&r| raw_to_string(r)).collect()
662 },
663 },
664 BNInstructionTextTokenType::StructOffsetByteValueToken => Self::StructOffsetByteValue,
665 BNInstructionTextTokenType::StructureHexDumpTextToken => {
666 Self::StructureHexDumpText { width: value.value }
667 }
668 BNInstructionTextTokenType::GotoLabelToken => Self::GotoLabel {
669 target: value.value,
670 },
671 BNInstructionTextTokenType::CommentToken => Self::Comment {
672 target: value.value,
673 },
674 BNInstructionTextTokenType::PossibleValueToken => {
675 Self::PossibleValue { value: value.value }
676 }
677 BNInstructionTextTokenType::PossibleValueTypeToken => Self::PossibleValueType,
679 BNInstructionTextTokenType::ArrayIndexToken => Self::ArrayIndex { index: value.value },
680 BNInstructionTextTokenType::IndentationToken => Self::Indentation,
681 BNInstructionTextTokenType::UnknownMemoryToken => Self::UnknownMemory,
682 BNInstructionTextTokenType::EnumerationMemberToken => Self::EnumerationMember {
683 value: value.value,
684 type_id: {
685 let raw_names =
688 unsafe { std::slice::from_raw_parts(value.typeNames, value.namesCount) };
689 raw_names.iter().filter_map(|&r| raw_to_string(r)).next()
690 },
691 },
692 BNInstructionTextTokenType::OperationToken => Self::Operation,
693 BNInstructionTextTokenType::BaseStructureNameToken => Self::BaseStructureName,
694 BNInstructionTextTokenType::BaseStructureSeparatorToken => Self::BaseStructureSeparator,
695 BNInstructionTextTokenType::BraceToken => Self::Brace {
696 hash: match value.value {
697 0 => None,
698 hash => Some(hash),
699 },
700 },
701 BNInstructionTextTokenType::CodeSymbolToken => Self::CodeSymbol {
702 value: value.value,
703 size: value.size,
704 },
705 BNInstructionTextTokenType::DataSymbolToken => Self::DataSymbol {
706 value: value.value,
707 size: value.size,
708 },
709 BNInstructionTextTokenType::LocalVariableToken => Self::LocalVariable {
710 variable_id: value.value,
711 ssa_version: value.operand,
712 },
713 BNInstructionTextTokenType::ImportToken => Self::Import {
714 target: value.value,
715 },
716 BNInstructionTextTokenType::AddressDisplayToken => Self::AddressDisplay {
717 address: value.value,
718 },
719 BNInstructionTextTokenType::IndirectImportToken => Self::IndirectImport {
720 target: value.value,
721 size: value.size,
722 source_operand: value.operand,
723 },
724 BNInstructionTextTokenType::ExternalSymbolToken => {
725 Self::ExternalSymbol { value: value.value }
726 }
727 BNInstructionTextTokenType::StackVariableToken => Self::StackVariable {
728 variable_id: value.value,
729 },
730 BNInstructionTextTokenType::AddressSeparatorToken => Self::AddressSeparator,
731 BNInstructionTextTokenType::CollapsedInformationToken => Self::CollapsedInformation,
732 BNInstructionTextTokenType::CollapseStateIndicatorToken => {
733 Self::CollapseStateIndicator {
734 hash: match value.value {
735 0 => None,
736 hash => Some(hash),
737 },
738 }
739 }
740 BNInstructionTextTokenType::NewLineToken => Self::NewLine { value: value.value },
741 }
742 }
743
744 fn try_value(&self) -> Option<u64> {
746 match self {
748 InstructionTextTokenKind::Integer { value, .. } => Some(*value),
749 InstructionTextTokenKind::PossibleAddress { value, .. } => Some(*value),
750 InstructionTextTokenKind::PossibleValue { value, .. } => Some(*value),
751 InstructionTextTokenKind::FloatingPoint { value, .. } => Some(*value as u64),
752 InstructionTextTokenKind::CodeRelativeAddress { value, .. } => Some(*value),
753 InstructionTextTokenKind::ArgumentName { value, .. } => Some(*value),
754 InstructionTextTokenKind::HexDumpByteValue { value, .. } => Some(*value as u64),
755 InstructionTextTokenKind::HexDumpText { width, .. } => Some(*width),
756 InstructionTextTokenKind::String { value, .. } => Some(*value),
757 InstructionTextTokenKind::StringContent { ty, .. } => Some(*ty as u64),
758 InstructionTextTokenKind::Keyword { value, .. } => Some(*value),
759 InstructionTextTokenKind::FieldName { offset, .. } => Some(*offset),
760 InstructionTextTokenKind::StructOffset { offset, .. } => Some(*offset),
761 InstructionTextTokenKind::StructureHexDumpText { width, .. } => Some(*width),
762 InstructionTextTokenKind::GotoLabel { target, .. } => Some(*target),
763 InstructionTextTokenKind::Comment { target, .. } => Some(*target),
764 InstructionTextTokenKind::ArrayIndex { index, .. } => Some(*index),
765 InstructionTextTokenKind::EnumerationMember { value, .. } => Some(*value),
766 InstructionTextTokenKind::LocalVariable { variable_id, .. } => Some(*variable_id),
767 InstructionTextTokenKind::Import { target, .. } => Some(*target),
768 InstructionTextTokenKind::AddressDisplay { address, .. } => Some(*address),
769 InstructionTextTokenKind::IndirectImport { target, .. } => Some(*target),
770 InstructionTextTokenKind::Brace { hash, .. } => *hash,
771 InstructionTextTokenKind::CodeSymbol { value, .. } => Some(*value),
772 InstructionTextTokenKind::DataSymbol { value, .. } => Some(*value),
773 InstructionTextTokenKind::ExternalSymbol { value, .. } => Some(*value),
774 InstructionTextTokenKind::StackVariable { variable_id, .. } => Some(*variable_id),
775 InstructionTextTokenKind::CollapseStateIndicator { hash, .. } => *hash,
776 InstructionTextTokenKind::NewLine { value, .. } => Some(*value),
777 _ => None,
778 }
779 }
780
781 fn try_size(&self) -> Option<usize> {
783 match self {
784 InstructionTextTokenKind::Integer { size, .. } => *size,
785 InstructionTextTokenKind::FloatingPoint { size, .. } => *size,
786 InstructionTextTokenKind::PossibleAddress { size, .. } => *size,
787 InstructionTextTokenKind::CodeRelativeAddress { size, .. } => *size,
788 InstructionTextTokenKind::CodeSymbol { size, .. } => Some(*size),
789 InstructionTextTokenKind::DataSymbol { size, .. } => Some(*size),
790 InstructionTextTokenKind::IndirectImport { size, .. } => Some(*size),
791 _ => None,
792 }
793 }
794
795 fn try_operand(&self) -> Option<usize> {
797 match self {
798 InstructionTextTokenKind::LocalVariable { ssa_version, .. } => Some(*ssa_version),
799 InstructionTextTokenKind::IndirectImport { source_operand, .. } => {
800 Some(*source_operand)
801 }
802 _ => None,
803 }
804 }
805
806 fn try_type_names(&self) -> Option<Vec<String>> {
808 match self {
809 InstructionTextTokenKind::FieldName { type_names, .. } => Some(type_names.clone()),
810 InstructionTextTokenKind::StructOffset { type_names, .. } => Some(type_names.clone()),
811 InstructionTextTokenKind::EnumerationMember { type_id, .. } => {
812 Some(vec![type_id.clone()?])
813 }
814 _ => None,
815 }
816 }
817}
818
819impl From<InstructionTextTokenKind> for BNInstructionTextTokenType {
820 fn from(value: InstructionTextTokenKind) -> Self {
821 match value {
822 InstructionTextTokenKind::Text => BNInstructionTextTokenType::TextToken,
823 InstructionTextTokenKind::Instruction => BNInstructionTextTokenType::InstructionToken,
824 InstructionTextTokenKind::OperandSeparator => {
825 BNInstructionTextTokenType::OperandSeparatorToken
826 }
827 InstructionTextTokenKind::Register => BNInstructionTextTokenType::RegisterToken,
828 InstructionTextTokenKind::Integer { .. } => BNInstructionTextTokenType::IntegerToken,
829 InstructionTextTokenKind::PossibleAddress { .. } => {
830 BNInstructionTextTokenType::PossibleAddressToken
831 }
832 InstructionTextTokenKind::BeginMemoryOperand => {
833 BNInstructionTextTokenType::BeginMemoryOperandToken
834 }
835 InstructionTextTokenKind::EndMemoryOperand => {
836 BNInstructionTextTokenType::EndMemoryOperandToken
837 }
838 InstructionTextTokenKind::FloatingPoint { .. } => {
839 BNInstructionTextTokenType::FloatingPointToken
840 }
841 InstructionTextTokenKind::Annotation => BNInstructionTextTokenType::AnnotationToken,
842 InstructionTextTokenKind::CodeRelativeAddress { .. } => {
843 BNInstructionTextTokenType::CodeRelativeAddressToken
844 }
845 InstructionTextTokenKind::ArgumentName { .. } => {
846 BNInstructionTextTokenType::ArgumentNameToken
847 }
848 InstructionTextTokenKind::HexDumpByteValue { .. } => {
849 BNInstructionTextTokenType::HexDumpByteValueToken
850 }
851 InstructionTextTokenKind::HexDumpSkippedByte => {
852 BNInstructionTextTokenType::HexDumpSkippedByteToken
853 }
854 InstructionTextTokenKind::HexDumpInvalidByte => {
855 BNInstructionTextTokenType::HexDumpInvalidByteToken
856 }
857 InstructionTextTokenKind::HexDumpText { .. } => {
858 BNInstructionTextTokenType::HexDumpTextToken
859 }
860 InstructionTextTokenKind::Opcode => BNInstructionTextTokenType::OpcodeToken,
861 InstructionTextTokenKind::String { .. } => BNInstructionTextTokenType::StringToken,
862 InstructionTextTokenKind::StringContent { .. } => {
863 BNInstructionTextTokenType::StringToken
864 }
865 InstructionTextTokenKind::CharacterConstant => {
866 BNInstructionTextTokenType::CharacterConstantToken
867 }
868 InstructionTextTokenKind::Keyword { .. } => BNInstructionTextTokenType::KeywordToken,
869 InstructionTextTokenKind::TypeName => BNInstructionTextTokenType::TypeNameToken,
870 InstructionTextTokenKind::FieldName { .. } => {
871 BNInstructionTextTokenType::FieldNameToken
872 }
873 InstructionTextTokenKind::NameSpace => BNInstructionTextTokenType::NameSpaceToken,
874 InstructionTextTokenKind::NameSpaceSeparator => {
875 BNInstructionTextTokenType::NameSpaceSeparatorToken
876 }
877 InstructionTextTokenKind::Tag => BNInstructionTextTokenType::TagToken,
878 InstructionTextTokenKind::StructOffset { .. } => {
879 BNInstructionTextTokenType::StructOffsetToken
880 }
881 InstructionTextTokenKind::StructOffsetByteValue => {
882 BNInstructionTextTokenType::StructOffsetByteValueToken
883 }
884 InstructionTextTokenKind::StructureHexDumpText { .. } => {
885 BNInstructionTextTokenType::StructureHexDumpTextToken
886 }
887 InstructionTextTokenKind::GotoLabel { .. } => {
888 BNInstructionTextTokenType::GotoLabelToken
889 }
890 InstructionTextTokenKind::Comment { .. } => BNInstructionTextTokenType::CommentToken,
891 InstructionTextTokenKind::PossibleValue { .. } => {
892 BNInstructionTextTokenType::PossibleValueToken
893 }
894 InstructionTextTokenKind::PossibleValueType => {
895 BNInstructionTextTokenType::PossibleValueTypeToken
896 }
897 InstructionTextTokenKind::ArrayIndex { .. } => {
898 BNInstructionTextTokenType::ArrayIndexToken
899 }
900 InstructionTextTokenKind::Indentation => BNInstructionTextTokenType::IndentationToken,
901 InstructionTextTokenKind::UnknownMemory => {
902 BNInstructionTextTokenType::UnknownMemoryToken
903 }
904 InstructionTextTokenKind::EnumerationMember { .. } => {
905 BNInstructionTextTokenType::EnumerationMemberToken
906 }
907 InstructionTextTokenKind::Operation => BNInstructionTextTokenType::OperationToken,
908 InstructionTextTokenKind::BaseStructureName => {
909 BNInstructionTextTokenType::BaseStructureNameToken
910 }
911 InstructionTextTokenKind::BaseStructureSeparator => {
912 BNInstructionTextTokenType::BaseStructureSeparatorToken
913 }
914 InstructionTextTokenKind::Brace { .. } => BNInstructionTextTokenType::BraceToken,
915 InstructionTextTokenKind::CodeSymbol { .. } => {
916 BNInstructionTextTokenType::CodeSymbolToken
917 }
918 InstructionTextTokenKind::DataSymbol { .. } => {
919 BNInstructionTextTokenType::DataSymbolToken
920 }
921 InstructionTextTokenKind::LocalVariable { .. } => {
922 BNInstructionTextTokenType::LocalVariableToken
923 }
924 InstructionTextTokenKind::Import { .. } => BNInstructionTextTokenType::ImportToken,
925 InstructionTextTokenKind::AddressDisplay { .. } => {
926 BNInstructionTextTokenType::AddressDisplayToken
927 }
928 InstructionTextTokenKind::IndirectImport { .. } => {
929 BNInstructionTextTokenType::IndirectImportToken
930 }
931 InstructionTextTokenKind::ExternalSymbol { .. } => {
932 BNInstructionTextTokenType::ExternalSymbolToken
933 }
934 InstructionTextTokenKind::StackVariable { .. } => {
935 BNInstructionTextTokenType::StackVariableToken
936 }
937 InstructionTextTokenKind::AddressSeparator => {
938 BNInstructionTextTokenType::AddressSeparatorToken
939 }
940 InstructionTextTokenKind::CollapsedInformation => {
941 BNInstructionTextTokenType::CollapsedInformationToken
942 }
943 InstructionTextTokenKind::CollapseStateIndicator { .. } => {
944 BNInstructionTextTokenType::CollapseStateIndicatorToken
945 }
946 InstructionTextTokenKind::NewLine { .. } => BNInstructionTextTokenType::NewLineToken,
947 }
948 }
949}
950
951impl Eq for InstructionTextTokenKind {}
952
953#[derive(Clone, Copy, PartialEq, Eq, Debug)]
954pub enum InstructionTextTokenContext {
955 Normal,
956 LocalVariable,
957 DataVariable,
958 FunctionReturn,
959 InstructionAddress,
960 ILInstructionIndex,
961 ConstData,
962 ConstStringData,
964 StringReference,
966 StringDataVariable,
968 StringDisplay,
972 Collapsed,
974 Expanded,
976 CollapsiblePadding,
978 DerivedStringReference,
980}
981
982impl From<BNInstructionTextTokenContext> for InstructionTextTokenContext {
983 fn from(value: BNInstructionTextTokenContext) -> Self {
984 match value {
985 BNInstructionTextTokenContext::NoTokenContext => Self::Normal,
986 BNInstructionTextTokenContext::LocalVariableTokenContext => Self::LocalVariable,
987 BNInstructionTextTokenContext::DataVariableTokenContext => Self::DataVariable,
988 BNInstructionTextTokenContext::FunctionReturnTokenContext => Self::FunctionReturn,
989 BNInstructionTextTokenContext::InstructionAddressTokenContext => {
990 Self::InstructionAddress
991 }
992 BNInstructionTextTokenContext::ILInstructionIndexTokenContext => {
993 Self::ILInstructionIndex
994 }
995 BNInstructionTextTokenContext::ConstDataTokenContext => Self::ConstData,
996 BNInstructionTextTokenContext::ConstStringDataTokenContext => Self::ConstStringData,
998 BNInstructionTextTokenContext::StringReferenceTokenContext => Self::StringReference,
999 BNInstructionTextTokenContext::StringDataVariableTokenContext => {
1000 Self::StringDataVariable
1001 }
1002 BNInstructionTextTokenContext::StringDisplayTokenContext => Self::StringDisplay,
1003 BNInstructionTextTokenContext::ContentCollapsedContext => Self::Collapsed,
1005 BNInstructionTextTokenContext::ContentExpandedContext => Self::Expanded,
1006 BNInstructionTextTokenContext::ContentCollapsiblePadding => Self::CollapsiblePadding,
1007 BNInstructionTextTokenContext::DerivedStringReferenceTokenContext => {
1008 Self::DerivedStringReference
1009 }
1010 }
1011 }
1012}
1013
1014impl From<InstructionTextTokenContext> for BNInstructionTextTokenContext {
1015 fn from(value: InstructionTextTokenContext) -> Self {
1016 match value {
1017 InstructionTextTokenContext::Normal => Self::NoTokenContext,
1018 InstructionTextTokenContext::LocalVariable => Self::LocalVariableTokenContext,
1019 InstructionTextTokenContext::DataVariable => Self::DataVariableTokenContext,
1020 InstructionTextTokenContext::FunctionReturn => Self::FunctionReturnTokenContext,
1021 InstructionTextTokenContext::InstructionAddress => Self::InstructionAddressTokenContext,
1022 InstructionTextTokenContext::ILInstructionIndex => Self::ILInstructionIndexTokenContext,
1023 InstructionTextTokenContext::ConstData => Self::ConstDataTokenContext,
1024 InstructionTextTokenContext::ConstStringData => Self::ConstStringDataTokenContext,
1025 InstructionTextTokenContext::StringReference => Self::StringReferenceTokenContext,
1026 InstructionTextTokenContext::StringDataVariable => Self::StringDataVariableTokenContext,
1027 InstructionTextTokenContext::StringDisplay => Self::StringDisplayTokenContext,
1028 InstructionTextTokenContext::Collapsed => Self::ContentCollapsedContext,
1029 InstructionTextTokenContext::Expanded => Self::ContentExpandedContext,
1030 InstructionTextTokenContext::CollapsiblePadding => Self::ContentCollapsiblePadding,
1031 InstructionTextTokenContext::DerivedStringReference => {
1032 Self::DerivedStringReferenceTokenContext
1033 }
1034 }
1035 }
1036}
1037
1038#[repr(transparent)]
1039pub struct DisassemblyTextRenderer {
1040 handle: NonNull<BNDisassemblyTextRenderer>,
1041}
1042
1043impl DisassemblyTextRenderer {
1044 pub unsafe fn ref_from_raw(handle: NonNull<BNDisassemblyTextRenderer>) -> Ref<Self> {
1045 Ref::new(Self { handle })
1046 }
1047
1048 pub fn from_function(func: &Function, settings: Option<&DisassemblySettings>) -> Ref<Self> {
1049 let settings_ptr = settings.map(|s| s.handle).unwrap_or(ptr::null_mut());
1050 let result = unsafe { BNCreateDisassemblyTextRenderer(func.handle, settings_ptr) };
1051 unsafe { Self::ref_from_raw(NonNull::new(result).unwrap()) }
1052 }
1053
1054 pub fn from_llil<M: FunctionMutability, F: FunctionForm>(
1055 func: &LowLevelILFunction<M, F>,
1056 settings: Option<&DisassemblySettings>,
1057 ) -> Ref<Self> {
1058 let settings_ptr = settings.map(|s| s.handle).unwrap_or(ptr::null_mut());
1059 let result =
1060 unsafe { BNCreateLowLevelILDisassemblyTextRenderer(func.handle, settings_ptr) };
1061 unsafe { Self::ref_from_raw(NonNull::new(result).unwrap()) }
1062 }
1063
1064 pub fn from_mlil(
1065 func: &MediumLevelILFunction,
1066 settings: Option<&DisassemblySettings>,
1067 ) -> Ref<Self> {
1068 let settings_ptr = settings.map(|s| s.handle).unwrap_or(ptr::null_mut());
1069 let result =
1070 unsafe { BNCreateMediumLevelILDisassemblyTextRenderer(func.handle, settings_ptr) };
1071 unsafe { Self::ref_from_raw(NonNull::new(result).unwrap()) }
1072 }
1073
1074 pub fn from_hlil(
1075 func: &HighLevelILFunction,
1076 settings: Option<&DisassemblySettings>,
1077 ) -> Ref<Self> {
1078 let settings_ptr = settings.map(|s| s.handle).unwrap_or(ptr::null_mut());
1079 let result =
1080 unsafe { BNCreateHighLevelILDisassemblyTextRenderer(func.handle, settings_ptr) };
1081 unsafe { Self::ref_from_raw(NonNull::new(result).unwrap()) }
1082 }
1083
1084 pub fn function(&self) -> Ref<Function> {
1085 let result = unsafe { BNGetDisassemblyTextRendererFunction(self.handle.as_ptr()) };
1086 assert!(!result.is_null());
1087 unsafe { Function::ref_from_raw(result) }
1088 }
1089
1090 pub fn llil<M: FunctionMutability, F: FunctionForm>(&self) -> Ref<LowLevelILFunction<M, F>> {
1091 let result =
1092 unsafe { BNGetDisassemblyTextRendererLowLevelILFunction(self.handle.as_ptr()) };
1093 assert!(!result.is_null());
1094 unsafe { LowLevelILFunction::ref_from_raw(result) }
1095 }
1096
1097 pub fn mlil(&self) -> Ref<MediumLevelILFunction> {
1098 let result =
1099 unsafe { BNGetDisassemblyTextRendererMediumLevelILFunction(self.handle.as_ptr()) };
1100 assert!(!result.is_null());
1101 unsafe { MediumLevelILFunction::ref_from_raw(result) }
1102 }
1103
1104 pub fn hlil(&self) -> Ref<HighLevelILFunction> {
1105 let result =
1106 unsafe { BNGetDisassemblyTextRendererHighLevelILFunction(self.handle.as_ptr()) };
1107 assert!(!result.is_null());
1108 unsafe { HighLevelILFunction::ref_from_raw(result, true) }
1109 }
1110
1111 pub fn basic_block(&self) -> Option<Ref<BasicBlock<NativeBlock>>> {
1112 let result = unsafe { BNGetDisassemblyTextRendererBasicBlock(self.handle.as_ptr()) };
1113 if result.is_null() {
1114 return None;
1115 }
1116 Some(unsafe { Ref::new(BasicBlock::from_raw(result, NativeBlock::new())) })
1117 }
1118
1119 pub fn set_basic_block(&self, value: Option<&BasicBlock<NativeBlock>>) {
1120 let block_ptr = value.map(|b| b.handle).unwrap_or(ptr::null_mut());
1121 unsafe { BNSetDisassemblyTextRendererBasicBlock(self.handle.as_ptr(), block_ptr) }
1122 }
1123
1124 pub fn arch(&self) -> CoreArchitecture {
1125 let result = unsafe { BNGetDisassemblyTextRendererArchitecture(self.handle.as_ptr()) };
1126 assert!(!result.is_null());
1127 unsafe { CoreArchitecture::from_raw(result) }
1128 }
1129
1130 pub fn set_arch(&self, value: CoreArchitecture) {
1131 unsafe { BNSetDisassemblyTextRendererArchitecture(self.handle.as_ptr(), value.handle) }
1132 }
1133
1134 pub fn settings(&self) -> Ref<DisassemblySettings> {
1135 let result = unsafe { BNGetDisassemblyTextRendererSettings(self.handle.as_ptr()) };
1136 unsafe { DisassemblySettings::ref_from_raw(result) }
1137 }
1138
1139 pub fn set_settings(&self, settings: Option<&DisassemblySettings>) {
1140 let settings_ptr = settings.map(|s| s.handle).unwrap_or(ptr::null_mut());
1141 unsafe { BNSetDisassemblyTextRendererSettings(self.handle.as_ptr(), settings_ptr) }
1142 }
1143
1144 pub fn is_il(&self) -> bool {
1145 unsafe { BNIsILDisassemblyTextRenderer(self.handle.as_ptr()) }
1146 }
1147
1148 pub fn has_data_flow(&self) -> bool {
1149 unsafe { BNDisassemblyTextRendererHasDataFlow(self.handle.as_ptr()) }
1150 }
1151
1152 pub fn instruction_annotations(&self, addr: u64) -> Array<InstructionTextToken> {
1154 let mut count = 0;
1155 let result = unsafe {
1156 BNGetDisassemblyTextRendererInstructionAnnotations(
1157 self.handle.as_ptr(),
1158 addr,
1159 &mut count,
1160 )
1161 };
1162 assert!(!result.is_null());
1163 unsafe { Array::new(result, count, ()) }
1164 }
1165
1166 pub fn instruction_text(&self, addr: u64) -> Option<(Array<DisassemblyTextLine>, usize)> {
1168 let mut count = 0;
1169 let mut length = 0;
1170 let mut lines: *mut BNDisassemblyTextLine = ptr::null_mut();
1171 let result = unsafe {
1172 BNGetDisassemblyTextRendererInstructionText(
1173 self.handle.as_ptr(),
1174 addr,
1175 &mut length,
1176 &mut lines,
1177 &mut count,
1178 )
1179 };
1180 result.then(|| (unsafe { Array::new(lines, count, ()) }, length))
1181 }
1182
1183 pub fn disassembly_text(&self, addr: u64) -> Option<(Array<DisassemblyTextLine>, usize)> {
1185 let mut count = 0;
1186 let mut length = 0;
1187 let mut lines: *mut BNDisassemblyTextLine = ptr::null_mut();
1188 let result = unsafe {
1189 BNGetDisassemblyTextRendererLines(
1190 self.handle.as_ptr(),
1191 addr,
1192 &mut length,
1193 &mut lines,
1194 &mut count,
1195 )
1196 };
1197 result.then(|| (unsafe { Array::new(lines, count, ()) }, length))
1198 }
1199
1200 pub fn is_integer_token(token_type: InstructionTextTokenType) -> bool {
1203 unsafe { BNIsIntegerToken(token_type) }
1204 }
1205
1206 pub fn reset_deduplicated_comments(&self) {
1207 unsafe { BNResetDisassemblyTextRendererDeduplicatedComments(self.handle.as_ptr()) }
1208 }
1209
1210 pub fn symbol_tokens(
1211 &self,
1212 addr: u64,
1213 size: usize,
1214 operand: Option<usize>,
1215 ) -> Option<Array<InstructionTextToken>> {
1216 let operand = operand.unwrap_or(0xffffffff);
1217 let mut count = 0;
1218 let mut tokens: *mut BNInstructionTextToken = ptr::null_mut();
1219 let result = unsafe {
1220 BNGetDisassemblyTextRendererSymbolTokens(
1221 self.handle.as_ptr(),
1222 addr,
1223 size,
1224 operand,
1225 &mut tokens,
1226 &mut count,
1227 )
1228 };
1229 result.then(|| unsafe { Array::new(tokens, count, ()) })
1230 }
1231
1232 pub fn stack_var_reference_tokens(
1233 &self,
1234 stack_ref: StackVariableReference,
1235 ) -> Array<InstructionTextToken> {
1236 let mut stack_ref_raw = StackVariableReference::into_raw(stack_ref);
1237 let mut count = 0;
1238 let tokens = unsafe {
1239 BNGetDisassemblyTextRendererStackVariableReferenceTokens(
1240 self.handle.as_ptr(),
1241 &mut stack_ref_raw,
1242 &mut count,
1243 )
1244 };
1245 StackVariableReference::free_raw(stack_ref_raw);
1246 assert!(!tokens.is_null());
1247 unsafe { Array::new(tokens, count, ()) }
1248 }
1249
1250 pub fn integer_token(
1251 &self,
1252 int_token: InstructionTextToken,
1253 location: impl Into<Location>,
1254 ) -> Array<InstructionTextToken> {
1255 let location = location.into();
1256 let arch = location
1257 .arch
1258 .map(|a| a.handle)
1259 .unwrap_or_else(std::ptr::null_mut);
1260 let mut count = 0;
1261 let mut int_token_raw = InstructionTextToken::into_raw(int_token);
1262 let tokens = unsafe {
1263 BNGetDisassemblyTextRendererIntegerTokens(
1264 self.handle.as_ptr(),
1265 &mut int_token_raw,
1266 arch,
1267 location.addr,
1268 &mut count,
1269 )
1270 };
1271 InstructionTextToken::free_raw(int_token_raw);
1272 assert!(!tokens.is_null());
1273 unsafe { Array::new(tokens, count, ()) }
1274 }
1275
1276 pub fn wrap_comment(
1277 &self,
1278 cur_line: DisassemblyTextLine,
1279 comment: &str,
1280 has_auto_annotations: bool,
1281 leading_spaces: &str,
1282 indent_spaces: &str,
1283 ) -> Array<DisassemblyTextLine> {
1284 let cur_line_raw = DisassemblyTextLine::into_raw(cur_line);
1285 let comment_raw = comment.to_cstr();
1286 let leading_spaces_raw = leading_spaces.to_cstr();
1287 let indent_spaces_raw = indent_spaces.to_cstr();
1288 let mut count = 0;
1289 let lines = unsafe {
1290 BNDisassemblyTextRendererWrapComment(
1291 self.handle.as_ptr(),
1292 &cur_line_raw,
1293 &mut count,
1294 comment_raw.as_ref().as_ptr() as *const ffi::c_char,
1295 has_auto_annotations,
1296 leading_spaces_raw.as_ref().as_ptr() as *const ffi::c_char,
1297 indent_spaces_raw.as_ref().as_ptr() as *const ffi::c_char,
1298 )
1299 };
1300 DisassemblyTextLine::free_raw(cur_line_raw);
1301 assert!(!lines.is_null());
1302 unsafe { Array::new(lines, count, ()) }
1303 }
1304}
1305
1306impl ToOwned for DisassemblyTextRenderer {
1307 type Owned = Ref<Self>;
1308
1309 fn to_owned(&self) -> Self::Owned {
1310 unsafe { RefCountable::inc_ref(self) }
1311 }
1312}
1313
1314unsafe impl RefCountable for DisassemblyTextRenderer {
1315 unsafe fn inc_ref(handle: &Self) -> Ref<Self> {
1316 Ref::new(Self {
1317 handle: NonNull::new(BNNewDisassemblyTextRendererReference(
1318 handle.handle.as_ptr(),
1319 ))
1320 .unwrap(),
1321 })
1322 }
1323
1324 unsafe fn dec_ref(handle: &Self) {
1325 BNFreeDisassemblyTextRenderer(handle.handle.as_ptr());
1326 }
1327}
1328
1329#[derive(PartialEq, Eq, Hash)]
1331pub struct DisassemblySettings {
1332 pub(crate) handle: *mut BNDisassemblySettings,
1333}
1334
1335impl DisassemblySettings {
1336 pub fn ref_from_raw(handle: *mut BNDisassemblySettings) -> Ref<Self> {
1337 debug_assert!(!handle.is_null());
1338 unsafe { Ref::new(Self { handle }) }
1339 }
1340
1341 pub fn new() -> Ref<Self> {
1342 let handle = unsafe { BNCreateDisassemblySettings() };
1343 Self::ref_from_raw(handle)
1344 }
1345
1346 pub fn set_option(&self, option: DisassemblyOption, state: bool) {
1347 unsafe { BNSetDisassemblySettingsOption(self.handle, option, state) }
1348 }
1349
1350 pub fn is_option_set(&self, option: DisassemblyOption) -> bool {
1351 unsafe { BNIsDisassemblySettingsOptionSet(self.handle, option) }
1352 }
1353}
1354
1355impl ToOwned for DisassemblySettings {
1356 type Owned = Ref<Self>;
1357
1358 fn to_owned(&self) -> Self::Owned {
1359 unsafe { RefCountable::inc_ref(self) }
1360 }
1361}
1362
1363unsafe impl RefCountable for DisassemblySettings {
1364 unsafe fn inc_ref(handle: &Self) -> Ref<Self> {
1365 Ref::new(Self {
1366 handle: BNNewDisassemblySettingsReference(handle.handle),
1367 })
1368 }
1369
1370 unsafe fn dec_ref(handle: &Self) {
1371 BNFreeDisassemblySettings(handle.handle);
1372 }
1373}