diff options
| author | iximeow <me@iximeow.net> | 2021-03-21 02:48:11 -0700 | 
|---|---|---|
| committer | iximeow <me@iximeow.net> | 2021-03-21 02:48:11 -0700 | 
| commit | 5223427b217cc567deb55ea420b8da58aea64d68 (patch) | |
| tree | 4b8256c45706e3ea94dd7234616a69e79ae45bff /src/long_mode | |
| parent | 0a3811ec18d2154f050aaf6e611a3d65f467c0cc (diff) | |
complete CET support, add UINTR, add missing VORP{S,D}, other cleanup
Diffstat (limited to 'src/long_mode')
| -rw-r--r-- | src/long_mode/display.rs | 26 | ||||
| -rw-r--r-- | src/long_mode/mod.rs | 116 | ||||
| -rw-r--r-- | src/long_mode/vex.rs | 10 | 
3 files changed, 133 insertions, 19 deletions
| 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 <T: fmt::Write, Color: fmt::Display, Y: YaxColors<Color>> Colorize<T, Color              Opcode::VDPPD |              Opcode::VDPPS |              Opcode::VRCPPS | +            Opcode::VORPD | +            Opcode::VORPS |              Opcode::VANDPD |              Opcode::VANDPS |              Opcode::VANDNPD | @@ -2298,6 +2314,11 @@ impl <T: fmt::Write, Color: fmt::Display, Y: YaxColors<Color>> Colorize<T, Color              Opcode::ENQCMD |              Opcode::ENQCMDS |              Opcode::PTWRITE | +            Opcode::UIRET | +            Opcode::TESTUI | +            Opcode::CLUI | +            Opcode::STUI | +            Opcode::SENDUIPI |              Opcode::LAR => { write!(out, "{}", colors.platform_op(self)) }              Opcode::CRC32 | @@ -2330,6 +2351,11 @@ impl <T: fmt::Write, Color: fmt::Display, Y: YaxColors<Color>> Colorize<T, Color              Opcode::LOADIWKEY |              Opcode::WRUSS |              Opcode::WRSS | +            Opcode::INCSSP | +            Opcode::SAVEPREVSSP | +            Opcode::SETSSBSY | +            Opcode::CLRSSBSY | +            Opcode::RSTORSSP |              Opcode::AESDEC |              Opcode::AESDECLAST |              Opcode::AESENC | diff --git a/src/long_mode/mod.rs b/src/long_mode/mod.rs index 8e64021..266bd2e 100644 --- a/src/long_mode/mod.rs +++ b/src/long_mode/mod.rs @@ -1488,6 +1488,8 @@ pub enum Opcode {      VPALIGNR,      VANDPD,      VANDPS, +    VORPD, +    VORPS,      VANDNPD,      VANDNPS,      VPAND, @@ -1940,6 +1942,11 @@ pub enum Opcode {      // CET      WRUSS,      WRSS, +    INCSSP, +    SAVEPREVSSP, +    SETSSBSY, +    CLRSSBSY, +    RSTORSSP,      // TDX      TDCALL, @@ -1951,6 +1958,13 @@ pub enum Opcode {      TPAUSE,      UMONITOR,      UMWAIT, + +    // UINTR +    UIRET, +    TESTUI, +    CLUI, +    STUI, +    SENDUIPI,  }  #[derive(Debug)] @@ -3109,6 +3123,8 @@ impl InstDecoder {              Opcode::VANDPS |              Opcode::VANDNPD |              Opcode::VANDNPS | +            Opcode::VORPD | +            Opcode::VORPS |              Opcode::VPANDN |              Opcode::VPAVGB |              Opcode::VPAVGW | @@ -7233,9 +7249,6 @@ fn unlikely_operands<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(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<T: Iterator<Item=u8>>(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 { | 
