aboutsummaryrefslogtreecommitdiff
path: root/vendor/gimli/src/read/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/gimli/src/read/mod.rs')
-rw-r--r--vendor/gimli/src/read/mod.rs827
1 files changed, 0 insertions, 827 deletions
diff --git a/vendor/gimli/src/read/mod.rs b/vendor/gimli/src/read/mod.rs
deleted file mode 100644
index 2ad7f6a..0000000
--- a/vendor/gimli/src/read/mod.rs
+++ /dev/null
@@ -1,827 +0,0 @@
-//! Read DWARF debugging information.
-//!
-//! * [Example Usage](#example-usage)
-//! * [API Structure](#api-structure)
-//! * [Using with `FallibleIterator`](#using-with-fallibleiterator)
-//!
-//! ## Example Usage
-//!
-//! Print out all of the functions in the debuggee program:
-//!
-//! ```rust,no_run
-//! # fn example() -> Result<(), gimli::Error> {
-//! # type R = gimli::EndianSlice<'static, gimli::LittleEndian>;
-//! # let get_file_section_reader = |name| -> Result<R, gimli::Error> { unimplemented!() };
-//! # let get_sup_file_section_reader = |name| -> Result<R, gimli::Error> { unimplemented!() };
-//! // Read the DWARF sections with whatever object loader you're using.
-//! // These closures should return a `Reader` instance (e.g. `EndianSlice`).
-//! let loader = |section: gimli::SectionId| { get_file_section_reader(section.name()) };
-//! let sup_loader = |section: gimli::SectionId| { get_sup_file_section_reader(section.name()) };
-//! let mut dwarf = gimli::Dwarf::load(loader)?;
-//! dwarf.load_sup(sup_loader)?;
-//!
-//! // Iterate over all compilation units.
-//! let mut iter = dwarf.units();
-//! while let Some(header) = iter.next()? {
-//! // Parse the abbreviations and other information for this compilation unit.
-//! let unit = dwarf.unit(header)?;
-//!
-//! // Iterate over all of this compilation unit's entries.
-//! let mut entries = unit.entries();
-//! while let Some((_, entry)) = entries.next_dfs()? {
-//! // If we find an entry for a function, print it.
-//! if entry.tag() == gimli::DW_TAG_subprogram {
-//! println!("Found a function: {:?}", entry);
-//! }
-//! }
-//! }
-//! # unreachable!()
-//! # }
-//! ```
-//!
-//! Full example programs:
-//!
-//! * [A simple parser](https://github.com/gimli-rs/gimli/blob/master/crates/examples/src/bin/simple.rs)
-//!
-//! * [A `dwarfdump`
-//! clone](https://github.com/gimli-rs/gimli/blob/master/crates/examples/src/bin/dwarfdump.rs)
-//!
-//! * [An `addr2line` clone](https://github.com/gimli-rs/addr2line)
-//!
-//! * [`ddbug`](https://github.com/gimli-rs/ddbug), a utility giving insight into
-//! code generation by making debugging information readable
-//!
-//! * [`dwprod`](https://github.com/fitzgen/dwprod), a tiny utility to list the
-//! compilers used to create each compilation unit within a shared library or
-//! executable (via `DW_AT_producer`)
-//!
-//! * [`dwarf-validate`](https://github.com/gimli-rs/gimli/blob/master/crates/examples/src/bin/dwarf-validate.rs),
-//! a program to validate the integrity of some DWARF and its references
-//! between sections and compilation units.
-//!
-//! ## API Structure
-//!
-//! * Basic familiarity with DWARF is assumed.
-//!
-//! * The [`Dwarf`](./struct.Dwarf.html) type contains the commonly used DWARF
-//! sections. It has methods that simplify access to debugging data that spans
-//! multiple sections. Use of this type is optional, but recommended.
-//!
-//! * Each section gets its own type. Consider these types the entry points to
-//! the library:
-//!
-//! * [`DebugAbbrev`](./struct.DebugAbbrev.html): The `.debug_abbrev` section.
-//!
-//! * [`DebugAddr`](./struct.DebugAddr.html): The `.debug_addr` section.
-//!
-//! * [`DebugAranges`](./struct.DebugAranges.html): The `.debug_aranges`
-//! section.
-//!
-//! * [`DebugFrame`](./struct.DebugFrame.html): The `.debug_frame` section.
-//!
-//! * [`DebugInfo`](./struct.DebugInfo.html): The `.debug_info` section.
-//!
-//! * [`DebugLine`](./struct.DebugLine.html): The `.debug_line` section.
-//!
-//! * [`DebugLineStr`](./struct.DebugLineStr.html): The `.debug_line_str` section.
-//!
-//! * [`DebugLoc`](./struct.DebugLoc.html): The `.debug_loc` section.
-//!
-//! * [`DebugLocLists`](./struct.DebugLocLists.html): The `.debug_loclists` section.
-//!
-//! * [`DebugPubNames`](./struct.DebugPubNames.html): The `.debug_pubnames`
-//! section.
-//!
-//! * [`DebugPubTypes`](./struct.DebugPubTypes.html): The `.debug_pubtypes`
-//! section.
-//!
-//! * [`DebugRanges`](./struct.DebugRanges.html): The `.debug_ranges` section.
-//!
-//! * [`DebugRngLists`](./struct.DebugRngLists.html): The `.debug_rnglists` section.
-//!
-//! * [`DebugStr`](./struct.DebugStr.html): The `.debug_str` section.
-//!
-//! * [`DebugStrOffsets`](./struct.DebugStrOffsets.html): The `.debug_str_offsets` section.
-//!
-//! * [`DebugTypes`](./struct.DebugTypes.html): The `.debug_types` section.
-//!
-//! * [`DebugCuIndex`](./struct.DebugCuIndex.html): The `.debug_cu_index` section.
-//!
-//! * [`DebugTuIndex`](./struct.DebugTuIndex.html): The `.debug_tu_index` section.
-//!
-//! * [`EhFrame`](./struct.EhFrame.html): The `.eh_frame` section.
-//!
-//! * [`EhFrameHdr`](./struct.EhFrameHdr.html): The `.eh_frame_hdr` section.
-//!
-//! * Each section type exposes methods for accessing the debugging data encoded
-//! in that section. For example, the [`DebugInfo`](./struct.DebugInfo.html)
-//! struct has the [`units`](./struct.DebugInfo.html#method.units) method for
-//! iterating over the compilation units defined within it.
-//!
-//! * Offsets into a section are strongly typed: an offset into `.debug_info` is
-//! the [`DebugInfoOffset`](./struct.DebugInfoOffset.html) type. It cannot be
-//! used to index into the [`DebugLine`](./struct.DebugLine.html) type because
-//! `DebugLine` represents the `.debug_line` section. There are similar types
-//! for offsets relative to a compilation unit rather than a section.
-//!
-//! ## Using with `FallibleIterator`
-//!
-//! The standard library's `Iterator` trait and related APIs do not play well
-//! with iterators where the `next` operation is fallible. One can make the
-//! `Iterator`'s associated `Item` type be a `Result<T, E>`, however the
-//! provided methods cannot gracefully handle the case when an `Err` is
-//! returned.
-//!
-//! This situation led to the
-//! [`fallible-iterator`](https://crates.io/crates/fallible-iterator) crate's
-//! existence. You can read more of the rationale for its existence in its
-//! docs. The crate provides the helpers you have come to expect (eg `map`,
-//! `filter`, etc) for iterators that can fail.
-//!
-//! `gimli`'s many lazy parsing iterators are a perfect match for the
-//! `fallible-iterator` crate's `FallibleIterator` trait because parsing is not
-//! done eagerly. Parse errors later in the input might only be discovered after
-//! having iterated through many items.
-//!
-//! To use `gimli` iterators with `FallibleIterator`, import the crate and trait
-//! into your code:
-//!
-//! ```
-//! # #[cfg(feature = "fallible-iterator")]
-//! # fn foo() {
-//! // Use the `FallibleIterator` trait so its methods are in scope!
-//! use fallible_iterator::FallibleIterator;
-//! use gimli::{DebugAranges, EndianSlice, LittleEndian};
-//!
-//! fn find_sum_of_address_range_lengths(aranges: DebugAranges<EndianSlice<LittleEndian>>)
-//! -> gimli::Result<u64>
-//! {
-//! // `DebugAranges::headers` returns a `FallibleIterator`!
-//! aranges.headers()
-//! // `flat_map` is provided by `FallibleIterator`!
-//! .flat_map(|header| Ok(header.entries()))
-//! // `map` is provided by `FallibleIterator`!
-//! .map(|arange| Ok(arange.length()))
-//! // `fold` is provided by `FallibleIterator`!
-//! .fold(0, |sum, len| Ok(sum + len))
-//! }
-//! # }
-//! # fn main() {}
-//! ```
-
-use core::fmt::{self, Debug};
-use core::result;
-#[cfg(feature = "std")]
-use std::{error, io};
-
-use crate::common::{Register, SectionId};
-use crate::constants;
-
-mod util;
-pub use util::*;
-
-mod addr;
-pub use self::addr::*;
-
-mod cfi;
-pub use self::cfi::*;
-
-#[cfg(feature = "read")]
-mod dwarf;
-#[cfg(feature = "read")]
-pub use self::dwarf::*;
-
-mod endian_slice;
-pub use self::endian_slice::*;
-
-#[cfg(feature = "endian-reader")]
-mod endian_reader;
-#[cfg(feature = "endian-reader")]
-pub use self::endian_reader::*;
-
-mod reader;
-pub use self::reader::*;
-
-#[cfg(feature = "read")]
-mod abbrev;
-#[cfg(feature = "read")]
-pub use self::abbrev::*;
-
-mod aranges;
-pub use self::aranges::*;
-
-mod index;
-pub use self::index::*;
-
-#[cfg(feature = "read")]
-mod line;
-#[cfg(feature = "read")]
-pub use self::line::*;
-
-mod lists;
-
-mod loclists;
-pub use self::loclists::*;
-
-#[cfg(feature = "read")]
-mod lookup;
-
-mod op;
-pub use self::op::*;
-
-#[cfg(feature = "read")]
-mod pubnames;
-#[cfg(feature = "read")]
-pub use self::pubnames::*;
-
-#[cfg(feature = "read")]
-mod pubtypes;
-#[cfg(feature = "read")]
-pub use self::pubtypes::*;
-
-mod rnglists;
-pub use self::rnglists::*;
-
-mod str;
-pub use self::str::*;
-
-/// An offset into the current compilation or type unit.
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Hash)]
-pub struct UnitOffset<T = usize>(pub T);
-
-#[cfg(feature = "read")]
-mod unit;
-#[cfg(feature = "read")]
-pub use self::unit::*;
-
-mod value;
-pub use self::value::*;
-
-/// Indicates that storage should be allocated on heap.
-#[derive(Debug, Clone, Copy, PartialEq, Eq)]
-pub struct StoreOnHeap;
-
-/// `EndianBuf` has been renamed to `EndianSlice`. For ease of upgrading across
-/// `gimli` versions, we export this type alias.
-#[deprecated(note = "EndianBuf has been renamed to EndianSlice, use that instead.")]
-pub type EndianBuf<'input, Endian> = EndianSlice<'input, Endian>;
-
-/// An error that occurred when parsing.
-#[derive(Debug, Clone, Copy, PartialEq, Eq)]
-pub enum Error {
- /// An I/O error occurred while reading.
- Io,
- /// Found a PC relative pointer, but the section base is undefined.
- PcRelativePointerButSectionBaseIsUndefined,
- /// Found a `.text` relative pointer, but the `.text` base is undefined.
- TextRelativePointerButTextBaseIsUndefined,
- /// Found a data relative pointer, but the data base is undefined.
- DataRelativePointerButDataBaseIsUndefined,
- /// Found a function relative pointer in a context that does not have a
- /// function base.
- FuncRelativePointerInBadContext,
- /// Cannot parse a pointer with a `DW_EH_PE_omit` encoding.
- CannotParseOmitPointerEncoding,
- /// An error parsing an unsigned LEB128 value.
- BadUnsignedLeb128,
- /// An error parsing a signed LEB128 value.
- BadSignedLeb128,
- /// An abbreviation declared that its tag is zero, but zero is reserved for
- /// null records.
- AbbreviationTagZero,
- /// An attribute specification declared that its form is zero, but zero is
- /// reserved for null records.
- AttributeFormZero,
- /// The abbreviation's has-children byte was not one of
- /// `DW_CHILDREN_{yes,no}`.
- BadHasChildren,
- /// The specified length is impossible.
- BadLength,
- /// Found an unknown `DW_FORM_*` type.
- UnknownForm,
- /// Expected a zero, found something else.
- ExpectedZero,
- /// Found an abbreviation code that has already been used.
- DuplicateAbbreviationCode,
- /// Found a duplicate arange.
- DuplicateArange,
- /// Found an unknown reserved length value.
- UnknownReservedLength,
- /// Found an unknown DWARF version.
- UnknownVersion(u64),
- /// Found a record with an unknown abbreviation code.
- UnknownAbbreviation,
- /// Hit the end of input before it was expected.
- UnexpectedEof(ReaderOffsetId),
- /// Read a null entry before it was expected.
- UnexpectedNull,
- /// Found an unknown standard opcode.
- UnknownStandardOpcode(constants::DwLns),
- /// Found an unknown extended opcode.
- UnknownExtendedOpcode(constants::DwLne),
- /// The specified address size is not supported.
- UnsupportedAddressSize(u8),
- /// The specified offset size is not supported.
- UnsupportedOffsetSize(u8),
- /// The specified field size is not supported.
- UnsupportedFieldSize(u8),
- /// The minimum instruction length must not be zero.
- MinimumInstructionLengthZero,
- /// The maximum operations per instruction must not be zero.
- MaximumOperationsPerInstructionZero,
- /// The line range must not be zero.
- LineRangeZero,
- /// The opcode base must not be zero.
- OpcodeBaseZero,
- /// Found an invalid UTF-8 string.
- BadUtf8,
- /// Expected to find the CIE ID, but found something else.
- NotCieId,
- /// Expected to find a pointer to a CIE, but found the CIE ID instead.
- NotCiePointer,
- /// Expected to find a pointer to an FDE, but found a CIE instead.
- NotFdePointer,
- /// Invalid branch target for a DW_OP_bra or DW_OP_skip.
- BadBranchTarget(u64),
- /// DW_OP_push_object_address used but no address passed in.
- InvalidPushObjectAddress,
- /// Not enough items on the stack when evaluating an expression.
- NotEnoughStackItems,
- /// Too many iterations to compute the expression.
- TooManyIterations,
- /// An unrecognized operation was found while parsing a DWARF
- /// expression.
- InvalidExpression(constants::DwOp),
- /// An unsupported operation was found while evaluating a DWARF expression.
- UnsupportedEvaluation,
- /// The expression had a piece followed by an expression
- /// terminator without a piece.
- InvalidPiece,
- /// An expression-terminating operation was followed by something
- /// other than the end of the expression or a piece operation.
- InvalidExpressionTerminator(u64),
- /// Division or modulus by zero when evaluating an expression.
- DivisionByZero,
- /// An expression operation used mismatching types.
- TypeMismatch,
- /// An expression operation required an integral type but saw a
- /// floating point type.
- IntegralTypeRequired,
- /// An expression operation used types that are not supported.
- UnsupportedTypeOperation,
- /// The shift value in an expression must be a non-negative integer.
- InvalidShiftExpression,
- /// An unknown DW_CFA_* instruction.
- UnknownCallFrameInstruction(constants::DwCfa),
- /// The end of an address range was before the beginning.
- InvalidAddressRange,
- /// The end offset of a loc list entry was before the beginning.
- InvalidLocationAddressRange,
- /// Encountered a call frame instruction in a context in which it is not
- /// valid.
- CfiInstructionInInvalidContext,
- /// When evaluating call frame instructions, found a `DW_CFA_restore_state`
- /// stack pop instruction, but the stack was empty, and had nothing to pop.
- PopWithEmptyStack,
- /// Do not have unwind info for the given address.
- NoUnwindInfoForAddress,
- /// An offset value was larger than the maximum supported value.
- UnsupportedOffset,
- /// The given pointer encoding is either unknown or invalid.
- UnknownPointerEncoding,
- /// Did not find an entry at the given offset.
- NoEntryAtGivenOffset,
- /// The given offset is out of bounds.
- OffsetOutOfBounds,
- /// Found an unknown CFI augmentation.
- UnknownAugmentation,
- /// We do not support the given pointer encoding yet.
- UnsupportedPointerEncoding,
- /// Registers larger than `u16` are not supported.
- UnsupportedRegister(u64),
- /// The CFI program defined more register rules than we have storage for.
- TooManyRegisterRules,
- /// Attempted to push onto the CFI or evaluation stack, but it was already
- /// at full capacity.
- StackFull,
- /// The `.eh_frame_hdr` binary search table claims to be variable-length encoded,
- /// which makes binary search impossible.
- VariableLengthSearchTable,
- /// The `DW_UT_*` value for this unit is not supported yet.
- UnsupportedUnitType,
- /// Ranges using AddressIndex are not supported yet.
- UnsupportedAddressIndex,
- /// Nonzero segment selector sizes aren't supported yet.
- UnsupportedSegmentSize,
- /// A compilation unit or type unit is missing its top level DIE.
- MissingUnitDie,
- /// A DIE attribute used an unsupported form.
- UnsupportedAttributeForm,
- /// Missing DW_LNCT_path in file entry format.
- MissingFileEntryFormatPath,
- /// Expected an attribute value to be a string form.
- ExpectedStringAttributeValue,
- /// `DW_FORM_implicit_const` used in an invalid context.
- InvalidImplicitConst,
- /// Invalid section count in `.dwp` index.
- InvalidIndexSectionCount,
- /// Invalid slot count in `.dwp` index.
- InvalidIndexSlotCount,
- /// Invalid hash row in `.dwp` index.
- InvalidIndexRow,
- /// Unknown section type in `.dwp` index.
- UnknownIndexSection,
-}
-
-impl fmt::Display for Error {
- #[inline]
- fn fmt(&self, f: &mut fmt::Formatter) -> ::core::result::Result<(), fmt::Error> {
- write!(f, "{}", self.description())
- }
-}
-
-impl Error {
- /// A short description of the error.
- pub fn description(&self) -> &str {
- match *self {
- Error::Io => "An I/O error occurred while reading.",
- Error::PcRelativePointerButSectionBaseIsUndefined => {
- "Found a PC relative pointer, but the section base is undefined."
- }
- Error::TextRelativePointerButTextBaseIsUndefined => {
- "Found a `.text` relative pointer, but the `.text` base is undefined."
- }
- Error::DataRelativePointerButDataBaseIsUndefined => {
- "Found a data relative pointer, but the data base is undefined."
- }
- Error::FuncRelativePointerInBadContext => {
- "Found a function relative pointer in a context that does not have a function base."
- }
- Error::CannotParseOmitPointerEncoding => {
- "Cannot parse a pointer with a `DW_EH_PE_omit` encoding."
- }
- Error::BadUnsignedLeb128 => "An error parsing an unsigned LEB128 value",
- Error::BadSignedLeb128 => "An error parsing a signed LEB128 value",
- Error::AbbreviationTagZero => {
- "An abbreviation declared that its tag is zero,
- but zero is reserved for null records"
- }
- Error::AttributeFormZero => {
- "An attribute specification declared that its form is zero,
- but zero is reserved for null records"
- }
- Error::BadHasChildren => {
- "The abbreviation's has-children byte was not one of
- `DW_CHILDREN_{yes,no}`"
- }
- Error::BadLength => "The specified length is impossible",
- Error::UnknownForm => "Found an unknown `DW_FORM_*` type",
- Error::ExpectedZero => "Expected a zero, found something else",
- Error::DuplicateAbbreviationCode => {
- "Found an abbreviation code that has already been used"
- }
- Error::DuplicateArange => "Found a duplicate arange",
- Error::UnknownReservedLength => "Found an unknown reserved length value",
- Error::UnknownVersion(_) => "Found an unknown DWARF version",
- Error::UnknownAbbreviation => "Found a record with an unknown abbreviation code",
- Error::UnexpectedEof(_) => "Hit the end of input before it was expected",
- Error::UnexpectedNull => "Read a null entry before it was expected.",
- Error::UnknownStandardOpcode(_) => "Found an unknown standard opcode",
- Error::UnknownExtendedOpcode(_) => "Found an unknown extended opcode",
- Error::UnsupportedAddressSize(_) => "The specified address size is not supported",
- Error::UnsupportedOffsetSize(_) => "The specified offset size is not supported",
- Error::UnsupportedFieldSize(_) => "The specified field size is not supported",
- Error::MinimumInstructionLengthZero => {
- "The minimum instruction length must not be zero."
- }
- Error::MaximumOperationsPerInstructionZero => {
- "The maximum operations per instruction must not be zero."
- }
- Error::LineRangeZero => "The line range must not be zero.",
- Error::OpcodeBaseZero => "The opcode base must not be zero.",
- Error::BadUtf8 => "Found an invalid UTF-8 string.",
- Error::NotCieId => "Expected to find the CIE ID, but found something else.",
- Error::NotCiePointer => "Expected to find a CIE pointer, but found the CIE ID instead.",
- Error::NotFdePointer => {
- "Expected to find an FDE pointer, but found a CIE pointer instead."
- }
- Error::BadBranchTarget(_) => "Invalid branch target in DWARF expression",
- Error::InvalidPushObjectAddress => {
- "DW_OP_push_object_address used but no object address given"
- }
- Error::NotEnoughStackItems => "Not enough items on stack when evaluating expression",
- Error::TooManyIterations => "Too many iterations to evaluate DWARF expression",
- Error::InvalidExpression(_) => "Invalid opcode in DWARF expression",
- Error::UnsupportedEvaluation => "Unsupported operation when evaluating expression",
- Error::InvalidPiece => {
- "DWARF expression has piece followed by non-piece expression at end"
- }
- Error::InvalidExpressionTerminator(_) => "Expected DW_OP_piece or DW_OP_bit_piece",
- Error::DivisionByZero => "Division or modulus by zero when evaluating expression",
- Error::TypeMismatch => "Type mismatch when evaluating expression",
- Error::IntegralTypeRequired => "Integral type expected when evaluating expression",
- Error::UnsupportedTypeOperation => {
- "An expression operation used types that are not supported"
- }
- Error::InvalidShiftExpression => {
- "The shift value in an expression must be a non-negative integer."
- }
- Error::UnknownCallFrameInstruction(_) => "An unknown DW_CFA_* instructiion",
- Error::InvalidAddressRange => {
- "The end of an address range must not be before the beginning."
- }
- Error::InvalidLocationAddressRange => {
- "The end offset of a location list entry must not be before the beginning."
- }
- Error::CfiInstructionInInvalidContext => {
- "Encountered a call frame instruction in a context in which it is not valid."
- }
- Error::PopWithEmptyStack => {
- "When evaluating call frame instructions, found a `DW_CFA_restore_state` stack pop \
- instruction, but the stack was empty, and had nothing to pop."
- }
- Error::NoUnwindInfoForAddress => "Do not have unwind info for the given address.",
- Error::UnsupportedOffset => {
- "An offset value was larger than the maximum supported value."
- }
- Error::UnknownPointerEncoding => {
- "The given pointer encoding is either unknown or invalid."
- }
- Error::NoEntryAtGivenOffset => "Did not find an entry at the given offset.",
- Error::OffsetOutOfBounds => "The given offset is out of bounds.",
- Error::UnknownAugmentation => "Found an unknown CFI augmentation.",
- Error::UnsupportedPointerEncoding => {
- "We do not support the given pointer encoding yet."
- }
- Error::UnsupportedRegister(_) => "Registers larger than `u16` are not supported.",
- Error::TooManyRegisterRules => {
- "The CFI program defined more register rules than we have storage for."
- }
- Error::StackFull => {
- "Attempted to push onto the CFI stack, but it was already at full capacity."
- }
- Error::VariableLengthSearchTable => {
- "The `.eh_frame_hdr` binary search table claims to be variable-length encoded, \
- which makes binary search impossible."
- }
- Error::UnsupportedUnitType => "The `DW_UT_*` value for this unit is not supported yet",
- Error::UnsupportedAddressIndex => "Ranges involving AddressIndex are not supported yet",
- Error::UnsupportedSegmentSize => "Nonzero segment size not supported yet",
- Error::MissingUnitDie => {
- "A compilation unit or type unit is missing its top level DIE."
- }
- Error::UnsupportedAttributeForm => "A DIE attribute used an unsupported form.",
- Error::MissingFileEntryFormatPath => "Missing DW_LNCT_path in file entry format.",
- Error::ExpectedStringAttributeValue => {
- "Expected an attribute value to be a string form."
- }
- Error::InvalidImplicitConst => "DW_FORM_implicit_const used in an invalid context.",
- Error::InvalidIndexSectionCount => "Invalid section count in `.dwp` index.",
- Error::InvalidIndexSlotCount => "Invalid slot count in `.dwp` index.",
- Error::InvalidIndexRow => "Invalid hash row in `.dwp` index.",
- Error::UnknownIndexSection => "Unknown section type in `.dwp` index.",
- }
- }
-}
-
-#[cfg(feature = "std")]
-impl error::Error for Error {}
-
-#[cfg(feature = "std")]
-impl From<io::Error> for Error {
- fn from(_: io::Error) -> Self {
- Error::Io
- }
-}
-
-/// The result of a parse.
-pub type Result<T> = result::Result<T, Error>;
-
-/// A convenience trait for loading DWARF sections from object files. To be
-/// used like:
-///
-/// ```
-/// use gimli::{DebugInfo, EndianSlice, LittleEndian, Reader, Section};
-///
-/// let buf = [0x00, 0x01, 0x02, 0x03];
-/// let reader = EndianSlice::new(&buf, LittleEndian);
-/// let loader = |name| -> Result<_, ()> { Ok(reader) };
-///
-/// let debug_info: DebugInfo<_> = Section::load(loader).unwrap();
-/// ```
-pub trait Section<R>: From<R> {
- /// Returns the section id for this type.
- fn id() -> SectionId;
-
- /// Returns the ELF section name for this type.
- fn section_name() -> &'static str {
- Self::id().name()
- }
-
- /// Returns the ELF section name (if any) for this type when used in a dwo
- /// file.
- fn dwo_section_name() -> Option<&'static str> {
- Self::id().dwo_name()
- }
-
- /// Returns the XCOFF section name (if any) for this type when used in a XCOFF
- /// file.
- fn xcoff_section_name() -> Option<&'static str> {
- Self::id().xcoff_name()
- }
-
- /// Try to load the section using the given loader function.
- fn load<F, E>(f: F) -> core::result::Result<Self, E>
- where
- F: FnOnce(SectionId) -> core::result::Result<R, E>,
- {
- f(Self::id()).map(From::from)
- }
-
- /// Returns the `Reader` for this section.
- fn reader(&self) -> &R
- where
- R: Reader;
-
- /// Returns the subrange of the section that is the contribution of
- /// a unit in a `.dwp` file.
- fn dwp_range(&self, offset: u32, size: u32) -> Result<Self>
- where
- R: Reader,
- {
- let mut data = self.reader().clone();
- data.skip(R::Offset::from_u32(offset))?;
- data.truncate(R::Offset::from_u32(size))?;
- Ok(data.into())
- }
-
- /// Returns the `Reader` for this section.
- fn lookup_offset_id(&self, id: ReaderOffsetId) -> Option<(SectionId, R::Offset)>
- where
- R: Reader,
- {
- self.reader()
- .lookup_offset_id(id)
- .map(|offset| (Self::id(), offset))
- }
-}
-
-impl Register {
- pub(crate) fn from_u64(x: u64) -> Result<Register> {
- let y = x as u16;
- if u64::from(y) == x {
- Ok(Register(y))
- } else {
- Err(Error::UnsupportedRegister(x))
- }
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use crate::common::Format;
- use crate::endianity::LittleEndian;
- use test_assembler::{Endian, Section};
-
- #[test]
- fn test_parse_initial_length_32_ok() {
- let section = Section::with_endian(Endian::Little).L32(0x7856_3412);
- let buf = section.get_contents().unwrap();
-
- let input = &mut EndianSlice::new(&buf, LittleEndian);
- match input.read_initial_length() {
- Ok((length, format)) => {
- assert_eq!(input.len(), 0);
- assert_eq!(format, Format::Dwarf32);
- assert_eq!(0x7856_3412, length);
- }
- otherwise => panic!("Unexpected result: {:?}", otherwise),
- }
- }
-
- #[test]
- fn test_parse_initial_length_64_ok() {
- let section = Section::with_endian(Endian::Little)
- // Dwarf_64_INITIAL_UNIT_LENGTH
- .L32(0xffff_ffff)
- // Actual length
- .L64(0xffde_bc9a_7856_3412);
- let buf = section.get_contents().unwrap();
- let input = &mut EndianSlice::new(&buf, LittleEndian);
-
- #[cfg(target_pointer_width = "64")]
- match input.read_initial_length() {
- Ok((length, format)) => {
- assert_eq!(input.len(), 0);
- assert_eq!(format, Format::Dwarf64);
- assert_eq!(0xffde_bc9a_7856_3412, length);
- }
- otherwise => panic!("Unexpected result: {:?}", otherwise),
- }
-
- #[cfg(target_pointer_width = "32")]
- match input.read_initial_length() {
- Err(Error::UnsupportedOffset) => {}
- otherwise => panic!("Unexpected result: {:?}", otherwise),
- };
- }
-
- #[test]
- fn test_parse_initial_length_unknown_reserved_value() {
- let section = Section::with_endian(Endian::Little).L32(0xffff_fffe);
- let buf = section.get_contents().unwrap();
-
- let input = &mut EndianSlice::new(&buf, LittleEndian);
- match input.read_initial_length() {
- Err(Error::UnknownReservedLength) => assert!(true),
- otherwise => panic!("Unexpected result: {:?}", otherwise),
- };
- }
-
- #[test]
- fn test_parse_initial_length_incomplete() {
- let buf = [0xff, 0xff, 0xff]; // Need at least 4 bytes.
-
- let input = &mut EndianSlice::new(&buf, LittleEndian);
- match input.read_initial_length() {
- Err(Error::UnexpectedEof(_)) => assert!(true),
- otherwise => panic!("Unexpected result: {:?}", otherwise),
- };
- }
-
- #[test]
- fn test_parse_initial_length_64_incomplete() {
- let section = Section::with_endian(Endian::Little)
- // Dwarf_64_INITIAL_UNIT_LENGTH
- .L32(0xffff_ffff)
- // Actual length is not long enough.
- .L32(0x7856_3412);
- let buf = section.get_contents().unwrap();
-
- let input = &mut EndianSlice::new(&buf, LittleEndian);
- match input.read_initial_length() {
- Err(Error::UnexpectedEof(_)) => assert!(true),
- otherwise => panic!("Unexpected result: {:?}", otherwise),
- };
- }
-
- #[test]
- fn test_parse_offset_32() {
- let section = Section::with_endian(Endian::Little).L32(0x0123_4567);
- let buf = section.get_contents().unwrap();
-
- let input = &mut EndianSlice::new(&buf, LittleEndian);
- match input.read_offset(Format::Dwarf32) {
- Ok(val) => {
- assert_eq!(input.len(), 0);
- assert_eq!(val, 0x0123_4567);
- }
- otherwise => panic!("Unexpected result: {:?}", otherwise),
- };
- }
-
- #[test]
- fn test_parse_offset_64_small() {
- let section = Section::with_endian(Endian::Little).L64(0x0123_4567);
- let buf = section.get_contents().unwrap();
-
- let input = &mut EndianSlice::new(&buf, LittleEndian);
- match input.read_offset(Format::Dwarf64) {
- Ok(val) => {
- assert_eq!(input.len(), 0);
- assert_eq!(val, 0x0123_4567);
- }
- otherwise => panic!("Unexpected result: {:?}", otherwise),
- };
- }
-
- #[test]
- #[cfg(target_pointer_width = "64")]
- fn test_parse_offset_64_large() {
- let section = Section::with_endian(Endian::Little).L64(0x0123_4567_89ab_cdef);
- let buf = section.get_contents().unwrap();
-
- let input = &mut EndianSlice::new(&buf, LittleEndian);
- match input.read_offset(Format::Dwarf64) {
- Ok(val) => {
- assert_eq!(input.len(), 0);
- assert_eq!(val, 0x0123_4567_89ab_cdef);
- }
- otherwise => panic!("Unexpected result: {:?}", otherwise),
- };
- }
-
- #[test]
- #[cfg(target_pointer_width = "32")]
- fn test_parse_offset_64_large() {
- let section = Section::with_endian(Endian::Little).L64(0x0123_4567_89ab_cdef);
- let buf = section.get_contents().unwrap();
-
- let input = &mut EndianSlice::new(&buf, LittleEndian);
- match input.read_offset(Format::Dwarf64) {
- Err(Error::UnsupportedOffset) => assert!(true),
- otherwise => panic!("Unexpected result: {:?}", otherwise),
- };
- }
-}