diff options
| author | iximeow <me@iximeow.net> | 2019-11-30 12:12:40 -0800 | 
|---|---|---|
| committer | iximeow <me@iximeow.net> | 2020-01-12 16:10:13 -0800 | 
| commit | 7561575f135e0ba72f0a90a5859d19f7b02a31e8 (patch) | |
| tree | 77f1f9edddc5eec033d6ac442abbc1f851dc6c7a | |
| parent | 2b9f85fed5c720725748417a2d91b6bb38ca2747 (diff) | |
fix 0x98 and 0x99 opcodes, lss/lfs/lgs decodes
also remove unnecessary variants in unlikely_operands and adjust
expectations of several tests
| -rw-r--r-- | src/display.rs | 16 | ||||
| -rw-r--r-- | src/lib.rs | 66 | ||||
| -rw-r--r-- | test/test.rs | 6 | 
3 files changed, 44 insertions, 44 deletions
| diff --git a/src/display.rs b/src/display.rs index 3e058df..5e42cef 100644 --- a/src/display.rs +++ b/src/display.rs @@ -331,8 +331,6 @@ impl fmt::Display for Opcode {              &Opcode::RETURN => write!(f, "{}", "ret"),              &Opcode::PUSHF => write!(f, "{}", "pushf"),              &Opcode::WAIT => write!(f, "{}", "wait"), -            &Opcode::CBW => write!(f, "{}", "cbw"), -            &Opcode::CDW => write!(f, "{}", "cdw"),              &Opcode::LODS => write!(f, "{}", "lods"),              &Opcode::STOS => write!(f, "{}", "stos"),              &Opcode::LAHF => write!(f, "{}", "lahf"), @@ -523,6 +521,12 @@ impl fmt::Display for Opcode {              &Opcode::VMREAD => write!(f, "{}", "vmread"),              &Opcode::VMWRITE => write!(f, "{}", "vmwrite"),              &Opcode::XORPS => write!(f, "{}", "xorps"), +            &Opcode::CBW => write!(f, "{}", "cbw"), +            &Opcode::CWDE => write!(f, "{}", "cwde"), +            &Opcode::CDQE => write!(f, "{}", "cdqe"), +            &Opcode::CBD => write!(f, "{}", "cbd"), +            &Opcode::CDQ => write!(f, "{}", "cdq"), +            &Opcode::CQO => write!(f, "{}", "cqo"),              &Opcode::Invalid => write!(f, "{}", "invalid"),          }      } @@ -720,6 +724,12 @@ impl <T: std::fmt::Write> Colorize<T> for Opcode {              Opcode::STC |              Opcode::STI |              Opcode::STD | +            Opcode::CBW | +            Opcode::CWDE | +            Opcode::CDQE | +            Opcode::CBD | +            Opcode::CDQ | +            Opcode::CQO |              Opcode::MOVDDUP |              Opcode::MOVSLDUP |              Opcode::MOVDQ2Q | @@ -731,8 +741,6 @@ impl <T: std::fmt::Write> Colorize<T> for Opcode {              Opcode::PEXTRW |              Opcode::PINSRW |              Opcode::MOV | -            Opcode::CBW | -            Opcode::CDW |              Opcode::LODS |              Opcode::STOS |              Opcode::LAHF | @@ -466,7 +466,11 @@ pub enum Opcode {      PUSHF,      WAIT,      CBW, -    CDW, +    CWDE, +    CDQE, +    CBD, +    CDQ, +    CQO,      LODS,      STOS,      LAHF, @@ -1088,6 +1092,8 @@ pub enum OperandCode {      ModRM_0x0fba,      ModRM_0xf238,      ModRM_0xf30fc7, +    CVT_AA, +    CVT_DA,      Rq_Cq_0,      Rq_Dq_0,      Cq_Rq_0, @@ -2310,10 +2316,10 @@ const OPCODE_0F_MAP: [OpcodeRecord; 256] = [  // 0xb0      OpcodeRecord(Interpretation::Instruction(Opcode::CMPXCHG), OperandCode::Eb_Gb),      OpcodeRecord(Interpretation::Instruction(Opcode::CMPXCHG), OperandCode::Ev_Gv), -    OpcodeRecord(Interpretation::Instruction(Opcode::LSS), OperandCode::G_M_q), +    OpcodeRecord(Interpretation::Instruction(Opcode::LSS), OperandCode::Gv_M),      OpcodeRecord(Interpretation::Instruction(Opcode::BTR), OperandCode::E_G_q), -    OpcodeRecord(Interpretation::Instruction(Opcode::LFS), OperandCode::G_M_q), -    OpcodeRecord(Interpretation::Instruction(Opcode::LGS), OperandCode::G_M_q), +    OpcodeRecord(Interpretation::Instruction(Opcode::LFS), OperandCode::Gv_M), +    OpcodeRecord(Interpretation::Instruction(Opcode::LGS), OperandCode::Gv_M),      OpcodeRecord(Interpretation::Instruction(Opcode::MOVZX_b), OperandCode::Gv_Eb),      OpcodeRecord(Interpretation::Instruction(Opcode::MOVZX_w), OperandCode::Gv_Ew),      OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing), // JMPE, ITANIUM @@ -2578,8 +2584,8 @@ const OPCODES: [OpcodeRecord; 256] = [      OpcodeRecord(Interpretation::Instruction(Opcode::XCHG), OperandCode::Zv_AX_R5),      OpcodeRecord(Interpretation::Instruction(Opcode::XCHG), OperandCode::Zv_AX_R6),      OpcodeRecord(Interpretation::Instruction(Opcode::XCHG), OperandCode::Zv_AX_R7), -    OpcodeRecord(Interpretation::Instruction(Opcode::CBW), OperandCode::AX_AL), -    OpcodeRecord(Interpretation::Instruction(Opcode::CBW), OperandCode::DX_AX), +    OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::CVT_AA), +    OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::CVT_DA),      OpcodeRecord(Interpretation::Instruction(Opcode::Invalid), OperandCode::Nothing),      OpcodeRecord(Interpretation::Prefix, OperandCode::Nothing),      OpcodeRecord(Interpretation::Instruction(Opcode::PUSHF), OperandCode::Nothing), @@ -3511,23 +3517,6 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut  fn unlikely_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut Instruction, operand_code: OperandCode, length: &mut u8) -> Result<(), ()> {      let mut bytes_read = 0;      match operand_code { -        OperandCode::Gb_Eb_Ib => { -            let mut ext = vec![Operand::Nothing; 2]; - -            // TODO -            panic!("oh no, a mul!"); -//            read_E(&mut bytes_iter, instruction, modrm, opwidth, &mut ext[0])?; -            /* -            instruction.operands[0] = -                RegSpec::gp_from_parts(r, instruction.prefixes.rex().r(), opwidth, instruction.prefixes.rex().present()); -            read_imm_signed(&mut bytes_iter, 1, 1).map(|imm| { -                ext[1] = imm; -                instruction.operands[1] = Operand::Many(ext); -            })? - -            instruction.operand_count = 3; -            */ -        }          OperandCode::Ew_Sw => {              let opwidth = 2;              let modrm = read_modrm(&mut bytes_iter, instruction, length)?; @@ -3575,20 +3564,23 @@ fn unlikely_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut                  instruction.operands[1] = read_M(&mut bytes_iter, instruction, modrm, length)?;              }          }, -        OperandCode::Gv_Ev_Iv => { -            let mut ext = vec![Operand::Nothing; 2]; - -            // TODO -            panic!("oh no, a mul!"); -//            read_E(&mut bytes_iter, instruction, modrm, opwidth, &mut ext[0])?; -            /* -            instruction.operands[0] = -                RegSpec::gp_from_parts(r, instruction.prefixes.rex().r(), opwidth, instruction.prefixes.rex().present()); -            read_imm_signed(&mut bytes_iter, if opwidth == 8 { 4 } else { opwidth }, opwidth).map(|imm| { -                ext[1] = imm; -                instruction.operands[1] = Operand::Many(ext); -            })? -            */ +        OperandCode::CVT_AA => { +            let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, instruction.prefixes); +            instruction.opcode = match opwidth { +                2 => { Opcode::CBW }, +                4 => { Opcode::CWDE }, +                8 => { Opcode::CDQE }, +                _ => { unreachable!("invalid operation width"); }, +            } +        } +        OperandCode::CVT_DA => { +            let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, instruction.prefixes); +            instruction.opcode = match opwidth { +                2 => { Opcode::CBD }, +                4 => { Opcode::CDQ }, +                8 => { Opcode::CQO }, +                _ => { unreachable!("invalid operation width"); }, +            }          }          OperandCode::Iw => {              instruction.imm = diff --git a/test/test.rs b/test/test.rs index 634dd54..479faef 100644 --- a/test/test.rs +++ b/test/test.rs @@ -232,15 +232,15 @@ fn test_bitwise() {  fn test_misc() {      test_display(&[0x9c], "pushf");      test_display(&[0x48, 0x98], "cdqe"); -    test_display(&[0x66, 0x2e, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00], "nop cs:[rax + rax]"); -    test_display(&[0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00], "nop cs:[rax + rax]"); +    test_display(&[0x66, 0x2e, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00], "nop cs:[rax + rax * 1]"); +    test_display(&[0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00], "nop [rax + rax * 1]");      test_display(&[0x48, 0x8d, 0xa4, 0xc7, 0x20, 0x00, 0x00, 0x12], "lea rsp, [rdi + rax * 8 + 0x12000020]");      test_display(&[0x33, 0xc0], "xor eax, eax");      test_display(&[0x48, 0x8d, 0x53, 0x08], "lea rdx, [rbx + 0x8]");      test_display(&[0x31, 0xc9], "xor ecx, ecx");      test_display(&[0x48, 0x29, 0xc8], "sub rax, rcx");      test_display(&[0x48, 0x03, 0x0b], "add rcx, [rbx]"); -    test_display(&[0x48, 0x8d, 0x0c, 0x12], "lea rcx, [rdx + rdx]"); +    test_display(&[0x48, 0x8d, 0x0c, 0x12], "lea rcx, [rdx + rdx * 1]");      test_display(&[0xf6, 0xc2, 0x18], "test dl, 0x18");      test_display(&[0xf3, 0x48, 0xab], "rep stosq");      test_display(&[0xf3, 0x48, 0xa5], "rep movsq"); | 
