symtool_backend/
error.rs

1//! Errors returned by this crate.
2
3pub type Result<T> = std::result::Result<T, Error>;
4pub type TransformResult<T, E> = std::result::Result<T, TransformError<E>>;
5
6/// An error
7#[derive(Debug)]
8pub enum Error {
9    /// An I/O error
10    Io(std::io::Error),
11
12    /// An error from goblin, the binary parser
13    Goblin(goblin::error::Error),
14
15    /// An error from scroll, used by the binary parser
16    Scroll(scroll::Error),
17
18    /// The loaded object is malformed
19    Malformed(String),
20
21    /// Replacing a string failed
22    ReplaceString {
23        original: String,
24        replacement: String,
25    },
26
27    /// The loaded object could not be recognized
28    UnknownObject,
29
30    /// Returned when loading a macOS fat binary
31    FatBinaryUnsupported,
32
33    /// The ELF section header did not match a symbol table
34    WrongSectionHeader(String),
35
36    /// A patch was too big to insert into the binary
37    PatchTooBig,
38}
39
40impl std::fmt::Display for Error {
41    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
42        match self {
43            Self::Io(e) => write!(f, "{}", e),
44            Self::Goblin(e) => write!(f, "{}", e),
45            Self::Scroll(e) => write!(f, "{}", e),
46            Self::Malformed(s) => write!(f, "{}", s),
47            Self::ReplaceString {
48                original,
49                replacement,
50            } => {
51                write!(
52                f,
53                "Replacement string (\"{}\") must be the same size or smaller than the original (\"{}\")", replacement, original)
54            }
55            Self::UnknownObject => write!(f, "Unknown object type"),
56            Self::FatBinaryUnsupported => write!(f, "Fat MachO binaries are not yet supported"),
57            Self::WrongSectionHeader(s) => write!(f, "{}", s),
58            Self::PatchTooBig => write!(f, "Patched data too big for original location"),
59        }
60    }
61}
62
63impl std::error::Error for Error {
64    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
65        match self {
66            Self::Io(e) => Some(e),
67            Self::Goblin(e) => Some(e),
68            Self::Scroll(e) => Some(e),
69            _ => None,
70        }
71    }
72}
73
74impl From<goblin::error::Error> for Error {
75    fn from(err: goblin::error::Error) -> Self {
76        Self::Goblin(err)
77    }
78}
79
80impl From<std::io::Error> for Error {
81    fn from(err: std::io::Error) -> Self {
82        Self::Io(err)
83    }
84}
85
86impl From<scroll::Error> for Error {
87    fn from(err: scroll::Error) -> Self {
88        Self::Scroll(err)
89    }
90}
91
92/// An error returned by the object transformer
93#[derive(Debug)]
94pub enum TransformError<T>
95where
96    T: std::error::Error,
97{
98    /// An error produced by symtool
99    SymTool(Error),
100
101    /// An error produced by the transformer
102    Transform(T),
103}
104
105impl<T> std::fmt::Display for TransformError<T>
106where
107    T: std::error::Error,
108{
109    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
110        match self {
111            Self::SymTool(e) => write!(f, "{}", e),
112            Self::Transform(e) => write!(f, "{}", e),
113        }
114    }
115}
116
117impl<T> std::error::Error for TransformError<T>
118where
119    T: std::error::Error + 'static,
120{
121    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
122        match self {
123            Self::SymTool(e) => Some(e),
124            Self::Transform(e) => e.source(),
125        }
126    }
127}
128
129impl<T> From<Error> for TransformError<T>
130where
131    T: std::error::Error,
132{
133    fn from(err: Error) -> Self {
134        Self::SymTool(err)
135    }
136}
137
138impl<T> From<goblin::error::Error> for TransformError<T>
139where
140    T: std::error::Error,
141{
142    fn from(err: goblin::error::Error) -> Self {
143        Self::SymTool(Error::Goblin(err))
144    }
145}
146
147impl<T> From<std::io::Error> for TransformError<T>
148where
149    T: std::error::Error,
150{
151    fn from(err: std::io::Error) -> Self {
152        Self::SymTool(Error::Io(err))
153    }
154}
155
156impl<T> From<scroll::Error> for TransformError<T>
157where
158    T: std::error::Error,
159{
160    fn from(err: scroll::Error) -> Self {
161        Self::SymTool(Error::Scroll(err))
162    }
163}