Skip to content

Commit 5f54f22

Browse files
committed
avoid using thiserror dependency to thorin
`thiserror` is great, but this reduces the number of new dependencies added to rustc's whitelist. Signed-off-by: David Wood <[email protected]>
1 parent 7fc0afd commit 5f54f22

File tree

3 files changed

+234
-62
lines changed

3 files changed

+234
-62
lines changed

Cargo.lock

Lines changed: 0 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

thorin/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,4 @@ edition = "2021"
1111
gimli = "0.26.1"
1212
indexmap = "1.7.0"
1313
object = { version = "0.27.1", features = [ "archive", "read", "write", "compression" ] }
14-
thiserror = "1.0.30"
1514
tracing = "0.1.29"

thorin/src/error.rs

Lines changed: 234 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,79 +1,253 @@
1-
use thiserror::Error;
1+
use std::error::Error as StdError;
2+
use std::fmt;
23

34
pub(crate) type Result<T> = std::result::Result<T, Error>;
45

6+
pub trait AsDynError<'a> {
7+
fn as_dyn_error(&self) -> &(dyn StdError + 'a);
8+
}
9+
10+
impl<'a, T: StdError + 'a> AsDynError<'a> for T {
11+
#[inline]
12+
fn as_dyn_error(&self) -> &(dyn StdError + 'a) {
13+
self
14+
}
15+
}
16+
517
/// Diagnostics (and contexts) emitted during DWARF packaging.
6-
#[derive(Debug, Error)]
18+
#[derive(Debug)]
719
pub enum Error {
8-
#[error("Failed to read input file")]
9-
ReadInput(#[source] std::io::Error),
10-
#[error("Failed to parse kind of input file")]
11-
ParseFileKind(#[source] object::Error),
12-
#[error("Failed to parse object file")]
13-
ParseObjectFile(#[source] object::Error),
14-
#[error("Failed to parse archive file")]
15-
ParseArchiveFile(#[source] object::Error),
16-
#[error("Failed to parse archive member")]
17-
ParseArchiveMember(#[source] object::Error),
18-
#[error("Input is not an archive or elf file")]
20+
/// Failure to read input file, this error occurs in the `Session::read_input` function
21+
/// provided by the user of `thorin`.
22+
ReadInput(std::io::Error),
23+
/// Failed to parse kind of input file. Input file kind is necessary to determine how to parse
24+
/// the rest of the input, and to validate that the input file is of a type that `thorin` can
25+
/// process.
26+
ParseFileKind(object::Error),
27+
/// Failed to parse object file.
28+
ParseObjectFile(object::Error),
29+
/// Failed to parse archive file.
30+
ParseArchiveFile(object::Error),
31+
/// Failed to parse archive member.
32+
ParseArchiveMember(object::Error),
33+
/// Invalid kind of input. Only archive and elf files are supported input files.
1934
InvalidInputKind,
20-
#[error("Failed to decompress data")]
21-
DecompressData(#[source] object::Error),
22-
#[error("Section without name at offset 0x{1:08x}")]
23-
NamelessSection(#[source] object::Error, usize),
24-
#[error("Relocation with invalid symbol for section `{0}` at offset 0x{1:08x}")]
35+
/// Failed to decompress data. `thorin` uses `object` for decompression, so `object` probably
36+
/// didn't have support for the type of compression used.
37+
DecompressData(object::Error),
38+
/// Section without a name.
39+
NamelessSection(object::Error, usize),
40+
/// Relocation has invalid symbol for a section.
2541
RelocationWithInvalidSymbol(String, usize),
26-
#[error("Multiple relocations for section `{0}` at offset 0x{1:08x}")]
42+
/// Multiple relocations for a section.
2743
MultipleRelocations(String, usize),
28-
#[error("Unsupported relocation for section {0} at offset 0x{1:08x}")]
44+
/// Unsupport relocations for a section.
2945
UnsupportedRelocation(String, usize),
30-
#[error("Failed loading executable `{0}`")]
31-
LoadingExecutable(String),
32-
#[error("Missing path attribute to DWARF object 0x{0:08x}")]
46+
/// Input object that has a `DwoId` (or `DebugTypeSignature`) does not have a
47+
/// `DW_AT_GNU_dwo_name` or `DW_AT_dwo_name` attribute.
3348
MissingDwoName(u64),
34-
#[error("Input DWARF object missing required section `{0}`")]
49+
/// Section required of input DWARF objects was missing.
3550
MissingRequiredSection(&'static str),
36-
#[error("Failed to parse unit header")]
37-
ParseUnitHeader(#[source] gimli::read::Error),
38-
#[error("Failed to parse unit")]
39-
ParseUnit(#[source] gimli::read::Error),
40-
#[error("Failed to concatenate `{1}` section from input DWARF object")]
41-
AppendSection(#[source] object::Error, &'static str),
42-
#[error("Failed to read header of `.debug_str_offsets.dwo` section")]
51+
/// Failed to parse unit header.
52+
ParseUnitHeader(gimli::read::Error),
53+
/// Failed to parse unit.
54+
ParseUnit(gimli::read::Error),
55+
/// Failed to add a section to the output object.
56+
AppendSection(object::Error, &'static str),
57+
/// Input file is DWARF 5 format but the `.debug_str_offsets.dwo` section doesn't have a
58+
/// header.
4359
StrOffsetsMissingHeader,
44-
#[error("Failed to read offset at index {1} of `.debug_str_offsets.dwo` section")]
45-
OffsetAtIndex(#[source] gimli::read::Error, u64),
46-
#[error("Failed to read string at offset {1:08x} of `.debug_str.dwo` section")]
47-
StrAtOffset(#[source] gimli::read::Error, usize),
48-
#[error("Failed to write string to in-progress `.debug_str.dwo` section")]
49-
WritingStrToStringTable(#[source] gimli::write::Error),
50-
#[error("Failed to parse index section")]
51-
ParseIndex(#[source] gimli::read::Error),
52-
#[error("Unit 0x{0:08x} from input DWARF package is not in its index")]
60+
/// Failed to read string offset from `.debug_str_offsets` at index.
61+
OffsetAtIndex(gimli::read::Error, u64),
62+
/// Failed to read string from `.debug_str` at offset.
63+
StrAtOffset(gimli::read::Error, usize),
64+
/// Failed to write string to string table.
65+
WritingStrToStringTable(gimli::write::Error),
66+
/// Failed to parse index section. If an input file is a DWARF package, its index section needs
67+
/// to be read to ensure that the contributions within it are preserved.
68+
ParseIndex(gimli::read::Error),
69+
/// Compilation unit in DWARF package is not its index.
5370
UnitNotInIndex(u64),
54-
#[error("Row {0} found in index's hash table not present in index")]
55-
RowNotInIndex(#[source] gimli::read::Error, u32),
56-
#[error("Section not found in unit's row in index")]
71+
/// Row for a compilation unit is not in the index.
72+
RowNotInIndex(gimli::read::Error, u32),
73+
/// Section not found in unit's row in index, i.e. a DWARF package contains a section but its
74+
/// index doesn't record contributions to it.
5775
SectionNotInRow,
58-
#[error("Unit `{0}` in input DWARF object with no data")]
76+
/// Compilation unit in input DWARF object has no content.
5977
EmptyUnit(u64),
60-
#[error("Failed to write `.debug_cu_index` of output DWARF package")]
61-
WriteCuIndex(#[source] gimli::write::Error),
62-
#[error("Failed to write `.debug_tu_index` of output DWARF package")]
63-
WriteTuIndex(#[source] gimli::write::Error),
64-
#[error("Unit 0x{0:08x} was referenced by executable but not found")]
78+
/// Failed to write `.debug_cu_index` to output.
79+
WriteCuIndex(gimli::write::Error),
80+
/// Failed to write `.debug_tu_index` to output.
81+
WriteTuIndex(gimli::write::Error),
82+
/// Unit referenced by an executable was not found.
6583
MissingReferencedUnit(u64),
66-
#[error("No output object was created from inputs")]
84+
/// No output object was created from inputs
6785
NoOutputObjectCreated,
6886

69-
#[error(transparent)]
70-
Io(#[from] std::io::Error),
71-
#[error(transparent)]
72-
ObjectRead(#[from] object::Error),
73-
#[error(transparent)]
74-
ObjectWrite(#[from] object::write::Error),
75-
#[error(transparent)]
76-
GimliRead(#[from] gimli::read::Error),
77-
#[error(transparent)]
78-
GimliWrite(#[from] gimli::write::Error),
87+
/// Catch-all for `std::io::Error`.
88+
Io(std::io::Error),
89+
/// Catch-all for `object::Error`.
90+
ObjectRead(object::Error),
91+
/// Catch-all for `object::write::Error`.
92+
ObjectWrite(object::write::Error),
93+
/// Catch-all for `gimli::read::Error`.
94+
GimliRead(gimli::read::Error),
95+
/// Catch-all for `gimli::write::Error`.
96+
GimliWrite(gimli::write::Error),
97+
}
98+
99+
impl StdError for Error {
100+
fn source(&self) -> Option<&(dyn StdError + 'static)> {
101+
match self {
102+
Error::ReadInput(source) => Some(source.as_dyn_error()),
103+
Error::ParseFileKind(source) => Some(source.as_dyn_error()),
104+
Error::ParseObjectFile(source) => Some(source.as_dyn_error()),
105+
Error::ParseArchiveFile(source) => Some(source.as_dyn_error()),
106+
Error::ParseArchiveMember(source) => Some(source.as_dyn_error()),
107+
Error::InvalidInputKind => None,
108+
Error::DecompressData(source) => Some(source.as_dyn_error()),
109+
Error::NamelessSection(source, _) => Some(source.as_dyn_error()),
110+
Error::RelocationWithInvalidSymbol(_, _) => None,
111+
Error::MultipleRelocations(_, _) => None,
112+
Error::UnsupportedRelocation(_, _) => None,
113+
Error::MissingDwoName(_) => None,
114+
Error::MissingRequiredSection(_) => None,
115+
Error::ParseUnitHeader(source) => Some(source.as_dyn_error()),
116+
Error::ParseUnit(source) => Some(source.as_dyn_error()),
117+
Error::AppendSection(source, _) => Some(source.as_dyn_error()),
118+
Error::StrOffsetsMissingHeader => None,
119+
Error::OffsetAtIndex(source, _) => Some(source.as_dyn_error()),
120+
Error::StrAtOffset(source, _) => Some(source.as_dyn_error()),
121+
Error::WritingStrToStringTable(source) => Some(source.as_dyn_error()),
122+
Error::ParseIndex(source) => Some(source.as_dyn_error()),
123+
Error::UnitNotInIndex(_) => None,
124+
Error::RowNotInIndex(source, _) => Some(source.as_dyn_error()),
125+
Error::SectionNotInRow => None,
126+
Error::EmptyUnit(_) => None,
127+
Error::WriteCuIndex(source) => Some(source.as_dyn_error()),
128+
Error::WriteTuIndex(source) => Some(source.as_dyn_error()),
129+
Error::MissingReferencedUnit(_) => None,
130+
Error::NoOutputObjectCreated => None,
131+
Error::Io(transparent) => StdError::source(transparent.as_dyn_error()),
132+
Error::ObjectRead(transparent) => StdError::source(transparent.as_dyn_error()),
133+
Error::ObjectWrite(transparent) => StdError::source(transparent.as_dyn_error()),
134+
Error::GimliRead(transparent) => StdError::source(transparent.as_dyn_error()),
135+
Error::GimliWrite(transparent) => StdError::source(transparent.as_dyn_error()),
136+
}
137+
}
138+
}
139+
140+
impl fmt::Display for Error {
141+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
142+
match self {
143+
Error::ReadInput(_) => write!(f, "Failed to read input file"),
144+
Error::ParseFileKind(_) => write!(f, "Failed to parse kind of input file"),
145+
Error::ParseObjectFile(_) => write!(f, "Failed to parse object file"),
146+
Error::ParseArchiveFile(_) => write!(f, "Failed to parse archive file"),
147+
Error::ParseArchiveMember(_) => write!(f, "Failed to parse archive member"),
148+
Error::InvalidInputKind => write!(f, "Input is not an archive or elf file"),
149+
Error::DecompressData(_) => write!(f, "Failed to decompress data"),
150+
Error::NamelessSection(_, offset) => {
151+
write!(f, "Section without name at offset 0x{:08x}", offset)
152+
}
153+
Error::RelocationWithInvalidSymbol(section, offset) => write!(
154+
f,
155+
"Relocation with invalid symbol for section `{}` at offset 0x{:08x}",
156+
section, offset
157+
),
158+
Error::MultipleRelocations(section, offset) => write!(
159+
f,
160+
"Multiple relocations for section `{}` at offset 0x{:08x}",
161+
section, offset
162+
),
163+
Error::UnsupportedRelocation(section, offset) => write!(
164+
f,
165+
"Unsupported relocation for section {} at offset 0x{:08x}",
166+
section, offset
167+
),
168+
Error::MissingDwoName(id) => {
169+
write!(f, "Missing path attribute to DWARF object 0x{:08x}", id)
170+
}
171+
Error::MissingRequiredSection(section) => {
172+
write!(f, "Input DWARF object missing required section `{}`", section)
173+
}
174+
Error::ParseUnitHeader(_) => write!(f, "Failed to parse unit header"),
175+
Error::ParseUnit(_) => write!(f, "Failed to parse unit"),
176+
Error::AppendSection(_, section) => {
177+
write!(f, "Failed to concatenate `{}` section from input DWARF object", section)
178+
}
179+
Error::StrOffsetsMissingHeader => {
180+
write!(f, "Failed to read header of `.debug_str_offsets.dwo` section")
181+
}
182+
Error::OffsetAtIndex(_, index) => write!(
183+
f,
184+
"Failed to read offset at index {} of `.debug_str_offsets.dwo` section",
185+
index
186+
),
187+
Error::StrAtOffset(_, offset) => write!(
188+
f,
189+
"Failed to read string at offset {:08x} of `.debug_str.dwo` section",
190+
offset
191+
),
192+
Error::WritingStrToStringTable(_) => {
193+
write!(f, "Failed to write string to in-progress `.debug_str.dwo` section")
194+
}
195+
Error::ParseIndex(_) => write!(f, "Failed to parse index section"),
196+
Error::UnitNotInIndex(unit) => {
197+
write!(f, "Unit 0x{0:08x} from input DWARF package is not in its index", unit)
198+
}
199+
Error::RowNotInIndex(_, row) => {
200+
write!(f, "Row {0} found in index's hash table not present in index", row)
201+
}
202+
Error::SectionNotInRow => write!(f, "Section not found in unit's row in index"),
203+
Error::EmptyUnit(unit) => {
204+
write!(f, "Unit `{}` in input DWARF object with no data", unit)
205+
}
206+
Error::WriteCuIndex(_) => {
207+
write!(f, "Failed to write `.debug_cu_index` of output DWARF package")
208+
}
209+
Error::WriteTuIndex(_) => {
210+
write!(f, "Failed to write `.debug_tu_index` of output DWARF package")
211+
}
212+
Error::MissingReferencedUnit(unit) => {
213+
write!(f, "Unit 0x{:08x} was referenced by executable but not found", unit)
214+
}
215+
Error::NoOutputObjectCreated => write!(f, "No output object was created from inputs"),
216+
Error::Io(e) => fmt::Display::fmt(e, f),
217+
Error::ObjectRead(e) => fmt::Display::fmt(e, f),
218+
Error::ObjectWrite(e) => fmt::Display::fmt(e, f),
219+
Error::GimliRead(e) => fmt::Display::fmt(e, f),
220+
Error::GimliWrite(e) => fmt::Display::fmt(e, f),
221+
}
222+
}
223+
}
224+
225+
impl From<std::io::Error> for Error {
226+
fn from(source: std::io::Error) -> Self {
227+
Error::Io(source)
228+
}
229+
}
230+
231+
impl From<object::Error> for Error {
232+
fn from(source: object::Error) -> Self {
233+
Error::ObjectRead(source)
234+
}
235+
}
236+
237+
impl From<object::write::Error> for Error {
238+
fn from(source: object::write::Error) -> Self {
239+
Error::ObjectWrite(source)
240+
}
241+
}
242+
243+
impl From<gimli::read::Error> for Error {
244+
fn from(source: gimli::read::Error) -> Self {
245+
Error::GimliRead(source)
246+
}
247+
}
248+
249+
impl From<gimli::write::Error> for Error {
250+
fn from(source: gimli::write::Error) -> Self {
251+
Error::GimliWrite(source)
252+
}
79253
}

0 commit comments

Comments
 (0)