aboutsummaryrefslogtreecommitdiff
path: root/src/armv7.rs
diff options
context:
space:
mode:
authoriximeow <me@iximeow.net>2021-09-28 19:48:39 -0700
committeriximeow <me@iximeow.net>2021-09-28 19:48:39 -0700
commitce99ad8e8e5260f3a8bac896e14faf54f0df6c58 (patch)
tree8daf5ccfd77d27ffaafa915a1e1f6608ce80a105 /src/armv7.rs
parent23bd0b37482a127c8f954ce7e068a507b9c1e09e (diff)
fix various armv8 and armv8 panics that should be Err.
in fact the decoder should _never_ panic. included here are tests that cover the entire 32-bit instruction space and ensure that decoding and display do not panic. these tests run uncomfortably slowly (1168s to decode the 4b "instruction" sequences on my desktop), but verify that panics are no longer an issue.
Diffstat (limited to 'src/armv7.rs')
-rw-r--r--src/armv7.rs31
1 files changed, 20 insertions, 11 deletions
diff --git a/src/armv7.rs b/src/armv7.rs
index 5894bc4..e858566 100644
--- a/src/armv7.rs
+++ b/src/armv7.rs
@@ -1367,11 +1367,12 @@ pub enum StatusRegMask {
}
impl StatusRegMask {
- fn from_raw(raw: u8) -> StatusRegMask {
+ fn from_raw(raw: u8) -> Result<StatusRegMask, DecodeError> {
if raw == 0 {
- panic!("invalid status reg mask value");
+ // invalid status reg mask value
+ return Err(DecodeError::InvalidOperand);
}
- [
+ Ok([
StatusRegMask::CPSR_C, // actually unreachable
StatusRegMask::CPSR_C,
StatusRegMask::CPSR_X,
@@ -1404,7 +1405,7 @@ impl StatusRegMask {
StatusRegMask::SPSR_FSC,
StatusRegMask::SPSR_FSX,
StatusRegMask::SPSR_FSXC,
- ][raw as usize]
+ ][raw as usize])
}
}
@@ -2925,7 +2926,11 @@ impl Decoder<ARMv7> for InstDecoder {
}
}
inst.opcode = Opcode::MSR;
- inst.operands[0] = Reg::from_sysm(R != 0, SYSm).expect("from_sysm works");
+ inst.operands[0] = if let Some(reg) = Reg::from_sysm(R != 0, SYSm) {
+ reg
+ } else {
+ return Err(DecodeError::InvalidOperand);
+ };
inst.operands[1] = Operand::Reg(Reg::from_u8(word as u8 & 0b1111));
inst.operands[2] = Operand::Nothing;
inst.operands[3] = Operand::Nothing;
@@ -2937,7 +2942,11 @@ impl Decoder<ARMv7> for InstDecoder {
}
inst.opcode = Opcode::MRS;
inst.operands[0] = Operand::Reg(Reg::from_u8((word >> 12) as u8 & 0b1111));
- inst.operands[1] = Reg::from_sysm(R != 0, SYSm).expect("from_sysm works");
+ inst.operands[1] = if let Some(reg) = Reg::from_sysm(R != 0, SYSm) {
+ reg
+ } else {
+ return Err(DecodeError::InvalidOperand);
+ };
inst.operands[2] = Operand::Nothing;
inst.operands[3] = Operand::Nothing;
}
@@ -2966,7 +2975,7 @@ impl Decoder<ARMv7> for InstDecoder {
let mask = (word >> 16) & 0b1111;
if mask & 0b11 == 0 {
if self.mode.is_user() {
- inst.operands[0] = Operand::StatusRegMask(StatusRegMask::from_raw(mask as u8));
+ inst.operands[0] = Operand::StatusRegMask(StatusRegMask::from_raw(mask as u8)?);
inst.operands[1] = Operand::Reg(Reg::from_u8(word as u8 & 0b1111));
inst.operands[2] = Operand::Nothing;
inst.operands[3] = Operand::Nothing;
@@ -2979,7 +2988,7 @@ impl Decoder<ARMv7> for InstDecoder {
if self.mode.is_system() {
// bit 22 is the high bit of opcode, so..
let R = (word >> 22) as u8 & 1;
- inst.operands[0] = Operand::StatusRegMask(StatusRegMask::from_raw((R << 4) | mask as u8));
+ inst.operands[0] = Operand::StatusRegMask(StatusRegMask::from_raw((R << 4) | mask as u8)?);
inst.operands[1] = Operand::Reg(Reg::from_u8(word as u8 & 0b1111));
inst.operands[2] = Operand::Nothing;
inst.operands[3] = Operand::Nothing;
@@ -2998,7 +3007,7 @@ impl Decoder<ARMv7> for InstDecoder {
let mask = (word >> 16) & 0b1111;
// bit 22 is the high bit of opcode, so..
let R = (word >> 22) & 1;
- inst.operands[0] = Operand::StatusRegMask(StatusRegMask::from_raw((R << 4) as u8 | mask as u8));
+ inst.operands[0] = Operand::StatusRegMask(StatusRegMask::from_raw((R << 4) as u8 | mask as u8)?);
inst.operands[1] = Operand::Reg(Reg::from_u8(word as u8 & 0b1111));
inst.operands[2] = Operand::Nothing;
inst.operands[3] = Operand::Nothing;
@@ -3397,7 +3406,7 @@ impl Decoder<ARMv7> for InstDecoder {
}
}
inst.operands = [
- Operand::StatusRegMask(StatusRegMask::from_raw(op1 as u8)),
+ Operand::StatusRegMask(StatusRegMask::from_raw(op1 as u8)?),
Operand::Imm32(word & 0xfff),
Operand::Nothing,
Operand::Nothing,
@@ -3414,7 +3423,7 @@ impl Decoder<ARMv7> for InstDecoder {
}
}
inst.operands = [
- Operand::StatusRegMask(StatusRegMask::from_raw((word >> 16) as u8 & 0b1111 | 0b10000)),
+ Operand::StatusRegMask(StatusRegMask::from_raw((word >> 16) as u8 & 0b1111 | 0b10000)?),
Operand::Imm32(word & 0xfff),
Operand::Nothing,
Operand::Nothing,