From dc9366f430874c25e4e44e2a365efea5fcc43382 Mon Sep 17 00:00:00 2001 From: iximeow Date: Sun, 4 Aug 2019 19:08:56 -0700 Subject: fix the hex/bits mismatch --- src/armv7.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/armv7.rs b/src/armv7.rs index e609086..52061c7 100644 --- a/src/armv7.rs +++ b/src/armv7.rs @@ -798,7 +798,7 @@ impl Decodable for Instruction { println!("{:032b}", word); println!(" {:05b}|{:04b}|{:04b}|{:04b}|1{:02b}1|{:04b}", flags, Rn, Rd, HiOffset, op, LoOffset); match op { - 0x00 => { + 0b00 => { // |c o n d|0 0 0 1|x x x x x x x x x x x x x x x x|1 0 0 1|x x x x| // this is swp or {ld,st}ex, conditional on bit 23 match flags { @@ -862,7 +862,7 @@ impl Decodable for Instruction { } } } - 0x01 => { + 0b01 => { // |c o n d|0 0 0 x|x x x x x x x x x x x x x x x x|1 0 1 1|x x x x| // page A5-201 self.opcode = Opcode::Incomplete(word); @@ -895,13 +895,13 @@ impl Decodable for Instruction { } } } - 0x10 => { + 0b10 => { // |c o n d|0 0 0 x|x x x x x x x x x x x x x x x x|1 1 0 1|x x x x| // page A5-201 self.opcode = Opcode::Incomplete(word); return Some(()); } - 0x11 => { + 0b11 => { // |c o n d|0 0 0 x|x x x x x x x x x x x x x x x x|1 1 1 1|x x x x| // page A5-201 self.opcode = Opcode::Incomplete(word); -- cgit v1.1 From 8b9d5f9c6003864870dccfe2c0f71729d4b99564 Mon Sep 17 00:00:00 2001 From: iximeow Date: Sun, 4 Aug 2019 19:12:25 -0700 Subject: fix issue with incorrectly decoding register shifts --- src/armv7.rs | 2 +- test/armv7.rs | 15 +++++++++++++++ test/test.rs | 2 +- 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/armv7.rs b/src/armv7.rs index 52061c7..a5467e5 100644 --- a/src/armv7.rs +++ b/src/armv7.rs @@ -487,7 +487,7 @@ fn format_shift(f: &mut T, Rm: u8, shift: ShiftSpec, colors: }, ShiftSpec::Register(v) => { let tpe = v & 0x3; - let Rs = v >> 2; + let Rs = v >> 3; write!(f, "{}, {} {}", reg_name_colorize(Rm, colors), shift_tpe_to_str(tpe), reg_name_colorize(Rs, colors)) }, } diff --git a/test/armv7.rs b/test/armv7.rs index c76cb4a..af5336c 100644 --- a/test/armv7.rs +++ b/test/armv7.rs @@ -163,6 +163,21 @@ fn test_decode_mov() { #[test] fn test_decode_arithmetic() { test_decode( + [0x18, 0x1d, 0x00, 0x00], + Instruction { + condition: ConditionCode::EQ, + opcode: Opcode::AND, + operands: Operands::ThreeOperandWithShift( + 1, 0, 8, ShiftSpec::Register(104) + ), + s: false + } + ); + test_display( + [0x18, 0x1d, 0x00, 0x00], + "andeq r1, r0, r8, lsl sp", + ); + test_decode( [0x03, 0x30, 0x8f, 0xe0], Instruction { condition: ConditionCode::AL, diff --git a/test/test.rs b/test/test.rs index 7dd54ea..72b7e50 100644 --- a/test/test.rs +++ b/test/test.rs @@ -5,5 +5,5 @@ extern crate test; extern crate yaxpeax_arch; extern crate yaxpeax_arm; -// mod armv7; +mod armv7; mod armv8; -- cgit v1.1 From 120adb21db26779729c026b576739b1de82bc198 Mon Sep 17 00:00:00 2001 From: iximeow Date: Sun, 4 Aug 2019 19:12:54 -0700 Subject: decode blx --- src/armv7.rs | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- test/armv7.rs | 4 +++ 2 files changed, 82 insertions(+), 4 deletions(-) diff --git a/src/armv7.rs b/src/armv7.rs index a5467e5..4a806f2 100644 --- a/src/armv7.rs +++ b/src/armv7.rs @@ -119,6 +119,9 @@ impl ShowContextual], T> for Instructi write!(out, " ")?; format_reg_list(out, list, colors)?; }, + Operands::OneOperand(a) => { + write!(out, " {}", reg_name_colorize(a, colors))?; + }, Operands::TwoOperand(a, b) => { write!(out, " {}, {}", reg_name_colorize(a, colors), reg_name_colorize(b, colors))?; }, @@ -409,6 +412,7 @@ pub enum ShiftSpec { #[derive(Debug, PartialEq, Eq)] pub enum Operands { RegisterList(u16), + OneOperand(u8), TwoOperand(u8, u8), RegImm(u8, u32), RegRegList(u8, u16), @@ -697,7 +701,34 @@ impl Decodable for Instruction { if cond == 0b1111 { // do unconditional instruction stuff self.condition = ConditionCode::AL; - self.opcode = Opcode::Incomplete(word); + let op1 = (word >> 20) as u8; + if op1 > 0x80 { + match (op1 >> 5) & 0b11 { + 0b00 => { + self.opcode = Opcode::Incomplete(word); + } + 0b01 => { + self.opcode = Opcode::BLX; + let operand = ((word & 0xffffff) as i32) << 8 >> 6; + self.operands = Operands::BranchOffset( + operand | ( + ((word >> 23) & 0b10) as i32 + ) + ); + } + 0b10 => { + self.opcode = Opcode::Incomplete(word); + } + 0b11 => { + self.opcode = Opcode::Incomplete(word); + } + _ => { + unreachable!(); + } + } + } else { + self.opcode = Opcode::Incomplete(word); + } return Some(()); } else { self.condition = ConditionCode::build(cond); @@ -915,11 +946,54 @@ impl Decodable for Instruction { // misc instructions in Figure A3-4 if s == false && opcode >= 0b1000 && opcode < 0b1100 { + let op2 = ((word >> 4) & 0x0f) as u8; // the instruction looks like // |c o n d|0 0 0|1 0 x x|0|x x x x|x x x x|x x x x x|x x|x|x x x x| - // misc instructions (page A5-194) - self.opcode = Opcode::Incomplete(word); - return Some(()); + if op2 & 0x08 == 0x00 { + let op2 = op2 & 0x07; + // |c o n d|0 0 0|1 0 x x|0|x x x x|x x x x|x x x x|0|x x|x|x x x x| + // misc instructions (page A5-194) + match op2 { + 0b000 => { + + }, + 0b001 => { + + }, + 0b010 => { + + }, + 0b011 => { + if opcode & 0b11 == 0b01 { + self.opcode = Opcode::BLX; + self.operands = Operands::OneOperand((word & 0x0f) as u8); + return Some(()); + } else { + return None; + } + }, + 0b100 => { + self.opcode = Opcode::Incomplete(word); + return Some(()); + }, + 0b101 => { + + } + 0b110 => { + }, + 0b111 => { + + }, + _ => { + unreachable!(); + } + } + } else { + // |c o n d|0 0 0|1 0 x x|0|x x x x|x x x x|x x x x|1|x x|x|x x x x| + // multiply and multiply-accumulate + self.opcode = Opcode::Incomplete(word); + return Some(()); + } } else { if opcode >= 16 { unreachable!(); diff --git a/test/armv7.rs b/test/armv7.rs index af5336c..f7ab079 100644 --- a/test/armv7.rs +++ b/test/armv7.rs @@ -86,6 +86,10 @@ fn test_decode_str_ldr() { #[test] fn test_decode_misc() { test_display( + [0x32, 0xff, 0x2f, 0xe1], + "blx r2" + ); + test_display( [0x02, 0x00, 0xa0, 0xe3], "mov r0, 0x2" ); -- cgit v1.1 From c20df7acc8cb12db124ab1a819719fadc40227c3 Mon Sep 17 00:00:00 2001 From: iximeow Date: Sun, 4 Aug 2019 19:16:11 -0700 Subject: immediates are not shifted, what was this about? --- src/armv7.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/armv7.rs b/src/armv7.rs index 4a806f2..03d4b77 100644 --- a/src/armv7.rs +++ b/src/armv7.rs @@ -126,7 +126,7 @@ impl ShowContextual], T> for Instructi write!(out, " {}, {}", reg_name_colorize(a, colors), reg_name_colorize(b, colors))?; }, Operands::RegImm(a, imm) => { - write!(out, " {}, {:#x}", reg_name_colorize(a, colors), imm * 4)?; + write!(out, " {}, {:#x}", reg_name_colorize(a, colors), imm)?; }, Operands::RegRegList(r, list) => { write!(out, " {}, ", reg_name_colorize(r, colors))?; -- cgit v1.1 From 77bc926bb3b0840bc91dd0774d01e8ca25c80616 Mon Sep 17 00:00:00 2001 From: iximeow Date: Tue, 6 Aug 2019 20:51:42 -0700 Subject: armv7 test cases --- test/armv7.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/armv7.rs b/test/armv7.rs index f7ab079..09f5333 100644 --- a/test/armv7.rs +++ b/test/armv7.rs @@ -330,7 +330,7 @@ fn test_decode_span() { instr); i += instr.len(); } - panic!("done"); +// panic!("done"); } /* * from debian 5.0.10 bash 3.2-4_arm -- cgit v1.1 From 22f9afd31c902ded123f175a95812955c965233f Mon Sep 17 00:00:00 2001 From: iximeow Date: Tue, 6 Aug 2019 20:52:04 -0700 Subject: armv8 serde/no-serde support plus contextual display .. ish --- src/armv8/a64.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/armv8/a64.rs b/src/armv8/a64.rs index d640292..e58d2a2 100644 --- a/src/armv8/a64.rs +++ b/src/armv8/a64.rs @@ -116,6 +116,18 @@ mod docs { } } +#[allow(non_snake_case)] +impl ShowContextual], T> for Instruction { + fn contextualize(&self, colors: Option<&ColorSettings>, address: u64, context: Option<&[Option]>, out: &mut T) -> std::fmt::Result { + write!(out, "{}", self) + } +} + +#[cfg(feature="use-serde")] +#[derive(Copy, Clone, Debug, Serialize, Deserialize)] +pub struct ARMv8 { } + +#[cfg(not(feature="use-serde"))] #[derive(Copy, Clone, Debug)] pub struct ARMv8 { } -- cgit v1.1 From f6dd37f8dd6d9d307c881cf44b5cf1856cc4ab74 Mon Sep 17 00:00:00 2001 From: iximeow Date: Mon, 30 Sep 2019 00:19:04 -0700 Subject: warnings-b-gone --- src/armv7.rs | 25 +++++++++++++++---------- src/armv8/a64.rs | 32 +++++++++++++++++--------------- 2 files changed, 32 insertions(+), 25 deletions(-) diff --git a/src/armv7.rs b/src/armv7.rs index 03d4b77..9fe6fea 100644 --- a/src/armv7.rs +++ b/src/armv7.rs @@ -1,5 +1,5 @@ -#[cfg(feature="use-serde")] -use serde::{Serialize, Deserialize}; +//#[cfg(feature="use-serde")] +//use serde::{Serialize, Deserialize}; use std::fmt::{Display, Formatter}; @@ -15,7 +15,7 @@ impl Display for ConditionedOpcode { #[allow(non_snake_case)] impl ShowContextual], T> for Instruction { - fn contextualize(&self, colors: Option<&ColorSettings>, address: u32, context: Option<&[Option]>, out: &mut T) -> std::fmt::Result { + fn contextualize(&self, colors: Option<&ColorSettings>, _address: u32, _context: Option<&[Option]>, out: &mut T) -> std::fmt::Result { match self.opcode { Opcode::LDR(true, false, false) => { match self.operands { @@ -94,8 +94,9 @@ impl ShowContextual], T> for Instructi _ => { unreachable!(); } } } - Opcode::STM(add, pre, wback, usermode) | - Opcode::LDM(add, pre, wback, usermode) => { + // TODO: [add, pre, usermode] + Opcode::STM(_add, _pre, wback, _usermode) | + Opcode::LDM(_add, _pre, wback, _usermode) => { match self.operands { Operands::RegRegList(Rr, list) => { ConditionedOpcode(self.opcode, self.condition).colorize(colors, out)?; @@ -132,13 +133,15 @@ impl ShowContextual], T> for Instructi write!(out, " {}, ", reg_name_colorize(r, colors))?; format_reg_list(out, list, colors)?; }, - Operands::TwoRegImm(a, b, imm) => { + Operands::TwoRegImm(_a, _b, _imm) => { + // TODO: write!(out, " ")?; }, Operands::ThreeOperand(a, b, c) => { write!(out, " {}, {}, {}", reg_name_colorize(a, colors), reg_name_colorize(b, colors), reg_name_colorize(c, colors))?; }, - Operands::ThreeOperandImm(a, b, imm) => { + Operands::ThreeOperandImm(_a, _b, _imm) => { + // TODO: write!(out, " ")?; }, Operands::ThreeOperandWithShift(a, b, c, shift) => { @@ -148,7 +151,8 @@ impl ShowContextual], T> for Instructi Operands::MulThreeRegs(a, b, c) => { write!(out, " {}, {}, {}", reg_name_colorize(a, colors), reg_name_colorize(b, colors), reg_name_colorize(c, colors))?; }, - Operands::MulFourRegs(a, b, c, d) => { + Operands::MulFourRegs(_a, _b, _c, _d) => { + // TODO: write!(out, " ")?; }, Operands::BranchOffset(imm) => { @@ -655,7 +659,7 @@ impl ConditionCode { 0b1100 => ConditionCode::GT, 0b1101 => ConditionCode::LE, 0b1110 => ConditionCode::AL, - _ => unsafe { + _ => { // this means the argument `value` must never be outside [0,15] // which itself means this function shouldn't be public unreachable!(); @@ -897,7 +901,7 @@ impl Decodable for Instruction { // |c o n d|0 0 0 x|x x x x x x x x x x x x x x x x|1 0 1 1|x x x x| // page A5-201 self.opcode = Opcode::Incomplete(word); - return Some(()); + // return Some(()); match flags { 0b00010 => { // self.opcode = Opcode::STRHT_sub; @@ -925,6 +929,7 @@ impl Decodable for Instruction { unreachable!(); } } + panic!("page a5-201"); } 0b10 => { // |c o n d|0 0 0 x|x x x x x x x x x x x x x x x x|1 1 0 1|x x x x| diff --git a/src/armv8/a64.rs b/src/armv8/a64.rs index e58d2a2..3e0403a 100644 --- a/src/armv8/a64.rs +++ b/src/armv8/a64.rs @@ -1,9 +1,9 @@ -#[cfg(feature="use-serde")] -use serde::{Serialize, Deserialize}; +//#[cfg(feature="use-serde")] +//use serde::{Serialize, Deserialize}; use std::fmt::{Display, Formatter}; -use yaxpeax_arch::{Arch, Colorize, Colored, ColorSettings, Decodable, LengthedInstruction, ShowContextual, YaxColors}; +use yaxpeax_arch::{Arch, ColorSettings, Decodable, LengthedInstruction, ShowContextual}; #[allow(non_snake_case)] mod docs { @@ -118,7 +118,7 @@ mod docs { #[allow(non_snake_case)] impl ShowContextual], T> for Instruction { - fn contextualize(&self, colors: Option<&ColorSettings>, address: u64, context: Option<&[Option]>, out: &mut T) -> std::fmt::Result { + fn contextualize(&self, _colors: Option<&ColorSettings>, _address: u64, _context: Option<&[Option]>, out: &mut T) -> std::fmt::Result { write!(out, "{}", self) } } @@ -1545,7 +1545,7 @@ impl Decodable for Instruction { } else { self.opcode = Opcode::Invalid; } - unreachable!(); + unreachable!("decode Rd: {}, Rn: {}, imms: {}, Rm: {}, No0: {}", Rd, Rn, imms, Rm, No0); } _ => { unreachable!() } } @@ -1605,7 +1605,8 @@ impl Decodable for Instruction { _ => { Opcode::Invalid } - } + }; + unreachable!("Rt: {}, Rn: {}, Rt2: {}, Rs: {}", Rt, Rn, Rt2, Rs); }, 0b00001 => { let Rt = (word & 0x1f) as u16; @@ -1643,6 +1644,7 @@ impl Decodable for Instruction { Operand::Nothing, Operand::Nothing, ]; + unreachable!("Rt: {}, Rn: {}, Rt2: {}, Rs: {}", Rt, Rn, Rt2, Rs); }, 0b01000 | 0b01001 => { @@ -1687,19 +1689,19 @@ impl Decodable for Instruction { let opc = (word >> 29) & 0x3; let Rt = word & 0x1f; let imm19 = (word >> 5) & 0x7fff; - panic!("C3.3.5 V==1"); + panic!("C3.3.5 V==1. opc: {}, Rt: {}, imm19: {}", opc, Rt, imm19); }, 0b10000 => { // load/store no-allocate pair (offset) // V == 0 let opc_L = ((word >> 22) & 1) | ((word >> 29) & 0x6); - panic!("C3.3.7 V==0"); + panic!("C3.3.7 V==0, opc_L: {}", opc_L); }, 0b10100 => { // load/store no-allocate pair (offset) // V == 1 let opc_L = ((word >> 22) & 1) | ((word >> 29) & 0x6); - panic!("C3.3.7 V==1"); + panic!("C3.3.7 V==1, opc_L: {}", opc_L); }, 0b10001 => { // load/store register pair (post-indexed) @@ -1707,7 +1709,7 @@ impl Decodable for Instruction { let Rt = (word & 0x1f) as u16; let Rn = ((word >> 5) & 0x1f) as u16; let Rt2 = ((word >> 10) & 0x1f) as u16; - let mut imm7 = (((((word >> 15) & 0x7f) as i16) << 9) >> 9); + let mut imm7 = ((((word >> 15) & 0x7f) as i16) << 9) >> 9; let opc_L = ((word >> 22) & 1) | ((word >> 29) & 0x6); let size = match opc_L { 0b000 => { @@ -1757,7 +1759,7 @@ impl Decodable for Instruction { // load/store register pair (post-indexed) // V == 1 let opc_L = ((word >> 22) & 1) | ((word >> 29) & 0x6); - panic!("C3.3.15 V==1"); + panic!("C3.3.15 V==1, opc_L: {}", opc_L); }, 0b10010 => { // load/store register pair (offset) @@ -1765,7 +1767,7 @@ impl Decodable for Instruction { let Rt = (word & 0x1f) as u16; let Rn = ((word >> 5) & 0x1f) as u16; let Rt2 = ((word >> 10) & 0x1f) as u16; - let mut imm7 = (((((word >> 15) & 0x7f) as i16) << 9) >> 9); + let mut imm7 = ((((word >> 15) & 0x7f) as i16) << 9) >> 9; let opc_L = ((word >> 22) & 1) | ((word >> 29) & 0x6); let size = match opc_L { 0b000 => { @@ -1815,7 +1817,7 @@ impl Decodable for Instruction { // load/store register pair (offset) // V == 1 let opc_L = ((word >> 22) & 1) | ((word >> 29) & 0x6); - panic!("C3.3.14 V==1"); + panic!("C3.3.14 V==1, opc_L: {}", opc_L); }, 0b10011 => { // load/store register pair (pre-indexed) @@ -1823,7 +1825,7 @@ impl Decodable for Instruction { let Rt = (word & 0x1f) as u16; let Rn = ((word >> 5) & 0x1f) as u16; let Rt2 = ((word >> 10) & 0x1f) as u16; - let mut imm7 = (((((word >> 15) & 0x7f) as i16) << 9) >> 9); + let mut imm7 = ((((word >> 15) & 0x7f) as i16) << 9) >> 9; let opc_L = ((word >> 22) & 1) | ((word >> 29) & 0x6); let size = match opc_L { 0b000 => { @@ -1873,7 +1875,7 @@ impl Decodable for Instruction { // load/store register pair (pre-indexed) // V == 1 let opc_L = ((word >> 22) & 1) | ((word >> 29) & 0x6); - panic!("C3.3.16 V==1"); + panic!("C3.3.16 V==1, opc_L: {}", opc_L); }, 0b11000 | 0b11001 => { -- cgit v1.1