summaryrefslogtreecommitdiff
path: root/rust/src/disassembly.rs
diff options
context:
space:
mode:
authorKyleMiles <krm504@nyu.edu>2022-02-14 18:41:40 -0500
committerKyleMiles <krm504@nyu.edu>2022-02-14 18:45:16 -0500
commit2845ba6208ce3c29998a48df5073ed15a11ead77 (patch)
tree7a50af1833dae6d4acaba420f714374fa8421dff /rust/src/disassembly.rs
parent6cd49edb317112acc73f7caeb285f4134a472d72 (diff)
Rust: Minor tweaks to 2890; merge architecture::InstructionTextToken and disassembly::InstructionTextToken; update examples
Diffstat (limited to 'rust/src/disassembly.rs')
-rw-r--r--rust/src/disassembly.rs130
1 files changed, 117 insertions, 13 deletions
diff --git a/rust/src/disassembly.rs b/rust/src/disassembly.rs
index 6266597c..ff00e8d0 100644
--- a/rust/src/disassembly.rs
+++ b/rust/src/disassembly.rs
@@ -28,30 +28,73 @@ use std::ptr;
pub type InstructionTextTokenType = BNInstructionTextTokenType;
pub type InstructionTextTokenContext = BNInstructionTextTokenContext;
+#[repr(C)]
pub struct InstructionTextToken(pub(crate) BNInstructionTextToken);
-// TODO : Consider remodeling this after types::EnumerationMember
+#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
+pub enum InstructionTextTokenContents {
+ Text,
+ Instruction,
+ OperandSeparator,
+ Register,
+ Integer(u64), // TODO size?
+ PossibleAddress(u64), // TODO size?
+ BeginMemoryOperand,
+ EndMemoryOperand,
+ FloatingPoint,
+ CodeRelativeAddress(u64),
+}
+
impl InstructionTextToken {
- // TODO : New vs new_with_value ?
pub(crate) unsafe fn from_raw(raw: &BNInstructionTextToken) -> Self {
Self(raw.clone())
}
- pub fn new(type_: InstructionTextTokenType, text: &str, value: u64) -> Self {
- let raw_name = BnString::new(text);
+ pub fn new(text: BnString, contents: InstructionTextTokenContents) -> Self {
+ let (value, address) = match contents {
+ InstructionTextTokenContents::Integer(v) => (v, 0),
+ InstructionTextTokenContents::PossibleAddress(v)
+ | InstructionTextTokenContents::CodeRelativeAddress(v) => (v, v),
+ _ => (0, 0),
+ };
+
+ let type_ = match contents {
+ InstructionTextTokenContents::Text => InstructionTextTokenType::TextToken,
+ InstructionTextTokenContents::Instruction => InstructionTextTokenType::InstructionToken,
+ InstructionTextTokenContents::OperandSeparator => {
+ InstructionTextTokenType::OperandSeparatorToken
+ }
+ InstructionTextTokenContents::Register => InstructionTextTokenType::RegisterToken,
+ InstructionTextTokenContents::Integer(_) => InstructionTextTokenType::IntegerToken,
+ InstructionTextTokenContents::PossibleAddress(_) => {
+ InstructionTextTokenType::PossibleAddressToken
+ }
+ InstructionTextTokenContents::BeginMemoryOperand => {
+ InstructionTextTokenType::BeginMemoryOperandToken
+ }
+ InstructionTextTokenContents::EndMemoryOperand => {
+ InstructionTextTokenType::EndMemoryOperandToken
+ }
+ InstructionTextTokenContents::FloatingPoint => {
+ InstructionTextTokenType::FloatingPointToken
+ }
+ InstructionTextTokenContents::CodeRelativeAddress(_) => {
+ InstructionTextTokenType::CodeRelativeAddressToken
+ }
+ };
- // TODO : Maybe impl Drop for this newtype and perhaps call from_raw for the BnString..I think it's a memory leak otherwise
+ let width = text.len() as u64;
InstructionTextToken(BNInstructionTextToken {
- type_: type_,
- text: raw_name.into_raw(),
- value: value,
- width: text.chars().count() as u64,
+ type_,
+ text: text.into_raw(),
+ value,
+ width,
size: 0,
- operand: 0xffffffff,
+ operand: 0xffff_ffff,
context: InstructionTextTokenContext::NoTokenContext,
confidence: BN_FULL_CONFIDENCE,
- address: 0,
+ address,
typeNames: ptr::null_mut(),
namesCount: 0,
})
@@ -68,6 +111,41 @@ impl InstructionTextToken {
pub fn text(&self) -> &BnStr {
unsafe { BnStr::from_raw(self.0.text) }
}
+
+ pub fn contents(&self) -> InstructionTextTokenContents {
+ use self::BNInstructionTextTokenType::*;
+ use self::InstructionTextTokenContents::*;
+
+ match self.0.type_ {
+ TextToken => Text,
+ InstructionToken => Instruction,
+ OperandSeparatorToken => OperandSeparator,
+ RegisterToken => Register,
+ IntegerToken => Integer(self.0.value),
+ PossibleAddressToken => PossibleAddress(self.0.value),
+ BeginMemoryOperandToken => BeginMemoryOperand,
+ EndMemoryOperandToken => EndMemoryOperand,
+ FloatingPointToken => FloatingPoint,
+ CodeRelativeAddressToken => CodeRelativeAddress(self.0.value),
+ _ => unimplemented!("woops"),
+ }
+ }
+
+ pub fn context(&self) -> InstructionTextTokenContext {
+ self.0.context
+ }
+
+ pub fn size(&self) -> usize {
+ self.0.size
+ }
+
+ pub fn operand(&self) -> usize {
+ self.0.operand
+ }
+
+ pub fn address(&self) -> u64 {
+ self.0.address
+ }
}
impl Default for InstructionTextToken {
@@ -88,6 +166,32 @@ impl Default for InstructionTextToken {
}
}
+impl Clone for InstructionTextToken {
+ fn clone(&self) -> Self {
+ InstructionTextToken(BNInstructionTextToken {
+ type_: self.0.type_,
+ context: self.0.context,
+ address: self.0.address,
+ size: self.0.size,
+ operand: self.0.operand,
+ value: self.0.value,
+ width: 0,
+ text: BnString::new(self.text()).into_raw(),
+ confidence: 0xff,
+ typeNames: ptr::null_mut(),
+ namesCount: 0,
+ })
+ }
+}
+
+// TODO : There is almost certainly a memory leak here - in the case where
+// `impl CoreOwnedArrayProvider for InstructionTextToken` doesn't get triggered
+// impl Drop for InstructionTextToken {
+// fn drop(&mut self) {
+// let _owned = unsafe { BnString::from_raw(self.0.text) };
+// }
+// }
+
impl CoreArrayProvider for InstructionTextToken {
type Raw = BNInstructionTextToken;
type Context = ();
@@ -198,8 +302,8 @@ impl From<Vec<InstructionTextToken>> for DisassemblyTextLine {
impl From<&Vec<&str>> for DisassemblyTextLine {
fn from(string_tokens: &Vec<&str>) -> Self {
let mut tokens: Vec<BNInstructionTextToken> = Vec::with_capacity(string_tokens.len());
- tokens.extend(string_tokens.iter().map(|token| {
- InstructionTextToken::new(InstructionTextTokenType::TextToken, token, 0).0
+ tokens.extend(string_tokens.iter().map(|&token| {
+ InstructionTextToken::new(BnString::new(token), InstructionTextTokenContents::Text).0
}));
assert!(tokens.len() == tokens.capacity());