diff options
| -rw-r--r-- | src/display.rs | 113 | ||||
| -rw-r--r-- | src/lib.rs | 33 | ||||
| -rw-r--r-- | test/test.rs | 4 | 
3 files changed, 91 insertions, 59 deletions
diff --git a/src/display.rs b/src/display.rs index 0694265..1c5792e 100644 --- a/src/display.rs +++ b/src/display.rs @@ -706,75 +706,78 @@ impl <T: std::fmt::Write> ShowContextual<u64, [Option<String>], T> for Instructi                  x.colorize(colors, out)?;              }          }; -        match self.opcode { -            Opcode::MOVSX_b | -            Opcode::MOVZX_b => { -                match context.and_then(|xs| xs[1].as_ref()) { -                    Some(s) => { write!(out, ", {}", s) } -                    None => { -                        match &self.operands[1] { -                            &OperandSpec::Nothing => { -                                unreachable!(); -                            }, -                            &OperandSpec::RegMMM => { -                                write!(out, ", ")?; -                            } -                            x @ _ => { -                                write!(out, ", byte ")?; -                                if let Some(prefix) = self.segment_override_for_op(1) { -                                    write!(out, "{}:", prefix)?; +        for i in 1..4 { +            match self.opcode { +                Opcode::MOVSX_b | +                Opcode::MOVZX_b => { +                    match context.and_then(|xs| xs[i].as_ref()) { +                        Some(s) => { write!(out, ", {}", s)? } +                        None => { +                            match &self.operands[i] { +                                &OperandSpec::Nothing => { +                                    return Ok(()); +                                }, +                                &OperandSpec::RegMMM => { +                                    write!(out, ", ")?; +                                } +                                x @ _ => { +                                    write!(out, ", byte ")?; +                                    if let Some(prefix) = self.segment_override_for_op(1) { +                                        write!(out, "{}:", prefix)?; +                                    }                                  }                              } +                            let x = Operand::from_spec(self, self.operands[i]); +                            x.colorize(colors, out)?                          } -                        let x = Operand::from_spec(self, self.operands[1]); -                        x.colorize(colors, out)                      } -                } -            }, -            Opcode::MOVSX_w | -            Opcode::MOVZX_w => { -                match context.and_then(|xs| xs[1].as_ref()) { -                    Some(s) => { write!(out, ", {}", s) } -                    None => { -                        match &self.operands[1] { -                            &OperandSpec::Nothing => { -                                unreachable!(); -                            }, -                            &OperandSpec::RegMMM => { -                                write!(out, ", ")?; -                            } -                            _ => { -                                write!(out, ", word ")?; -                                if let Some(prefix) = self.segment_override_for_op(1) { -                                    write!(out, "{}:", prefix)?; +                }, +                Opcode::MOVSX_w | +                Opcode::MOVZX_w => { +                    match context.and_then(|xs| xs[i].as_ref()) { +                        Some(s) => { write!(out, ", {}", s)? } +                        None => { +                            match &self.operands[i] { +                                &OperandSpec::Nothing => { +                                    return Ok(()); +                                }, +                                &OperandSpec::RegMMM => { +                                    write!(out, ", ")?; +                                } +                                _ => { +                                    write!(out, ", word ")?; +                                    if let Some(prefix) = self.segment_override_for_op(1) { +                                        write!(out, "{}:", prefix)?; +                                    }                                  }                              } +                            let x = Operand::from_spec(self, self.operands[i]); +                            x.colorize(colors, out)?                          } -                        let x = Operand::from_spec(self, self.operands[1]); -                        x.colorize(colors, out)                      } -                } -            }, -            _ => { -                match context.and_then(|xs| xs[1].as_ref()) { -                    Some(s) => { write!(out, ", {}", s) } -                    None => { -                        match &self.operands[1] { -                            &OperandSpec::Nothing => { -                                return Ok(()); -                            }, -                            _ => { -                                write!(out, ", ")?; -                                if let Some(prefix) = self.segment_override_for_op(1) { -                                    write!(out, "{}:", prefix)?; +                }, +                _ => { +                    match context.and_then(|xs| xs[i].as_ref()) { +                        Some(s) => { write!(out, ", {}", s)? } +                        None => { +                            match &self.operands[i] { +                                &OperandSpec::Nothing => { +                                    return Ok(()); +                                }, +                                _ => { +                                    write!(out, ", ")?; +                                    if let Some(prefix) = self.segment_override_for_op(1) { +                                        write!(out, "{}:", prefix)?; +                                    } +                                    let x = Operand::from_spec(self, self.operands[i]); +                                    x.colorize(colors, out)?                                  } -                                let x = Operand::from_spec(self, self.operands[1]); -                                x.colorize(colors, out)                              }                          }                      }                  }              }          } +        Ok(())      }  } @@ -1522,7 +1522,6 @@ fn read_opcode_f20f_map<T: Iterator<Item=u8>>(bytes_iter: &mut T, length: &mut u              Some(record)          }          None => { -            unsafe { unreachable_unchecked(); }              None          }      } @@ -1810,7 +1809,6 @@ fn read_opcode_f30f_map<T: Iterator<Item=u8>>(bytes_iter: &mut T, length: &mut u              Some(record)          }          None => { -            unsafe { unreachable_unchecked(); }              None          }      } @@ -2139,7 +2137,6 @@ fn read_opcode_0f_map<T: Iterator<Item=u8>>(bytes_iter: &mut T, length: &mut u8)              Some(record)          }          None => { -            unsafe { unreachable_unchecked(); }              None          }      } @@ -2806,7 +2803,11 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut              }          } else {              opwidth = 1; -            bank = RegisterBank::B; +            if instruction.prefixes.rex().present() { +                bank = RegisterBank::rB; +            } else { +                bank = RegisterBank::B; +            }          };          modrm = read_modrm(&mut bytes_iter, instruction, length)?;          instruction.modrm_rrr = @@ -3017,6 +3018,7 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut                      instruction.imm = read_imm_signed(&mut bytes_iter, numwidth, length)? as u64;                      bytes_read = numwidth;                      instruction.operands[1] = match opwidth { +                        1 => OperandSpec::ImmI8,                          2 => OperandSpec::ImmI16,                          4 => OperandSpec::ImmI32,                          8 => OperandSpec::ImmI64, @@ -3192,6 +3194,29 @@ pub fn read_operands<T: Iterator<Item=u8>>(mut bytes_iter: T, instruction: &mut              instruction.operand_count = 1;              instruction.operands[0] = OperandSpec::ImmI32;          } +        OperandCode::Gb_Eb_Ib => { +            instruction.operands[0] = OperandSpec::RegRRR; +            instruction.operands[1] = mem_oper; +            instruction.imm = +                read_imm_signed(&mut bytes_iter, 1, length)? as u64; +            instruction.operands[2] = OperandSpec::ImmI8; +            instruction.operand_count = 3; +        } +        OperandCode::Gv_Ev_Iv => { +            let opwidth = imm_width_from_prefixes_64(SizeCode::vqp, instruction.prefixes); +            let numwidth = if opwidth == 8 { 4 } else { opwidth }; +            instruction.operands[0] = OperandSpec::RegRRR; +            instruction.operands[1] = mem_oper; +            instruction.imm = +                read_imm_signed(&mut bytes_iter, numwidth, length)? as u64; +            instruction.operands[2] = match opwidth { +                2 => OperandSpec::ImmI16, +                4 => OperandSpec::ImmI32, +                8 => OperandSpec::ImmI64, +                _ => unsafe { unreachable_unchecked() } +            }; +            instruction.operand_count = 3; +        }          OperandCode::Nothing => {              instruction.operand_count = 0;          } diff --git a/test/test.rs b/test/test.rs index 3182503..b88e470 100644 --- a/test/test.rs +++ b/test/test.rs @@ -88,6 +88,9 @@ fn test_system() {  fn test_arithmetic() {      test_display(&[0x81, 0xec, 0x10, 0x03, 0x00, 0x00], "sub esp, 0x310");      test_display(&[0x0f, 0xaf, 0xc2], "imul eax, edx"); +    test_display(&[0x4b, 0x69, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65], "imul rax, [r11 + 0x6f], 0x656c706d"); +    test_display(&[0x4b, 0x6b, 0x43, 0x6f, 0x6d], "imul al, [r11 + 0x6f], 0x6d"); +    test_display(&[0x4f, 0x4e, 0x00, 0xcc], "add spl, r9b");  }  #[test] @@ -188,6 +191,7 @@ fn test_control_flow() {  #[test]  fn test_test_cmp() { +    test_display(&[0xf6, 0x05, 0x2c, 0x9b, 0xff, 0xff, 0x01], "test [rip - 0x64d4], 0x1");      test_display(&[0x48, 0x3d, 0x01, 0xf0, 0xff, 0xff], "cmp rax, -0xfff");      test_display(&[0x3d, 0x01, 0xf0, 0xff, 0xff], "cmp eax, -0xfff");      test_display(&[0x48, 0x83, 0xf8, 0xff], "cmp rax, -0x1");  | 
