diff options
| author | iximeow <me@iximeow.net> | 2019-06-23 16:09:26 -0700 | 
|---|---|---|
| committer | iximeow <me@iximeow.net> | 2020-01-12 16:10:13 -0800 | 
| commit | 06b9d518496b90e83ad8b9857973442b978ed3e6 (patch) | |
| tree | 54bd23c987510f6d726bb817979a438034d101e3 /src | |
| parent | 66bc9435b54495e24715939e119b059b06231e8b (diff) | |
begin supporting f30f instructions
fix issue where non-relevant prefixes on 0f opcodes may cause incorrect invalid decodes
Diffstat (limited to 'src')
| -rw-r--r-- | src/display.rs | 22 | ||||
| -rw-r--r-- | src/lib.rs | 114 | 
2 files changed, 130 insertions, 6 deletions
| diff --git a/src/display.rs b/src/display.rs index 7dba44d..ca2b2f7 100644 --- a/src/display.rs +++ b/src/display.rs @@ -184,6 +184,13 @@ impl fmt::Display for Opcode {      fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {          match self {              &Opcode::MOVSS => write!(f, "{}", "movss"), +            &Opcode::SQRTSS => write!(f, "{}", "sqrtss"), +            &Opcode::ADDSS => write!(f, "{}", "addss"), +            &Opcode::SUBSS => write!(f, "{}", "subss"), +            &Opcode::MULSS => write!(f, "{}", "mulss"), +            &Opcode::DIVSS => write!(f, "{}", "divss"), +            &Opcode::MINSS => write!(f, "{}", "minss"), +            &Opcode::MAXSS => write!(f, "{}", "maxss"),              &Opcode::MOVSD => write!(f, "{}", "movsd"),              &Opcode::SQRTSD => write!(f, "{}", "sqrtsd"),              &Opcode::ADDSD => write!(f, "{}", "addsd"), @@ -193,6 +200,7 @@ impl fmt::Display for Opcode {              &Opcode::MINSD => write!(f, "{}", "minsd"),              &Opcode::MAXSD => write!(f, "{}", "maxsd"),              &Opcode::MOVDDUP => write!(f, "{}", "movddup"), +            &Opcode::MOVSLDUP => write!(f, "{}", "movsldup"),              &Opcode::HADDPS => write!(f, "{}", "haddps"),              &Opcode::HSUBPS => write!(f, "{}", "hsubps"),              &Opcode::ADDSUBPS => write!(f, "{}", "addsubps"), @@ -201,6 +209,9 @@ impl fmt::Display for Opcode {              &Opcode::CVTTSD2SI => write!(f, "{}", "cvttsd2si"),              &Opcode::CVTSD2SI => write!(f, "{}", "cvtsd2si"),              &Opcode::CVTSD2SS => write!(f, "{}", "cvtsd2ss"), +            &Opcode::CVTTSS2SI => write!(f, "{}", "cvttss2si"), +            &Opcode::CVTSS2SI => write!(f, "{}", "cvtss2si"), +            &Opcode::CVTSS2SD => write!(f, "{}", "cvtss2sd"),              &Opcode::LDDQU => write!(f, "{}", "lddqu"),              &Opcode::STI => write!(f, "{}", "sti"),              &Opcode::STD => write!(f, "{}", "std"), @@ -371,7 +382,13 @@ impl <T: std::fmt::Write> Colorize<T> for Opcode {              Opcode::SUBSD |              Opcode::MULSD |              Opcode::DIVSD | +            Opcode::SQRTSS | +            Opcode::ADDSS | +            Opcode::SUBSS | +            Opcode::MULSS | +            Opcode::DIVSS |              Opcode::MOVDDUP | +            Opcode::MOVSLDUP |              Opcode::HADDPS |              Opcode::HSUBPS |              Opcode::ADDSUBPS | @@ -444,6 +461,9 @@ impl <T: std::fmt::Write> Colorize<T> for Opcode {              Opcode::CVTTSD2SI |              Opcode::CVTSD2SI |              Opcode::CVTSD2SS | +            Opcode::CVTTSS2SI | +            Opcode::CVTSS2SI | +            Opcode::CVTSS2SD |              Opcode::LDDQU |              Opcode::CLC |              Opcode::CLI | @@ -501,6 +521,8 @@ impl <T: std::fmt::Write> Colorize<T> for Opcode {              Opcode::MINSD |              Opcode::MAXSD | +            Opcode::MINSS | +            Opcode::MAXSS |              Opcode::CMPS |              Opcode::SCAS |              Opcode::TEST | @@ -235,8 +235,15 @@ pub enum Segment {  #[allow(non_camel_case_types)]  #[derive(Copy, Clone, Debug, Eq, PartialEq)]  pub enum Opcode { -    MOVSD,      MOVSS, +    ADDSS, +    SUBSS, +    MULSS, +    DIVSS, +    MINSS, +    MAXSS, +    SQRTSS, +    MOVSD,      SQRTSD,      ADDSD,      SUBSD, @@ -244,6 +251,7 @@ pub enum Opcode {      DIVSD,      MINSD,      MAXSD, +    MOVSLDUP,      MOVDDUP,      HADDPS,      HSUBPS, @@ -253,6 +261,9 @@ pub enum Opcode {      CVTTSD2SI,      CVTSD2SI,      CVTSD2SS, +    CVTTSS2SI, +    CVTSS2SI, +    CVTSS2SD,      LDDQU,      MOVZX_b,      MOVZX_w, @@ -862,7 +873,91 @@ fn read_opcode_f20f_map<T: Iterator<Item=u8>>(bytes_iter: &mut T, instruction: &      }  }  fn read_opcode_f30f_map<T: Iterator<Item=u8>>(bytes_iter: &mut T, instruction: &mut Instruction, prefixes: Prefixes, length: &mut u8) -> Result<OperandCode, String> { -    Err("f30f opcode map unsupported".to_string()) +    match bytes_iter.next() { +        Some(b) => { +            *length += 1; +            match b { +                0x10 => { +                    instruction.prefixes = prefixes; +                    instruction.opcode = Opcode::MOVSS; +                    Ok(OperandCode::G_E_xmm) +                }, +                0x11 => { +                    instruction.prefixes = prefixes; +                    instruction.opcode = Opcode::MOVSS; +                    Ok(OperandCode::E_G_xmm) +                }, +                0x12 => { +                    instruction.prefixes = prefixes; +                    instruction.opcode = Opcode::MOVSLDUP; +                    Ok(OperandCode::G_E_xmm) +                }, +                0x2a => { +                    instruction.prefixes = prefixes; +                    instruction.opcode = Opcode::CVTSI2SS; +                    Ok(OperandCode::G_E_xmm) +                }, +                0x2c => { +                    instruction.prefixes = prefixes; +                    instruction.opcode = Opcode::CVTTSS2SI; +                    Ok(OperandCode::G_E_xmm) +                }, +                0x2d => { +                    instruction.prefixes = prefixes; +                    instruction.opcode = Opcode::CVTSS2SI; +                    Ok(OperandCode::G_E_xmm) +                }, +                0x51 => { +                    instruction.prefixes = prefixes; +                    instruction.opcode = Opcode::SQRTSS; +                    Ok(OperandCode::G_E_xmm) +                }, +                0x58 => { +                    instruction.prefixes = prefixes; +                    instruction.opcode = Opcode::ADDSS; +                    Ok(OperandCode::G_E_xmm) +                }, +                0x59 => { +                    instruction.prefixes = prefixes; +                    instruction.opcode = Opcode::MULSS; +                    Ok(OperandCode::G_E_xmm) +                }, +                0x5a => { +                    instruction.prefixes = prefixes; +                    instruction.opcode = Opcode::CVTSS2SD; +                    Ok(OperandCode::G_E_xmm) +                }, +                0x5c => { +                    instruction.prefixes = prefixes; +                    instruction.opcode = Opcode::SUBSS; +                    Ok(OperandCode::G_E_xmm) +                }, +                0x5d => { +                    instruction.prefixes = prefixes; +                    instruction.opcode = Opcode::MINSS; +                    Ok(OperandCode::G_E_xmm) +                }, +                0x5e => { +                    instruction.prefixes = prefixes; +                    instruction.opcode = Opcode::DIVSS; +                    Ok(OperandCode::G_E_xmm) +                }, +                0x5f => { +                    instruction.prefixes = prefixes; +                    instruction.opcode = Opcode::MAXSS; +                    Ok(OperandCode::G_E_xmm) +                }, +                _ => { +                    instruction.prefixes = prefixes; +                    instruction.opcode = Opcode::Invalid; +                    Err("Invalid opcode".to_string()) +                } +            } +        } +        None => { +            Err("No more bytes".to_owned()) +        } +    }  }  fn read_opcode_0f_map<T: Iterator<Item=u8>>(bytes_iter: &mut T, instruction: &mut Instruction, prefixes: Prefixes, length: &mut u8) -> Result<OperandCode, String> {      match bytes_iter.next() { @@ -1236,16 +1331,20 @@ fn read_opcode<T: Iterator<Item=u8>>(bytes_iter: &mut T, instruction: &mut Instr                                      };                                  },                                  0x26 => { -                                    prefixes.set_es() +                                    prefixes.set_es(); +                                    alternate_opcode_map = None;                                  },                                  0x2e => { -                                    prefixes.set_cs() +                                    prefixes.set_cs(); +                                    alternate_opcode_map = None;                                  },                                  0x36 => { -                                    prefixes.set_ss() +                                    prefixes.set_ss(); +                                    alternate_opcode_map = None;                                  },                                  0x3e => { -                                    prefixes.set_ds() +                                    prefixes.set_ds(); +                                    alternate_opcode_map = None;                                  },                                  0x06                                  | 0x07 @@ -1293,9 +1392,11 @@ fn read_opcode<T: Iterator<Item=u8>>(bytes_iter: &mut T, instruction: &mut Instr                      },                      0x64 => {                          prefixes.set_fs(); +                        alternate_opcode_map = None;                      },                      0x65 => {                          prefixes.set_gs(); +                        alternate_opcode_map = None;                      },                      0x66 => {                          prefixes.set_operand_size(); @@ -1303,6 +1404,7 @@ fn read_opcode<T: Iterator<Item=u8>>(bytes_iter: &mut T, instruction: &mut Instr                      },                      0x67 => {                          prefixes.set_address_size(); +                        alternate_opcode_map = None;                      },                      0x68 => {                          instruction.prefixes = prefixes; | 
