aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoriximeow <me@iximeow.net>2019-10-19 22:59:58 -0700
committeriximeow <me@iximeow.net>2020-01-12 16:10:13 -0800
commit98fcbbcb92554090651a15460319ce7ae4038c6a (patch)
tree402e1ac3bbf9eedce53adfcde1ca61ea21441651
parent3c9597a105670c91a6c11493204a4828ed54d235 (diff)
decode shift-by-cl and fix error decoding sign-extending operands
-rw-r--r--src/display.rs17
-rw-r--r--src/lib.rs23
-rw-r--r--test/test.rs1
3 files changed, 33 insertions, 8 deletions
diff --git a/src/display.rs b/src/display.rs
index 2a1dcc2..fc3f1bd 100644
--- a/src/display.rs
+++ b/src/display.rs
@@ -6,7 +6,22 @@ use std::fmt;
use yaxpeax_arch::{Colorize, ColorSettings, ShowContextual, YaxColors};
use yaxpeax_arch::display::*;
-use ::{RegSpec, RegisterBank, Opcode, Operand, Instruction, Segment};
+use ::{RegSpec, RegisterBank, Opcode, Operand, Instruction, Segment, PrefixRex};
+
+impl fmt::Display for PrefixRex {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ if self.present() {
+ write!(f, "rex:{}{}{}{}",
+ if self.w() { "w" } else { "-" },
+ if self.r() { "r" } else { "-" },
+ if self.x() { "x" } else { "-" },
+ if self.b() { "b" } else { "-" },
+ )
+ } else {
+ write!(f, "rex:none")
+ }
+ }
+}
impl fmt::Display for Segment {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
diff --git a/src/lib.rs b/src/lib.rs
index 7dcd0a2..38619b7 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -772,7 +772,7 @@ pub enum OperandCode {
Fw,
Gv_Eb,
Gv_Ew,
- Gv_Ed,
+ Gdq_Ed,
G_E_xmm,
G_E_xmm_Ib,
Gv_M,
@@ -1266,7 +1266,7 @@ const OPCODE_F30F_MAP: [OpcodeRecord; 256] = [
OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
- OpcodeRecord(Interpretation::Instruction(Opcode::MOVDQU), OperandCode::Nothing),
+ OpcodeRecord(Interpretation::Instruction(Opcode::MOVDQU), OperandCode::G_E_xmm),
// 0x70
OpcodeRecord(Interpretation::Instruction(Opcode::PSHUFHW), OperandCode::G_E_xmm_Ib),
OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
@@ -1885,7 +1885,7 @@ const OPCODES: [OpcodeRecord; 256] = [
OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),
- OpcodeRecord(Interpretation::Instruction(Opcode::MOVSXD), OperandCode::Gv_Ed),
+ OpcodeRecord(Interpretation::Instruction(Opcode::MOVSXD), OperandCode::Gdq_Ed),
OpcodeRecord(Interpretation::Prefix, OperandCode::Nothing),
OpcodeRecord(Interpretation::Prefix, OperandCode::Nothing),
OpcodeRecord(Interpretation::Prefix, OperandCode::Nothing),
@@ -2519,6 +2519,16 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut
instruction.opcode = BITWISE_OPCODE_MAP[((modrm >> 3) & 7) as usize].clone();
instruction.operands[1] = Operand::ImmediateI8(1);
},
+ OperandCode::ModRM_0xd3_Ev_CL => {
+ let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, &instruction.prefixes);
+ let modrm = read_modrm(&mut bytes_iter, &mut instruction.length).unwrap();
+ let (mod_bits, r, m) = octets_of(modrm);
+
+ read_E(&mut bytes_iter, instruction, modrm, opwidth, 0).unwrap();
+ let opcode = BITWISE_OPCODE_MAP[r as usize].clone();
+ instruction.opcode = opcode;
+ instruction.operands[1] = Operand::Register(RegSpec::cl());
+ }
OperandCode::ModRM_0xf6 => {
let opwidth = 1;
let modrm = read_modrm(&mut bytes_iter, &mut instruction.length).unwrap();
@@ -2723,13 +2733,12 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut
read_E(&mut bytes_iter, instruction, modrm, opwidth, 1).unwrap();
}
},
- // TODO: verify M
- OperandCode::Gv_Ed => {
- let opwidth = 4;
+ OperandCode::Gdq_Ed => {
+ let opwidth = 8;
let modrm = read_modrm(&mut bytes_iter, &mut instruction.length).unwrap();
// println!("mod_bits: {:2b}, r: {:3b}, m: {:3b}", mod_bits, r, m);
- read_E(&mut bytes_iter, instruction, modrm, opwidth, 1).unwrap();
+ read_E(&mut bytes_iter, instruction, modrm, 4 /* opwidth */, 1).unwrap();
instruction.operands[0] =
Operand::Register(RegSpec::gp_from_parts((modrm >> 3) & 7, instruction.prefixes.rex().r(), opwidth, instruction.prefixes.rex().present()));
},
diff --git a/test/test.rs b/test/test.rs
index df0e1343..cd28685 100644
--- a/test/test.rs
+++ b/test/test.rs
@@ -107,6 +107,7 @@ fn test_mov() {
test_display(&[0x89, 0x55, 0x94], "mov [rbp - 0x6c], edx");
test_display(&[0x65, 0x4c, 0x89, 0x04, 0x25, 0xa8, 0x01, 0x00, 0x00], "mov gs:[0x1a8], r8");
test_display(&[0x0f, 0xbe, 0x83, 0xb4, 0x00, 0x00, 0x00], "movsx eax, byte [rbx + 0xb4]");
+ test_display(&[0x46, 0x63, 0xc1], "movsxd r8, ecx");
test_display(&[0x48, 0x63, 0x04, 0xba], "movsxd rax, [rdx + rdi * 4]");
test_display(&[0xf3, 0x0f, 0x6f, 0x07], "movdqu xmm0, xmmword [rdi]");
test_display(&[0xf3, 0x0f, 0x7f, 0x45, 0x00], "movdqu xmmword [rbp], xmm0");