diff options
| author | iximeow <me@iximeow.net> | 2022-05-07 09:40:26 -0700 | 
|---|---|---|
| committer | iximeow <me@iximeow.net> | 2022-05-07 09:40:26 -0700 | 
| commit | 8ce99ef32e1db656138bb95ab57506100ffd6fdd (patch) | |
| tree | 947570523e0212739fe15ce4dead8f84e1c668ba /src | |
| parent | d58bfcb1ba2ceee1abe368ba81d31240e711d215 (diff) | |
more annotation fixes?
Diffstat (limited to 'src')
| -rw-r--r-- | src/long_mode/mod.rs | 53 | 
1 files changed, 30 insertions, 23 deletions
| diff --git a/src/long_mode/mod.rs b/src/long_mode/mod.rs index 6475d4e..2f3e510 100644 --- a/src/long_mode/mod.rs +++ b/src/long_mode/mod.rs @@ -5608,7 +5608,7 @@ pub(self) fn read_E<  >(words: &mut T, instr: &mut Instruction, modrm: u8, width: u8, sink: &mut S) -> Result<OperandSpec, DecodeError> {      let bank = width_to_gp_reg_bank(width, instr.prefixes.rex_unchecked().present());      if modrm >= 0b11000000 { -        read_modrm_reg(instr, modrm, bank) +        read_modrm_reg(instr, words, modrm, bank, sink)      } else {          read_M(words, instr, modrm, sink)      } @@ -5643,7 +5643,7 @@ pub(self) fn read_E_xmm<      S: DescriptionSink<FieldDescription>,  >(words: &mut T, instr: &mut Instruction, modrm: u8, sink: &mut S) -> Result<OperandSpec, DecodeError> {      if modrm >= 0b11000000 { -        read_modrm_reg(instr, modrm, RegisterBank::X) +        read_modrm_reg(instr, words, modrm, RegisterBank::X, sink)      } else {          read_M(words, instr, modrm, sink)      } @@ -5654,7 +5654,7 @@ pub(self) fn read_E_ymm<      S: DescriptionSink<FieldDescription>,  >(words: &mut T, instr: &mut Instruction, modrm: u8, sink: &mut S) -> Result<OperandSpec, DecodeError> {      if modrm >= 0b11000000 { -        read_modrm_reg(instr, modrm, RegisterBank::Y) +        read_modrm_reg(instr, words, modrm, RegisterBank::Y, sink)      } else {          read_M(words, instr, modrm, sink)      } @@ -5665,7 +5665,7 @@ pub(self) fn read_E_vex<      S: DescriptionSink<FieldDescription>,  >(words: &mut T, instr: &mut Instruction, modrm: u8, bank: RegisterBank, sink: &mut S) -> Result<OperandSpec, DecodeError> {      if modrm >= 0b11000000 { -        read_modrm_reg(instr, modrm, bank) +        read_modrm_reg(instr, words, modrm, bank, sink)      } else {          let res = read_M(words, instr, modrm, sink)?;          if (modrm & 0b01_000_000) == 0b01_000_000 { @@ -5676,8 +5676,18 @@ pub(self) fn read_E_vex<  }  #[allow(non_snake_case)] -fn read_modrm_reg(instr: &mut Instruction, modrm: u8, reg_bank: RegisterBank) -> Result<OperandSpec, DecodeError> { +#[inline(always)] +fn read_modrm_reg< +    T: Reader<<Arch as yaxpeax_arch::Arch>::Address, <Arch as yaxpeax_arch::Arch>::Word>, +    S: DescriptionSink<FieldDescription>, +>(instr: &mut Instruction, words: &mut T, modrm: u8, reg_bank: RegisterBank, sink: &mut S) -> Result<OperandSpec, DecodeError> {      instr.regs[1] = RegSpec::from_parts(modrm & 7, instr.prefixes.rex_unchecked().b(), reg_bank); +    sink.record( +        words.offset() as u32 * 8 - 8, +        words.offset() as u32 * 8 - 6, +        InnerDescription::RegisterNumber("mmm", modrm & 7, instr.regs[1]) +            .with_id(words.offset() as u32 * 8 - 8 + 2) +    );      Ok(OperandSpec::RegMMM)  } @@ -7838,14 +7848,7 @@ fn read_operands<              if operand_code.bits() == (OperandCode::Gv_M as u16) {                  return Err(DecodeError::InvalidOperand);              } -            let res = read_modrm_reg(instruction, modrm, bank)?; -            sink.record( -                modrm_start, -                modrm_start + 2, -                InnerDescription::RegisterNumber("mmm", modrm & 7, instruction.regs[1]) -                    .with_id(modrm_start + 2) -            ); -            res +            read_modrm_reg(instruction, words, modrm, bank, sink)?          } else {              read_M(words, instruction, modrm, sink)?          }; @@ -7885,12 +7888,16 @@ fn read_operands<          modrm = read_modrm(words)?;          instruction.regs[0].bank = bank;          instruction.regs[0].num = ((modrm >> 3) & 7) + if instruction.prefixes.rex_unchecked().r() { 0b1000 } else { 0 }; -        sink.record( -            modrm_start + 3, -            modrm_start + 5, -            InnerDescription::RegisterNumber("rrr", (modrm >> 3) & 7, instruction.regs[0]) -                .with_id(modrm_start + 3) -        ); + +        // for some encodings, the rrr field selects an opcode, not an operand +        if operand_code.bits() != OperandCode::ModRM_0xc1_Ev_Ib as u16 && operand_code.bits() != OperandCode::ModRM_0xff_Ev as u16 { +            sink.record( +                modrm_start + 3, +                modrm_start + 5, +                InnerDescription::RegisterNumber("rrr", (modrm >> 3) & 7, instruction.regs[0]) +                    .with_id(modrm_start + 3) +            ); +        }          mem_oper = if modrm >= 0b11000000 {              sink.record( @@ -7899,7 +7906,7 @@ fn read_operands<                  InnerDescription::Misc("mmm field is a register number (mod bits: 11)")                      .with_id(modrm_start + 0)              ); -            read_modrm_reg(instruction, modrm, bank)? +            read_modrm_reg(instruction, words, modrm, bank, sink)?          } else {              read_M(words, instruction, modrm, sink)?          }; @@ -8272,9 +8279,9 @@ fn read_operands<                  };                  if op == 5 {                      sink.record( -                        modrm_start - 8, -                        modrm_start - 1, -                        InnerDescription::Number("imm", instruction.imm as i64) +                        words.offset() as u32 * 8 - 8, +                        words.offset() as u32 * 8 - 1, +                        InnerDescription::Number("imm", num as i64)                              .with_id(modrm_start - 8)                      );                  } else { | 
