monster/engine/
bug.rs

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}