From 6f10ec12b4c81e4d040b933b1e3ee01da5ac9a0c Mon Sep 17 00:00:00 2001 From: iximeow Date: Sun, 13 Apr 2025 19:34:39 -0700 Subject: fuzz cases: only 64 system registers, display should never panic --- src/lib.rs | 47 +++++++++++++++++++++++++++++++---------------- 1 file changed, 31 insertions(+), 16 deletions(-) (limited to 'src/lib.rs') diff --git a/src/lib.rs b/src/lib.rs index 115d78e..6c89dec 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -112,7 +112,7 @@ impl Predicate { } } -#[derive(Debug, Copy, Clone, Default)] +#[derive(Debug, Copy, Clone, Default, PartialEq)] pub struct LoopEnd { loops_ended: u8 } @@ -163,6 +163,16 @@ pub struct InstructionPacket { loop_effect: LoopEnd, } +impl PartialEq for InstructionPacket { + fn eq(&self, other: &Self) -> bool { + let instructions = self.instruction_count as usize; + self.instruction_count == other.instruction_count && + self.word_count == other.word_count && + self.loop_effect == other.loop_effect && + self.instructions[..instructions] == other.instructions[..instructions] + } +} + /// a decoded `hexagon` instruction. this is only one of potentially several instructions in an /// [`InstructionPacket`]. /// @@ -1204,8 +1214,8 @@ trait DecodeHandler::Address, ::Wor fn read_inst_word(&mut self, words: &mut T) -> Result::DecodeError>; fn on_decode_start(&mut self) {} fn on_decode_end(&mut self) {} - fn start_instruction(&mut self); - fn end_instruction(&mut self); + fn start_instruction(&mut self) -> Result<(), ::DecodeError> { Ok(()) } + fn end_instruction(&mut self) -> Result<(), ::DecodeError> { Ok(()) } fn on_loop_end(&mut self, loop_num: u8); fn on_opcode_decoded(&mut self, _opcode: Opcode) -> Result<(), ::DecodeError> { Ok(()) } fn on_source_decoded(&mut self, _operand: Operand) -> Result<(), ::DecodeError> { Ok(()) } @@ -1368,9 +1378,13 @@ impl::Address, ::Word self.read_u32(words) } fn on_word_read(&mut self, _word: ::Word) { } - fn start_instruction(&mut self) { } - fn end_instruction(&mut self) { + fn start_instruction(&mut self) -> Result<(), ::DecodeError> { + opcode_check!(self.instruction_count < self.instructions.len() as u8); + Ok(()) + } + fn end_instruction(&mut self) -> Result<(), ::DecodeError> { self.instruction_count += 1; + Ok(()) } } @@ -1981,12 +1995,12 @@ fn decode_packet< parse_lo: fn(&mut H, u16, &mut Option) -> Result<(), ::DecodeError>, parse_hi: fn(&mut H, u16, &mut Option) -> Result<(), ::DecodeError>, ) -> Result<(), yaxpeax_arch::StandardDecodeError> { - self.handler.start_instruction(); + self.handler.start_instruction()?; parse_lo(self.handler, self.subinstr_low, self.extender)?; - self.handler.end_instruction(); - self.handler.start_instruction(); + self.handler.end_instruction()?; + self.handler.start_instruction()?; parse_hi(self.handler, self.subinstr_high, self.extender)?; - self.handler.end_instruction(); + self.handler.end_instruction()?; Ok(()) } } @@ -2080,7 +2094,7 @@ fn decode_packet< if iclass == 0b0000 { extender = Some((inst & 0x3fff) | ((inst >> 2) & 0x3ffc000)); } else { - handler.start_instruction(); + handler.start_instruction()?; decode_instruction(decoder, handler, inst, &mut extender)?; // V73 section 10.9: // > The constant extender serves as a prefix for an instruction: it does not execute @@ -2095,7 +2109,7 @@ fn decode_packet< // if the extender was not consumed, the instruction (packet) is invalid return Err(DecodeError::InvalidOpcode); } - handler.end_instruction(); + handler.end_instruction()?; } current_word += 1; @@ -3113,9 +3127,9 @@ fn decode_instruction< 0b0111000 => { // not in V73! store to supervisor register? let sssss = reg_b16(inst); - let ddddddd = inst & 0b111_1111; + let dddddd = inst & 0b11_1111; handler.on_opcode_decoded(Opcode::TransferRegister)?; - handler.on_dest_decoded(Operand::sr(ddddddd as u8))?; + handler.on_dest_decoded(Operand::sr(dddddd as u8))?; handler.on_source_decoded(Operand::gpr(sssss))?; } // TODO: 1001000 loop0 goes here @@ -3152,9 +3166,9 @@ fn decode_instruction< 0b1110110 | 0b1110111 => { // not in V73! load supervisor register? let sssss = reg_b0(inst); - let ddddddd = (inst >> 16) & 0b111_1111; + let dddddd = (inst >> 16) & 0b11_1111; handler.on_opcode_decoded(Opcode::TransferRegister)?; - handler.on_source_decoded(Operand::sr(ddddddd as u8))?; + handler.on_source_decoded(Operand::sr(dddddd as u8))?; handler.on_dest_decoded(Operand::gpr(sssss))?; } 0b1111000 | 0b1111001 | @@ -3763,7 +3777,8 @@ fn decode_instruction< handler.on_opcode_decoded(Opcode::Nop)?; } _ => { - unreachable!("impossible pattern"); + // anything left unhandled is invalid.. + opcode_check!(false); } } } -- cgit v1.1