lldb/
instruction.rs

1// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
2// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
3// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
4// option. This file may not be copied, modified, or distributed
5// except according to those terms.
6
7use crate::{sys, SBAddress, SBData, SBStream, SBTarget};
8use std::ffi::CStr;
9use std::fmt;
10
11/// A machine instruction.
12pub struct SBInstruction {
13    /// The underlying raw `SBInstructionRef`.
14    pub raw: sys::SBInstructionRef,
15}
16
17impl SBInstruction {
18    /// Construct a new `SBInstruction`.
19    pub(crate) fn wrap(raw: sys::SBInstructionRef) -> SBInstruction {
20        SBInstruction { raw }
21    }
22
23    /// Construct a new `Some(SBInstruction)` or `None`.
24    #[allow(dead_code)]
25    pub(crate) fn maybe_wrap(raw: sys::SBInstructionRef) -> Option<SBInstruction> {
26        if unsafe { sys::SBInstructionIsValid(raw) } {
27            Some(SBInstruction { raw })
28        } else {
29            None
30        }
31    }
32
33    /// Check whether or not this is a valid `SBInstruction` value.
34    pub fn is_valid(&self) -> bool {
35        unsafe { sys::SBInstructionIsValid(self.raw) }
36    }
37
38    /// Get the address of the instruction.
39    pub fn address(&self) -> SBAddress {
40        SBAddress::wrap(unsafe { sys::SBInstructionGetAddress(self.raw) })
41    }
42
43    #[allow(missing_docs)]
44    pub fn mnemonic(&self, target: &SBTarget) -> &str {
45        unsafe {
46            match CStr::from_ptr(sys::SBInstructionGetMnemonic(self.raw, target.raw)).to_str() {
47                Ok(s) => s,
48                _ => panic!("Invalid string?"),
49            }
50        }
51    }
52
53    #[allow(missing_docs)]
54    pub fn operands(&self, target: &SBTarget) -> &str {
55        unsafe {
56            match CStr::from_ptr(sys::SBInstructionGetOperands(self.raw, target.raw)).to_str() {
57                Ok(s) => s,
58                _ => panic!("Invalid string?"),
59            }
60        }
61    }
62
63    #[allow(missing_docs)]
64    pub fn comment(&self, target: &SBTarget) -> &str {
65        unsafe {
66            match CStr::from_ptr(sys::SBInstructionGetComment(self.raw, target.raw)).to_str() {
67                Ok(s) => s,
68                _ => panic!("Invalid string?"),
69            }
70        }
71    }
72
73    #[allow(missing_docs)]
74    pub fn data(&self, target: &SBTarget) -> SBData {
75        SBData::wrap(unsafe { sys::SBInstructionGetData(self.raw, target.raw) })
76    }
77
78    #[allow(missing_docs)]
79    pub fn byte_size(&self) -> usize {
80        unsafe { sys::SBInstructionGetByteSize(self.raw) }
81    }
82
83    #[allow(missing_docs)]
84    pub fn is_branch(&self) -> bool {
85        unsafe { sys::SBInstructionDoesBranch(self.raw) }
86    }
87
88    #[allow(missing_docs)]
89    pub fn has_delay_slot(&self) -> bool {
90        unsafe { sys::SBInstructionHasDelaySlot(self.raw) }
91    }
92}
93
94impl Clone for SBInstruction {
95    fn clone(&self) -> SBInstruction {
96        SBInstruction {
97            raw: unsafe { sys::CloneSBInstruction(self.raw) },
98        }
99    }
100}
101
102impl fmt::Debug for SBInstruction {
103    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
104        let stream = SBStream::new();
105        unsafe { sys::SBInstructionGetDescription(self.raw, stream.raw) };
106        write!(fmt, "SBInstruction {{ {} }}", stream.data())
107    }
108}
109
110impl Drop for SBInstruction {
111    fn drop(&mut self) {
112        unsafe { sys::DisposeSBInstruction(self.raw) };
113    }
114}
115
116unsafe impl Send for SBInstruction {}
117unsafe impl Sync for SBInstruction {}