From 5223427b217cc567deb55ea420b8da58aea64d68 Mon Sep 17 00:00:00 2001 From: iximeow Date: Sun, 21 Mar 2021 02:48:11 -0700 Subject: complete CET support, add UINTR, add missing VORP{S,D}, other cleanup --- src/long_mode/display.rs | 26 +++++++++++ src/long_mode/mod.rs | 116 +++++++++++++++++++++++++++++++++++++++-------- src/long_mode/vex.rs | 10 ++++ 3 files changed, 133 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/long_mode/display.rs b/src/long_mode/display.rs index 8f7bd9b..5c733a2 100644 --- a/src/long_mode/display.rs +++ b/src/long_mode/display.rs @@ -848,6 +848,8 @@ const MNEMONICS: &[&'static str] = &[ "vpalignr", "vandps", "vandpd", + "vorps", + "vorpd", "vandnps", "vandnpd", "vpand", @@ -1285,6 +1287,11 @@ const MNEMONICS: &[&'static str] = &[ // CET "wruss", "wrss", + "incssp", + "saveprevssp", + "setssbsy", + "clrssbsy", + "rstorssp", // TDX "tdcall", @@ -1296,6 +1303,13 @@ const MNEMONICS: &[&'static str] = &[ "tpause", "umonitor", "umwait", + + // UINTR + "uiret", + "testui", + "clui", + "stui", + "senduipi", ]; impl Opcode { @@ -1462,6 +1476,8 @@ impl > Colorize> Colorize { write!(out, "{}", colors.platform_op(self)) } Opcode::CRC32 | @@ -2330,6 +2351,11 @@ impl > Colorize>(decoder: &InstDecoder, mut bytes_iter 0x1d => { instruction.opcode = Opcode::PF2ID; } - 0x59 => { - instruction.opcode = Opcode::PMULHRW; - } 0x8a => { instruction.opcode = Opcode::PFNACC; } @@ -7293,9 +7306,6 @@ fn unlikely_operands>(decoder: &InstDecoder, mut bytes_iter 0xbb => { instruction.opcode = Opcode::PSWAPD; } - 0xbe => { - instruction.opcode = Opcode::PFPNACC; - } 0xbf => { instruction.opcode = Opcode::PAVGUSB; } @@ -7414,9 +7424,10 @@ fn unlikely_operands>(decoder: &InstDecoder, mut bytes_iter instruction.opcode = Opcode::VMXON; instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, opwidth, length)?; if instruction.operands[0] == OperandSpec::RegMMM { - // this would be invalid as `vmxon`, so fall back to the parse as - // f3-prefixed rdrand - instruction.opcode = Opcode::RDRAND; + // invalid as `vmxon`, reg-form is `senduipi` + instruction.opcode = Opcode::SENDUIPI; + // and the operand is always a qword register + instruction.modrm_mmm.bank = RegisterBank::Q; } instruction.operand_count = 1; } @@ -8301,20 +8312,69 @@ fn unlikely_operands>(decoder: &InstDecoder, mut bytes_iter } else if r == 5 { let mod_bits = modrm >> 6; if mod_bits != 0b11 { - instruction.opcode = Opcode::Invalid; - instruction.operands[0] = OperandSpec::Nothing; - instruction.operand_count = 0; - return Err(DecodeError::InvalidOpcode); + if !instruction.prefixes.rep() { + return Err(DecodeError::InvalidOpcode); + } + instruction.opcode = Opcode::RSTORSSP; + instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, 8, length)?; + instruction.operand_count = 1; + return Ok(()); } let m = modrm & 7; match m { + 0b000 => { + if !instruction.prefixes.rep() || instruction.prefixes.operand_size() || instruction.prefixes.repnz() { + return Err(DecodeError::InvalidOpcode); + } + instruction.opcode = Opcode::SETSSBSY; + instruction.operands[0] = OperandSpec::Nothing; + instruction.operand_count = 0; + } + 0b010 => { + if !instruction.prefixes.rep() || instruction.prefixes.operand_size() || instruction.prefixes.repnz() { + return Err(DecodeError::InvalidOpcode); + } + instruction.opcode = Opcode::SAVEPREVSSP; + instruction.operands[0] = OperandSpec::Nothing; + instruction.operand_count = 0; + } + 0b100 => { + if instruction.prefixes.rep() { + instruction.opcode = Opcode::UIRET; + instruction.operands[0] = OperandSpec::Nothing; + instruction.operand_count = 0; + } + } + 0b101 => { + if instruction.prefixes.rep() { + instruction.opcode = Opcode::TESTUI; + instruction.operands[0] = OperandSpec::Nothing; + instruction.operand_count = 0; + } + } 0b110 => { + if instruction.prefixes.rep() { + instruction.opcode = Opcode::CLUI; + instruction.operands[0] = OperandSpec::Nothing; + instruction.operand_count = 0; + return Ok(()); + } else if instruction.prefixes.operand_size() || instruction.prefixes.repnz() { + return Err(DecodeError::InvalidOpcode); + } instruction.opcode = Opcode::RDPKRU; instruction.operands[0] = OperandSpec::Nothing; instruction.operand_count = 0; } 0b111 => { + if instruction.prefixes.rep() { + instruction.opcode = Opcode::STUI; + instruction.operands[0] = OperandSpec::Nothing; + instruction.operand_count = 0; + return Ok(()); + } else if instruction.prefixes.operand_size() || instruction.prefixes.repnz() { + return Err(DecodeError::InvalidOpcode); + } instruction.opcode = Opcode::WRPKRU; instruction.operands[0] = OperandSpec::Nothing; instruction.operand_count = 0; @@ -8509,13 +8569,21 @@ fn unlikely_operands>(decoder: &InstDecoder, mut bytes_iter instruction.operands[0] = OperandSpec::RegMMM; instruction.operand_count = 1; } + 5 => { + instruction.opcode = Opcode::INCSSP; + let opwidth = if instruction.prefixes.rex().w() { + RegisterBank::Q + } else { + RegisterBank::D + }; + instruction.modrm_mmm = RegSpec::from_parts(m, instruction.prefixes.rex().x(), opwidth); + instruction.operands[0] = OperandSpec::RegMMM; + instruction.operand_count = 1; + } 6 => { instruction.opcode = Opcode::UMONITOR; - instruction.modrm_rrr = RegSpec { - bank: RegisterBank::Q, - num: m + if instruction.prefixes.rex().x() { 0b1000 } else { 0 }, - }; - instruction.operands[0] = OperandSpec::RegRRR; + instruction.modrm_mmm = RegSpec::from_parts(m, instruction.prefixes.rex().x(), RegisterBank::Q); + instruction.operands[0] = OperandSpec::RegMMM; instruction.operand_count = 1; } _ => { @@ -8525,7 +8593,17 @@ fn unlikely_operands>(decoder: &InstDecoder, mut bytes_iter } return Ok(()); } else { - return Err(DecodeError::InvalidOperand); + match r { + 6 => { + instruction.opcode = Opcode::CLRSSBSY; + instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, 8, length)?; + instruction.operand_count = 1; + return Ok(()); + } + _ => { + return Err(DecodeError::InvalidOperand); + } + } } } diff --git a/src/long_mode/vex.rs b/src/long_mode/vex.rs index 71a5724..41f5c29 100644 --- a/src/long_mode/vex.rs +++ b/src/long_mode/vex.rs @@ -952,6 +952,11 @@ fn read_vex_instruction>(opcode_map: VEXOpcodeMap, bytes: & } else { VEXOperandCode::G_V_E_xmm }), + 0x56 => (Opcode::VORPS, if L { + VEXOperandCode::G_V_E_ymm + } else { + VEXOperandCode::G_V_E_xmm + }), 0x57 => (Opcode::VXORPS, if L { VEXOperandCode::G_V_E_ymm } else { @@ -1099,6 +1104,11 @@ fn read_vex_instruction>(opcode_map: VEXOpcodeMap, bytes: & } else { VEXOperandCode::G_V_E_xmm }), + 0x56 => (Opcode::VORPD, if L { + VEXOperandCode::G_V_E_ymm + } else { + VEXOperandCode::G_V_E_xmm + }), 0x57 => (Opcode::VXORPD, if L { VEXOperandCode::G_V_E_ymm } else { -- cgit v1.1