1use std::error::Error as StdError;
2use std::fmt;
3
4pub(crate) type Result<T> = std::result::Result<T, Error>;
5
6pub trait AsDynError<'a> {
8 fn as_dyn_error(&self) -> &(dyn StdError + 'a);
9}
10
11impl<'a, T: StdError + 'a> AsDynError<'a> for T {
12 #[inline]
13 fn as_dyn_error(&self) -> &(dyn StdError + 'a) {
14 self
15 }
16}
17
18#[derive(Debug)]
20#[non_exhaustive]
21pub enum Error {
22 ReadInput(std::io::Error),
26 ParseFileKind(object::Error),
31 ParseObjectFile(object::Error),
33 ParseArchiveFile(object::Error),
35 ParseArchiveMember(object::Error),
37 InvalidInputKind,
41 DecompressData(object::Error),
46 NamelessSection(object::Error, usize),
48 RelocationWithInvalidSymbol(String, usize),
50 MultipleRelocations(String, usize),
52 UnsupportedRelocation(String, usize),
54 MissingDwoName(u64),
57 NoCompilationUnits,
59 NoDie,
61 TopLevelDieNotUnit,
63 MissingRequiredSection(&'static str),
65 ParseUnitAbbreviations(gimli::read::Error),
67 ParseUnitHeader(gimli::read::Error),
69 ParseUnit(gimli::read::Error),
71 IncompatibleIndexVersion(String, u16, u16),
73 OffsetAtIndex(gimli::read::Error, u64),
75 StrAtOffset(gimli::read::Error, usize),
77 ParseIndex(gimli::read::Error, String),
82 UnitNotInIndex(u64),
84 RowNotInIndex(gimli::read::Error, u32),
86 SectionNotInRow,
89 EmptyUnit(u64),
91 MultipleDebugInfoSection,
93 MultipleDebugTypesSection,
95 NotSplitUnit,
97 DuplicateUnit(u64),
99 MissingReferencedUnit(u64),
101 NoOutputObjectCreated,
103 MixedInputEncodings,
105
106 Io(std::io::Error),
108 ObjectRead(object::Error),
110 ObjectWrite(object::write::Error),
112 GimliRead(gimli::read::Error),
114 GimliWrite(gimli::write::Error),
116}
117
118impl StdError for Error {
119 fn source(&self) -> Option<&(dyn StdError + 'static)> {
120 match self {
121 Error::ReadInput(source) => Some(source.as_dyn_error()),
122 Error::ParseFileKind(source) => Some(source.as_dyn_error()),
123 Error::ParseObjectFile(source) => Some(source.as_dyn_error()),
124 Error::ParseArchiveFile(source) => Some(source.as_dyn_error()),
125 Error::ParseArchiveMember(source) => Some(source.as_dyn_error()),
126 Error::InvalidInputKind => None,
127 Error::DecompressData(source) => Some(source.as_dyn_error()),
128 Error::NamelessSection(source, _) => Some(source.as_dyn_error()),
129 Error::RelocationWithInvalidSymbol(_, _) => None,
130 Error::MultipleRelocations(_, _) => None,
131 Error::UnsupportedRelocation(_, _) => None,
132 Error::MissingDwoName(_) => None,
133 Error::NoCompilationUnits => None,
134 Error::NoDie => None,
135 Error::TopLevelDieNotUnit => None,
136 Error::MissingRequiredSection(_) => None,
137 Error::ParseUnitAbbreviations(source) => Some(source.as_dyn_error()),
138 Error::ParseUnitHeader(source) => Some(source.as_dyn_error()),
139 Error::ParseUnit(source) => Some(source.as_dyn_error()),
140 Error::IncompatibleIndexVersion(_, _, _) => None,
141 Error::OffsetAtIndex(source, _) => Some(source.as_dyn_error()),
142 Error::StrAtOffset(source, _) => Some(source.as_dyn_error()),
143 Error::ParseIndex(source, _) => Some(source.as_dyn_error()),
144 Error::UnitNotInIndex(_) => None,
145 Error::RowNotInIndex(source, _) => Some(source.as_dyn_error()),
146 Error::SectionNotInRow => None,
147 Error::EmptyUnit(_) => None,
148 Error::MultipleDebugInfoSection => None,
149 Error::MultipleDebugTypesSection => None,
150 Error::NotSplitUnit => None,
151 Error::DuplicateUnit(_) => None,
152 Error::MissingReferencedUnit(_) => None,
153 Error::NoOutputObjectCreated => None,
154 Error::MixedInputEncodings => None,
155 Error::Io(transparent) => StdError::source(transparent.as_dyn_error()),
156 Error::ObjectRead(transparent) => StdError::source(transparent.as_dyn_error()),
157 Error::ObjectWrite(transparent) => StdError::source(transparent.as_dyn_error()),
158 Error::GimliRead(transparent) => StdError::source(transparent.as_dyn_error()),
159 Error::GimliWrite(transparent) => StdError::source(transparent.as_dyn_error()),
160 }
161 }
162}
163
164impl fmt::Display for Error {
165 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
166 match self {
167 Error::ReadInput(_) => write!(f, "Failed to read input file"),
168 Error::ParseFileKind(_) => write!(f, "Failed to parse input file kind"),
169 Error::ParseObjectFile(_) => write!(f, "Failed to parse input object file"),
170 Error::ParseArchiveFile(_) => write!(f, "Failed to parse input archive file"),
171 Error::ParseArchiveMember(_) => write!(f, "Failed to parse archive member"),
172 Error::InvalidInputKind => write!(f, "Input is not an archive or elf object"),
173 Error::DecompressData(_) => write!(f, "Failed to decompress compressed section"),
174 Error::NamelessSection(_, offset) => {
175 write!(f, "Section without name at offset 0x{:08x}", offset)
176 }
177 Error::RelocationWithInvalidSymbol(section, offset) => write!(
178 f,
179 "Relocation with invalid symbol for section `{}` at offset 0x{:08x}",
180 section, offset
181 ),
182 Error::MultipleRelocations(section, offset) => write!(
183 f,
184 "Multiple relocations for section `{}` at offset 0x{:08x}",
185 section, offset
186 ),
187 Error::UnsupportedRelocation(section, offset) => write!(
188 f,
189 "Unsupported relocation for section {} at offset 0x{:08x}",
190 section, offset
191 ),
192 Error::MissingDwoName(id) => {
193 write!(f, "Missing path attribute to DWARF object (0x{:08x})", id)
194 }
195 Error::NoCompilationUnits => {
196 write!(f, "Input object has no compilation units")
197 }
198 Error::NoDie => {
199 write!(f, "No top-level debugging information entry in compilation/type unit")
200 }
201 Error::TopLevelDieNotUnit => {
202 write!(f, "Top-level debugging information entry is not a compilation/type unit")
203 }
204 Error::MissingRequiredSection(section) => {
205 write!(f, "Input object missing required section `{}`", section)
206 }
207 Error::ParseUnitAbbreviations(_) => write!(f, "Failed to parse unit abbreviations"),
208 Error::ParseUnitHeader(_) => write!(f, "Failed to parse unit header"),
209 Error::ParseUnit(_) => write!(f, "Failed to parse unit"),
210 Error::IncompatibleIndexVersion(section, format, actual) => {
211 write!(
212 f,
213 "Incompatible `{}` index version: found version {}, expected version {}",
214 section, actual, format
215 )
216 }
217 Error::OffsetAtIndex(_, index) => {
218 write!(f, "Read offset at index {} of `.debug_str_offsets.dwo` section", index)
219 }
220 Error::StrAtOffset(_, offset) => {
221 write!(f, "Read string at offset 0x{:08x} of `.debug_str.dwo` section", offset)
222 }
223 Error::ParseIndex(_, section) => {
224 write!(f, "Failed to parse `{}` index section", section)
225 }
226 Error::UnitNotInIndex(unit) => {
227 write!(f, "Unit 0x{0:08x} from input package is not in its index", unit)
228 }
229 Error::RowNotInIndex(_, row) => {
230 write!(f, "Row {0} found in index's hash table not present in index", row)
231 }
232 Error::SectionNotInRow => write!(f, "Section not found in unit's row in index"),
233 Error::EmptyUnit(unit) => {
234 write!(f, "Unit 0x{:08x} in input DWARF object with no data", unit)
235 }
236 Error::MultipleDebugInfoSection => {
237 write!(f, "Multiple `.debug_info.dwo` sections")
238 }
239 Error::MultipleDebugTypesSection => {
240 write!(f, "Multiple `.debug_types.dwo` sections in a package")
241 }
242 Error::NotSplitUnit => {
243 write!(f, "Regular compilation unit in object (missing dwo identifier)")
244 }
245 Error::DuplicateUnit(unit) => {
246 write!(f, "Duplicate split compilation unit (0x{:08x})", unit)
247 }
248 Error::MissingReferencedUnit(unit) => {
249 write!(f, "Unit 0x{:08x} referenced by executable was not found", unit)
250 }
251 Error::NoOutputObjectCreated => write!(f, "No output object was created from inputs"),
252 Error::MixedInputEncodings => write!(f, "Input objects haved mixed encodings"),
253 Error::Io(e) => fmt::Display::fmt(e, f),
254 Error::ObjectRead(e) => fmt::Display::fmt(e, f),
255 Error::ObjectWrite(e) => fmt::Display::fmt(e, f),
256 Error::GimliRead(e) => fmt::Display::fmt(e, f),
257 Error::GimliWrite(e) => fmt::Display::fmt(e, f),
258 }
259 }
260}
261
262impl From<std::io::Error> for Error {
263 fn from(source: std::io::Error) -> Self {
264 Error::Io(source)
265 }
266}
267
268impl From<object::Error> for Error {
269 fn from(source: object::Error) -> Self {
270 Error::ObjectRead(source)
271 }
272}
273
274impl From<object::write::Error> for Error {
275 fn from(source: object::write::Error) -> Self {
276 Error::ObjectWrite(source)
277 }
278}
279
280impl From<gimli::read::Error> for Error {
281 fn from(source: gimli::read::Error) -> Self {
282 Error::GimliRead(source)
283 }
284}
285
286impl From<gimli::write::Error> for Error {
287 fn from(source: gimli::write::Error) -> Self {
288 Error::GimliWrite(source)
289 }
290}