From b6ace85e557fc69f155b60890929452ac5ef0fb9 Mon Sep 17 00:00:00 2001 From: iximeow Date: Sat, 25 May 2019 07:52:41 -0700 Subject: more serde friendliness, cli, cld, clc, sti, std, stc support --- src/display.rs | 12 ++++++++++++ src/lib.rs | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 71 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/display.rs b/src/display.rs index b500992..50375f2 100644 --- a/src/display.rs +++ b/src/display.rs @@ -174,6 +174,12 @@ impl Colorize for Operand { impl fmt::Display for Opcode { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { + &Opcode::STI => write!(f, "{}", "sti"), + &Opcode::STD => write!(f, "{}", "std"), + &Opcode::STC => write!(f, "{}", "stc"), + &Opcode::CLI => write!(f, "{}", "cli"), + &Opcode::CLD => write!(f, "{}", "cld"), + &Opcode::CLC => write!(f, "{}", "clc"), &Opcode::SLDT => write!(f, "{}", "sldt"), &Opcode::STR => write!(f, "{}", "str"), &Opcode::LLDT => write!(f, "{}", "lldt"), @@ -393,6 +399,12 @@ impl Colorize for Opcode { Opcode::JG => { write!(out, "{}", colors.control_flow_op(self)) } /* Data transfer */ + Opcode::CLC | + Opcode::CLI | + Opcode::CLD | + Opcode::STC | + Opcode::STI | + Opcode::STD | Opcode::MOV | Opcode::CBW | Opcode::CDW | diff --git a/src/lib.rs b/src/lib.rs index 8057114..234735f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -18,6 +18,13 @@ use std::hint::unreachable_unchecked; use yaxpeax_arch::{Arch, ColorSettings, Decodable, LengthedInstruction}; +#[cfg(feature="use-serde")] +#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Serialize, Deserialize)] +pub struct RegSpec { + pub num: u8, + pub bank: RegisterBank +} +#[cfg(not(feature="use-serde"))] #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] pub struct RegSpec { pub num: u8, @@ -165,6 +172,15 @@ pub enum Operand { Nothing } +#[cfg(feature="use-serde")] +#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Serialize, Deserialize)] +pub enum RegisterBank { + Q, D, W, B, rB, // Quadword, Dword, Word, Byte + CR, DR, S, EIP, RIP, EFlags, RFlags, // Control reg, Debug reg, Selector, ... + X, Y, Z, // XMM, YMM, ZMM + ST, MM, // ST, MM regs (x87, mmx) +} +#[cfg(not(feature="use-serde"))] #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] pub enum RegisterBank { Q, D, W, B, rB, // Quadword, Dword, Word, Byte @@ -329,6 +345,12 @@ pub enum Opcode { LTR, VERR, VERW, + CLC, + STC, + CLI, + STI, + CLD, + STD, JMPE, Invalid } @@ -340,13 +362,18 @@ pub struct Instruction { pub length: u8 } +// the Hash, Eq, and PartialEq impls here are possibly misleading. +// They exist because downstream some structs are spelled like +// Foo for T == x86_64. This is only to access associated types +// which themselves are bounded, but their #[derive] require T to +// implement these traits. #[cfg(feature="use-serde")] -#[derive(Debug, Serialize, Deserialize)] +#[derive(Hash, Eq, PartialEq, Debug, Serialize, Deserialize)] #[allow(non_camel_case_types)] pub struct x86_64; #[cfg(not(feature="use-serde"))] -#[derive(Debug)] +#[derive(Hash, Eq, PartialEq, Debug)] #[allow(non_camel_case_types)] pub struct x86_64; @@ -1420,6 +1447,36 @@ fn read_opcode>(bytes_iter: &mut T, instruction: &mut Instr instruction.opcode = Opcode::Invalid; return Ok(OperandCode::ModRM_0xf7); }, + 0xf8 => { + instruction.prefixes = prefixes; + instruction.opcode = Opcode::CLC; + return Ok(OperandCode::Nothing); + } + 0xf9 => { + instruction.prefixes = prefixes; + instruction.opcode = Opcode::STC; + return Ok(OperandCode::Nothing); + } + 0xfa => { + instruction.prefixes = prefixes; + instruction.opcode = Opcode::CLI; + return Ok(OperandCode::Nothing); + } + 0xfb => { + instruction.prefixes = prefixes; + instruction.opcode = Opcode::STI; + return Ok(OperandCode::Nothing); + } + 0xfc => { + instruction.prefixes = prefixes; + instruction.opcode = Opcode::CLD; + return Ok(OperandCode::Nothing); + } + 0xfd => { + instruction.prefixes = prefixes; + instruction.opcode = Opcode::STD; + return Ok(OperandCode::Nothing); + } 0xfe => { instruction.prefixes = prefixes; instruction.opcode = Opcode::Invalid; -- cgit v1.1