diff options
-rw-r--r-- | CHANGELOG | 7 | ||||
-rw-r--r-- | Cargo.toml | 4 | ||||
-rw-r--r-- | src/lib.rs | 53 | ||||
-rw-r--r-- | test/test.rs | 8 |
4 files changed, 24 insertions, 48 deletions
diff --git a/CHANGELOG b/CHANGELOG new file mode 100644 index 0000000..cfb11b0 --- /dev/null +++ b/CHANGELOG @@ -0,0 +1,7 @@ +# 0.1.0 + +update yaxpeax-arch to 0.2.2, update impls + +# 0.0.4 + +first version with changelog, decoder is "complete" @@ -1,14 +1,14 @@ [package] name = "yaxpeax-mips" -version = "0.0.4" +version = "0.1.0" authors = [ "iximeow <me@iximeow.net>" ] license = "0BSD" repository = "http://git.iximeow.net/yaxpeax-mips/" description = "mips decoders for the yaxpeax project" [dependencies] -yaxpeax-arch = { version = "0.0.5", default-features = false, features = [] } +yaxpeax-arch = { version = "0.2.2", default-features = false, features = [] } "serde" = { version = "1.0", optional = true } "serde_derive" = { version = "1.0", optional = true } "num_enum" = { version = "0.2", default-features = false } @@ -1,41 +1,15 @@ extern crate num_enum; extern crate yaxpeax_arch; -use std::convert::TryInto; -use std::fmt; use std::mem; use num_enum::IntoPrimitive; -use yaxpeax_arch::{Arch, AddressDiff, Decoder, LengthedInstruction}; +use yaxpeax_arch::{Arch, AddressDiff, Decoder, LengthedInstruction, Reader, StandardDecodeError}; mod display; #[derive(Debug, PartialEq)] -pub enum DecodeError { - ExhaustedInput, - InvalidOpcode, - InvalidOperand, -} - -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"), - } - } -} - -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 } -} - - -#[derive(Debug, PartialEq)] pub struct Instruction { word: u32, operands: [OperandSpec; 3], @@ -254,18 +228,15 @@ pub enum Operand { JOffset(i32) } -#[cfg(feature="use-serde")] -#[derive(Debug, Serialize, Deserialize)] -pub struct MIPS; - -#[cfg(not(feature="use-serde"))] +#[cfg_attr(feature="use-serde", derive(Serialize, Deserialize))] #[derive(Debug)] pub struct MIPS; impl Arch for MIPS { type Address = u32; + type Word = yaxpeax_arch::U32le; type Instruction = Instruction; - type DecodeError = DecodeError; + type DecodeError = StandardDecodeError; type Decoder = MipsDecoder; type Operand = Operand; } @@ -273,13 +244,9 @@ impl Arch for MIPS { #[derive(Default, Debug)] pub struct MipsDecoder {} -impl Decoder<Instruction> for MipsDecoder { - type Error = DecodeError; - - fn decode_into<T: IntoIterator<Item=u8>>(&self, instruction: &mut Instruction, bytes: T) -> Result<(), Self::Error> { - let mut bytes_iter = bytes.into_iter(); - let word: Vec<u8> = bytes_iter.by_ref().take(4).collect(); - let word = u32::from_le_bytes(word.as_slice().try_into().map_err(|_| DecodeError::ExhaustedInput)?); +impl Decoder<MIPS> for MipsDecoder { + fn decode_into<T: Reader<<MIPS as Arch>::Address, <MIPS as Arch>::Word>>(&self, instruction: &mut Instruction, words: &mut T) -> Result<(), <MIPS as Arch>::DecodeError> { + let word = words.next()?.0; instruction.word = word; @@ -292,7 +259,7 @@ impl Decoder<Instruction> for MipsDecoder { let opc = (word & 0b111111) as u8; if [0b000101, 0b001110, 0b010101, 0b101000, 0b101001, 0b110101, 0b110111, 0b111001, 0b111101].contains(&opc) { - return Err(DecodeError::InvalidOpcode); + return Err(StandardDecodeError::InvalidOpcode); } // operands in the secondary map have kind of a mess of operands. except for 0b100000 @@ -354,7 +321,7 @@ impl Decoder<Instruction> for MipsDecoder { // reject all 0b11xxx patterns, and the right half of table A-40, section REGIMM, // except two outliers. if opc >= 0b10_011000 || (opc & 0b00_00100 > 0 && (opc != 0b10_001100 || opc != 0b10_001110)) { - return Err(DecodeError::InvalidOpcode); + return Err(StandardDecodeError::InvalidOpcode); } instruction.opcode = unsafe { mem::transmute::<u8, Opcode>(opc) @@ -363,7 +330,7 @@ impl Decoder<Instruction> for MipsDecoder { } else { if opc & 0b111100 == 0b011100 || opc == 0b111011 { // reserved opcode - return Err(DecodeError::InvalidOpcode); + return Err(StandardDecodeError::InvalidOpcode); } instruction.opcode = unsafe { mem::transmute::<u8, Opcode>(opc) diff --git a/test/test.rs b/test/test.rs index 431a349..0238853 100644 --- a/test/test.rs +++ b/test/test.rs @@ -1,12 +1,13 @@ extern crate yaxpeax_arch; extern crate yaxpeax_mips; -use yaxpeax_arch::{Arch, Decoder}; +use yaxpeax_arch::{Arch, Decoder, U8Reader}; use yaxpeax_mips::{MIPS, Instruction}; //, Opcode}; #[allow(dead_code)] fn test_decode(data: [u8; 4], expected: Instruction) { - let instr = <MIPS as Arch>::Decoder::default().decode(data.to_vec()).unwrap(); + let mut reader = U8Reader::new(&data[..]); + let instr = <MIPS as Arch>::Decoder::default().decode(&mut reader).unwrap(); assert!( instr == expected, "decode error for {:02x}{:02x}{:02x}{:02x}:\n decoded: {:?}\n expected: {:?}\n", @@ -16,7 +17,8 @@ fn test_decode(data: [u8; 4], expected: Instruction) { } fn test_display(data: [u8; 4], expected: &'static str) { - let instr = <MIPS as Arch>::Decoder::default().decode(data.to_vec()).unwrap(); + let mut reader = U8Reader::new(&data[..]); + let instr = <MIPS as Arch>::Decoder::default().decode(&mut reader).unwrap(); let text = format!("{}", instr); assert!( text == expected, |