From 68e719a30e989d6580f8077cb9afa5af3ddffa9a Mon Sep 17 00:00:00 2001 From: iximeow Date: Sun, 21 Mar 2021 01:21:11 -0700 Subject: add tdx decoder flag to come --- src/long_mode/display.rs | 10 ++++++++++ src/long_mode/mod.rs | 48 +++++++++++++++++++++++++++++++++++++++++++++--- 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 > Colorize 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>(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"); +} -- cgit v1.1