diff options
author | iximeow <me@iximeow.net> | 2019-05-25 07:52:41 -0700 |
---|---|---|
committer | iximeow <me@iximeow.net> | 2020-01-12 16:10:13 -0800 |
commit | b6ace85e557fc69f155b60890929452ac5ef0fb9 (patch) | |
tree | 187380b9bddc8c502bf962e640574ed58f0e8c57 /src | |
parent | 153e8b77d364893a460a7d779347febae36e5b5a (diff) |
more serde friendliness, cli, cld, clc, sti, std, stc support
Diffstat (limited to 'src')
-rw-r--r-- | src/display.rs | 12 | ||||
-rw-r--r-- | src/lib.rs | 61 |
2 files changed, 71 insertions, 2 deletions
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 <T: std::fmt::Write> Colorize<T> 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 <T: std::fmt::Write> Colorize<T> 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 | @@ -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<T> 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<T: Iterator<Item=u8>>(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; |