diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/long_mode/mod.rs | 27 | ||||
| -rw-r--r-- | src/long_mode/vex.rs | 1 | ||||
| -rw-r--r-- | src/protected_mode/mod.rs | 23 | ||||
| -rw-r--r-- | src/protected_mode/vex.rs | 1 | ||||
| -rw-r--r-- | src/shared/evex.in | 2 | 
5 files changed, 53 insertions, 1 deletions
diff --git a/src/long_mode/mod.rs b/src/long_mode/mod.rs index 29a76a8..8d83986 100644 --- a/src/long_mode/mod.rs +++ b/src/long_mode/mod.rs @@ -7970,6 +7970,8 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter              // lsl is weird. the full register width is written, but only the low 16 bits are used.              if instruction.operands[1] == OperandSpec::RegMMM {                  instruction.modrm_mmm.bank = RegisterBank::D; +            } else { +                instruction.mem_size = 2;              }              instruction.modrm_rrr =                  RegSpec::gp_from_parts((modrm >> 3) & 7, instruction.prefixes.rex().r(), opwidth, instruction.prefixes.rex().present()); @@ -8166,6 +8168,13 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter                  instruction.modrm_rrr.num &= 0b111;                  instruction.opcode = Opcode::MOVD;              } +            if instruction.operands[1] != OperandSpec::RegMMM { +                if instruction.prefixes.rex().w() { +                    instruction.mem_size = 4; +                } else { +                    instruction.mem_size = 8; +                } +            }          }          OperandCode::ModRM_0x0f0d => {              let modrm = read_modrm(&mut bytes_iter, length)?; @@ -9138,6 +9147,9 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter                  unreachable!("r <= 8");              }              instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, 2, length)?; +            if instruction.operands[0] != OperandSpec::RegMMM { +                instruction.mem_size = 2; +            }          }          OperandCode::ModRM_0x0f01 => {              let opwidth = imm_width_from_prefixes_64(SizeCode::vq, instruction.prefixes); @@ -9770,6 +9782,9 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter              }              instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, opwidth, length)?; +            if instruction.operands[0] != OperandSpec::RegMMM { +                instruction.mem_size = opwidth; +            }              instruction.imm = read_imm_signed(&mut bytes_iter, 1, length)? as u64;              instruction.operands[1] = OperandSpec::ImmI8; @@ -9912,12 +9927,18 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter              instruction.operands[0] = OperandSpec::Deref;              instruction.operands[1] = OperandSpec::RegRRR;              instruction.operand_count = 2; +            instruction.mem_size = 1;          }          OperandCode::Yv_DX => {              instruction.modrm_rrr = RegSpec::dx();              instruction.modrm_mmm = RegSpec::rdi();              instruction.operands[0] = OperandSpec::Deref;              instruction.operands[1] = OperandSpec::RegRRR; +            if instruction.prefixes.operand_size() { +                instruction.mem_size = 2; +            } else { +                instruction.mem_size = 4; +            }              instruction.operand_count = 2;          }          OperandCode::DX_Xb => { @@ -9926,6 +9947,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter              instruction.operands[0] = OperandSpec::RegRRR;              instruction.operands[1] = OperandSpec::Deref;              instruction.operand_count = 2; +            instruction.mem_size = 1;          }          OperandCode::AH => {              instruction.operands[0] = OperandSpec::Nothing; @@ -9936,6 +9958,11 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter              instruction.modrm_mmm = RegSpec::rsi();              instruction.operands[0] = OperandSpec::RegRRR;              instruction.operands[1] = OperandSpec::Deref; +            if instruction.prefixes.operand_size() { +                instruction.mem_size = 2; +            } else { +                instruction.mem_size = 4; +            }              instruction.operand_count = 2;          }          OperandCode::x87_d8 | diff --git a/src/long_mode/vex.rs b/src/long_mode/vex.rs index ab69e51..31297f7 100644 --- a/src/long_mode/vex.rs +++ b/src/long_mode/vex.rs @@ -442,6 +442,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst              Ok(())          }          VEXOperandCode::Nothing => { +            instruction.operand_count = 0;              Ok(())          },          VEXOperandCode::Ev_G_xmm_imm8 => { diff --git a/src/protected_mode/mod.rs b/src/protected_mode/mod.rs index 88b41c9..76f3a43 100644 --- a/src/protected_mode/mod.rs +++ b/src/protected_mode/mod.rs @@ -7845,6 +7845,8 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter              // lsl is weird. the full register width is written, but only the low 16 bits are used.              if instruction.operands[1] == OperandSpec::RegMMM {                  instruction.modrm_mmm.bank = RegisterBank::D; +            } else { +                instruction.mem_size = 2;              }              instruction.operand_count = 2;          }, @@ -8013,6 +8015,9 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter              instruction.modrm_rrr =                  RegSpec::from_parts((modrm >> 3) & 7, RegisterBank::X);              instruction.operands[1] = read_E_xmm(&mut bytes_iter, instruction, modrm, length)?; +            if instruction.operands[1] != OperandSpec::RegMMM { +                instruction.mem_size = 8; +            }          }          OperandCode::ModRM_0x0f0d => {              let modrm = read_modrm(&mut bytes_iter, length)?; @@ -8924,6 +8929,9 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter                  unreachable!("r <= 8");              }              instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, 2, length)?; +            if instruction.operands[0] != OperandSpec::RegMMM { +                instruction.mem_size = 2; +            }          }          OperandCode::ModRM_0x0f01 => {              let opwidth = if instruction.prefixes.operand_size() { @@ -9533,6 +9541,9 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter              }              instruction.operands[0] = read_E(&mut bytes_iter, instruction, modrm, opwidth, length)?; +            if instruction.operands[0] != OperandSpec::RegMMM { +                instruction.mem_size = opwidth; +            }              instruction.imm = read_imm_signed(&mut bytes_iter, 1, length)? as u32;              instruction.operands[1] = OperandSpec::ImmI8; @@ -9685,12 +9696,18 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter              instruction.operands[0] = OperandSpec::Deref;              instruction.operands[1] = OperandSpec::RegRRR;              instruction.operand_count = 2; +            instruction.mem_size = 1;          }          OperandCode::Yv_DX => {              instruction.modrm_rrr = RegSpec::dx();              instruction.modrm_mmm = RegSpec::edi();              instruction.operands[0] = OperandSpec::Deref;              instruction.operands[1] = OperandSpec::RegRRR; +            if instruction.prefixes.operand_size() { +                instruction.mem_size = 2; +            } else { +                instruction.mem_size = 4; +            }              instruction.operand_count = 2;          }          OperandCode::DX_Xb => { @@ -9699,6 +9716,7 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter              instruction.operands[0] = OperandSpec::RegRRR;              instruction.operands[1] = OperandSpec::Deref;              instruction.operand_count = 2; +            instruction.mem_size = 1;          }          OperandCode::AH => {              instruction.operands[0] = OperandSpec::Nothing; @@ -9709,6 +9727,11 @@ fn unlikely_operands<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter              instruction.modrm_mmm = RegSpec::esi();              instruction.operands[0] = OperandSpec::RegRRR;              instruction.operands[1] = OperandSpec::Deref; +            if instruction.prefixes.operand_size() { +                instruction.mem_size = 2; +            } else { +                instruction.mem_size = 4; +            }              instruction.operand_count = 2;          }          OperandCode::x87_d8 | diff --git a/src/protected_mode/vex.rs b/src/protected_mode/vex.rs index 09379cf..73d10b5 100644 --- a/src/protected_mode/vex.rs +++ b/src/protected_mode/vex.rs @@ -438,6 +438,7 @@ fn read_vex_operands<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut Inst              Ok(())          }          VEXOperandCode::Nothing => { +            instruction.mem_size = 1;              Ok(())          },          VEXOperandCode::Ev_G_xmm_imm8 => { diff --git a/src/shared/evex.in b/src/shared/evex.in index e7e0aa1..17c9bb7 100644 --- a/src/shared/evex.in +++ b/src/shared/evex.in @@ -53,7 +53,7 @@ pub(crate) fn read_evex<T: Iterator<Item=u8>>(bytes: &mut T, instruction: &mut I      let table_idx = ((m << 2) | p) as usize;      let table = generated::TABLES[table_idx];      if table as *const [_]  == &generated::DUMMY[..] as *const [_] { -        panic!("no table for m={}, p={}", m, p); +        return Err(DecodeError::InvalidOpcode);      }      let mut index_lower = 0;      if instruction.prefixes.evex_unchecked().vex().l() {  | 
