diff options
| author | iximeow <me@iximeow.net> | 2021-07-06 18:19:19 -0700 | 
|---|---|---|
| committer | iximeow <me@iximeow.net> | 2021-07-06 18:21:16 -0700 | 
| commit | e98b04b473465a161aefd8d6cf7213f08b54758f (patch) | |
| tree | 99e3c5ae7792e36229afeb20750e1b81b33d7210 | |
| parent | 0eed3ca0c9413071a15bd5171a3522a413aae383 (diff) | |
update yaxpeax-arch to 0.2.3, tag 0.1.00.1.0
| -rw-r--r-- | CHANGELOG | 7 | ||||
| -rw-r--r-- | Cargo.toml | 4 | ||||
| -rw-r--r-- | src/display.rs | 14 | ||||
| -rw-r--r-- | src/lib.rs | 91 | ||||
| -rw-r--r-- | test/test.rs | 20 | 
5 files changed, 45 insertions, 91 deletions
| diff --git a/CHANGELOG b/CHANGELOG new file mode 100644 index 0000000..0c9b6f0 --- /dev/null +++ b/CHANGELOG @@ -0,0 +1,7 @@ +# 0.1.0 + +update yaxpeax-arch to 0.2.3, apply API updates + +# 0.0.5 + +first version with changelog, theoretically complete @@ -1,14 +1,14 @@  [package]  name = "yaxpeax-msp430" -version = "0.0.6" +version = "0.1.0"  authors = [ "iximeow <me@iximeow.net>" ]  license = "0BSD"  repository = "http://git.iximeow.net/yaxpeax-msp430/"  description = "msp430 decoders for the yaxpeax project"  [dependencies] -yaxpeax-arch = { version = "0.0.5", default-features = false, features = [] } +yaxpeax-arch = { version = "0.2.3", default-features = false, features = [] }  "serde" = { version = "1.0", optional = true }  "serde_derive" = { version = "1.0", optional = true } diff --git a/src/display.rs b/src/display.rs index 54147f7..12153b1 100644 --- a/src/display.rs +++ b/src/display.rs @@ -1,6 +1,6 @@ -use ::{MSP430, Operand, Opcode, Instruction, Width, DecodeError}; +use ::{MSP430, Operand, Opcode, Instruction, Width}; -use std::fmt::{self, Display, Formatter}; +use std::fmt::{Display, Formatter};  use std;  use yaxpeax_arch::{Arch, Colorize, NoColors, ShowContextual, YaxColors}; @@ -12,16 +12,6 @@ impl Display for Instruction {      }  } -impl fmt::Display for DecodeError { -    fn fmt(&self, f:  &mut fmt::Formatter) -> fmt::Result { -        match self { -            DecodeError::ExhaustedInput => write!(f, "exhausted input"), -            DecodeError::InvalidOpcode => write!(f, "invalid opcode"), -            DecodeError::InvalidOperand => write!(f, "invalid operand"), -        } -    } -} -  /// No per-operand when contextualizing an instruction.  pub struct NoContext; @@ -7,23 +7,20 @@ extern crate serde;  extern crate yaxpeax_arch; -use yaxpeax_arch::{Arch, AddressDiff, Decoder, LengthedInstruction}; +use yaxpeax_arch::{Arch, AddressDiff, Decoder, LengthedInstruction, Reader, StandardDecodeError, U16le};  mod display;  pub use display::NoContext; -#[cfg(feature="use-serde")] -#[derive(Debug, Serialize, Deserialize)] -pub struct MSP430; - -#[cfg(not(feature="use-serde"))] +#[cfg_attr(feature="use-serde", derive(Serialize, Deserialize))]  #[derive(Debug)]  pub struct MSP430;  impl Arch for MSP430 {      type Address = u16; +    type Word = U16le;      type Instruction = Instruction; -    type DecodeError = DecodeError; +    type DecodeError = StandardDecodeError;      type Decoder = InstDecoder;      type Operand = Operand;  } @@ -126,19 +123,6 @@ pub enum Operand {      Nothing  } -#[derive(Debug, PartialEq)] -pub enum DecodeError { -    ExhaustedInput, -    InvalidOpcode, -    InvalidOperand, -} - -impl yaxpeax_arch::DecodeError for DecodeError { -    fn data_exhausted(&self) -> bool { self == &DecodeError::ExhaustedInput } -    fn bad_opcode(&self) -> bool { self == &DecodeError::InvalidOpcode } -    fn bad_operand(&self) -> bool { self == &DecodeError::InvalidOperand } -} -  impl yaxpeax_arch::Instruction for Instruction {      // TODO: this is wrong!!      fn well_defined(&self) -> bool { true } @@ -174,10 +158,7 @@ impl Default for InstDecoder {      }  } -impl Decoder<Instruction> for InstDecoder { -    type Error = DecodeError; - -    fn decode_into<T: IntoIterator<Item=u8>>(&self, inst: &mut Instruction, bytes: T) -> Result<(), Self::Error> { +/*          let mut bytes_iter = bytes.into_iter();          let word: Vec<u8> = bytes_iter.by_ref().take(2).collect(); @@ -186,42 +167,32 @@ impl Decoder<Instruction> for InstDecoder {              [low, high] => (high as u16) << 8 | (low as u16),              _ => unreachable!()          }; +        */ -        fn decode_operand<T: Iterator<Item=u8>>(bytes: &mut T, reg: u8, mode: u8, oper: &mut Operand) -> bool { +impl Decoder<MSP430> for InstDecoder { +    fn decode_into<T: Reader<<MSP430 as Arch>::Address, <MSP430 as Arch>::Word>>(&self, inst: &mut Instruction, words: &mut T) -> Result<(), <MSP430 as Arch>::DecodeError> { +        let fullword = words.next()?.0; + +        fn decode_operand<T: Reader<<MSP430 as Arch>::Address, <MSP430 as Arch>::Word>>(words: &mut T, reg: u8, mode: u8, oper: &mut Operand) -> Result<(), StandardDecodeError> {              *oper = match reg {                  0 => {                      if mode == 0 {                          Operand::Register(reg)                      } else if mode == 1 { -                        let next = match bytes.take(2).collect::<Vec<u8>>()[..] { -                            [] | [_] => { return false; }, -                            [low, high] => { ((high as u16) << 8) | (low as u16) }, -                            _ => { unreachable!() } -                        }; -                        Operand::Symbolic(next) +                        Operand::Symbolic(words.next()?.0)                      } else if mode == 2 {                          Operand::RegisterIndirect(reg)                      } else if mode == 3 { -                        let next = match bytes.take(2).collect::<Vec<u8>>()[..] { -                            [] | [_] => { return false; }, -                            [low, high] => { ((high as u16) << 8) | (low as u16) }, -                            _ => { unreachable!() } -                        }; -                        Operand::Immediate(next) +                        Operand::Immediate(words.next()?.0)                      } else { -                        return false; +                        return Err(StandardDecodeError::InvalidOperand);                      }                  },                  2 => {                      match mode {                          0 => { Operand::Register(reg) },                          1 => { -                            let next = match bytes.take(2).collect::<Vec<u8>>()[..] { -                                [] | [_] => { return false; }, -                                [low, high] => { ((high as u16) << 8) | (low as u16) }, -                                _ => { unreachable!() } -                            }; -                            Operand::Absolute(next) +                            Operand::Absolute(words.next()?.0)                          },                          2 => { Operand::Const8 },                          3 => { Operand::Const4 }, @@ -241,12 +212,7 @@ impl Decoder<Instruction> for InstDecoder {                      match mode {                          0 => { Operand::Register(reg) },                          1 => { -                            let next = match bytes.take(2).collect::<Vec<u8>>()[..] { -                                [] | [_] => { return false; }, -                                [low, high] => { ((high as u16) << 8) | (low as u16) }, -                                _ => { unreachable!() } -                            }; -                            Operand::Indexed(reg, next) +                            Operand::Indexed(reg, words.next()?.0)                          },                          2 => { Operand::RegisterIndirect(reg) },                          3 => { Operand::IndirectAutoinc(reg) }, @@ -254,7 +220,7 @@ impl Decoder<Instruction> for InstDecoder {                      }                  }              }; -            return true; +            return Ok(());          }          inst.op_width = Width::W; @@ -271,7 +237,7 @@ impl Decoder<Instruction> for InstDecoder {              instrword if instrword < 0x2000 => {                  // microcorruption msp430 is non-standard and accepts invalid instructions..                  if !self.microcorruption_quirks() { -                    return Err(DecodeError::InvalidOpcode); +                    return Err(StandardDecodeError::InvalidOpcode);                  }                  let (opcode_idx, operands) = ((instrword & 0x0380) >> 7, instrword & 0x7f); @@ -290,7 +256,7 @@ impl Decoder<Instruction> for InstDecoder {                          } else {                              if x == 1 || x == 3 || x == 5 {                                  inst.opcode = Opcode::Invalid(instrword); -                                return Err(DecodeError::InvalidOpcode); +                                return Err(StandardDecodeError::InvalidOpcode);                              }                              Width:: B                          }; @@ -299,10 +265,7 @@ impl Decoder<Instruction> for InstDecoder {                              ((instrword & 0x0030) >> 4) as u8,                              (instrword & 0x000f) as u8                          ); -                        if !decode_operand(&mut bytes_iter, source, As, &mut inst.operands[0]) { -                            inst.opcode = Opcode::Invalid(instrword); -                            return Err(DecodeError::InvalidOperand); -                        }; +                        decode_operand(words, source, As, &mut inst.operands[0])?;                          inst.operands[1] = Operand::Nothing;                          Ok(())                      }, @@ -314,12 +277,12 @@ impl Decoder<Instruction> for InstDecoder {                              Ok(())                          } else {                              inst.opcode = Opcode::Invalid(instrword); -                            return Err(DecodeError::InvalidOperand); +                            return Err(StandardDecodeError::InvalidOperand);                          }                      }                      7 => {                          inst.opcode = Opcode::Invalid(instrword); -                        return Err(DecodeError::InvalidOpcode); +                        return Err(StandardDecodeError::InvalidOpcode);                      }                      _ => {                          unreachable!(); @@ -366,14 +329,8 @@ impl Decoder<Instruction> for InstDecoder {                      ((instrword & 0x0030) >> 4) as u8,                      (instrword & 0x000f) as u8                  ); -                if !decode_operand(&mut bytes_iter, source, As, &mut inst.operands[0]) { -                    inst.opcode = Opcode::Invalid(instrword); -                    return Err(DecodeError::InvalidOperand); -                } -                if !decode_operand(&mut bytes_iter, dest, Ad, &mut inst.operands[1]) { -                    inst.opcode = Opcode::Invalid(instrword); -                    return Err(DecodeError::InvalidOperand); -                } +                decode_operand(words, source, As, &mut inst.operands[0])?; +                decode_operand(words, dest, Ad, &mut inst.operands[1])?;                  Ok(())              }          } diff --git a/test/test.rs b/test/test.rs index 663b080..eb2399e 100644 --- a/test/test.rs +++ b/test/test.rs @@ -1,26 +1,26 @@  extern crate yaxpeax_arch;  extern crate yaxpeax_msp430; -use yaxpeax_arch::{Arch, Decoder}; +use yaxpeax_arch::{Arch, Decoder, U8Reader};  use yaxpeax_msp430::{Opcode, MSP430};  #[test]  fn test_decode() { -    let decoder = <MSP430 as Arch>::Decoder::default(); +    fn decode(bytes: &[u8]) -> yaxpeax_msp430::Instruction { +        let decoder = <MSP430 as Arch>::Decoder::default(); +        let mut reader = U8Reader::new(bytes); +        decoder.decode(&mut reader).unwrap() +    } -    let data = [0x02, 0x12]; -    let instr = decoder.decode(data.iter().cloned()).unwrap(); +    let instr = decode(&[0x02, 0x12][..]);      assert!(instr.opcode == Opcode::PUSH); -    let data = [0xb1, 0x92, 0x8d, 0x49]; -    let instr = decoder.decode(data.iter().cloned()).unwrap(); +    let instr = decode(&[0xb1, 0x92, 0x8d, 0x49][..]);      assert!(instr.opcode == Opcode::CMP); -    let data = [0x12, 0x00, 0x3f, 0x40]; -    let instr = decoder.decode(data.iter().cloned()).unwrap(); +    let instr = decode(&[0x12, 0x00, 0x3f, 0x40][..]);      assert!(instr.opcode == Opcode::RRC); -    let data = [0x20, 0x0e]; -    let instr = decoder.decode(data.iter().cloned()).unwrap(); +    let instr = decode(&[0x20, 0x0e][..]);      assert!(instr.opcode == Opcode::PUSH);  } | 
