summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoriximeow <me@iximeow.net>2021-07-06 17:50:56 -0700
committeriximeow <me@iximeow.net>2021-07-06 17:52:31 -0700
commitbc3bf7337fc643b55bf7e599c1a488b999b1e73c (patch)
tree1f609f284518c4d468855995804967005446d5fd
parentbd0ecaafb838f02bb6064b6abb5dcb8910422d2b (diff)
update yaxpeax-arch to 0.1.0, update implsHEAD0.1.0no-gods-no-
-rw-r--r--CHANGELOG7
-rw-r--r--Cargo.toml4
-rw-r--r--src/lib.rs53
-rw-r--r--test/test.rs8
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"
diff --git a/Cargo.toml b/Cargo.toml
index 06b4aa0..bf6c633 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -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 }
diff --git a/src/lib.rs b/src/lib.rs
index 074d660..d2139a9 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -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,