summaryrefslogtreecommitdiffstats
path: root/vendor/thorin-dwp/src/error.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/thorin-dwp/src/error.rs')
-rw-r--r--vendor/thorin-dwp/src/error.rs294
1 files changed, 294 insertions, 0 deletions
diff --git a/vendor/thorin-dwp/src/error.rs b/vendor/thorin-dwp/src/error.rs
new file mode 100644
index 000000000..e49722afa
--- /dev/null
+++ b/vendor/thorin-dwp/src/error.rs
@@ -0,0 +1,294 @@
+use std::error::Error as StdError;
+use std::fmt;
+
+pub(crate) type Result<T> = std::result::Result<T, Error>;
+
+/// Helper trait for converting an error to a `&dyn std::error::Error`.
+pub trait AsDynError<'a> {
+ fn as_dyn_error(&self) -> &(dyn StdError + 'a);
+}
+
+impl<'a, T: StdError + 'a> AsDynError<'a> for T {
+ #[inline]
+ fn as_dyn_error(&self) -> &(dyn StdError + 'a) {
+ self
+ }
+}
+
+/// Diagnostics (and contexts) emitted during DWARF packaging.
+#[derive(Debug)]
+#[non_exhaustive]
+pub enum Error {
+ /// Failure to read input file.
+ ///
+ /// This error occurs in the `Session::read_input` function provided by the user of `thorin`.
+ ReadInput(std::io::Error),
+ /// Failed to parse kind of input file.
+ ///
+ /// Input file kind is necessary to determine how to parse the rest of the input, and to
+ /// validate that the input file is of a type that `thorin` can process.
+ ParseFileKind(object::Error),
+ /// Failed to parse object file.
+ ParseObjectFile(object::Error),
+ /// Failed to parse archive file.
+ ParseArchiveFile(object::Error),
+ /// Failed to parse archive member.
+ ParseArchiveMember(object::Error),
+ /// Invalid kind of input.
+ ///
+ /// Only archive and elf files are supported input files.
+ InvalidInputKind,
+ /// Failed to decompress data.
+ ///
+ /// `thorin` uses `object` for decompression, so `object` probably didn't have support for the
+ /// type of compression used.
+ DecompressData(object::Error),
+ /// Section without a name.
+ NamelessSection(object::Error, usize),
+ /// Relocation has invalid symbol for a section.
+ RelocationWithInvalidSymbol(String, usize),
+ /// Multiple relocations for a section.
+ MultipleRelocations(String, usize),
+ /// Unsupported relocations for a section.
+ UnsupportedRelocation(String, usize),
+ /// Input object that has a `DwoId` (or `DebugTypeSignature`) does not have a
+ /// `DW_AT_GNU_dwo_name` or `DW_AT_dwo_name` attribute.
+ MissingDwoName(u64),
+ /// Input object has no compilation units.
+ NoCompilationUnits,
+ /// No top-level debugging information entry in unit.
+ NoDie,
+ /// Top-level debugging information entry is not a compilation/type unit.
+ TopLevelDieNotUnit,
+ /// Section required of input DWARF objects was missing.
+ MissingRequiredSection(&'static str),
+ /// Failed to parse unit abbreviations.
+ ParseUnitAbbreviations(gimli::read::Error),
+ /// Failed to parse unit attribute.
+ ParseUnitAttribute(gimli::read::Error),
+ /// Failed to parse unit header.
+ ParseUnitHeader(gimli::read::Error),
+ /// Failed to parse unit.
+ ParseUnit(gimli::read::Error),
+ /// Input DWARF package has a different index version than the version being output.
+ IncompatibleIndexVersion(String, u16, u16),
+ /// Failed to read string offset from `.debug_str_offsets` at index.
+ OffsetAtIndex(gimli::read::Error, u64),
+ /// Failed to read string from `.debug_str` at offset.
+ StrAtOffset(gimli::read::Error, usize),
+ /// Failed to parse index section.
+ ///
+ /// If an input file is a DWARF package, its index section needs to be read to ensure that the
+ /// contributions within it are preserved.
+ ParseIndex(gimli::read::Error, String),
+ /// Compilation unit in DWARF package is not its index.
+ UnitNotInIndex(u64),
+ /// Row for a compilation unit is not in the index.
+ RowNotInIndex(gimli::read::Error, u32),
+ /// Section not found in unit's row in index, i.e. a DWARF package contains a section but its
+ /// index doesn't record contributions to it.
+ SectionNotInRow,
+ /// Compilation unit in input DWARF object has no content.
+ EmptyUnit(u64),
+ /// Found multiple `.debug_info.dwo` sections.
+ MultipleDebugInfoSection,
+ /// Found multiple `.debug_types.dwo` sections in a DWARF package file.
+ MultipleDebugTypesSection,
+ /// Found a regular compilation unit in a DWARF object.
+ NotSplitUnit,
+ /// Found duplicate split compilation unit.
+ DuplicateUnit(u64),
+ /// Unit referenced by an executable was not found.
+ MissingReferencedUnit(u64),
+ /// No output object was created from inputs
+ NoOutputObjectCreated,
+ /// Input objects have different encodings.
+ MixedInputEncodings,
+
+ /// Catch-all for `std::io::Error`.
+ Io(std::io::Error),
+ /// Catch-all for `object::Error`.
+ ObjectRead(object::Error),
+ /// Catch-all for `object::write::Error`.
+ ObjectWrite(object::write::Error),
+ /// Catch-all for `gimli::read::Error`.
+ GimliRead(gimli::read::Error),
+ /// Catch-all for `gimli::write::Error`.
+ GimliWrite(gimli::write::Error),
+}
+
+impl StdError for Error {
+ fn source(&self) -> Option<&(dyn StdError + 'static)> {
+ match self {
+ Error::ReadInput(source) => Some(source.as_dyn_error()),
+ Error::ParseFileKind(source) => Some(source.as_dyn_error()),
+ Error::ParseObjectFile(source) => Some(source.as_dyn_error()),
+ Error::ParseArchiveFile(source) => Some(source.as_dyn_error()),
+ Error::ParseArchiveMember(source) => Some(source.as_dyn_error()),
+ Error::InvalidInputKind => None,
+ Error::DecompressData(source) => Some(source.as_dyn_error()),
+ Error::NamelessSection(source, _) => Some(source.as_dyn_error()),
+ Error::RelocationWithInvalidSymbol(_, _) => None,
+ Error::MultipleRelocations(_, _) => None,
+ Error::UnsupportedRelocation(_, _) => None,
+ Error::MissingDwoName(_) => None,
+ Error::NoCompilationUnits => None,
+ Error::NoDie => None,
+ Error::TopLevelDieNotUnit => None,
+ Error::MissingRequiredSection(_) => None,
+ Error::ParseUnitAbbreviations(source) => Some(source.as_dyn_error()),
+ Error::ParseUnitAttribute(source) => Some(source.as_dyn_error()),
+ Error::ParseUnitHeader(source) => Some(source.as_dyn_error()),
+ Error::ParseUnit(source) => Some(source.as_dyn_error()),
+ Error::IncompatibleIndexVersion(_, _, _) => None,
+ Error::OffsetAtIndex(source, _) => Some(source.as_dyn_error()),
+ Error::StrAtOffset(source, _) => Some(source.as_dyn_error()),
+ Error::ParseIndex(source, _) => Some(source.as_dyn_error()),
+ Error::UnitNotInIndex(_) => None,
+ Error::RowNotInIndex(source, _) => Some(source.as_dyn_error()),
+ Error::SectionNotInRow => None,
+ Error::EmptyUnit(_) => None,
+ Error::MultipleDebugInfoSection => None,
+ Error::MultipleDebugTypesSection => None,
+ Error::NotSplitUnit => None,
+ Error::DuplicateUnit(_) => None,
+ Error::MissingReferencedUnit(_) => None,
+ Error::NoOutputObjectCreated => None,
+ Error::MixedInputEncodings => None,
+ Error::Io(transparent) => StdError::source(transparent.as_dyn_error()),
+ Error::ObjectRead(transparent) => StdError::source(transparent.as_dyn_error()),
+ Error::ObjectWrite(transparent) => StdError::source(transparent.as_dyn_error()),
+ Error::GimliRead(transparent) => StdError::source(transparent.as_dyn_error()),
+ Error::GimliWrite(transparent) => StdError::source(transparent.as_dyn_error()),
+ }
+ }
+}
+
+impl fmt::Display for Error {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match self {
+ Error::ReadInput(_) => write!(f, "Failed to read input file"),
+ Error::ParseFileKind(_) => write!(f, "Failed to parse input file kind"),
+ Error::ParseObjectFile(_) => write!(f, "Failed to parse input object file"),
+ Error::ParseArchiveFile(_) => write!(f, "Failed to parse input archive file"),
+ Error::ParseArchiveMember(_) => write!(f, "Failed to parse archive member"),
+ Error::InvalidInputKind => write!(f, "Input is not an archive or elf object"),
+ Error::DecompressData(_) => write!(f, "Failed to decompress compressed section"),
+ Error::NamelessSection(_, offset) => {
+ write!(f, "Section without name at offset 0x{:08x}", offset)
+ }
+ Error::RelocationWithInvalidSymbol(section, offset) => write!(
+ f,
+ "Relocation with invalid symbol for section `{}` at offset 0x{:08x}",
+ section, offset
+ ),
+ Error::MultipleRelocations(section, offset) => write!(
+ f,
+ "Multiple relocations for section `{}` at offset 0x{:08x}",
+ section, offset
+ ),
+ Error::UnsupportedRelocation(section, offset) => write!(
+ f,
+ "Unsupported relocation for section {} at offset 0x{:08x}",
+ section, offset
+ ),
+ Error::MissingDwoName(id) => {
+ write!(f, "Missing path attribute to DWARF object (0x{:08x})", id)
+ }
+ Error::NoCompilationUnits => {
+ write!(f, "Input object has no compilation units")
+ }
+ Error::NoDie => {
+ write!(f, "No top-level debugging information entry in compilation/type unit")
+ }
+ Error::TopLevelDieNotUnit => {
+ write!(f, "Top-level debugging information entry is not a compilation/type unit")
+ }
+ Error::MissingRequiredSection(section) => {
+ write!(f, "Input object missing required section `{}`", section)
+ }
+ Error::ParseUnitAbbreviations(_) => write!(f, "Failed to parse unit abbreviations"),
+ Error::ParseUnitAttribute(_) => write!(f, "Failed to parse unit attribute"),
+ Error::ParseUnitHeader(_) => write!(f, "Failed to parse unit header"),
+ Error::ParseUnit(_) => write!(f, "Failed to parse unit"),
+ Error::IncompatibleIndexVersion(section, format, actual) => {
+ write!(
+ f,
+ "Incompatible `{}` index version: found version {}, expected version {}",
+ section, actual, format
+ )
+ }
+ Error::OffsetAtIndex(_, index) => {
+ write!(f, "Read offset at index {} of `.debug_str_offsets.dwo` section", index)
+ }
+ Error::StrAtOffset(_, offset) => {
+ write!(f, "Read string at offset 0x{:08x} of `.debug_str.dwo` section", offset)
+ }
+ Error::ParseIndex(_, section) => {
+ write!(f, "Failed to parse `{}` index section", section)
+ }
+ Error::UnitNotInIndex(unit) => {
+ write!(f, "Unit 0x{0:08x} from input package is not in its index", unit)
+ }
+ Error::RowNotInIndex(_, row) => {
+ write!(f, "Row {0} found in index's hash table not present in index", row)
+ }
+ Error::SectionNotInRow => write!(f, "Section not found in unit's row in index"),
+ Error::EmptyUnit(unit) => {
+ write!(f, "Unit 0x{:08x} in input DWARF object with no data", unit)
+ }
+ Error::MultipleDebugInfoSection => {
+ write!(f, "Multiple `.debug_info.dwo` sections")
+ }
+ Error::MultipleDebugTypesSection => {
+ write!(f, "Multiple `.debug_types.dwo` sections in a package")
+ }
+ Error::NotSplitUnit => {
+ write!(f, "Regular compilation unit in object (missing dwo identifier)")
+ }
+ Error::DuplicateUnit(unit) => {
+ write!(f, "Duplicate split compilation unit (0x{:08x})", unit)
+ }
+ Error::MissingReferencedUnit(unit) => {
+ write!(f, "Unit 0x{:08x} referenced by executable was not found", unit)
+ }
+ Error::NoOutputObjectCreated => write!(f, "No output object was created from inputs"),
+ Error::MixedInputEncodings => write!(f, "Input objects haved mixed encodings"),
+ Error::Io(e) => fmt::Display::fmt(e, f),
+ Error::ObjectRead(e) => fmt::Display::fmt(e, f),
+ Error::ObjectWrite(e) => fmt::Display::fmt(e, f),
+ Error::GimliRead(e) => fmt::Display::fmt(e, f),
+ Error::GimliWrite(e) => fmt::Display::fmt(e, f),
+ }
+ }
+}
+
+impl From<std::io::Error> for Error {
+ fn from(source: std::io::Error) -> Self {
+ Error::Io(source)
+ }
+}
+
+impl From<object::Error> for Error {
+ fn from(source: object::Error) -> Self {
+ Error::ObjectRead(source)
+ }
+}
+
+impl From<object::write::Error> for Error {
+ fn from(source: object::write::Error) -> Self {
+ Error::ObjectWrite(source)
+ }
+}
+
+impl From<gimli::read::Error> for Error {
+ fn from(source: gimli::read::Error) -> Self {
+ Error::GimliRead(source)
+ }
+}
+
+impl From<gimli::write::Error> for Error {
+ fn from(source: gimli::write::Error) -> Self {
+ Error::GimliWrite(source)
+ }
+}