summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLofty <dan.ravensloft@gmail.com>2021-08-12 16:01:48 +0100
committeriximeow <me@iximeow.net>2021-08-22 15:24:18 -0700
commit9578910d7ee5d149ec9a9c46d86f484dc9868bf1 (patch)
tree294da350fa8740b72b5d52f9a6dbe1522b8a1c39
parent6322b555e8e5bc9212dd501f09902b3840a20554 (diff)
B8 instructions cannot be predicated
-rw-r--r--src/lib.rs16
-rw-r--r--tests/test.rs60
2 files changed, 74 insertions, 2 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 79a5184..4ae7146 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1323,6 +1323,22 @@ impl yaxpeax_arch::Instruction for InstructionBundle {
insn.predicate() == 0
};
+ for insn in &self.instructions {
+ match insn.opcode {
+ // B8 family instructions cannot be predicated
+ Opcode::Cover | Opcode::Clrrb | Opcode::Clrrb_pr | Opcode::Rfi | Opcode::Bsw_0 | Opcode::Bsw_1 | Opcode::Epc => {
+ if insn.predicate() != 0 {
+ return false;
+ }
+ },
+ // Undefined opcode regions
+ Opcode::Purple | Opcode::Cyan | Opcode::Brown | Opcode::White => {
+ return false;
+ },
+ _ => {},
+ }
+ }
+
if self.instructions[0].opcode() == Opcode::Alloc && !validate_alloc(&self.instructions[0]) {
return false;
}
diff --git a/tests/test.rs b/tests/test.rs
index 3734e20..38b8060 100644
--- a/tests/test.rs
+++ b/tests/test.rs
@@ -1,5 +1,5 @@
use yaxpeax_ia64::InstDecoder;
-use yaxpeax_arch::{Decoder, U8Reader};
+use yaxpeax_arch::{Decoder, Instruction, U8Reader};
// from elf64-ia64-vms.c
// 0x0b, 0x78, 0x00, 0x02, 0x00, 0x24, 0x00, 0x41, 0x3c, 0x70, 0x27, 0xc0, 0x01, 0x08, 0x00, 0x84
@@ -33,12 +33,14 @@ fn test_invalid_instruction() {
let mut reader = U8Reader::new(&data[..]);
let inst = decoder.decode(&mut reader).unwrap();
assert_eq!(format!("{}", inst), expected);
+ assert!(!inst.well_defined());
let expected = "[MII] purple.nt3; break.i 0x0; break.i 0x0";
let data = [0x00, 0x00, 0x00, 0x00, 0x0E, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00];
let mut reader = U8Reader::new(&data[..]);
let inst = decoder.decode(&mut reader).unwrap();
assert_eq!(format!("{}", inst), expected);
+ assert!(!inst.well_defined());
}
#[test]
fn test_ad_hoc() {
@@ -2336,7 +2338,6 @@ fn test_indirection() {
// alloc has special restrictions that need to be checked.
#[test]
fn test_alloc_restrictions() {
- use yaxpeax_arch::Instruction;
let decoder = InstDecoder::default();
// size of frame cannot be greater than 96.
@@ -2387,3 +2388,58 @@ fn test_alloc_restrictions() {
assert_eq!(format!("{}", inst), expected);
assert!(inst.well_defined());
}
+
+#[test]
+fn test_predication_not_allowed() {
+ let decoder = InstDecoder::default();
+
+ // B8 instructions cannot be predicated
+ let expected = "[BBB] (p01) cover; break.b 0x0; break.b 0x0";
+ let data = [0x36, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00];
+ let mut reader = U8Reader::new(&data[..]);
+ let inst = decoder.decode(&mut reader).unwrap();
+ assert_eq!(format!("{}", inst), expected);
+ assert!(!inst.well_defined());
+
+ let expected = "[BBB] (p01) clrrb; break.b 0x0; break.b 0x0";
+ let data = [0x36, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00];
+ let mut reader = U8Reader::new(&data[..]);
+ let inst = decoder.decode(&mut reader).unwrap();
+ assert_eq!(format!("{}", inst), expected);
+ assert!(!inst.well_defined());
+
+ let expected = "[BBB] (p01) clrrb.pr; break.b 0x0; break.b 0x0";
+ let data = [0x36, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00];
+ let mut reader = U8Reader::new(&data[..]);
+ let inst = decoder.decode(&mut reader).unwrap();
+ assert_eq!(format!("{}", inst), expected);
+ assert!(!inst.well_defined());
+
+ let expected = "[BBB] (p01) rfi; break.b 0x0; break.b 0x0";
+ let data = [0x36, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00];
+ let mut reader = U8Reader::new(&data[..]);
+ let inst = decoder.decode(&mut reader).unwrap();
+ assert_eq!(format!("{}", inst), expected);
+ assert!(!inst.well_defined());
+
+ let expected = "[BBB] (p01) bsw.0; break.b 0x0; break.b 0x0";
+ let data = [0x36, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00];
+ let mut reader = U8Reader::new(&data[..]);
+ let inst = decoder.decode(&mut reader).unwrap();
+ assert_eq!(format!("{}", inst), expected);
+ assert!(!inst.well_defined());
+
+ let expected = "[BBB] (p01) bsw.1; break.b 0x0; break.b 0x0";
+ let data = [0x36, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00];
+ let mut reader = U8Reader::new(&data[..]);
+ let inst = decoder.decode(&mut reader).unwrap();
+ assert_eq!(format!("{}", inst), expected);
+ assert!(!inst.well_defined());
+
+ let expected = "[BBB] (p01) epc; break.b 0x0; break.b 0x0";
+ let data = [0x36, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00];
+ let mut reader = U8Reader::new(&data[..]);
+ let inst = decoder.decode(&mut reader).unwrap();
+ assert_eq!(format!("{}", inst), expected);
+ assert!(!inst.well_defined());
+}