riscv_etrace/binary/
error.rs1#[cfg(feature = "alloc")]
6use alloc::boxed::Box;
7use core::fmt;
8
9pub trait Miss: MaybeMiss {
11 fn miss(address: u64) -> Self;
16}
17
18impl<T, E: Miss> Miss for Result<T, E> {
19 fn miss(address: u64) -> Self {
20 Err(<E as Miss>::miss(address))
21 }
22}
23
24#[cfg(feature = "alloc")]
25impl Miss for Box<dyn MaybeMiss> {
26 fn miss(address: u64) -> Self {
27 Box::new(NoInstruction::miss(address))
28 }
29}
30
31#[cfg(feature = "alloc")]
32impl Miss for Box<dyn MaybeMissError> {
33 fn miss(address: u64) -> Self {
34 Box::new(NoInstruction::miss(address))
35 }
36}
37
38#[cfg(feature = "either")]
39impl<L: Miss, R: MaybeMiss> Miss for either::Either<L, R> {
40 fn miss(address: u64) -> Self {
41 either::Left(Miss::miss(address))
42 }
43}
44
45pub trait MaybeMiss {
53 fn is_miss(&self) -> bool;
59}
60
61impl<T, E: MaybeMiss> MaybeMiss for Result<T, E> {
62 fn is_miss(&self) -> bool {
63 match self {
64 Ok(_) => false,
65 Err(e) => e.is_miss(),
66 }
67 }
68}
69
70#[cfg(feature = "alloc")]
71impl<E: MaybeMiss + ?Sized> MaybeMiss for Box<E> {
72 fn is_miss(&self) -> bool {
73 E::is_miss(self.as_ref())
74 }
75}
76
77#[cfg(feature = "either")]
78impl<L: MaybeMiss, R: MaybeMiss> MaybeMiss for either::Either<L, R> {
79 fn is_miss(&self) -> bool {
80 either::for_both!(self, e => e.is_miss())
81 }
82}
83
84pub trait MaybeMissError: MaybeMiss + core::error::Error + Sync + Send {}
86
87impl<T: MaybeMiss + core::error::Error + Sync + Send + ?Sized> MaybeMissError for T {}
88
89#[derive(Copy, Clone, Debug, PartialEq, Eq)]
91pub enum SegmentError {
92 AddressNotCovered,
94 ExceededHostUSize(core::num::TryFromIntError),
96 InvalidInstruction,
98}
99
100impl Miss for SegmentError {
101 fn miss(_: u64) -> Self {
102 Self::AddressNotCovered
103 }
104}
105
106impl MaybeMiss for SegmentError {
107 fn is_miss(&self) -> bool {
108 matches!(self, Self::AddressNotCovered)
109 }
110}
111
112impl core::error::Error for SegmentError {
113 fn source(&self) -> Option<&(dyn core::error::Error + 'static)> {
114 match self {
115 Self::ExceededHostUSize(e) => Some(e),
116 _ => None,
117 }
118 }
119}
120
121impl fmt::Display for SegmentError {
122 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
123 match self {
124 Self::AddressNotCovered => write!(f, "Given address not covered"),
125 Self::ExceededHostUSize(_) => write!(
126 f,
127 "An offset exceeds what can be represented with host native addresses"
128 ),
129 Self::InvalidInstruction => write!(f, "No valid instruction at address"),
130 }
131 }
132}
133
134#[derive(Copy, Clone, Debug, PartialEq, Eq)]
136pub struct NoInstruction;
137
138impl Miss for NoInstruction {
139 fn miss(_: u64) -> Self {
140 NoInstruction
141 }
142}
143
144impl MaybeMiss for NoInstruction {
145 fn is_miss(&self) -> bool {
146 true
147 }
148}
149
150impl core::error::Error for NoInstruction {}
151
152impl fmt::Display for NoInstruction {
153 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
154 write!(f, "No Instruction availible")
155 }
156}