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"); +} |