diff options
| -rw-r--r-- | src/long_mode/display.rs | 10 | ||||
| -rw-r--r-- | src/long_mode/mod.rs | 48 | ||||
| -rw-r--r-- | test/long_mode/mod.rs | 24 | 
3 files changed, 72 insertions, 10 deletions
diff --git a/src/long_mode/display.rs b/src/long_mode/display.rs index 3e38d8d..9986194 100644 --- a/src/long_mode/display.rs +++ b/src/long_mode/display.rs @@ -1285,6 +1285,12 @@ const MNEMONICS: &[&'static str] = &[      // CET      "wruss",      "wrss", + +    // TDX +    "tdcall", +    "seamret", +    "seamops", +    "seamcall",  ];  impl Opcode { @@ -2223,6 +2229,10 @@ impl <T: fmt::Write, Color: fmt::Display, Y: YaxColors<Color>> Colorize<T, Color              Opcode::SYSRET |              Opcode::CLTS |              Opcode::SYSCALL | +            Opcode::TDCALL | +            Opcode::SEAMRET | +            Opcode::SEAMOPS | +            Opcode::SEAMCALL |              Opcode::LSL |              Opcode::SLDT |              Opcode::STR | diff --git a/src/long_mode/mod.rs b/src/long_mode/mod.rs index 9410b2b..5014e05 100644 --- a/src/long_mode/mod.rs +++ b/src/long_mode/mod.rs @@ -1944,6 +1944,12 @@ pub enum Opcode {      // CET      WRUSS,      WRSS, + +    // TDX +    TDCALL, +    SEAMRET, +    SEAMOPS, +    SEAMCALL,  }  #[derive(Debug)] @@ -3995,6 +4001,7 @@ enum OperandCode {      ModRM_0x0f00 = OperandCodeBuilder::new().read_modrm().special_case(40).bits(),      ModRM_0x0f01 = OperandCodeBuilder::new().read_modrm().special_case(41).bits(), +    ModRM_0x660f01 = OperandCodeBuilder::new().read_modrm().special_case(52).bits(),      ModRM_0x0f0d = OperandCodeBuilder::new().read_modrm().special_case(42).bits(),      ModRM_0x0f0f = OperandCodeBuilder::new().read_modrm().special_case(65).bits(), // 3dnow      ModRM_0x0fae = OperandCodeBuilder::new().read_modrm().special_case(43).bits(), @@ -4866,7 +4873,7 @@ fn read_0f_opcode(opcode: u8, prefixes: &mut Prefixes) -> OpcodeRecord {      if prefixes.repnz() {          match opcode {              0x00 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x0f00), -            0x01 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x0f01), +            0x01 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),              0x02 => OpcodeRecord(Interpretation::Instruction(Opcode::LAR), OperandCode::Gv_Ew),              0x03 => OpcodeRecord(Interpretation::Instruction(Opcode::LSL), OperandCode::Gv_Ew_LSL),              0x04 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), @@ -5143,7 +5150,7 @@ fn read_0f_opcode(opcode: u8, prefixes: &mut Prefixes) -> OpcodeRecord {      } else if prefixes.rep() {          match opcode {              0x00 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x0f00), -            0x01 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x0f01), +            0x01 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),              0x02 => OpcodeRecord(Interpretation::Instruction(Opcode::LAR), OperandCode::Gv_Ew),              0x03 => OpcodeRecord(Interpretation::Instruction(Opcode::LSL), OperandCode::Gv_Ew_LSL),              0x04 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), @@ -5420,7 +5427,7 @@ fn read_0f_opcode(opcode: u8, prefixes: &mut Prefixes) -> OpcodeRecord {      } else if prefixes.operand_size() {          match opcode {              0x00 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x0f00), -            0x01 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x0f01), +            0x01 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::ModRM_0x660f01),              0x02 => OpcodeRecord(Interpretation::Instruction(Opcode::LAR), OperandCode::Gv_Ew),              0x03 => OpcodeRecord(Interpretation::Instruction(Opcode::LSL), OperandCode::Gv_Ew_LSL),              0x04 => OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), @@ -8096,6 +8103,41 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter              }              instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, 2, length)?;          } +        OperandCode::ModRM_0x660f01 => { +            let modrm = read_modrm(&mut bytes_iter, length)?; +            let r = (modrm >> 3) & 7; +            if r == 1 { +                let mod_bits = modrm >> 6; +                let m = modrm & 7; +                if mod_bits == 0b11 { +                    instruction.operands[0] = OperandSpec::Nothing; +                    instruction.operand_count = 0; +                    match m { +                        0b100 => { +                            instruction.opcode = Opcode::TDCALL; +                        } +                        0b101 => { +                            instruction.opcode = Opcode::SEAMRET; +                        } +                        0b110 => { +                            instruction.opcode = Opcode::SEAMOPS; +                        } +                        0b111 => { +                            instruction.opcode = Opcode::SEAMCALL; +                        } +                        _ => { +                            instruction.opcode = Opcode::Invalid; +                            return Err(DecodeError::InvalidOpcode); +                        } +                    } +                    return Ok(()); +                } else { +                    return Err(DecodeError::InvalidOpcode); +                } +            } else { +                return Err(DecodeError::InvalidOpcode); +            } +        }          OperandCode::ModRM_0x0f01 => {              let opwidth = imm_width_from_prefixes_64(SizeCode::vq, instruction.prefixes);              let modrm = read_modrm(&mut bytes_iter, length)?; diff --git a/test/long_mode/mod.rs b/test/long_mode/mod.rs index b024103..3e8a307 100644 --- a/test/long_mode/mod.rs +++ b/test/long_mode/mod.rs @@ -607,13 +607,15 @@ fn test_sse3() {      test_instr(&[0xf2, 0x0f, 0x12, 0xcf], "movddup xmm1, xmm7");      test_instr(&[0xf2, 0x4f, 0x0f, 0x12, 0xcf], "movddup xmm9, xmm15"); -    test_instr(&[0x66, 0x0f, 0x01, 0xc8], "monitor"); -    test_instr(&[0xf2, 0x0f, 0x01, 0xc8], "monitor"); -    test_instr(&[0xf3, 0x0f, 0x01, 0xc8], "monitor"); - -    test_instr(&[0x66, 0x0f, 0x01, 0xc9], "mwait"); -    test_instr(&[0xf2, 0x0f, 0x01, 0xc9], "mwait"); -    test_instr(&[0xf3, 0x0f, 0x01, 0xc9], "mwait"); +    test_instr(&[0x0f, 0x01, 0xc8], "monitor"); +    test_invalid(&[0x66, 0x0f, 0x01, 0xc8]); +    test_invalid(&[0xf3, 0x0f, 0x01, 0xc8]); +    test_invalid(&[0xf2, 0x0f, 0x01, 0xc8]); + +    test_instr(&[0x0f, 0x01, 0xc9], "mwait"); +    test_invalid(&[0x66, 0x0f, 0x01, 0xc9]); +    test_invalid(&[0xf2, 0x0f, 0x01, 0xc9]); +    test_invalid(&[0xf3, 0x0f, 0x01, 0xc9]);  }  #[test] @@ -2335,3 +2337,11 @@ fn test_gfni() {      test_display(&[0x66, 0x36, 0x0f, 0x3a, 0xce, 0x8c, 0x56, 0x9e, 0x82, 0xd1, 0xbe, 0xad], "gf2p8affineqb xmm1, [rsi + rdx * 2 - 0x412e7d62], 0xad");      test_display(&[0x66, 0x4e, 0x0f, 0x38, 0xcf, 0x1c, 0x54], "gf2p8mulb xmm11, [rsp + r10 * 2]");  } + +#[test] +fn test_tdx() { +    test_display(&[0x66, 0x0f, 0x01, 0xcc], "tdcall"); +    test_display(&[0x66, 0x0f, 0x01, 0xcd], "seamret"); +    test_display(&[0x66, 0x0f, 0x01, 0xce], "seamops"); +    test_display(&[0x66, 0x0f, 0x01, 0xcf], "seamcall"); +}  | 
