aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/long_mode/display.rs15
-rw-r--r--src/long_mode/mod.rs26
-rw-r--r--src/protected_mode/mod.rs26
-rw-r--r--test/long_mode/operand.rs15
-rw-r--r--test/protected_mode/operand.rs14
5 files changed, 75 insertions, 21 deletions
diff --git a/src/long_mode/display.rs b/src/long_mode/display.rs
index b1fb7f8..d042119 100644
--- a/src/long_mode/display.rs
+++ b/src/long_mode/display.rs
@@ -3308,17 +3308,6 @@ impl Instruction {
}
}
-const MEM_SIZE_STRINGS: [&'static str; 64] = [
- "byte", "word", "BUG", "dword", "BUG", "BUG", "BUG", "qword",
- "far", "mword", "BUG", "BUG", "BUG", "BUG", "BUG", "xmmword",
- "BUG", "BUG", "BUG", "BUG", "BUG", "BUG", "BUG", "BUG",
- "BUG", "BUG", "BUG", "BUG", "BUG", "BUG", "BUG", "ymmword",
- "BUG", "BUG", "BUG", "BUG", "BUG", "BUG", "BUG", "BUG",
- "BUG", "BUG", "BUG", "BUG", "BUG", "BUG", "BUG", "BUG",
- "BUG", "BUG", "BUG", "BUG", "BUG", "BUG", "BUG", "BUG",
- "BUG", "BUG", "BUG", "BUG", "BUG", "BUG", "ptr", "zmmword",
-];
-
fn contextualize_intel<T: fmt::Write, Y: YaxColors>(instr: &Instruction, colors: &Y, _address: u64, _context: Option<&NoContext>, out: &mut T) -> fmt::Result {
if instr.prefixes.lock() {
write!(out, "lock ")?;
@@ -3345,7 +3334,7 @@ fn contextualize_intel<T: fmt::Write, Y: YaxColors>(instr: &Instruction, colors:
let x = Operand::from_spec(instr, instr.operands[0]);
if x.is_memory() {
- out.write_str(MEM_SIZE_STRINGS[instr.mem_size as usize - 1])?;
+ out.write_str(super::MEM_SIZE_STRINGS[instr.mem_size as usize - 1])?;
out.write_str(" ")?;
}
@@ -3365,7 +3354,7 @@ fn contextualize_intel<T: fmt::Write, Y: YaxColors>(instr: &Instruction, colors:
out.write_str(", ")?;
let x = Operand::from_spec(instr, instr.operands[i as usize]);
if x.is_memory() {
- out.write_str(MEM_SIZE_STRINGS[instr.mem_size as usize - 1])?;
+ out.write_str(super::MEM_SIZE_STRINGS[instr.mem_size as usize - 1])?;
out.write_str(" ")?;
}
if let Some(prefix) = instr.segment_override_for_op(i) {
diff --git a/src/long_mode/mod.rs b/src/long_mode/mod.rs
index f2b2b57..4babca3 100644
--- a/src/long_mode/mod.rs
+++ b/src/long_mode/mod.rs
@@ -2757,9 +2757,9 @@ pub struct InstDecoder {
}
impl InstDecoder {
- /// Instantiates an x86_64 decoder that decodes the bare minimum of x86_64.
+ /// instantiates an x86_64 decoder that decodes the bare minimum of x86_64.
///
- /// Pedantic and only decodes what the spec says is well-defined, rejecting undefined sequences
+ /// pedantic and only decodes what the spec says is well-defined, rejecting undefined sequences
/// and any instructions defined by extensions.
pub fn minimal() -> Self {
InstDecoder {
@@ -2767,6 +2767,15 @@ impl InstDecoder {
}
}
+ /// helper to decode an instruction directly from a byte slice.
+ ///
+ /// this lets callers avoid the work of setting up a [`yaxpeax_arch::U8Reader`] for the slice
+ /// to decode.
+ pub fn decode_slice(&self, data: &[u8]) -> Result<Instruction, DecodeError> {
+ let mut reader = yaxpeax_arch::U8Reader::new(data);
+ self.decode(&mut reader)
+ }
+
pub fn sse3(&self) -> bool {
self.flags & (1 << 0) != 0
}
@@ -4194,6 +4203,17 @@ impl Default for Instruction {
}
}
+const MEM_SIZE_STRINGS: [&'static str; 64] = [
+ "byte", "word", "BUG", "dword", "BUG", "BUG", "BUG", "qword",
+ "far", "mword", "BUG", "BUG", "BUG", "BUG", "BUG", "xmmword",
+ "BUG", "BUG", "BUG", "BUG", "BUG", "BUG", "BUG", "BUG",
+ "BUG", "BUG", "BUG", "BUG", "BUG", "BUG", "BUG", "ymmword",
+ "BUG", "BUG", "BUG", "BUG", "BUG", "BUG", "BUG", "BUG",
+ "BUG", "BUG", "BUG", "BUG", "BUG", "BUG", "BUG", "BUG",
+ "BUG", "BUG", "BUG", "BUG", "BUG", "BUG", "BUG", "BUG",
+ "BUG", "BUG", "BUG", "BUG", "BUG", "BUG", "ptr", "zmmword",
+];
+
pub struct MemoryAccessSize {
size: u8,
}
@@ -4207,7 +4227,7 @@ impl MemoryAccessSize {
}
pub fn size_name(&self) -> &'static str {
- "name_strings"
+ MEM_SIZE_STRINGS[self.size as usize - 1]
}
}
diff --git a/src/protected_mode/mod.rs b/src/protected_mode/mod.rs
index 589d7a3..a088ad6 100644
--- a/src/protected_mode/mod.rs
+++ b/src/protected_mode/mod.rs
@@ -2684,9 +2684,9 @@ pub struct InstDecoder {
}
impl InstDecoder {
- /// Instantiates an x86 decoder that decodes the bare minimum of protected-mode x86.
+ /// instantiates an x86 decoder that decodes the bare minimum of protected-mode x86.
///
- /// Pedantic and only decodes what the spec says is well-defined, rejecting undefined sequences
+ /// pedantic and only decodes what the spec says is well-defined, rejecting undefined sequences
/// and any instructions defined by extensions.
pub fn minimal() -> Self {
InstDecoder {
@@ -2694,6 +2694,15 @@ impl InstDecoder {
}
}
+ /// helper to decode an instruction directly from a byte slice.
+ ///
+ /// this lets callers avoid the work of setting up a [`yaxpeax_arch::U8Reader`] for the slice
+ /// to decode.
+ pub fn decode_slice(&self, data: &[u8]) -> Result<Instruction, DecodeError> {
+ let mut reader = yaxpeax_arch::U8Reader::new(data);
+ self.decode(&mut reader)
+ }
+
pub fn sse3(&self) -> bool {
self.flags & (1 << 0) != 0
}
@@ -4103,6 +4112,17 @@ impl Default for Instruction {
}
}
+const MEM_SIZE_STRINGS: [&'static str; 64] = [
+ "byte", "word", "BUG", "dword", "far", "ptr", "BUG", "qword",
+ "BUG", "mword", "BUG", "BUG", "BUG", "BUG", "BUG", "xmmword",
+ "BUG", "BUG", "BUG", "BUG", "BUG", "BUG", "BUG", "BUG",
+ "BUG", "BUG", "BUG", "BUG", "BUG", "BUG", "BUG", "ymmword",
+ "BUG", "BUG", "BUG", "BUG", "BUG", "BUG", "BUG", "BUG",
+ "BUG", "BUG", "BUG", "BUG", "BUG", "BUG", "BUG", "BUG",
+ "BUG", "BUG", "BUG", "BUG", "BUG", "BUG", "BUG", "BUG",
+ "BUG", "BUG", "BUG", "BUG", "BUG", "BUG", "ptr", "zmmword",
+];
+
pub struct MemoryAccessSize {
size: u8,
}
@@ -4116,7 +4136,7 @@ impl MemoryAccessSize {
}
pub fn size_name(&self) -> &'static str {
- "name_strings"
+ MEM_SIZE_STRINGS[self.size as usize - 1]
}
}
diff --git a/test/long_mode/operand.rs b/test/long_mode/operand.rs
index 77ce256..5a51ef3 100644
--- a/test/long_mode/operand.rs
+++ b/test/long_mode/operand.rs
@@ -1,4 +1,4 @@
-use yaxpeax_x86::long_mode::{Operand, RegSpec};
+use yaxpeax_x86::long_mode::{InstDecoder, MemoryAccessSize, Operand, RegSpec};
#[test]
fn register_widths() {
@@ -12,5 +12,18 @@ fn register_widths() {
#[test]
fn memory_widths() {
+ // the register operand directly doesn't report a size - it comes from the `Instruction` for
+ // which this is an operand.
assert_eq!(Operand::RegDeref(RegSpec::rsp()).width(), None);
+
+ fn mem_size_of(data: &[u8]) -> MemoryAccessSize {
+ let decoder = InstDecoder::default();
+ decoder.decode_slice(data).unwrap().mem_size().unwrap()
+ }
+
+ // and checking the memory size direcly reports correct names
+ assert_eq!(mem_size_of(&[0x32, 0x00]).size_name(), "byte");
+ assert_eq!(mem_size_of(&[0x66, 0x33, 0x00]).size_name(), "word");
+ assert_eq!(mem_size_of(&[0x33, 0x00]).size_name(), "dword");
+ assert_eq!(mem_size_of(&[0x48, 0x33, 0x00]).size_name(), "qword");
}
diff --git a/test/protected_mode/operand.rs b/test/protected_mode/operand.rs
index 028cb8f..b2d3624 100644
--- a/test/protected_mode/operand.rs
+++ b/test/protected_mode/operand.rs
@@ -1,4 +1,4 @@
-use yaxpeax_x86::protected_mode::{Operand, RegSpec};
+use yaxpeax_x86::protected_mode::{InstDecoder, MemoryAccessSize, Operand, RegSpec};
#[test]
fn register_widths() {
@@ -11,5 +11,17 @@ fn register_widths() {
#[test]
fn memory_widths() {
+ // the register operand directly doesn't report a size - it comes from the `Instruction` for
+ // which this is an operand.
assert_eq!(Operand::RegDeref(RegSpec::esp()).width(), None);
+
+ fn mem_size_of(data: &[u8]) -> MemoryAccessSize {
+ let decoder = InstDecoder::default();
+ decoder.decode_slice(data).unwrap().mem_size().unwrap()
+ }
+
+ // and checking the memory size direcly reports correct names
+ assert_eq!(mem_size_of(&[0x32, 0x00]).size_name(), "byte");
+ assert_eq!(mem_size_of(&[0x66, 0x33, 0x00]).size_name(), "word");
+ assert_eq!(mem_size_of(&[0x33, 0x00]).size_name(), "dword");
}