1use super::system::instruction_to_str;
2use riscu::Instruction;
3use std::fmt;
4
5pub trait BugInfo: fmt::Display + fmt::Debug + Clone {
6 type Value: fmt::Display + fmt::Debug + Clone;
7}
8
9#[derive(Debug, Clone)]
10pub enum Bug<Info: BugInfo> {
11 DivisionByZero {
12 info: Info,
13 },
14
15 AccessToUnitializedMemory {
16 info: Info,
17 reason: UninitializedMemoryAccessReason<Info>,
18 },
19
20 AccessToUnalignedAddress {
21 info: Info,
22 address: u64,
23 },
24
25 AccessToOutOfRangeAddress {
26 info: Info,
27 },
28
29 ExitCodeGreaterZero {
30 info: Info,
31 exit_code: Info::Value,
32 address: u64,
33 },
34}
35
36impl<Info> fmt::Display for Bug<Info>
37where
38 Info: BugInfo,
39{
40 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
41 match self {
42 Bug::DivisionByZero { info } => write!(f, "reason: division by zero\n{}", info),
43 Bug::AccessToUnitializedMemory { info, reason } => write!(
44 f,
45 "reason: access to uninitialized memory\n{}\n{}",
46 info, reason,
47 ),
48 Bug::AccessToUnalignedAddress { info, address } => write!(
49 f,
50 "reason: access to unaligned memory address {:#x}\n{}",
51 address, info
52 ),
53 Bug::AccessToOutOfRangeAddress { info } => write!(
54 f,
55 "reason: accessed a memory address out of virtual address space\n{}",
56 info,
57 ),
58 Bug::ExitCodeGreaterZero {
59 info,
60 exit_code,
61 address,
62 } => write!(
63 f,
64 "reason: exit code ({}) greater than zero at pc={:#x}\n{}",
65 exit_code, address, info
66 ),
67 }
68 }
69}
70
71#[derive(Debug, Clone)]
72pub enum UninitializedMemoryAccessReason<Info: BugInfo> {
73 ReadUnintializedMemoryAddress {
74 description: String,
75 address: u64,
76 },
77 InstructionWithUninitializedOperand {
78 instruction: Instruction,
79 operands: Vec<Info::Value>,
80 },
81}
82
83impl<Info> fmt::Display for UninitializedMemoryAccessReason<Info>
84where
85 Info: BugInfo,
86{
87 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
88 match self {
89 UninitializedMemoryAccessReason::InstructionWithUninitializedOperand {
90 instruction,
91 operands,
92 } => write!(
93 f,
94 "instruction: {} operands: {:?}",
95 instruction_to_str(*instruction),
96 operands
97 ),
98 UninitializedMemoryAccessReason::ReadUnintializedMemoryAddress {
99 description,
100 address,
101 } => write!(f, "{} (pc: {:#x})", description, address),
102 }
103 }
104}