//! Functions for parsing DWARF `.debug_info` and `.debug_types` sections.

use core::cell::Cell;
use core::ops::{Range, RangeFrom, RangeTo};
use core::{u16, u8};

use crate::common::{
    DebugAbbrevOffset, DebugAddrBase, DebugAddrIndex, DebugInfoOffset, DebugLineOffset,
    DebugLineStrOffset, DebugLocListsBase, DebugLocListsIndex, DebugMacinfoOffset,
    DebugMacroOffset, DebugRngListsBase, DebugRngListsIndex, DebugStrOffset, DebugStrOffsetsBase,
    DebugStrOffsetsIndex, DebugTypeSignature, DebugTypesOffset, DwoId, Encoding, Format,
    LocationListsOffset, RawRangeListsOffset, SectionId, UnitSectionOffset,
};
use crate::constants;
use crate::endianity::Endianity;
use crate::read::abbrev::get_attribute_size;
use crate::read::{
    Abbreviation, Abbreviations, AttributeSpecification, DebugAbbrev, DebugStr, EndianSlice, Error,
    Expression, Reader, ReaderOffset, Result, Section, UnitOffset,
};

impl<T: ReaderOffset> DebugTypesOffset<T> {
    /// Convert an offset to be relative to the start of the given unit,
    /// instead of relative to the start of the .debug_types section.
    /// Returns `None` if the offset is not within the unit entries.
    pub fn to_unit_offset<R>(&self, unit: &UnitHeader<R>) -> Option<UnitOffset<T>>
    where
        R: Reader<Offset = T>,
    {
        let unit_offset = unit.offset().as_debug_types_offset()?;
        let offset = UnitOffset(self.0.checked_sub(unit_offset.0)?);
        if !unit.is_valid_offset(offset) {
            return None;
        }
        Some(offset)
    }
}

impl<T: ReaderOffset> DebugInfoOffset<T> {
    /// Convert an offset to be relative to the start of the given unit,
    /// instead of relative to the start of the .debug_info section.
    /// Returns `None` if the offset is not within this unit entries.
    pub fn to_unit_offset<R>(&self, unit: &UnitHeader<R>) -> Option<UnitOffset<T>>
    where
        R: Reader<Offset = T>,
    {
        let unit_offset = unit.offset().as_debug_info_offset()?;
        let offset = UnitOffset(self.0.checked_sub(unit_offset.0)?);
        if !unit.is_valid_offset(offset) {
            return None;
        }
        Some(offset)
    }
}

impl<T: ReaderOffset> UnitOffset<T> {
    /// Convert an offset to be relative to the start of the .debug_info section,
    /// instead of relative to the start of the given unit. Returns None if the
    /// provided unit lives in the .debug_types section.
    pub fn to_debug_info_offset<R>(&self, unit: &UnitHeader<R>) -> Option<DebugInfoOffset<T>>
    where
        R: Reader<Offset = T>,
    {
        let unit_offset = unit.offset().as_debug_info_offset()?;
        Some(DebugInfoOffset(unit_offset.0 + self.0))
    }

    /// Convert an offset to be relative to the start of the .debug_types section,
    /// instead of relative to the start of the given unit. Returns None if the
    /// provided unit lives in the .debug_info section.
    pub fn to_debug_types_offset<R>(&self, unit: &UnitHeader<R>) -> Option<DebugTypesOffset<T>>
    where
        R: Reader<Offset = T>,
    {
        let unit_offset = unit.offset().as_debug_types_offset()?;
        Some(DebugTypesOffset(unit_offset.0 + self.0))
    }
}

/// The `DebugInfo` struct represents the DWARF debugging information found in
/// the `.debug_info` section.
#[derive(Debug, Default, Clone, Copy)]
pub struct DebugInfo<R> {
    debug_info_section: R,
}

impl<'input, Endian> DebugInfo<EndianSlice<'input, Endian>>
where
    Endian: Endianity,
{
    /// Construct a new `DebugInfo` instance from the data in the `.debug_info`
    /// section.
    ///
    /// It is the caller's responsibility to read the `.debug_info` section and
    /// present it as a `&[u8]` slice. That means using some ELF loader on
    /// Linux, a Mach-O loader on macOS, etc.
    ///
    /// ```
    /// use gimli::{DebugInfo, LittleEndian};
    ///
    /// # let buf = [0x00, 0x01, 0x02, 0x03];
    /// # let read_debug_info_section_somehow = || &buf;
    /// let debug_info = DebugInfo::new(read_debug_info_section_somehow(), LittleEndian);
    /// ```
    pub fn new(debug_info_section: &'input [u8], endian: Endian) -> Self {
        Self::from(EndianSlice::new(debug_info_section, endian))
    }
}

impl<R: Reader> DebugInfo<R> {
    /// Iterate the units in this `.debug_info` section.
    ///
    /// ```
    /// use gimli::{DebugInfo, LittleEndian};
    ///
    /// # let buf = [];
    /// # let read_debug_info_section_somehow = || &buf;
    /// let debug_info = DebugInfo::new(read_debug_info_section_somehow(), LittleEndian);
    ///
    /// let mut iter = debug_info.units();
    /// while let Some(unit) = iter.next().unwrap() {
    ///     println!("unit's length is {}", unit.unit_length());
    /// }
    /// ```
    ///
    /// Can be [used with
    /// `FallibleIterator`](./index.html#using-with-fallibleiterator).
    pub fn units(&self) -> DebugInfoUnitHeadersIter<R> {
        DebugInfoUnitHeadersIter {
            input: self.debug_info_section.clone(),
            offset: DebugInfoOffset(R::Offset::from_u8(0)),
        }
    }

    /// Get the UnitHeader located at offset from this .debug_info section.
    ///
    ///
    pub fn header_from_offset(&self, offset: DebugInfoOffset<R::Offset>) -> Result<UnitHeader<R>> {
        let input = &mut self.debug_info_section.clone();
        input.skip(offset.0)?;
        parse_unit_header(input, offset.into())
    }
}

impl<T> DebugInfo<T> {
    /// Create a `DebugInfo` section that references the data in `self`.
    ///
    /// This is useful when `R` implements `Reader` but `T` does not.
    ///
    /// ## Example Usage
    ///
    /// ```rust,no_run
    /// # let load_section = || unimplemented!();
    /// // Read the DWARF section into a `Vec` with whatever object loader you're using.
    /// let owned_section: gimli::DebugInfo<Vec<u8>> = load_section();
    /// // Create a reference to the DWARF section.
    /// let section = owned_section.borrow(|section| {
    ///     gimli::EndianSlice::new(&section, gimli::LittleEndian)
    /// });
    /// ```
    pub fn borrow<'a, F, R>(&'a self, mut borrow: F) -> DebugInfo<R>
    where
        F: FnMut(&'a T) -> R,
    {
        borrow(&self.debug_info_section).into()
    }
}

impl<R> Section<R> for DebugInfo<R> {
    fn id() -> SectionId {
        SectionId::DebugInfo
    }

    fn reader(&self) -> &R {
        &self.debug_info_section
    }
}

impl<R> From<R> for DebugInfo<R> {
    fn from(debug_info_section: R) -> Self {
        DebugInfo { debug_info_section }
    }
}

/// An iterator over the units of a .debug_info section.
///
/// See the [documentation on
/// `DebugInfo::units`](./struct.DebugInfo.html#method.units) for more detail.
#[derive(Clone, Debug)]
pub struct DebugInfoUnitHeadersIter<R: Reader> {
    input: R,
    offset: DebugInfoOffset<R::Offset>,
}

impl<R: Reader> DebugInfoUnitHeadersIter<R> {
    /// Advance the iterator to the next unit header.
    pub fn next(&mut self) -> Result<Option<UnitHeader<R>>> {
        if self.input.is_empty() {
            Ok(None)
        } else {
            let len = self.input.len();
            match parse_unit_header(&mut self.input, self.offset.into()) {
                Ok(header) => {
                    self.offset.0 += len - self.input.len();
                    Ok(Some(header))
                }
                Err(e) => {
                    self.input.empty();
                    Err(e)
                }
            }
        }
    }
}

#[cfg(feature = "fallible-iterator")]
impl<R: Reader> fallible_iterator::FallibleIterator for DebugInfoUnitHeadersIter<R> {
    type Item = UnitHeader<R>;
    type Error = Error;

    fn next(&mut self) -> ::core::result::Result<Option<Self::Item>, Self::Error> {
        DebugInfoUnitHeadersIter::next(self)
    }
}

/// Parse the unit type from the unit header.
fn parse_unit_type<R: Reader>(input: &mut R) -> Result<constants::DwUt> {
    let val = input.read_u8()?;
    Ok(constants::DwUt(val))
}

/// Parse the `debug_abbrev_offset` in the compilation unit header.
fn parse_debug_abbrev_offset<R: Reader>(
    input: &mut R,
    format: Format,
) -> Result<DebugAbbrevOffset<R::Offset>> {
    input.read_offset(format).map(DebugAbbrevOffset)
}

/// Parse the `debug_info_offset` in the arange header.
pub(crate) fn parse_debug_info_offset<R: Reader>(
    input: &mut R,
    format: Format,
) -> Result<DebugInfoOffset<R::Offset>> {
    input.read_offset(format).map(DebugInfoOffset)
}

/// This enum specifies the type of the unit and any type
/// specific data carried in the header (e.g. the type
/// signature/type offset of a type unit).
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum UnitType<Offset>
where
    Offset: ReaderOffset,
{
    /// In DWARF5, a unit with type `DW_UT_compile`. In previous DWARF versions,
    /// any unit appearing in the .debug_info section.
    Compilation,
    /// In DWARF5, a unit with type `DW_UT_type`. In DWARF4, any unit appearing
    /// in the .debug_types section.
    Type {
        /// The unique type signature for this type unit.
        type_signature: DebugTypeSignature,
        /// The offset within this type unit where the type is defined.
        type_offset: UnitOffset<Offset>,
    },
    /// A unit with type `DW_UT_partial`. The root DIE of this unit should be a
    /// `DW_TAG_partial_unit`.
    Partial,
    /// A unit with type `DW_UT_skeleton`. The enclosed dwo_id can be used to
    /// link this with the corresponding `SplitCompilation` unit in a dwo file.
    /// NB: The non-standard GNU split DWARF extension to DWARF 4 will instead
    /// be a `Compilation` unit with the dwo_id present as an attribute on the
    /// root DIE.
    Skeleton(DwoId),
    /// A unit with type `DW_UT_split_compile`. The enclosed dwo_id can be used to
    /// link this with the corresponding `Skeleton` unit in the original binary.
    /// NB: The non-standard GNU split DWARF extension to DWARF 4 will instead
    /// be a `Compilation` unit with the dwo_id present as an attribute on the
    /// root DIE.
    SplitCompilation(DwoId),
    /// A unit with type `DW_UT_split_type`. A split type unit is identical to a
    /// conventional type unit except for the section in which it appears.
    SplitType {
        /// The unique type signature for this type unit.
        type_signature: DebugTypeSignature,
        /// The offset within this type unit where the type is defined.
        type_offset: UnitOffset<Offset>,
    },
}

impl<Offset> UnitType<Offset>
where
    Offset: ReaderOffset,
{
    // TODO: This will be used by the DWARF writing code once it
    // supports unit types other than simple compilation units.
    #[allow(unused)]
    pub(crate) fn dw_ut(&self) -> constants::DwUt {
        match self {
            UnitType::Compilation => constants::DW_UT_compile,
            UnitType::Type { .. } => constants::DW_UT_type,
            UnitType::Partial => constants::DW_UT_partial,
            UnitType::Skeleton(_) => constants::DW_UT_skeleton,
            UnitType::SplitCompilation(_) => constants::DW_UT_split_compile,
            UnitType::SplitType { .. } => constants::DW_UT_split_type,
        }
    }
}

/// The common fields for the headers of compilation units and
/// type units.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct UnitHeader<R, Offset = <R as Reader>::Offset>
where
    R: Reader<Offset = Offset>,
    Offset: ReaderOffset,
{
    encoding: Encoding,
    unit_length: Offset,
    unit_type: UnitType<Offset>,
    debug_abbrev_offset: DebugAbbrevOffset<Offset>,
    unit_offset: UnitSectionOffset<Offset>,
    entries_buf: R,
}

/// Static methods.
impl<R, Offset> UnitHeader<R, Offset>
where
    R: Reader<Offset = Offset>,
    Offset: ReaderOffset,
{
    /// Construct a new `UnitHeader`.
    pub fn new(
        encoding: Encoding,
        unit_length: Offset,
        unit_type: UnitType<Offset>,
        debug_abbrev_offset: DebugAbbrevOffset<Offset>,
        unit_offset: UnitSectionOffset<Offset>,
        entries_buf: R,
    ) -> Self {
        UnitHeader {
            encoding,
            unit_length,
            unit_type,
            debug_abbrev_offset,
            unit_offset,
            entries_buf,
        }
    }
}

/// Instance methods.
impl<R, Offset> UnitHeader<R, Offset>
where
    R: Reader<Offset = Offset>,
    Offset: ReaderOffset,
{
    /// Get the offset of this unit within its section.
    pub fn offset(&self) -> UnitSectionOffset<Offset> {
        self.unit_offset
    }

    /// Return the serialized size of the common unit header for the given
    /// DWARF format.
    pub fn size_of_header(&self) -> usize {
        let unit_length_size = self.encoding.format.initial_length_size() as usize;
        let version_size = 2;
        let debug_abbrev_offset_size = self.encoding.format.word_size() as usize;
        let address_size_size = 1;
        let unit_type_size = if self.encoding.version == 5 { 1 } else { 0 };
        let type_specific_size = match self.unit_type {
            UnitType::Compilation | UnitType::Partial => 0,
            UnitType::Type { .. } | UnitType::SplitType { .. } => {
                let type_signature_size = 8;
                let type_offset_size = self.encoding.format.word_size() as usize;
                type_signature_size + type_offset_size
            }
            UnitType::Skeleton(_) | UnitType::SplitCompilation(_) => 8,
        };

        unit_length_size
            + version_size
            + debug_abbrev_offset_size
            + address_size_size
            + unit_type_size
            + type_specific_size
    }

    /// Get the length of the debugging info for this compilation unit, not
    /// including the byte length of the encoded length itself.
    pub fn unit_length(&self) -> Offset {
        self.unit_length
    }

    /// Get the length of the debugging info for this compilation unit,
    /// including the byte length of the encoded length itself.
    pub fn length_including_self(&self) -> Offset {
        Offset::from_u8(self.format().initial_length_size()) + self.unit_length
    }

    /// Return the encoding parameters for this unit.
    pub fn encoding(&self) -> Encoding {
        self.encoding
    }

    /// Get the DWARF version of the debugging info for this compilation unit.
    pub fn version(&self) -> u16 {
        self.encoding.version
    }

    /// Get the UnitType of this unit.
    pub fn type_(&self) -> UnitType<Offset> {
        self.unit_type
    }

    /// The offset into the `.debug_abbrev` section for this compilation unit's
    /// debugging information entries' abbreviations.
    pub fn debug_abbrev_offset(&self) -> DebugAbbrevOffset<Offset> {
        self.debug_abbrev_offset
    }

    /// The size of addresses (in bytes) in this compilation unit.
    pub fn address_size(&self) -> u8 {
        self.encoding.address_size
    }

    /// Whether this compilation unit is encoded in 64- or 32-bit DWARF.
    pub fn format(&self) -> Format {
        self.encoding.format
    }

    /// The serialized size of the header for this compilation unit.
    pub fn header_size(&self) -> Offset {
        self.length_including_self() - self.entries_buf.len()
    }

    pub(crate) fn is_valid_offset(&self, offset: UnitOffset<Offset>) -> bool {
        let size_of_header = self.header_size();
        if offset.0 < size_of_header {
            return false;
        }

        let relative_to_entries_buf = offset.0 - size_of_header;
        relative_to_entries_buf < self.entries_buf.len()
    }

    /// Get the underlying bytes for the supplied range.
    pub fn range(&self, idx: Range<UnitOffset<Offset>>) -> Result<R> {
        if !self.is_valid_offset(idx.start) {
            return Err(Error::OffsetOutOfBounds);
        }
        if !self.is_valid_offset(idx.end) {
            return Err(Error::OffsetOutOfBounds);
        }
        assert!(idx.start <= idx.end);
        let size_of_header = self.header_size();
        let start = idx.start.0 - size_of_header;
        let end = idx.end.0 - size_of_header;
        let mut input = self.entries_buf.clone();
        input.skip(start)?;
        input.truncate(end - start)?;
        Ok(input)
    }

    /// Get the underlying bytes for the supplied range.
    pub fn range_from(&self, idx: RangeFrom<UnitOffset<Offset>>) -> Result<R> {
        if !self.is_valid_offset(idx.start) {
            return Err(Error::OffsetOutOfBounds);
        }
        let start = idx.start.0 - self.header_size();
        let mut input = self.entries_buf.clone();
        input.skip(start)?;
        Ok(input)
    }

    /// Get the underlying bytes for the supplied range.
    pub fn range_to(&self, idx: RangeTo<UnitOffset<Offset>>) -> Result<R> {
        if !self.is_valid_offset(idx.end) {
            return Err(Error::OffsetOutOfBounds);
        }
        let end = idx.end.0 - self.header_size();
        let mut input = self.entries_buf.clone();
        input.truncate(end)?;
        Ok(input)
    }

    /// Read the `DebuggingInformationEntry` at the given offset.
    pub fn entry<'me, 'abbrev>(
        &'me self,
        abbreviations: &'abbrev Abbreviations,
        offset: UnitOffset<Offset>,
    ) -> Result<DebuggingInformationEntry<'abbrev, 'me, R>> {
        let mut input = self.range_from(offset..)?;
        let entry = DebuggingInformationEntry::parse(&mut input, self, abbreviations)?;
        entry.ok_or(Error::NoEntryAtGivenOffset)
    }

    /// Navigate this unit's `DebuggingInformationEntry`s.
    pub fn entries<'me, 'abbrev>(
        &'me self,
        abbreviations: &'abbrev Abbreviations,
    ) -> EntriesCursor<'abbrev, 'me, R> {
        EntriesCursor {
            unit: self,
            input: self.entries_buf.clone(),
            abbreviations,
            cached_current: None,
            delta_depth: 0,
        }
    }

    /// Navigate this compilation unit's `DebuggingInformationEntry`s
    /// starting at the given offset.
    pub fn entries_at_offset<'me, 'abbrev>(
        &'me self,
        abbreviations: &'abbrev Abbreviations,
        offset: UnitOffset<Offset>,
    ) -> Result<EntriesCursor<'abbrev, 'me, R>> {
        let input = self.range_from(offset..)?;
        Ok(EntriesCursor {
            unit: self,
            input,
            abbreviations,
            cached_current: None,
            delta_depth: 0,
        })
    }

    /// Navigate this unit's `DebuggingInformationEntry`s as a tree
    /// starting at the given offset.
    pub fn entries_tree<'me, 'abbrev>(
        &'me self,
        abbreviations: &'abbrev Abbreviations,
        offset: Option<UnitOffset<Offset>>,
    ) -> Result<EntriesTree<'abbrev, 'me, R>> {
        let input = match offset {
            Some(offset) => self.range_from(offset..)?,
            None => self.entries_buf.clone(),
        };
        Ok(EntriesTree::new(input, self, abbreviations))
    }

    /// Read the raw data that defines the Debugging Information Entries.
    pub fn entries_raw<'me, 'abbrev>(
        &'me self,
        abbreviations: &'abbrev Abbreviations,
        offset: Option<UnitOffset<Offset>>,
    ) -> Result<EntriesRaw<'abbrev, 'me, R>> {
        let input = match offset {
            Some(offset) => self.range_from(offset..)?,
            None => self.entries_buf.clone(),
        };
        Ok(EntriesRaw {
            input,
            unit: self,
            abbreviations,
            depth: 0,
        })
    }

    /// Parse this unit's abbreviations.
    pub fn abbreviations(&self, debug_abbrev: &DebugAbbrev<R>) -> Result<Abbreviations> {
        debug_abbrev.abbreviations(self.debug_abbrev_offset())
    }
}

/// Parse a unit header.
fn parse_unit_header<R, Offset>(
    input: &mut R,
    unit_offset: UnitSectionOffset<Offset>,
) -> Result<UnitHeader<R>>
where
    R: Reader<Offset = Offset>,
    Offset: ReaderOffset,
{
    let (unit_length, format) = input.read_initial_length()?;
    let mut rest = input.split(unit_length)?;

    let version = rest.read_u16()?;
    let abbrev_offset;
    let address_size;
    let unit_type;
    // DWARF 1 was very different, and is obsolete, so isn't supported by this
    // reader.
    if 2 <= version && version <= 4 {
        abbrev_offset = parse_debug_abbrev_offset(&mut rest, format)?;
        address_size = rest.read_u8()?;
        // Before DWARF5, all units in the .debug_info section are compilation
        // units, and all units in the .debug_types section are type units.
        unit_type = match unit_offset {
            UnitSectionOffset::DebugInfoOffset(_) => constants::DW_UT_compile,
            UnitSectionOffset::DebugTypesOffset(_) => constants::DW_UT_type,
        };
    } else if version == 5 {
        unit_type = parse_unit_type(&mut rest)?;
        address_size = rest.read_u8()?;
        abbrev_offset = parse_debug_abbrev_offset(&mut rest, format)?;
    } else {
        return Err(Error::UnknownVersion(u64::from(version)));
    }
    let encoding = Encoding {
        format,
        version,
        address_size,
    };

    // Parse any data specific to this type of unit.
    let unit_type = match unit_type {
        constants::DW_UT_compile => UnitType::Compilation,
        constants::DW_UT_type => {
            let type_signature = parse_type_signature(&mut rest)?;
            let type_offset = parse_type_offset(&mut rest, format)?;
            UnitType::Type {
                type_signature,
                type_offset,
            }
        }
        constants::DW_UT_partial => UnitType::Partial,
        constants::DW_UT_skeleton => {
            let dwo_id = parse_dwo_id(&mut rest)?;
            UnitType::Skeleton(dwo_id)
        }
        constants::DW_UT_split_compile => {
            let dwo_id = parse_dwo_id(&mut rest)?;
            UnitType::SplitCompilation(dwo_id)
        }
        constants::DW_UT_split_type => {
            let type_signature = parse_type_signature(&mut rest)?;
            let type_offset = parse_type_offset(&mut rest, format)?;
            UnitType::SplitType {
                type_signature,
                type_offset,
            }
        }
        _ => return Err(Error::UnsupportedUnitType),
    };

    Ok(UnitHeader::new(
        encoding,
        unit_length,
        unit_type,
        abbrev_offset,
        unit_offset,
        rest,
    ))
}

/// Parse a dwo_id from a header
fn parse_dwo_id<R: Reader>(input: &mut R) -> Result<DwoId> {
    Ok(DwoId(input.read_u64()?))
}

/// A Debugging Information Entry (DIE).
///
/// DIEs have a set of attributes and optionally have children DIEs as well.
#[derive(Clone, Debug)]
pub struct DebuggingInformationEntry<'abbrev, 'unit, R, Offset = <R as Reader>::Offset>
where
    R: Reader<Offset = Offset>,
    Offset: ReaderOffset,
{
    offset: UnitOffset<Offset>,
    attrs_slice: R,
    attrs_len: Cell<Option<Offset>>,
    abbrev: &'abbrev Abbreviation,
    unit: &'unit UnitHeader<R, Offset>,
}

impl<'abbrev, 'unit, R, Offset> DebuggingInformationEntry<'abbrev, 'unit, R, Offset>
where
    R: Reader<Offset = Offset>,
    Offset: ReaderOffset,
{
    /// Construct a new `DebuggingInformationEntry`.
    pub fn new(
        offset: UnitOffset<Offset>,
        attrs_slice: R,
        abbrev: &'abbrev Abbreviation,
        unit: &'unit UnitHeader<R, Offset>,
    ) -> Self {
        DebuggingInformationEntry {
            offset,
            attrs_slice,
            attrs_len: Cell::new(None),
            abbrev,
            unit,
        }
    }

    /// Get this entry's code.
    pub fn code(&self) -> u64 {
        self.abbrev.code()
    }

    /// Get this entry's offset.
    pub fn offset(&self) -> UnitOffset<Offset> {
        self.offset
    }

    /// Get this entry's `DW_TAG_whatever` tag.
    ///
    /// ```
    /// # use gimli::{DebugAbbrev, DebugInfo, LittleEndian};
    /// # let info_buf = [
    /// #     // Comilation unit header
    /// #
    /// #     // 32-bit unit length = 12
    /// #     0x0c, 0x00, 0x00, 0x00,
    /// #     // Version 4
    /// #     0x04, 0x00,
    /// #     // debug_abbrev_offset
    /// #     0x00, 0x00, 0x00, 0x00,
    /// #     // Address size
    /// #     0x04,
    /// #
    /// #     // DIEs
    /// #
    /// #     // Abbreviation code
    /// #     0x01,
    /// #     // Attribute of form DW_FORM_string = "foo\0"
    /// #     0x66, 0x6f, 0x6f, 0x00,
    /// # ];
    /// # let debug_info = DebugInfo::new(&info_buf, LittleEndian);
    /// # let abbrev_buf = [
    /// #     // Code
    /// #     0x01,
    /// #     // DW_TAG_subprogram
    /// #     0x2e,
    /// #     // DW_CHILDREN_no
    /// #     0x00,
    /// #     // Begin attributes
    /// #       // Attribute name = DW_AT_name
    /// #       0x03,
    /// #       // Attribute form = DW_FORM_string
    /// #       0x08,
    /// #     // End attributes
    /// #     0x00,
    /// #     0x00,
    /// #     // Null terminator
    /// #     0x00
    /// # ];
    /// # let debug_abbrev = DebugAbbrev::new(&abbrev_buf, LittleEndian);
    /// # let unit = debug_info.units().next().unwrap().unwrap();
    /// # let abbrevs = unit.abbreviations(&debug_abbrev).unwrap();
    /// # let mut cursor = unit.entries(&abbrevs);
    /// # let (_, entry) = cursor.next_dfs().unwrap().unwrap();
    /// # let mut get_some_entry = || entry;
    /// let entry = get_some_entry();
    ///
    /// match entry.tag() {
    ///     gimli::DW_TAG_subprogram =>
    ///         println!("this entry contains debug info about a function"),
    ///     gimli::DW_TAG_inlined_subroutine =>
    ///         println!("this entry contains debug info about a particular instance of inlining"),
    ///     gimli::DW_TAG_variable =>
    ///         println!("this entry contains debug info about a local variable"),
    ///     gimli::DW_TAG_formal_parameter =>
    ///         println!("this entry contains debug info about a function parameter"),
    ///     otherwise =>
    ///         println!("this entry is some other kind of data: {:?}", otherwise),
    /// };
    /// ```
    pub fn tag(&self) -> constants::DwTag {
        self.abbrev.tag()
    }

    /// Return true if this entry's type can have children, false otherwise.
    pub fn has_children(&self) -> bool {
        self.abbrev.has_children()
    }

    /// Iterate over this entry's set of attributes.
    ///
    /// ```
    /// use gimli::{DebugAbbrev, DebugInfo, LittleEndian};
    ///
    /// // Read the `.debug_info` section.
    ///
    /// # let info_buf = [
    /// #     // Comilation unit header
    /// #
    /// #     // 32-bit unit length = 12
    /// #     0x0c, 0x00, 0x00, 0x00,
    /// #     // Version 4
    /// #     0x04, 0x00,
    /// #     // debug_abbrev_offset
    /// #     0x00, 0x00, 0x00, 0x00,
    /// #     // Address size
    /// #     0x04,
    /// #
    /// #     // DIEs
    /// #
    /// #     // Abbreviation code
    /// #     0x01,
    /// #     // Attribute of form DW_FORM_string = "foo\0"
    /// #     0x66, 0x6f, 0x6f, 0x00,
    /// # ];
    /// # let read_debug_info_section_somehow = || &info_buf;
    /// let debug_info = DebugInfo::new(read_debug_info_section_somehow(), LittleEndian);
    ///
    /// // Get the data about the first compilation unit out of the `.debug_info`.
    ///
    /// let unit = debug_info.units().next()
    ///     .expect("Should have at least one compilation unit")
    ///     .expect("and it should parse ok");
    ///
    /// // Read the `.debug_abbrev` section and parse the
    /// // abbreviations for our compilation unit.
    ///
    /// # let abbrev_buf = [
    /// #     // Code
    /// #     0x01,
    /// #     // DW_TAG_subprogram
    /// #     0x2e,
    /// #     // DW_CHILDREN_no
    /// #     0x00,
    /// #     // Begin attributes
    /// #       // Attribute name = DW_AT_name
    /// #       0x03,
    /// #       // Attribute form = DW_FORM_string
    /// #       0x08,
    /// #     // End attributes
    /// #     0x00,
    /// #     0x00,
    /// #     // Null terminator
    /// #     0x00
    /// # ];
    /// # let read_debug_abbrev_section_somehow = || &abbrev_buf;
    /// let debug_abbrev = DebugAbbrev::new(read_debug_abbrev_section_somehow(), LittleEndian);
    /// let abbrevs = unit.abbreviations(&debug_abbrev).unwrap();
    ///
    /// // Get the first entry from that compilation unit.
    ///
    /// let mut cursor = unit.entries(&abbrevs);
    /// let (_, entry) = cursor.next_dfs()
    ///     .expect("Should parse next entry")
    ///     .expect("Should have at least one entry");
    ///
    /// // Finally, print the first entry's attributes.
    ///
    /// let mut attrs = entry.attrs();
    /// while let Some(attr) = attrs.next().unwrap() {
    ///     println!("Attribute name = {:?}", attr.name());
    ///     println!("Attribute value = {:?}", attr.value());
    /// }
    /// ```
    ///
    /// Can be [used with
    /// `FallibleIterator`](./index.html#using-with-fallibleiterator).
    pub fn attrs<'me>(&'me self) -> AttrsIter<'abbrev, 'me, 'unit, R> {
        AttrsIter {
            input: self.attrs_slice.clone(),
            attributes: self.abbrev.attributes(),
            entry: self,
        }
    }

    /// Find the first attribute in this entry which has the given name,
    /// and return it. Returns `Ok(None)` if no attribute is found.
    pub fn attr(&self, name: constants::DwAt) -> Result<Option<Attribute<R>>> {
        let mut attrs = self.attrs();
        while let Some(attr) = attrs.next()? {
            if attr.name() == name {
                return Ok(Some(attr));
            }
        }
        Ok(None)
    }

    /// Find the first attribute in this entry which has the given name,
    /// and return its raw value. Returns `Ok(None)` if no attribute is found.
    pub fn attr_value_raw(&self, name: constants::DwAt) -> Result<Option<AttributeValue<R>>> {
        self.attr(name)
            .map(|attr| attr.map(|attr| attr.raw_value()))
    }

    /// Find the first attribute in this entry which has the given name,
    /// and return its normalized value.  Returns `Ok(None)` if no
    /// attribute is found.
    pub fn attr_value(&self, name: constants::DwAt) -> Result<Option<AttributeValue<R>>> {
        self.attr(name).map(|attr| attr.map(|attr| attr.value()))
    }

    /// Return the input buffer after the last attribute.
    #[inline(always)]
    fn after_attrs(&self) -> Result<R> {
        if let Some(attrs_len) = self.attrs_len.get() {
            let mut input = self.attrs_slice.clone();
            input.skip(attrs_len)?;
            Ok(input)
        } else {
            let mut attrs = self.attrs();
            while attrs.next()?.is_some() {}
            Ok(attrs.input)
        }
    }

    /// Use the `DW_AT_sibling` attribute to find the input buffer for the
    /// next sibling. Returns `None` if the attribute is missing or invalid.
    fn sibling(&self) -> Option<R> {
        let attr = self.attr_value(constants::DW_AT_sibling);
        if let Ok(Some(AttributeValue::UnitRef(offset))) = attr {
            if offset.0 > self.offset.0 {
                if let Ok(input) = self.unit.range_from(offset..) {
                    return Some(input);
                }
            }
        }
        None
    }

    /// Parse an entry. Returns `Ok(None)` for null entries.
    #[inline(always)]
    fn parse(
        input: &mut R,
        unit: &'unit UnitHeader<R>,
        abbreviations: &'abbrev Abbreviations,
    ) -> Result<Option<Self>> {
        let offset = unit.header_size() + input.offset_from(&unit.entries_buf);
        let code = input.read_uleb128()?;
        if code == 0 {
            return Ok(None);
        };
        let abbrev = abbreviations.get(code).ok_or(Error::UnknownAbbreviation)?;
        Ok(Some(DebuggingInformationEntry {
            offset: UnitOffset(offset),
            attrs_slice: input.clone(),
            attrs_len: Cell::new(None),
            abbrev,
            unit,
        }))
    }
}

/// The value of an attribute in a `DebuggingInformationEntry`.
//
// Set the discriminant size so that all variants use the same alignment
// for their data.  This gives better code generation in `parse_attribute`.
#[repr(u64)]
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum AttributeValue<R, Offset = <R as Reader>::Offset>
where
    R: Reader<Offset = Offset>,
    Offset: ReaderOffset,
{
    /// "Refers to some location in the address space of the described program."
    Addr(u64),

    /// A slice of an arbitrary number of bytes.
    Block(R),

    /// A one byte constant data value. How to interpret the byte depends on context.
    ///
    /// From section 7 of the standard: "Depending on context, it may be a
    /// signed integer, an unsigned integer, a floating-point constant, or
    /// anything else."
    Data1(u8),

    /// A two byte constant data value. How to interpret the bytes depends on context.
    ///
    /// These bytes have been converted from `R::Endian`. This may need to be reversed
    /// if this was not required.
    ///
    /// From section 7 of the standard: "Depending on context, it may be a
    /// signed integer, an unsigned integer, a floating-point constant, or
    /// anything else."
    Data2(u16),

    /// A four byte constant data value. How to interpret the bytes depends on context.
    ///
    /// These bytes have been converted from `R::Endian`. This may need to be reversed
    /// if this was not required.
    ///
    /// From section 7 of the standard: "Depending on context, it may be a
    /// signed integer, an unsigned integer, a floating-point constant, or
    /// anything else."
    Data4(u32),

    /// An eight byte constant data value. How to interpret the bytes depends on context.
    ///
    /// These bytes have been converted from `R::Endian`. This may need to be reversed
    /// if this was not required.
    ///
    /// From section 7 of the standard: "Depending on context, it may be a
    /// signed integer, an unsigned integer, a floating-point constant, or
    /// anything else."
    Data8(u64),

    /// A signed integer constant.
    Sdata(i64),

    /// An unsigned integer constant.
    Udata(u64),

    /// "The information bytes contain a DWARF expression (see Section 2.5) or
    /// location description (see Section 2.6)."
    Exprloc(Expression<R>),

    /// A boolean that indicates presence or absence of the attribute.
    Flag(bool),

    /// An offset into another section. Which section this is an offset into
    /// depends on context.
    SecOffset(Offset),

    /// An offset to a set of addresses in the `.debug_addr` section.
    DebugAddrBase(DebugAddrBase<Offset>),

    /// An index into a set of addresses in the `.debug_addr` section.
    DebugAddrIndex(DebugAddrIndex<Offset>),

    /// An offset into the current compilation unit.
    UnitRef(UnitOffset<Offset>),

    /// An offset into the current `.debug_info` section, but possibly a
    /// different compilation unit from the current one.
    DebugInfoRef(DebugInfoOffset<Offset>),

    /// An offset into the `.debug_info` section of the supplementary object file.
    DebugInfoRefSup(DebugInfoOffset<Offset>),

    /// An offset into the `.debug_line` section.
    DebugLineRef(DebugLineOffset<Offset>),

    /// An offset into either the `.debug_loc` section or the `.debug_loclists` section.
    LocationListsRef(LocationListsOffset<Offset>),

    /// An offset to a set of offsets in the `.debug_loclists` section.
    DebugLocListsBase(DebugLocListsBase<Offset>),

    /// An index into a set of offsets in the `.debug_loclists` section.
    DebugLocListsIndex(DebugLocListsIndex<Offset>),

    /// An offset into the `.debug_macinfo` section.
    DebugMacinfoRef(DebugMacinfoOffset<Offset>),

    /// An offset into the `.debug_macro` section.
    DebugMacroRef(DebugMacroOffset<Offset>),

    /// An offset into the `.debug_ranges` section.
    RangeListsRef(RawRangeListsOffset<Offset>),

    /// An offset to a set of offsets in the `.debug_rnglists` section.
    DebugRngListsBase(DebugRngListsBase<Offset>),

    /// An index into a set of offsets in the `.debug_rnglists` section.
    DebugRngListsIndex(DebugRngListsIndex<Offset>),

    /// A type signature.
    DebugTypesRef(DebugTypeSignature),

    /// An offset into the `.debug_str` section.
    DebugStrRef(DebugStrOffset<Offset>),

    /// An offset into the `.debug_str` section of the supplementary object file.
    DebugStrRefSup(DebugStrOffset<Offset>),

    /// An offset to a set of entries in the `.debug_str_offsets` section.
    DebugStrOffsetsBase(DebugStrOffsetsBase<Offset>),

    /// An index into a set of entries in the `.debug_str_offsets` section.
    DebugStrOffsetsIndex(DebugStrOffsetsIndex<Offset>),

    /// An offset into the `.debug_line_str` section.
    DebugLineStrRef(DebugLineStrOffset<Offset>),

    /// A slice of bytes representing a string. Does not include a final null byte.
    /// Not guaranteed to be UTF-8 or anything like that.
    String(R),

    /// The value of a `DW_AT_encoding` attribute.
    Encoding(constants::DwAte),

    /// The value of a `DW_AT_decimal_sign` attribute.
    DecimalSign(constants::DwDs),

    /// The value of a `DW_AT_endianity` attribute.
    Endianity(constants::DwEnd),

    /// The value of a `DW_AT_accessibility` attribute.
    Accessibility(constants::DwAccess),

    /// The value of a `DW_AT_visibility` attribute.
    Visibility(constants::DwVis),

    /// The value of a `DW_AT_virtuality` attribute.
    Virtuality(constants::DwVirtuality),

    /// The value of a `DW_AT_language` attribute.
    Language(constants::DwLang),

    /// The value of a `DW_AT_address_class` attribute.
    AddressClass(constants::DwAddr),

    /// The value of a `DW_AT_identifier_case` attribute.
    IdentifierCase(constants::DwId),

    /// The value of a `DW_AT_calling_convention` attribute.
    CallingConvention(constants::DwCc),

    /// The value of a `DW_AT_inline` attribute.
    Inline(constants::DwInl),

    /// The value of a `DW_AT_ordering` attribute.
    Ordering(constants::DwOrd),

    /// An index into the filename entries from the line number information
    /// table for the compilation unit containing this value.
    FileIndex(u64),

    /// An implementation-defined identifier uniquely identifying a compilation
    /// unit.
    DwoId(DwoId),
}

/// An attribute in a `DebuggingInformationEntry`, consisting of a name and
/// associated value.
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub struct Attribute<R: Reader> {
    name: constants::DwAt,
    value: AttributeValue<R>,
}

impl<R: Reader> Attribute<R> {
    /// Get this attribute's name.
    pub fn name(&self) -> constants::DwAt {
        self.name
    }

    /// Get this attribute's raw value.
    pub fn raw_value(&self) -> AttributeValue<R> {
        self.value.clone()
    }

    /// Get this attribute's normalized value.
    ///
    /// Attribute values can potentially be encoded in multiple equivalent forms,
    /// and may have special meaning depending on the attribute name.  This method
    /// converts the attribute value to a normalized form based on the attribute
    /// name.
    ///
    /// See "Table 7.5: Attribute encodings" and "Table 7.6: Attribute form encodings".
    pub fn value(&self) -> AttributeValue<R> {
        // Table 7.5 shows the possible attribute classes for each name.
        // Table 7.6 shows the possible attribute classes for each form.
        // For each attribute name, we need to match on the form, and
        // convert it to one of the classes that is allowed for both
        // the name and the form.
        //
        // The individual class conversions rarely vary for each name,
        // so for each class conversion we define a macro that matches
        // on the allowed forms for that class.
        //
        // For some classes, we don't need to do any conversion, so their
        // macro is empty.  In the future we may want to fill them in to
        // provide strict checking of the forms for each class.  For now,
        // they simply provide a way to document the allowed classes for
        // each name.

        // DW_FORM_addr
        // DW_FORM_addrx
        // DW_FORM_addrx1
        // DW_FORM_addrx2
        // DW_FORM_addrx3
        // DW_FORM_addrx4
        macro_rules! address {
            () => {};
        }
        // DW_FORM_sec_offset
        macro_rules! addrptr {
            () => {
                if let Some(offset) = self.offset_value() {
                    return AttributeValue::DebugAddrBase(DebugAddrBase(offset));
                }
            };
        }
        // DW_FORM_block
        // DW_FORM_block1
        // DW_FORM_block2
        // DW_FORM_block4
        macro_rules! block {
            () => {};
        }
        // DW_FORM_sdata
        // DW_FORM_udata
        // DW_FORM_data1
        // DW_FORM_data2
        // DW_FORM_data4
        // DW_FORM_data8
        // DW_FORM_data16
        // DW_FORM_implicit_const
        macro_rules! constant {
            ($value:ident, $variant:ident) => {
                if let Some(value) = self.$value() {
                    return AttributeValue::$variant(value);
                }
            };
            ($value:ident, $variant:ident, $constant:ident) => {
                if let Some(value) = self.$value() {
                    return AttributeValue::$variant(constants::$constant(value));
                }
            };
        }
        // DW_FORM_exprloc
        macro_rules! exprloc {
            () => {
                if let Some(value) = self.exprloc_value() {
                    return AttributeValue::Exprloc(value);
                }
            };
        }
        // DW_FORM_flag
        // DW_FORM_flag_present
        macro_rules! flag {
            () => {};
        }
        // DW_FORM_sec_offset
        macro_rules! lineptr {
            () => {
                if let Some(offset) = self.offset_value() {
                    return AttributeValue::DebugLineRef(DebugLineOffset(offset));
                }
            };
        }
        // This also covers `loclist` in DWARF version 5.
        // DW_FORM_sec_offset
        // DW_FORM_loclistx
        macro_rules! loclistptr {
            () => {
                // DebugLocListsIndex is also an allowed form in DWARF version 5.
                if let Some(offset) = self.offset_value() {
                    return AttributeValue::LocationListsRef(LocationListsOffset(offset));
                }
            };
        }
        // DW_FORM_sec_offset
        macro_rules! loclistsptr {
            () => {
                if let Some(offset) = self.offset_value() {
                    return AttributeValue::DebugLocListsBase(DebugLocListsBase(offset));
                }
            };
        }
        // DWARF version <= 4.
        // DW_FORM_sec_offset
        macro_rules! macinfoptr {
            () => {
                if let Some(offset) = self.offset_value() {
                    return AttributeValue::DebugMacinfoRef(DebugMacinfoOffset(offset));
                }
            };
        }
        // DWARF version >= 5.
        // DW_FORM_sec_offset
        macro_rules! macroptr {
            () => {
                if let Some(offset) = self.offset_value() {
                    return AttributeValue::DebugMacroRef(DebugMacroOffset(offset));
                }
            };
        }
        // DW_FORM_ref_addr
        // DW_FORM_ref1
        // DW_FORM_ref2
        // DW_FORM_ref4
        // DW_FORM_ref8
        // DW_FORM_ref_udata
        // DW_FORM_ref_sig8
        // DW_FORM_ref_sup4
        // DW_FORM_ref_sup8
        macro_rules! reference {
            () => {};
        }
        // This also covers `rnglist` in DWARF version 5.
        // DW_FORM_sec_offset
        // DW_FORM_rnglistx
        macro_rules! rangelistptr {
            () => {
                // DebugRngListsIndex is also an allowed form in DWARF version 5.
                if let Some(offset) = self.offset_value() {
                    return AttributeValue::RangeListsRef(RawRangeListsOffset(offset));
                }
            };
        }
        // DW_FORM_sec_offset
        macro_rules! rnglistsptr {
            () => {
                if let Some(offset) = self.offset_value() {
                    return AttributeValue::DebugRngListsBase(DebugRngListsBase(offset));
                }
            };
        }
        // DW_FORM_string
        // DW_FORM_strp
        // DW_FORM_strx
        // DW_FORM_strx1
        // DW_FORM_strx2
        // DW_FORM_strx3
        // DW_FORM_strx4
        // DW_FORM_strp_sup
        // DW_FORM_line_strp
        macro_rules! string {
            () => {};
        }
        // DW_FORM_sec_offset
        macro_rules! stroffsetsptr {
            () => {
                if let Some(offset) = self.offset_value() {
                    return AttributeValue::DebugStrOffsetsBase(DebugStrOffsetsBase(offset));
                }
            };
        }
        // This isn't a separate form but it's useful to distinguish it from a generic udata.
        macro_rules! dwoid {
            () => {
                if let Some(value) = self.udata_value() {
                    return AttributeValue::DwoId(DwoId(value));
                }
            };
        }

        // Perform the allowed class conversions for each attribute name.
        match self.name {
            constants::DW_AT_sibling => {
                reference!();
            }
            constants::DW_AT_location => {
                exprloc!();
                loclistptr!();
            }
            constants::DW_AT_name => {
                string!();
            }
            constants::DW_AT_ordering => {
                constant!(u8_value, Ordering, DwOrd);
            }
            constants::DW_AT_byte_size
            | constants::DW_AT_bit_offset
            | constants::DW_AT_bit_size => {
                constant!(udata_value, Udata);
                exprloc!();
                reference!();
            }
            constants::DW_AT_stmt_list => {
                lineptr!();
            }
            constants::DW_AT_low_pc => {
                address!();
            }
            constants::DW_AT_high_pc => {
                address!();
                constant!(udata_value, Udata);
            }
            constants::DW_AT_language => {
                constant!(u16_value, Language, DwLang);
            }
            constants::DW_AT_discr => {
                reference!();
            }
            constants::DW_AT_discr_value => {
                // constant: depends on type of DW_TAG_variant_part,
                // so caller must normalize.
            }
            constants::DW_AT_visibility => {
                constant!(u8_value, Visibility, DwVis);
            }
            constants::DW_AT_import => {
                reference!();
            }
            constants::DW_AT_string_length => {
                exprloc!();
                loclistptr!();
                reference!();
            }
            constants::DW_AT_common_reference => {
                reference!();
            }
            constants::DW_AT_comp_dir => {
                string!();
            }
            constants::DW_AT_const_value => {
                // TODO: constant: sign depends on DW_AT_type.
                block!();
                string!();
            }
            constants::DW_AT_containing_type => {
                reference!();
            }
            constants::DW_AT_default_value => {
                // TODO: constant: sign depends on DW_AT_type.
                reference!();
                flag!();
            }
            constants::DW_AT_inline => {
                constant!(u8_value, Inline, DwInl);
            }
            constants::DW_AT_is_optional => {
                flag!();
            }
            constants::DW_AT_lower_bound => {
                // TODO: constant: sign depends on DW_AT_type.
                exprloc!();
                reference!();
            }
            constants::DW_AT_producer => {
                string!();
            }
            constants::DW_AT_prototyped => {
                flag!();
            }
            constants::DW_AT_return_addr => {
                exprloc!();
                loclistptr!();
            }
            constants::DW_AT_start_scope => {
                // TODO: constant
                rangelistptr!();
            }
            constants::DW_AT_bit_stride => {
                constant!(udata_value, Udata);
                exprloc!();
                reference!();
            }
            constants::DW_AT_upper_bound => {
                // TODO: constant: sign depends on DW_AT_type.
                exprloc!();
                reference!();
            }
            constants::DW_AT_abstract_origin => {
                reference!();
            }
            constants::DW_AT_accessibility => {
                constant!(u8_value, Accessibility, DwAccess);
            }
            constants::DW_AT_address_class => {
                constant!(udata_value, AddressClass, DwAddr);
            }
            constants::DW_AT_artificial => {
                flag!();
            }
            constants::DW_AT_base_types => {
                reference!();
            }
            constants::DW_AT_calling_convention => {
                constant!(u8_value, CallingConvention, DwCc);
            }
            constants::DW_AT_count => {
                // TODO: constant
                exprloc!();
                reference!();
            }
            constants::DW_AT_data_member_location => {
                // Constants must be handled before loclistptr so that DW_FORM_data4/8
                // are correctly interpreted for DWARF version 4+.
                constant!(udata_value, Udata);
                exprloc!();
                loclistptr!();
            }
            constants::DW_AT_decl_column => {
                constant!(udata_value, Udata);
            }
            constants::DW_AT_decl_file => {
                constant!(udata_value, FileIndex);
            }
            constants::DW_AT_decl_line => {
                constant!(udata_value, Udata);
            }
            constants::DW_AT_declaration => {
                flag!();
            }
            constants::DW_AT_discr_list => {
                block!();
            }
            constants::DW_AT_encoding => {
                constant!(u8_value, Encoding, DwAte);
            }
            constants::DW_AT_external => {
                flag!();
            }
            constants::DW_AT_frame_base => {
                exprloc!();
                loclistptr!();
            }
            constants::DW_AT_friend => {
                reference!();
            }
            constants::DW_AT_identifier_case => {
                constant!(u8_value, IdentifierCase, DwId);
            }
            constants::DW_AT_macro_info => {
                macinfoptr!();
            }
            constants::DW_AT_namelist_item => {
                reference!();
            }
            constants::DW_AT_priority => {
                reference!();
            }
            constants::DW_AT_segment => {
                exprloc!();
                loclistptr!();
            }
            constants::DW_AT_specification => {
                reference!();
            }
            constants::DW_AT_static_link => {
                exprloc!();
                loclistptr!();
            }
            constants::DW_AT_type => {
                reference!();
            }
            constants::DW_AT_use_location => {
                exprloc!();
                loclistptr!();
            }
            constants::DW_AT_variable_parameter => {
                flag!();
            }
            constants::DW_AT_virtuality => {
                constant!(u8_value, Virtuality, DwVirtuality);
            }
            constants::DW_AT_vtable_elem_location => {
                exprloc!();
                loclistptr!();
            }
            constants::DW_AT_allocated => {
                // TODO: constant
                exprloc!();
                reference!();
            }
            constants::DW_AT_associated => {
                // TODO: constant
                exprloc!();
                reference!();
            }
            constants::DW_AT_data_location => {
                exprloc!();
            }
            constants::DW_AT_byte_stride => {
                constant!(udata_value, Udata);
                exprloc!();
                reference!();
            }
            constants::DW_AT_entry_pc => {
                // TODO: constant
                address!();
            }
            constants::DW_AT_use_UTF8 => {
                flag!();
            }
            constants::DW_AT_extension => {
                reference!();
            }
            constants::DW_AT_ranges => {
                rangelistptr!();
            }
            constants::DW_AT_trampoline => {
                address!();
                flag!();
                reference!();
                string!();
            }
            constants::DW_AT_call_column => {
                constant!(udata_value, Udata);
            }
            constants::DW_AT_call_file => {
                constant!(udata_value, FileIndex);
            }
            constants::DW_AT_call_line => {
                constant!(udata_value, Udata);
            }
            constants::DW_AT_description => {
                string!();
            }
            constants::DW_AT_binary_scale => {
                // TODO: constant
            }
            constants::DW_AT_decimal_scale => {
                // TODO: constant
            }
            constants::DW_AT_small => {
                reference!();
            }
            constants::DW_AT_decimal_sign => {
                constant!(u8_value, DecimalSign, DwDs);
            }
            constants::DW_AT_digit_count => {
                // TODO: constant
            }
            constants::DW_AT_picture_string => {
                string!();
            }
            constants::DW_AT_mutable => {
                flag!();
            }
            constants::DW_AT_threads_scaled => {
                flag!();
            }
            constants::DW_AT_explicit => {
                flag!();
            }
            constants::DW_AT_object_pointer => {
                reference!();
            }
            constants::DW_AT_endianity => {
                constant!(u8_value, Endianity, DwEnd);
            }
            constants::DW_AT_elemental => {
                flag!();
            }
            constants::DW_AT_pure => {
                flag!();
            }
            constants::DW_AT_recursive => {
                flag!();
            }
            constants::DW_AT_signature => {
                reference!();
            }
            constants::DW_AT_main_subprogram => {
                flag!();
            }
            constants::DW_AT_data_bit_offset => {
                // TODO: constant
            }
            constants::DW_AT_const_expr => {
                flag!();
            }
            constants::DW_AT_enum_class => {
                flag!();
            }
            constants::DW_AT_linkage_name => {
                string!();
            }
            constants::DW_AT_string_length_bit_size => {
                // TODO: constant
            }
            constants::DW_AT_string_length_byte_size => {
                // TODO: constant
            }
            constants::DW_AT_rank => {
                // TODO: constant
                exprloc!();
            }
            constants::DW_AT_str_offsets_base => {
                stroffsetsptr!();
            }
            constants::DW_AT_addr_base | constants::DW_AT_GNU_addr_base => {
                addrptr!();
            }
            constants::DW_AT_rnglists_base | constants::DW_AT_GNU_ranges_base => {
                rnglistsptr!();
            }
            constants::DW_AT_dwo_name => {
                string!();
            }
            constants::DW_AT_reference => {
                flag!();
            }
            constants::DW_AT_rvalue_reference => {
                flag!();
            }
            constants::DW_AT_macros => {
                macroptr!();
            }
            constants::DW_AT_call_all_calls => {
                flag!();
            }
            constants::DW_AT_call_all_source_calls => {
                flag!();
            }
            constants::DW_AT_call_all_tail_calls => {
                flag!();
            }
            constants::DW_AT_call_return_pc => {
                address!();
            }
            constants::DW_AT_call_value => {
                exprloc!();
            }
            constants::DW_AT_call_origin => {
                exprloc!();
            }
            constants::DW_AT_call_parameter => {
                reference!();
            }
            constants::DW_AT_call_pc => {
                address!();
            }
            constants::DW_AT_call_tail_call => {
                flag!();
            }
            constants::DW_AT_call_target => {
                exprloc!();
            }
            constants::DW_AT_call_target_clobbered => {
                exprloc!();
            }
            constants::DW_AT_call_data_location => {
                exprloc!();
            }
            constants::DW_AT_call_data_value => {
                exprloc!();
            }
            constants::DW_AT_noreturn => {
                flag!();
            }
            constants::DW_AT_alignment => {
                // TODO: constant
            }
            constants::DW_AT_export_symbols => {
                flag!();
            }
            constants::DW_AT_deleted => {
                flag!();
            }
            constants::DW_AT_defaulted => {
                // TODO: constant
            }
            constants::DW_AT_loclists_base => {
                loclistsptr!();
            }
            constants::DW_AT_GNU_dwo_id => {
                dwoid!();
            }
            _ => {}
        }
        self.value.clone()
    }

    /// Try to convert this attribute's value to a u8.
    #[inline]
    pub fn u8_value(&self) -> Option<u8> {
        self.value.u8_value()
    }

    /// Try to convert this attribute's value to a u16.
    #[inline]
    pub fn u16_value(&self) -> Option<u16> {
        self.value.u16_value()
    }

    /// Try to convert this attribute's value to an unsigned integer.
    #[inline]
    pub fn udata_value(&self) -> Option<u64> {
        self.value.udata_value()
    }

    /// Try to convert this attribute's value to a signed integer.
    #[inline]
    pub fn sdata_value(&self) -> Option<i64> {
        self.value.sdata_value()
    }

    /// Try to convert this attribute's value to an offset.
    #[inline]
    pub fn offset_value(&self) -> Option<R::Offset> {
        self.value.offset_value()
    }

    /// Try to convert this attribute's value to an expression or location buffer.
    ///
    /// Expressions and locations may be `DW_FORM_block*` or `DW_FORM_exprloc`.
    /// The standard doesn't mention `DW_FORM_block*` as a possible form, but
    /// it is encountered in practice.
    #[inline]
    pub fn exprloc_value(&self) -> Option<Expression<R>> {
        self.value.exprloc_value()
    }

    /// Try to return this attribute's value as a string slice.
    ///
    /// If this attribute's value is either an inline `DW_FORM_string` string,
    /// or a `DW_FORM_strp` reference to an offset into the `.debug_str`
    /// section, return the attribute's string value as `Some`. Other attribute
    /// value forms are returned as `None`.
    ///
    /// Warning: this function does not handle all possible string forms.
    /// Use `Dwarf::attr_string` instead.
    #[inline]
    pub fn string_value(&self, debug_str: &DebugStr<R>) -> Option<R> {
        self.value.string_value(debug_str)
    }

    /// Try to return this attribute's value as a string slice.
    ///
    /// If this attribute's value is either an inline `DW_FORM_string` string,
    /// or a `DW_FORM_strp` reference to an offset into the `.debug_str`
    /// section, or a `DW_FORM_strp_sup` reference to an offset into a supplementary
    /// object file, return the attribute's string value as `Some`. Other attribute
    /// value forms are returned as `None`.
    ///
    /// Warning: this function does not handle all possible string forms.
    /// Use `Dwarf::attr_string` instead.
    #[inline]
    pub fn string_value_sup(
        &self,
        debug_str: &DebugStr<R>,
        debug_str_sup: Option<&DebugStr<R>>,
    ) -> Option<R> {
        self.value.string_value_sup(debug_str, debug_str_sup)
    }
}

impl<R, Offset> AttributeValue<R, Offset>
where
    R: Reader<Offset = Offset>,
    Offset: ReaderOffset,
{
    /// Try to convert this attribute's value to a u8.
    pub fn u8_value(&self) -> Option<u8> {
        if let Some(value) = self.udata_value() {
            if value <= u64::from(u8::MAX) {
                return Some(value as u8);
            }
        }
        None
    }

    /// Try to convert this attribute's value to a u16.
    pub fn u16_value(&self) -> Option<u16> {
        if let Some(value) = self.udata_value() {
            if value <= u64::from(u16::MAX) {
                return Some(value as u16);
            }
        }
        None
    }

    /// Try to convert this attribute's value to an unsigned integer.
    pub fn udata_value(&self) -> Option<u64> {
        Some(match *self {
            AttributeValue::Data1(data) => u64::from(data),
            AttributeValue::Data2(data) => u64::from(data),
            AttributeValue::Data4(data) => u64::from(data),
            AttributeValue::Data8(data) => data,
            AttributeValue::Udata(data) => data,
            AttributeValue::Sdata(data) => {
                if data < 0 {
                    // Maybe we should emit a warning here
                    return None;
                }
                data as u64
            }
            _ => return None,
        })
    }

    /// Try to convert this attribute's value to a signed integer.
    pub fn sdata_value(&self) -> Option<i64> {
        Some(match *self {
            AttributeValue::Data1(data) => i64::from(data as i8),
            AttributeValue::Data2(data) => i64::from(data as i16),
            AttributeValue::Data4(data) => i64::from(data as i32),
            AttributeValue::Data8(data) => data as i64,
            AttributeValue::Sdata(data) => data,
            AttributeValue::Udata(data) => {
                if data > i64::max_value() as u64 {
                    // Maybe we should emit a warning here
                    return None;
                }
                data as i64
            }
            _ => return None,
        })
    }

    /// Try to convert this attribute's value to an offset.
    pub fn offset_value(&self) -> Option<R::Offset> {
        // While offsets will be DW_FORM_data4/8 in DWARF version 2/3,
        // these have already been converted to `SecOffset.
        if let AttributeValue::SecOffset(offset) = *self {
            Some(offset)
        } else {
            None
        }
    }

    /// Try to convert this attribute's value to an expression or location buffer.
    ///
    /// Expressions and locations may be `DW_FORM_block*` or `DW_FORM_exprloc`.
    /// The standard doesn't mention `DW_FORM_block*` as a possible form, but
    /// it is encountered in practice.
    pub fn exprloc_value(&self) -> Option<Expression<R>> {
        Some(match *self {
            AttributeValue::Block(ref data) => Expression(data.clone()),
            AttributeValue::Exprloc(ref data) => data.clone(),
            _ => return None,
        })
    }

    /// Try to return this attribute's value as a string slice.
    ///
    /// If this attribute's value is either an inline `DW_FORM_string` string,
    /// or a `DW_FORM_strp` reference to an offset into the `.debug_str`
    /// section, return the attribute's string value as `Some`. Other attribute
    /// value forms are returned as `None`.
    ///
    /// Warning: this function does not handle all possible string forms.
    /// Use `Dwarf::attr_string` instead.
    pub fn string_value(&self, debug_str: &DebugStr<R>) -> Option<R> {
        match *self {
            AttributeValue::String(ref string) => Some(string.clone()),
            AttributeValue::DebugStrRef(offset) => debug_str.get_str(offset).ok(),
            _ => None,
        }
    }

    /// Try to return this attribute's value as a string slice.
    ///
    /// If this attribute's value is either an inline `DW_FORM_string` string,
    /// or a `DW_FORM_strp` reference to an offset into the `.debug_str`
    /// section, or a `DW_FORM_strp_sup` reference to an offset into a supplementary
    /// object file, return the attribute's string value as `Some`. Other attribute
    /// value forms are returned as `None`.
    ///
    /// Warning: this function does not handle all possible string forms.
    /// Use `Dwarf::attr_string` instead.
    pub fn string_value_sup(
        &self,
        debug_str: &DebugStr<R>,
        debug_str_sup: Option<&DebugStr<R>>,
    ) -> Option<R> {
        match *self {
            AttributeValue::String(ref string) => Some(string.clone()),
            AttributeValue::DebugStrRef(offset) => debug_str.get_str(offset).ok(),
            AttributeValue::DebugStrRefSup(offset) => {
                debug_str_sup.and_then(|s| s.get_str(offset).ok())
            }
            _ => None,
        }
    }
}

fn length_u8_value<R: Reader>(input: &mut R) -> Result<R> {
    let len = input.read_u8().map(R::Offset::from_u8)?;
    input.split(len)
}

fn length_u16_value<R: Reader>(input: &mut R) -> Result<R> {
    let len = input.read_u16().map(R::Offset::from_u16)?;
    input.split(len)
}

fn length_u32_value<R: Reader>(input: &mut R) -> Result<R> {
    let len = input.read_u32().map(R::Offset::from_u32)?;
    input.split(len)
}

fn length_uleb128_value<R: Reader>(input: &mut R) -> Result<R> {
    let len = input.read_uleb128().and_then(R::Offset::from_u64)?;
    input.split(len)
}

// Return true if the given `name` can be a section offset in DWARF version 2/3.
// This is required to correctly handle relocations.
fn allow_section_offset(name: constants::DwAt, version: u16) -> bool {
    match name {
        constants::DW_AT_location
        | constants::DW_AT_stmt_list
        | constants::DW_AT_string_length
        | constants::DW_AT_return_addr
        | constants::DW_AT_start_scope
        | constants::DW_AT_frame_base
        | constants::DW_AT_macro_info
        | constants::DW_AT_macros
        | constants::DW_AT_segment
        | constants::DW_AT_static_link
        | constants::DW_AT_use_location
        | constants::DW_AT_vtable_elem_location
        | constants::DW_AT_ranges => true,
        constants::DW_AT_data_member_location => version == 2 || version == 3,
        _ => false,
    }
}

pub(crate) fn parse_attribute<R: Reader>(
    input: &mut R,
    encoding: Encoding,
    spec: AttributeSpecification,
) -> Result<Attribute<R>> {
    let mut form = spec.form();
    loop {
        let value = match form {
            constants::DW_FORM_indirect => {
                let dynamic_form = input.read_uleb128_u16()?;
                form = constants::DwForm(dynamic_form);
                continue;
            }
            constants::DW_FORM_addr => {
                let addr = input.read_address(encoding.address_size)?;
                AttributeValue::Addr(addr)
            }
            constants::DW_FORM_block1 => {
                let block = length_u8_value(input)?;
                AttributeValue::Block(block)
            }
            constants::DW_FORM_block2 => {
                let block = length_u16_value(input)?;
                AttributeValue::Block(block)
            }
            constants::DW_FORM_block4 => {
                let block = length_u32_value(input)?;
                AttributeValue::Block(block)
            }
            constants::DW_FORM_block => {
                let block = length_uleb128_value(input)?;
                AttributeValue::Block(block)
            }
            constants::DW_FORM_data1 => {
                let data = input.read_u8()?;
                AttributeValue::Data1(data)
            }
            constants::DW_FORM_data2 => {
                let data = input.read_u16()?;
                AttributeValue::Data2(data)
            }
            constants::DW_FORM_data4 => {
                // DWARF version 2/3 may use DW_FORM_data4/8 for section offsets.
                // Ensure we handle relocations here.
                if encoding.format == Format::Dwarf32
                    && allow_section_offset(spec.name(), encoding.version)
                {
                    let offset = input.read_offset(Format::Dwarf32)?;
                    AttributeValue::SecOffset(offset)
                } else {
                    let data = input.read_u32()?;
                    AttributeValue::Data4(data)
                }
            }
            constants::DW_FORM_data8 => {
                // DWARF version 2/3 may use DW_FORM_data4/8 for section offsets.
                // Ensure we handle relocations here.
                if encoding.format == Format::Dwarf64
                    && allow_section_offset(spec.name(), encoding.version)
                {
                    let offset = input.read_offset(Format::Dwarf64)?;
                    AttributeValue::SecOffset(offset)
                } else {
                    let data = input.read_u64()?;
                    AttributeValue::Data8(data)
                }
            }
            constants::DW_FORM_data16 => {
                let block = input.split(R::Offset::from_u8(16))?;
                AttributeValue::Block(block)
            }
            constants::DW_FORM_udata => {
                let data = input.read_uleb128()?;
                AttributeValue::Udata(data)
            }
            constants::DW_FORM_sdata => {
                let data = input.read_sleb128()?;
                AttributeValue::Sdata(data)
            }
            constants::DW_FORM_exprloc => {
                let block = length_uleb128_value(input)?;
                AttributeValue::Exprloc(Expression(block))
            }
            constants::DW_FORM_flag => {
                let present = input.read_u8()?;
                AttributeValue::Flag(present != 0)
            }
            constants::DW_FORM_flag_present => {
                // FlagPresent is this weird compile time always true thing that
                // isn't actually present in the serialized DIEs, only in the abbreviation.
                AttributeValue::Flag(true)
            }
            constants::DW_FORM_sec_offset => {
                let offset = input.read_offset(encoding.format)?;
                AttributeValue::SecOffset(offset)
            }
            constants::DW_FORM_ref1 => {
                let reference = input.read_u8().map(R::Offset::from_u8)?;
                AttributeValue::UnitRef(UnitOffset(reference))
            }
            constants::DW_FORM_ref2 => {
                let reference = input.read_u16().map(R::Offset::from_u16)?;
                AttributeValue::UnitRef(UnitOffset(reference))
            }
            constants::DW_FORM_ref4 => {
                let reference = input.read_u32().map(R::Offset::from_u32)?;
                AttributeValue::UnitRef(UnitOffset(reference))
            }
            constants::DW_FORM_ref8 => {
                let reference = input.read_u64().and_then(R::Offset::from_u64)?;
                AttributeValue::UnitRef(UnitOffset(reference))
            }
            constants::DW_FORM_ref_udata => {
                let reference = input.read_uleb128().and_then(R::Offset::from_u64)?;
                AttributeValue::UnitRef(UnitOffset(reference))
            }
            constants::DW_FORM_ref_addr => {
                // This is an offset, but DWARF version 2 specifies that DW_FORM_ref_addr
                // has the same size as an address on the target system.  This was changed
                // in DWARF version 3.
                let offset = if encoding.version == 2 {
                    input.read_sized_offset(encoding.address_size)?
                } else {
                    input.read_offset(encoding.format)?
                };
                AttributeValue::DebugInfoRef(DebugInfoOffset(offset))
            }
            constants::DW_FORM_ref_sig8 => {
                let signature = input.read_u64()?;
                AttributeValue::DebugTypesRef(DebugTypeSignature(signature))
            }
            constants::DW_FORM_ref_sup4 => {
                let offset = input.read_u32().map(R::Offset::from_u32)?;
                AttributeValue::DebugInfoRefSup(DebugInfoOffset(offset))
            }
            constants::DW_FORM_ref_sup8 => {
                let offset = input.read_u64().and_then(R::Offset::from_u64)?;
                AttributeValue::DebugInfoRefSup(DebugInfoOffset(offset))
            }
            constants::DW_FORM_GNU_ref_alt => {
                let offset = input.read_offset(encoding.format)?;
                AttributeValue::DebugInfoRefSup(DebugInfoOffset(offset))
            }
            constants::DW_FORM_string => {
                let string = input.read_null_terminated_slice()?;
                AttributeValue::String(string)
            }
            constants::DW_FORM_strp => {
                let offset = input.read_offset(encoding.format)?;
                AttributeValue::DebugStrRef(DebugStrOffset(offset))
            }
            constants::DW_FORM_strp_sup | constants::DW_FORM_GNU_strp_alt => {
                let offset = input.read_offset(encoding.format)?;
                AttributeValue::DebugStrRefSup(DebugStrOffset(offset))
            }
            constants::DW_FORM_line_strp => {
                let offset = input.read_offset(encoding.format)?;
                AttributeValue::DebugLineStrRef(DebugLineStrOffset(offset))
            }
            constants::DW_FORM_implicit_const => {
                let data = spec
                    .implicit_const_value()
                    .ok_or(Error::InvalidImplicitConst)?;
                AttributeValue::Sdata(data)
            }
            constants::DW_FORM_strx | constants::DW_FORM_GNU_str_index => {
                let index = input.read_uleb128().and_then(R::Offset::from_u64)?;
                AttributeValue::DebugStrOffsetsIndex(DebugStrOffsetsIndex(index))
            }
            constants::DW_FORM_strx1 => {
                let index = input.read_u8().map(R::Offset::from_u8)?;
                AttributeValue::DebugStrOffsetsIndex(DebugStrOffsetsIndex(index))
            }
            constants::DW_FORM_strx2 => {
                let index = input.read_u16().map(R::Offset::from_u16)?;
                AttributeValue::DebugStrOffsetsIndex(DebugStrOffsetsIndex(index))
            }
            constants::DW_FORM_strx3 => {
                let index = input.read_uint(3).and_then(R::Offset::from_u64)?;
                AttributeValue::DebugStrOffsetsIndex(DebugStrOffsetsIndex(index))
            }
            constants::DW_FORM_strx4 => {
                let index = input.read_u32().map(R::Offset::from_u32)?;
                AttributeValue::DebugStrOffsetsIndex(DebugStrOffsetsIndex(index))
            }
            constants::DW_FORM_addrx | constants::DW_FORM_GNU_addr_index => {
                let index = input.read_uleb128().and_then(R::Offset::from_u64)?;
                AttributeValue::DebugAddrIndex(DebugAddrIndex(index))
            }
            constants::DW_FORM_addrx1 => {
                let index = input.read_u8().map(R::Offset::from_u8)?;
                AttributeValue::DebugAddrIndex(DebugAddrIndex(index))
            }
            constants::DW_FORM_addrx2 => {
                let index = input.read_u16().map(R::Offset::from_u16)?;
                AttributeValue::DebugAddrIndex(DebugAddrIndex(index))
            }
            constants::DW_FORM_addrx3 => {
                let index = input.read_uint(3).and_then(R::Offset::from_u64)?;
                AttributeValue::DebugAddrIndex(DebugAddrIndex(index))
            }
            constants::DW_FORM_addrx4 => {
                let index = input.read_u32().map(R::Offset::from_u32)?;
                AttributeValue::DebugAddrIndex(DebugAddrIndex(index))
            }
            constants::DW_FORM_loclistx => {
                let index = input.read_uleb128().and_then(R::Offset::from_u64)?;
                AttributeValue::DebugLocListsIndex(DebugLocListsIndex(index))
            }
            constants::DW_FORM_rnglistx => {
                let index = input.read_uleb128().and_then(R::Offset::from_u64)?;
                AttributeValue::DebugRngListsIndex(DebugRngListsIndex(index))
            }
            _ => {
                return Err(Error::UnknownForm);
            }
        };
        let attr = Attribute {
            name: spec.name(),
            value,
        };
        return Ok(attr);
    }
}

pub(crate) fn skip_attributes<R: Reader>(
    input: &mut R,
    encoding: Encoding,
    specs: &[AttributeSpecification],
) -> Result<()> {
    let mut skip_bytes = R::Offset::from_u8(0);
    for spec in specs {
        let mut form = spec.form();
        loop {
            if let Some(len) = get_attribute_size(form, encoding) {
                // We know the length of this attribute. Accumulate that length.
                skip_bytes += R::Offset::from_u8(len);
                break;
            }

            // We have encountered a variable-length attribute.
            if skip_bytes != R::Offset::from_u8(0) {
                // Skip the accumulated skip bytes and then read the attribute normally.
                input.skip(skip_bytes)?;
                skip_bytes = R::Offset::from_u8(0);
            }

            match form {
                constants::DW_FORM_indirect => {
                    let dynamic_form = input.read_uleb128_u16()?;
                    form = constants::DwForm(dynamic_form);
                    continue;
                }
                constants::DW_FORM_block1 => {
                    skip_bytes = input.read_u8().map(R::Offset::from_u8)?;
                }
                constants::DW_FORM_block2 => {
                    skip_bytes = input.read_u16().map(R::Offset::from_u16)?;
                }
                constants::DW_FORM_block4 => {
                    skip_bytes = input.read_u32().map(R::Offset::from_u32)?;
                }
                constants::DW_FORM_block | constants::DW_FORM_exprloc => {
                    skip_bytes = input.read_uleb128().and_then(R::Offset::from_u64)?;
                }
                constants::DW_FORM_string => {
                    let _ = input.read_null_terminated_slice()?;
                }
                constants::DW_FORM_udata
                | constants::DW_FORM_sdata
                | constants::DW_FORM_ref_udata
                | constants::DW_FORM_strx
                | constants::DW_FORM_GNU_str_index
                | constants::DW_FORM_addrx
                | constants::DW_FORM_GNU_addr_index
                | constants::DW_FORM_loclistx
                | constants::DW_FORM_rnglistx => {
                    input.skip_leb128()?;
                }
                _ => {
                    return Err(Error::UnknownForm);
                }
            };
            break;
        }
    }
    if skip_bytes != R::Offset::from_u8(0) {
        // Skip the remaining accumulated skip bytes.
        input.skip(skip_bytes)?;
    }
    Ok(())
}

/// An iterator over a particular entry's attributes.
///
/// See [the documentation for
/// `DebuggingInformationEntry::attrs()`](./struct.DebuggingInformationEntry.html#method.attrs)
/// for details.
///
/// Can be [used with
/// `FallibleIterator`](./index.html#using-with-fallibleiterator).
#[derive(Clone, Copy, Debug)]
pub struct AttrsIter<'abbrev, 'entry, 'unit, R: Reader> {
    input: R,
    attributes: &'abbrev [AttributeSpecification],
    entry: &'entry DebuggingInformationEntry<'abbrev, 'unit, R>,
}

impl<'abbrev, 'entry, 'unit, R: Reader> AttrsIter<'abbrev, 'entry, 'unit, R> {
    /// Advance the iterator and return the next attribute.
    ///
    /// Returns `None` when iteration is finished. If an error
    /// occurs while parsing the next attribute, then this error
    /// is returned, and all subsequent calls return `None`.
    #[inline(always)]
    pub fn next(&mut self) -> Result<Option<Attribute<R>>> {
        if self.attributes.is_empty() {
            // Now that we have parsed all of the attributes, we know where
            // either (1) this entry's children start, if the abbreviation says
            // this entry has children; or (2) where this entry's siblings
            // begin.
            if let Some(end) = self.entry.attrs_len.get() {
                debug_assert_eq!(end, self.input.offset_from(&self.entry.attrs_slice));
            } else {
                self.entry
                    .attrs_len
                    .set(Some(self.input.offset_from(&self.entry.attrs_slice)));
            }

            return Ok(None);
        }

        let spec = self.attributes[0];
        let rest_spec = &self.attributes[1..];
        match parse_attribute(&mut self.input, self.entry.unit.encoding(), spec) {
            Ok(attr) => {
                self.attributes = rest_spec;
                Ok(Some(attr))
            }
            Err(e) => {
                self.input.empty();
                Err(e)
            }
        }
    }
}

#[cfg(feature = "fallible-iterator")]
impl<'abbrev, 'entry, 'unit, R: Reader> fallible_iterator::FallibleIterator
    for AttrsIter<'abbrev, 'entry, 'unit, R>
{
    type Item = Attribute<R>;
    type Error = Error;

    fn next(&mut self) -> ::core::result::Result<Option<Self::Item>, Self::Error> {
        AttrsIter::next(self)
    }
}

/// A raw reader of the data that defines the Debugging Information Entries.
///
/// `EntriesRaw` provides primitives to read the components of Debugging Information
/// Entries (DIEs). A DIE consists of an abbreviation code (read with `read_abbreviation`)
/// followed by a number of attributes (read with `read_attribute`).
/// The user must provide the control flow to read these correctly.
/// In particular, all attributes must always be read before reading another
/// abbreviation code.
///
/// `EntriesRaw` lacks some features of `EntriesCursor`, such as the ability to skip
/// to the next sibling DIE. However, this also allows it to optimize better, since it
/// does not need to perform the extra bookkeeping required to support these features,
/// and thus it is suitable for cases where performance is important.
///
/// ## Example Usage
/// ```rust,no_run
/// # fn example() -> Result<(), gimli::Error> {
/// # let debug_info = gimli::DebugInfo::new(&[], gimli::LittleEndian);
/// # let get_some_unit = || debug_info.units().next().unwrap().unwrap();
/// let unit = get_some_unit();
/// # let debug_abbrev = gimli::DebugAbbrev::new(&[], gimli::LittleEndian);
/// # let get_abbrevs_for_unit = |_| unit.abbreviations(&debug_abbrev).unwrap();
/// let abbrevs = get_abbrevs_for_unit(&unit);
///
/// let mut entries = unit.entries_raw(&abbrevs, None)?;
/// while !entries.is_empty() {
///     let abbrev = if let Some(abbrev) = entries.read_abbreviation()? {
///         abbrev
///     } else {
///         // Null entry with no attributes.
///         continue
///     };
///     match abbrev.tag() {
///         gimli::DW_TAG_subprogram => {
///             // Loop over attributes for DIEs we care about.
///             for spec in abbrev.attributes() {
///                 let attr = entries.read_attribute(*spec)?;
///                 match attr.name() {
///                     // Handle attributes.
///                     _ => {}
///                 }
///             }
///         }
///         _ => {
///             // Skip attributes for DIEs we don't care about.
///             entries.skip_attributes(abbrev.attributes());
///         }
///     }
/// }
/// # unreachable!()
/// # }
/// ```
#[derive(Clone, Debug)]
pub struct EntriesRaw<'abbrev, 'unit, R>
where
    R: Reader,
{
    input: R,
    unit: &'unit UnitHeader<R>,
    abbreviations: &'abbrev Abbreviations,
    depth: isize,
}

impl<'abbrev, 'unit, R: Reader> EntriesRaw<'abbrev, 'unit, R> {
    /// Return true if there is no more input.
    #[inline]
    pub fn is_empty(&self) -> bool {
        self.input.is_empty()
    }

    /// Return the unit offset at which the reader will read next.
    ///
    /// If you want the offset of the next entry, then this must be called prior to reading
    /// the next entry.
    pub fn next_offset(&self) -> UnitOffset<R::Offset> {
        UnitOffset(self.unit.header_size() + self.input.offset_from(&self.unit.entries_buf))
    }

    /// Return the depth of the next entry.
    ///
    /// This depth is updated when `read_abbreviation` is called, and is updated
    /// based on null entries and the `has_children` field in the abbreviation.
    #[inline]
    pub fn next_depth(&self) -> isize {
        self.depth
    }

    /// Read an abbreviation code and lookup the corresponding `Abbreviation`.
    ///
    /// Returns `Ok(None)` for null entries.
    #[inline]
    pub fn read_abbreviation(&mut self) -> Result<Option<&'abbrev Abbreviation>> {
        let code = self.input.read_uleb128()?;
        if code == 0 {
            self.depth -= 1;
            return Ok(None);
        };
        let abbrev = self
            .abbreviations
            .get(code)
            .ok_or(Error::UnknownAbbreviation)?;
        if abbrev.has_children() {
            self.depth += 1;
        }
        Ok(Some(abbrev))
    }

    /// Read an attribute.
    #[inline]
    pub fn read_attribute(&mut self, spec: AttributeSpecification) -> Result<Attribute<R>> {
        parse_attribute(&mut self.input, self.unit.encoding(), spec)
    }

    /// Skip all the attributes of an abbreviation.
    #[inline]
    pub fn skip_attributes(&mut self, specs: &[AttributeSpecification]) -> Result<()> {
        skip_attributes(&mut self.input, self.unit.encoding(), specs)
    }
}

/// A cursor into the Debugging Information Entries tree for a compilation unit.
///
/// The `EntriesCursor` can traverse the DIE tree in DFS order using `next_dfs()`,
/// or skip to the next sibling of the entry the cursor is currently pointing to
/// using `next_sibling()`.
///
/// It is also possible to traverse the DIE tree at a lower abstraction level
/// using `next_entry()`. This method does not skip over null entries, or provide
/// any indication of the current tree depth. In this case, you must use `current()`
/// to obtain the current entry, and `current().has_children()` to determine if
/// the entry following the current entry will be a sibling or child. `current()`
/// will return `None` if the current entry is a null entry, which signifies the
/// end of the current tree depth.
#[derive(Clone, Debug)]
pub struct EntriesCursor<'abbrev, 'unit, R>
where
    R: Reader,
{
    input: R,
    unit: &'unit UnitHeader<R>,
    abbreviations: &'abbrev Abbreviations,
    cached_current: Option<DebuggingInformationEntry<'abbrev, 'unit, R>>,
    delta_depth: isize,
}

impl<'abbrev, 'unit, R: Reader> EntriesCursor<'abbrev, 'unit, R> {
    /// Get a reference to the entry that the cursor is currently pointing to.
    ///
    /// If the cursor is not pointing at an entry, or if the current entry is a
    /// null entry, then `None` is returned.
    #[inline]
    pub fn current(&self) -> Option<&DebuggingInformationEntry<'abbrev, 'unit, R>> {
        self.cached_current.as_ref()
    }

    /// Move the cursor to the next DIE in the tree.
    ///
    /// Returns `Some` if there is a next entry, even if this entry is null.
    /// If there is no next entry, then `None` is returned.
    pub fn next_entry(&mut self) -> Result<Option<()>> {
        if let Some(ref current) = self.cached_current {
            self.input = current.after_attrs()?;
        }

        if self.input.is_empty() {
            self.cached_current = None;
            self.delta_depth = 0;
            return Ok(None);
        }

        match DebuggingInformationEntry::parse(&mut self.input, self.unit, self.abbreviations) {
            Ok(Some(entry)) => {
                self.delta_depth = entry.has_children() as isize;
                self.cached_current = Some(entry);
                Ok(Some(()))
            }
            Ok(None) => {
                self.delta_depth = -1;
                self.cached_current = None;
                Ok(Some(()))
            }
            Err(e) => {
                self.input.empty();
                self.delta_depth = 0;
                self.cached_current = None;
                Err(e)
            }
        }
    }

    /// Move the cursor to the next DIE in the tree in DFS order.
    ///
    /// Upon successful movement of the cursor, return the delta traversal
    /// depth and the entry:
    ///
    ///   * If we moved down into the previous current entry's children, we get
    ///     `Some((1, entry))`.
    ///
    ///   * If we moved to the previous current entry's sibling, we get
    ///     `Some((0, entry))`.
    ///
    ///   * If the previous entry does not have any siblings and we move up to
    ///     its parent's next sibling, then we get `Some((-1, entry))`. Note that
    ///     if the parent doesn't have a next sibling, then it could go up to the
    ///     parent's parent's next sibling and return `Some((-2, entry))`, etc.
    ///
    /// If there is no next entry, then `None` is returned.
    ///
    /// Here is an example that finds the first entry in a compilation unit that
    /// does not have any children.
    ///
    /// ```
    /// # use gimli::{DebugAbbrev, DebugInfo, LittleEndian};
    /// # let info_buf = [
    /// #     // Comilation unit header
    /// #
    /// #     // 32-bit unit length = 25
    /// #     0x19, 0x00, 0x00, 0x00,
    /// #     // Version 4
    /// #     0x04, 0x00,
    /// #     // debug_abbrev_offset
    /// #     0x00, 0x00, 0x00, 0x00,
    /// #     // Address size
    /// #     0x04,
    /// #
    /// #     // DIEs
    /// #
    /// #     // Abbreviation code
    /// #     0x01,
    /// #     // Attribute of form DW_FORM_string = "foo\0"
    /// #     0x66, 0x6f, 0x6f, 0x00,
    /// #
    /// #       // Children
    /// #
    /// #       // Abbreviation code
    /// #       0x01,
    /// #       // Attribute of form DW_FORM_string = "foo\0"
    /// #       0x66, 0x6f, 0x6f, 0x00,
    /// #
    /// #         // Children
    /// #
    /// #         // Abbreviation code
    /// #         0x01,
    /// #         // Attribute of form DW_FORM_string = "foo\0"
    /// #         0x66, 0x6f, 0x6f, 0x00,
    /// #
    /// #           // Children
    /// #
    /// #           // End of children
    /// #           0x00,
    /// #
    /// #         // End of children
    /// #         0x00,
    /// #
    /// #       // End of children
    /// #       0x00,
    /// # ];
    /// # let debug_info = DebugInfo::new(&info_buf, LittleEndian);
    /// #
    /// # let abbrev_buf = [
    /// #     // Code
    /// #     0x01,
    /// #     // DW_TAG_subprogram
    /// #     0x2e,
    /// #     // DW_CHILDREN_yes
    /// #     0x01,
    /// #     // Begin attributes
    /// #       // Attribute name = DW_AT_name
    /// #       0x03,
    /// #       // Attribute form = DW_FORM_string
    /// #       0x08,
    /// #     // End attributes
    /// #     0x00,
    /// #     0x00,
    /// #     // Null terminator
    /// #     0x00
    /// # ];
    /// # let debug_abbrev = DebugAbbrev::new(&abbrev_buf, LittleEndian);
    /// #
    /// # let get_some_unit = || debug_info.units().next().unwrap().unwrap();
    ///
    /// let unit = get_some_unit();
    /// # let get_abbrevs_for_unit = |_| unit.abbreviations(&debug_abbrev).unwrap();
    /// let abbrevs = get_abbrevs_for_unit(&unit);
    ///
    /// let mut first_entry_with_no_children = None;
    /// let mut cursor = unit.entries(&abbrevs);
    ///
    /// // Move the cursor to the root.
    /// assert!(cursor.next_dfs().unwrap().is_some());
    ///
    /// // Traverse the DIE tree in depth-first search order.
    /// let mut depth = 0;
    /// while let Some((delta_depth, current)) = cursor.next_dfs().expect("Should parse next dfs") {
    ///     // Update depth value, and break out of the loop when we
    ///     // return to the original starting position.
    ///     depth += delta_depth;
    ///     if depth <= 0 {
    ///         break;
    ///     }
    ///
    ///     first_entry_with_no_children = Some(current.clone());
    /// }
    ///
    /// println!("The first entry with no children is {:?}",
    ///          first_entry_with_no_children.unwrap());
    /// ```
    pub fn next_dfs(
        &mut self,
    ) -> Result<Option<(isize, &DebuggingInformationEntry<'abbrev, 'unit, R>)>> {
        let mut delta_depth = self.delta_depth;
        loop {
            // The next entry should be the one we want.
            if self.next_entry()?.is_some() {
                if let Some(ref entry) = self.cached_current {
                    return Ok(Some((delta_depth, entry)));
                }

                // next_entry() read a null entry.
                delta_depth += self.delta_depth;
            } else {
                return Ok(None);
            }
        }
    }

    /// Move the cursor to the next sibling DIE of the current one.
    ///
    /// Returns `Ok(Some(entry))` when the cursor has been moved to
    /// the next sibling, `Ok(None)` when there is no next sibling.
    ///
    /// The depth of the cursor is never changed if this method returns `Ok`.
    /// Once `Ok(None)` is returned, this method will continue to return
    /// `Ok(None)` until either `next_entry` or `next_dfs` is called.
    ///
    /// Here is an example that iterates over all of the direct children of the
    /// root entry:
    ///
    /// ```
    /// # use gimli::{DebugAbbrev, DebugInfo, LittleEndian};
    /// # let info_buf = [
    /// #     // Comilation unit header
    /// #
    /// #     // 32-bit unit length = 25
    /// #     0x19, 0x00, 0x00, 0x00,
    /// #     // Version 4
    /// #     0x04, 0x00,
    /// #     // debug_abbrev_offset
    /// #     0x00, 0x00, 0x00, 0x00,
    /// #     // Address size
    /// #     0x04,
    /// #
    /// #     // DIEs
    /// #
    /// #     // Abbreviation code
    /// #     0x01,
    /// #     // Attribute of form DW_FORM_string = "foo\0"
    /// #     0x66, 0x6f, 0x6f, 0x00,
    /// #
    /// #       // Children
    /// #
    /// #       // Abbreviation code
    /// #       0x01,
    /// #       // Attribute of form DW_FORM_string = "foo\0"
    /// #       0x66, 0x6f, 0x6f, 0x00,
    /// #
    /// #         // Children
    /// #
    /// #         // Abbreviation code
    /// #         0x01,
    /// #         // Attribute of form DW_FORM_string = "foo\0"
    /// #         0x66, 0x6f, 0x6f, 0x00,
    /// #
    /// #           // Children
    /// #
    /// #           // End of children
    /// #           0x00,
    /// #
    /// #         // End of children
    /// #         0x00,
    /// #
    /// #       // End of children
    /// #       0x00,
    /// # ];
    /// # let debug_info = DebugInfo::new(&info_buf, LittleEndian);
    /// #
    /// # let get_some_unit = || debug_info.units().next().unwrap().unwrap();
    ///
    /// # let abbrev_buf = [
    /// #     // Code
    /// #     0x01,
    /// #     // DW_TAG_subprogram
    /// #     0x2e,
    /// #     // DW_CHILDREN_yes
    /// #     0x01,
    /// #     // Begin attributes
    /// #       // Attribute name = DW_AT_name
    /// #       0x03,
    /// #       // Attribute form = DW_FORM_string
    /// #       0x08,
    /// #     // End attributes
    /// #     0x00,
    /// #     0x00,
    /// #     // Null terminator
    /// #     0x00
    /// # ];
    /// # let debug_abbrev = DebugAbbrev::new(&abbrev_buf, LittleEndian);
    /// #
    /// let unit = get_some_unit();
    /// # let get_abbrevs_for_unit = |_| unit.abbreviations(&debug_abbrev).unwrap();
    /// let abbrevs = get_abbrevs_for_unit(&unit);
    ///
    /// let mut cursor = unit.entries(&abbrevs);
    ///
    /// // Move the cursor to the root.
    /// assert!(cursor.next_dfs().unwrap().is_some());
    ///
    /// // Move the cursor to the root's first child.
    /// assert!(cursor.next_dfs().unwrap().is_some());
    ///
    /// // Iterate the root's children.
    /// loop {
    ///     {
    ///         let current = cursor.current().expect("Should be at an entry");
    ///         println!("{:?} is a child of the root", current);
    ///     }
    ///
    ///     if cursor.next_sibling().expect("Should parse next sibling").is_none() {
    ///         break;
    ///     }
    /// }
    /// ```
    pub fn next_sibling(
        &mut self,
    ) -> Result<Option<&DebuggingInformationEntry<'abbrev, 'unit, R>>> {
        if self.current().is_none() {
            // We're already at the null for the end of the sibling list.
            return Ok(None);
        }

        // Loop until we find an entry at the current level.
        let mut depth = 0;
        loop {
            // Use is_some() and unwrap() to keep borrow checker happy.
            if self.current().is_some() && self.current().unwrap().has_children() {
                if let Some(sibling_input) = self.current().unwrap().sibling() {
                    // Fast path: this entry has a DW_AT_sibling
                    // attribute pointing to its sibling, so jump
                    // to it (which keeps us at the same depth).
                    self.input = sibling_input;
                    self.cached_current = None;
                } else {
                    // This entry has children, so the next entry is
                    // down one level.
                    depth += 1;
                }
            }

            if self.next_entry()?.is_none() {
                // End of input.
                return Ok(None);
            }

            if depth == 0 {
                // Found an entry at the current level.
                return Ok(self.current());
            }

            if self.current().is_none() {
                // A null entry means the end of a child list, so we're
                // back up a level.
                depth -= 1;
            }
        }
    }
}

/// The state information for a tree view of the Debugging Information Entries.
///
/// The `EntriesTree` can be used to recursively iterate through the DIE
/// tree, following the parent/child relationships. The `EntriesTree` contains
/// shared state for all nodes in the tree, avoiding any duplicate parsing of
/// entries during the traversal.
///
/// ## Example Usage
/// ```rust,no_run
/// # fn example() -> Result<(), gimli::Error> {
/// # let debug_info = gimli::DebugInfo::new(&[], gimli::LittleEndian);
/// # let get_some_unit = || debug_info.units().next().unwrap().unwrap();
/// let unit = get_some_unit();
/// # let debug_abbrev = gimli::DebugAbbrev::new(&[], gimli::LittleEndian);
/// # let get_abbrevs_for_unit = |_| unit.abbreviations(&debug_abbrev).unwrap();
/// let abbrevs = get_abbrevs_for_unit(&unit);
///
/// let mut tree = unit.entries_tree(&abbrevs, None)?;
/// let root = tree.root()?;
/// process_tree(root)?;
/// # unreachable!()
/// # }
///
/// fn process_tree<R>(mut node: gimli::EntriesTreeNode<R>) -> gimli::Result<()>
///     where R: gimli::Reader
/// {
///     {
///         // Examine the entry attributes.
///         let mut attrs = node.entry().attrs();
///         while let Some(attr) = attrs.next()? {
///         }
///     }
///     let mut children = node.children();
///     while let Some(child) = children.next()? {
///         // Recursively process a child.
///         process_tree(child);
///     }
///     Ok(())
/// }
/// ```
#[derive(Clone, Debug)]
pub struct EntriesTree<'abbrev, 'unit, R>
where
    R: Reader,
{
    root: R,
    unit: &'unit UnitHeader<R>,
    abbreviations: &'abbrev Abbreviations,
    input: R,
    entry: Option<DebuggingInformationEntry<'abbrev, 'unit, R>>,
    depth: isize,
}

impl<'abbrev, 'unit, R: Reader> EntriesTree<'abbrev, 'unit, R> {
    fn new(root: R, unit: &'unit UnitHeader<R>, abbreviations: &'abbrev Abbreviations) -> Self {
        let input = root.clone();
        EntriesTree {
            root,
            unit,
            abbreviations,
            input,
            entry: None,
            depth: 0,
        }
    }

    /// Returns the root node of the tree.
    pub fn root<'me>(&'me mut self) -> Result<EntriesTreeNode<'abbrev, 'unit, 'me, R>> {
        self.input = self.root.clone();
        self.entry =
            DebuggingInformationEntry::parse(&mut self.input, self.unit, self.abbreviations)?;
        if self.entry.is_none() {
            return Err(Error::UnexpectedNull);
        }
        self.depth = 0;
        Ok(EntriesTreeNode::new(self, 1))
    }

    /// Move the cursor to the next entry at the specified depth.
    ///
    /// Requires `depth <= self.depth + 1`.
    ///
    /// Returns `true` if successful.
    fn next(&mut self, depth: isize) -> Result<bool> {
        if self.depth < depth {
            debug_assert_eq!(self.depth + 1, depth);

            match self.entry {
                Some(ref entry) => {
                    if !entry.has_children() {
                        return Ok(false);
                    }
                    self.depth += 1;
                    self.input = entry.after_attrs()?;
                }
                None => return Ok(false),
            }

            if self.input.is_empty() {
                self.entry = None;
                return Ok(false);
            }

            return match DebuggingInformationEntry::parse(
                &mut self.input,
                self.unit,
                self.abbreviations,
            ) {
                Ok(entry) => {
                    self.entry = entry;
                    Ok(self.entry.is_some())
                }
                Err(e) => {
                    self.input.empty();
                    self.entry = None;
                    Err(e)
                }
            };
        }

        loop {
            match self.entry {
                Some(ref entry) => {
                    if entry.has_children() {
                        if let Some(sibling_input) = entry.sibling() {
                            // Fast path: this entry has a DW_AT_sibling
                            // attribute pointing to its sibling, so jump
                            // to it (which keeps us at the same depth).
                            self.input = sibling_input;
                        } else {
                            // This entry has children, so the next entry is
                            // down one level.
                            self.depth += 1;
                            self.input = entry.after_attrs()?;
                        }
                    } else {
                        // This entry has no children, so next entry is at same depth.
                        self.input = entry.after_attrs()?;
                    }
                }
                None => {
                    // This entry is a null, so next entry is up one level.
                    self.depth -= 1;
                }
            }

            if self.input.is_empty() {
                self.entry = None;
                return Ok(false);
            }

            match DebuggingInformationEntry::parse(&mut self.input, self.unit, self.abbreviations) {
                Ok(entry) => {
                    self.entry = entry;
                    if self.depth == depth {
                        return Ok(self.entry.is_some());
                    }
                }
                Err(e) => {
                    self.input.empty();
                    self.entry = None;
                    return Err(e);
                }
            }
        }
    }
}

/// A node in the Debugging Information Entry tree.
///
/// The root node of a tree can be obtained
/// via [`EntriesTree::root`](./struct.EntriesTree.html#method.root).
#[derive(Debug)]
pub struct EntriesTreeNode<'abbrev, 'unit, 'tree, R: Reader> {
    tree: &'tree mut EntriesTree<'abbrev, 'unit, R>,
    depth: isize,
}

impl<'abbrev, 'unit, 'tree, R: Reader> EntriesTreeNode<'abbrev, 'unit, 'tree, R> {
    fn new(
        tree: &'tree mut EntriesTree<'abbrev, 'unit, R>,
        depth: isize,
    ) -> EntriesTreeNode<'abbrev, 'unit, 'tree, R> {
        debug_assert!(tree.entry.is_some());
        EntriesTreeNode { tree, depth }
    }

    /// Returns the current entry in the tree.
    pub fn entry(&self) -> &DebuggingInformationEntry<'abbrev, 'unit, R> {
        // We never create a node without an entry.
        self.tree.entry.as_ref().unwrap()
    }

    /// Create an iterator for the children of the current entry.
    ///
    /// The current entry can no longer be accessed after creating the
    /// iterator.
    pub fn children(self) -> EntriesTreeIter<'abbrev, 'unit, 'tree, R> {
        EntriesTreeIter::new(self.tree, self.depth)
    }
}

/// An iterator that allows traversal of the children of an
/// `EntriesTreeNode`.
///
/// The items returned by this iterator are also `EntriesTreeNode`s,
/// which allow recursive traversal of grandchildren, etc.
#[derive(Debug)]
pub struct EntriesTreeIter<'abbrev, 'unit, 'tree, R: Reader> {
    tree: &'tree mut EntriesTree<'abbrev, 'unit, R>,
    depth: isize,
    empty: bool,
}

impl<'abbrev, 'unit, 'tree, R: Reader> EntriesTreeIter<'abbrev, 'unit, 'tree, R> {
    fn new(
        tree: &'tree mut EntriesTree<'abbrev, 'unit, R>,
        depth: isize,
    ) -> EntriesTreeIter<'abbrev, 'unit, 'tree, R> {
        EntriesTreeIter {
            tree,
            depth,
            empty: false,
        }
    }

    /// Returns an `EntriesTreeNode` for the next child entry.
    ///
    /// Returns `None` if there are no more children.
    pub fn next<'me>(&'me mut self) -> Result<Option<EntriesTreeNode<'abbrev, 'unit, 'me, R>>> {
        if self.empty {
            Ok(None)
        } else if self.tree.next(self.depth)? {
            Ok(Some(EntriesTreeNode::new(self.tree, self.depth + 1)))
        } else {
            self.empty = true;
            Ok(None)
        }
    }
}

/// Parse a type unit header's unique type signature. Callers should handle
/// unique-ness checking.
fn parse_type_signature<R: Reader>(input: &mut R) -> Result<DebugTypeSignature> {
    input.read_u64().map(DebugTypeSignature)
}

/// Parse a type unit header's type offset.
fn parse_type_offset<R: Reader>(input: &mut R, format: Format) -> Result<UnitOffset<R::Offset>> {
    input.read_offset(format).map(UnitOffset)
}

/// The `DebugTypes` struct represents the DWARF type information
/// found in the `.debug_types` section.
#[derive(Debug, Default, Clone, Copy)]
pub struct DebugTypes<R> {
    debug_types_section: R,
}

impl<'input, Endian> DebugTypes<EndianSlice<'input, Endian>>
where
    Endian: Endianity,
{
    /// Construct a new `DebugTypes` instance from the data in the `.debug_types`
    /// section.
    ///
    /// It is the caller's responsibility to read the `.debug_types` section and
    /// present it as a `&[u8]` slice. That means using some ELF loader on
    /// Linux, a Mach-O loader on macOS, etc.
    ///
    /// ```
    /// use gimli::{DebugTypes, LittleEndian};
    ///
    /// # let buf = [0x00, 0x01, 0x02, 0x03];
    /// # let read_debug_types_section_somehow = || &buf;
    /// let debug_types = DebugTypes::new(read_debug_types_section_somehow(), LittleEndian);
    /// ```
    pub fn new(debug_types_section: &'input [u8], endian: Endian) -> Self {
        Self::from(EndianSlice::new(debug_types_section, endian))
    }
}

impl<T> DebugTypes<T> {
    /// Create a `DebugTypes` section that references the data in `self`.
    ///
    /// This is useful when `R` implements `Reader` but `T` does not.
    ///
    /// ## Example Usage
    ///
    /// ```rust,no_run
    /// # let load_section = || unimplemented!();
    /// // Read the DWARF section into a `Vec` with whatever object loader you're using.
    /// let owned_section: gimli::DebugTypes<Vec<u8>> = load_section();
    /// // Create a reference to the DWARF section.
    /// let section = owned_section.borrow(|section| {
    ///     gimli::EndianSlice::new(&section, gimli::LittleEndian)
    /// });
    /// ```
    pub fn borrow<'a, F, R>(&'a self, mut borrow: F) -> DebugTypes<R>
    where
        F: FnMut(&'a T) -> R,
    {
        borrow(&self.debug_types_section).into()
    }
}

impl<R> Section<R> for DebugTypes<R> {
    fn id() -> SectionId {
        SectionId::DebugTypes
    }

    fn reader(&self) -> &R {
        &self.debug_types_section
    }
}

impl<R> From<R> for DebugTypes<R> {
    fn from(debug_types_section: R) -> Self {
        DebugTypes {
            debug_types_section,
        }
    }
}

impl<R: Reader> DebugTypes<R> {
    /// Iterate the type-units in this `.debug_types` section.
    ///
    /// ```
    /// use gimli::{DebugTypes, LittleEndian};
    ///
    /// # let buf = [];
    /// # let read_debug_types_section_somehow = || &buf;
    /// let debug_types = DebugTypes::new(read_debug_types_section_somehow(), LittleEndian);
    ///
    /// let mut iter = debug_types.units();
    /// while let Some(unit) = iter.next().unwrap() {
    ///     println!("unit's length is {}", unit.unit_length());
    /// }
    /// ```
    ///
    /// Can be [used with
    /// `FallibleIterator`](./index.html#using-with-fallibleiterator).
    pub fn units(&self) -> DebugTypesUnitHeadersIter<R> {
        DebugTypesUnitHeadersIter {
            input: self.debug_types_section.clone(),
            offset: DebugTypesOffset(R::Offset::from_u8(0)),
        }
    }
}

/// An iterator over the type-units of this `.debug_types` section.
///
/// See the [documentation on
/// `DebugTypes::units`](./struct.DebugTypes.html#method.units) for
/// more detail.
#[derive(Clone, Debug)]
pub struct DebugTypesUnitHeadersIter<R: Reader> {
    input: R,
    offset: DebugTypesOffset<R::Offset>,
}

impl<R: Reader> DebugTypesUnitHeadersIter<R> {
    /// Advance the iterator to the next type unit header.
    pub fn next(&mut self) -> Result<Option<UnitHeader<R>>> {
        if self.input.is_empty() {
            Ok(None)
        } else {
            let len = self.input.len();
            match parse_unit_header(&mut self.input, self.offset.into()) {
                Ok(header) => {
                    self.offset.0 += len - self.input.len();
                    Ok(Some(header))
                }
                Err(e) => {
                    self.input.empty();
                    Err(e)
                }
            }
        }
    }
}

#[cfg(feature = "fallible-iterator")]
impl<R: Reader> fallible_iterator::FallibleIterator for DebugTypesUnitHeadersIter<R> {
    type Item = UnitHeader<R>;
    type Error = Error;

    fn next(&mut self) -> ::core::result::Result<Option<Self::Item>, Self::Error> {
        DebugTypesUnitHeadersIter::next(self)
    }
}

#[cfg(test)]
// Tests require leb128::write.
#[cfg(feature = "write")]
mod tests {
    use super::*;
    use crate::constants;
    use crate::constants::*;
    use crate::endianity::{Endianity, LittleEndian};
    use crate::leb128;
    use crate::read::abbrev::tests::AbbrevSectionMethods;
    use crate::read::{
        Abbreviation, AttributeSpecification, DebugAbbrev, EndianSlice, Error, Result,
    };
    use crate::test_util::GimliSectionMethods;
    use alloc::vec::Vec;
    use core::cell::Cell;
    use test_assembler::{Endian, Label, LabelMaker, Section};

    // Mixin methods for `Section` to help define binary test data.

    trait UnitSectionMethods {
        fn unit<'input, E>(self, unit: &mut UnitHeader<EndianSlice<'input, E>>) -> Self
        where
            E: Endianity;
        fn die<F>(self, code: u64, attr: F) -> Self
        where
            F: Fn(Section) -> Section;
        fn die_null(self) -> Self;
        fn attr_string(self, s: &str) -> Self;
        fn attr_ref1(self, o: u8) -> Self;
        fn offset(self, offset: usize, format: Format) -> Self;
    }

    impl UnitSectionMethods for Section {
        fn unit<'input, E>(self, unit: &mut UnitHeader<EndianSlice<'input, E>>) -> Self
        where
            E: Endianity,
        {
            let size = self.size();
            let length = Label::new();
            let start = Label::new();
            let end = Label::new();

            let section = match unit.format() {
                Format::Dwarf32 => self.L32(&length),
                Format::Dwarf64 => self.L32(0xffff_ffff).L64(&length),
            };

            let section = match unit.version() {
                2 | 3 | 4 => section
                    .mark(&start)
                    .L16(unit.version())
                    .offset(unit.debug_abbrev_offset.0, unit.format())
                    .D8(unit.address_size()),
                5 => section
                    .mark(&start)
                    .L16(unit.version())
                    .D8(unit.type_().dw_ut().0)
                    .D8(unit.address_size())
                    .offset(unit.debug_abbrev_offset.0, unit.format()),
                _ => unreachable!(),
            };

            let section = match unit.type_() {
                UnitType::Compilation | UnitType::Partial => {
                    unit.unit_offset = DebugInfoOffset(size as usize).into();
                    section
                }
                UnitType::Type {
                    type_signature,
                    type_offset,
                }
                | UnitType::SplitType {
                    type_signature,
                    type_offset,
                } => {
                    if unit.version() == 5 {
                        unit.unit_offset = DebugInfoOffset(size as usize).into();
                    } else {
                        unit.unit_offset = DebugTypesOffset(size as usize).into();
                    }
                    section
                        .L64(type_signature.0)
                        .offset(type_offset.0, unit.format())
                }
                UnitType::Skeleton(dwo_id) | UnitType::SplitCompilation(dwo_id) => {
                    unit.unit_offset = DebugInfoOffset(size as usize).into();
                    section.L64(dwo_id.0)
                }
            };

            let section = section.append_bytes(unit.entries_buf.slice()).mark(&end);

            unit.unit_length = (&end - &start) as usize;
            length.set_const(unit.unit_length as u64);

            section
        }

        fn die<F>(self, code: u64, attr: F) -> Self
        where
            F: Fn(Section) -> Section,
        {
            let section = self.uleb(code);
            attr(section)
        }

        fn die_null(self) -> Self {
            self.D8(0)
        }

        fn attr_string(self, attr: &str) -> Self {
            self.append_bytes(attr.as_bytes()).D8(0)
        }

        fn attr_ref1(self, attr: u8) -> Self {
            self.D8(attr)
        }

        fn offset(self, offset: usize, format: Format) -> Self {
            match format {
                Format::Dwarf32 => self.L32(offset as u32),
                Format::Dwarf64 => self.L64(offset as u64),
            }
        }
    }

    /// Ensure that `UnitHeader<R>` is covariant wrt R.
    #[test]
    fn test_unit_header_variance() {
        /// This only needs to compile.
        fn _f<'a: 'b, 'b, E: Endianity>(
            x: UnitHeader<EndianSlice<'a, E>>,
        ) -> UnitHeader<EndianSlice<'b, E>> {
            x
        }
    }

    #[test]
    fn test_parse_debug_abbrev_offset_32() {
        let section = Section::with_endian(Endian::Little).L32(0x0403_0201);
        let buf = section.get_contents().unwrap();
        let buf = &mut EndianSlice::new(&buf, LittleEndian);

        match parse_debug_abbrev_offset(buf, Format::Dwarf32) {
            Ok(val) => assert_eq!(val, DebugAbbrevOffset(0x0403_0201)),
            otherwise => panic!("Unexpected result: {:?}", otherwise),
        };
    }

    #[test]
    fn test_parse_debug_abbrev_offset_32_incomplete() {
        let buf = [0x01, 0x02];
        let buf = &mut EndianSlice::new(&buf, LittleEndian);

        match parse_debug_abbrev_offset(buf, Format::Dwarf32) {
            Err(Error::UnexpectedEof(_)) => assert!(true),
            otherwise => panic!("Unexpected result: {:?}", otherwise),
        };
    }

    #[test]
    #[cfg(target_pointer_width = "64")]
    fn test_parse_debug_abbrev_offset_64() {
        let section = Section::with_endian(Endian::Little).L64(0x0807_0605_0403_0201);
        let buf = section.get_contents().unwrap();
        let buf = &mut EndianSlice::new(&buf, LittleEndian);

        match parse_debug_abbrev_offset(buf, Format::Dwarf64) {
            Ok(val) => assert_eq!(val, DebugAbbrevOffset(0x0807_0605_0403_0201)),
            otherwise => panic!("Unexpected result: {:?}", otherwise),
        };
    }

    #[test]
    fn test_parse_debug_abbrev_offset_64_incomplete() {
        let buf = [0x01, 0x02];
        let buf = &mut EndianSlice::new(&buf, LittleEndian);

        match parse_debug_abbrev_offset(buf, Format::Dwarf64) {
            Err(Error::UnexpectedEof(_)) => assert!(true),
            otherwise => panic!("Unexpected result: {:?}", otherwise),
        };
    }

    #[test]
    fn test_parse_debug_info_offset_32() {
        let section = Section::with_endian(Endian::Little).L32(0x0403_0201);
        let buf = section.get_contents().unwrap();
        let buf = &mut EndianSlice::new(&buf, LittleEndian);

        match parse_debug_info_offset(buf, Format::Dwarf32) {
            Ok(val) => assert_eq!(val, DebugInfoOffset(0x0403_0201)),
            otherwise => panic!("Unexpected result: {:?}", otherwise),
        };
    }

    #[test]
    fn test_parse_debug_info_offset_32_incomplete() {
        let buf = [0x01, 0x02];
        let buf = &mut EndianSlice::new(&buf, LittleEndian);

        match parse_debug_info_offset(buf, Format::Dwarf32) {
            Err(Error::UnexpectedEof(_)) => assert!(true),
            otherwise => panic!("Unexpected result: {:?}", otherwise),
        };
    }

    #[test]
    #[cfg(target_pointer_width = "64")]
    fn test_parse_debug_info_offset_64() {
        let section = Section::with_endian(Endian::Little).L64(0x0807_0605_0403_0201);
        let buf = section.get_contents().unwrap();
        let buf = &mut EndianSlice::new(&buf, LittleEndian);

        match parse_debug_info_offset(buf, Format::Dwarf64) {
            Ok(val) => assert_eq!(val, DebugInfoOffset(0x0807_0605_0403_0201)),
            otherwise => panic!("Unexpected result: {:?}", otherwise),
        };
    }

    #[test]
    fn test_parse_debug_info_offset_64_incomplete() {
        let buf = [0x01, 0x02];
        let buf = &mut EndianSlice::new(&buf, LittleEndian);

        match parse_debug_info_offset(buf, Format::Dwarf64) {
            Err(Error::UnexpectedEof(_)) => assert!(true),
            otherwise => panic!("Unexpected result: {:?}", otherwise),
        };
    }

    #[test]
    #[cfg(target_pointer_width = "64")]
    fn test_units() {
        let expected_rest = &[1, 2, 3, 4, 5, 6, 7, 8, 9];
        let mut unit64 = UnitHeader {
            encoding: Encoding {
                format: Format::Dwarf64,
                version: 4,
                address_size: 8,
            },
            unit_length: 0,
            unit_type: UnitType::Compilation,
            debug_abbrev_offset: DebugAbbrevOffset(0x0102_0304_0506_0708),
            unit_offset: DebugInfoOffset(0).into(),
            entries_buf: EndianSlice::new(expected_rest, LittleEndian),
        };
        let mut unit32 = UnitHeader {
            encoding: Encoding {
                format: Format::Dwarf32,
                version: 4,
                address_size: 4,
            },
            unit_length: 0,
            unit_type: UnitType::Compilation,
            debug_abbrev_offset: DebugAbbrevOffset(0x0807_0605),
            unit_offset: DebugInfoOffset(0).into(),
            entries_buf: EndianSlice::new(expected_rest, LittleEndian),
        };
        let section = Section::with_endian(Endian::Little)
            .unit(&mut unit64)
            .unit(&mut unit32);
        let buf = section.get_contents().unwrap();

        let debug_info = DebugInfo::new(&buf, LittleEndian);
        let mut units = debug_info.units();

        assert_eq!(units.next(), Ok(Some(unit64)));
        assert_eq!(units.next(), Ok(Some(unit32)));
        assert_eq!(units.next(), Ok(None));
    }

    #[test]
    fn test_unit_version_unknown_version() {
        let buf = [0x02, 0x00, 0x00, 0x00, 0xab, 0xcd];
        let rest = &mut EndianSlice::new(&buf, LittleEndian);

        match parse_unit_header(rest, DebugInfoOffset(0).into()) {
            Err(Error::UnknownVersion(0xcdab)) => assert!(true),
            otherwise => panic!("Unexpected result: {:?}", otherwise),
        };

        let buf = [0x02, 0x00, 0x00, 0x00, 0x1, 0x0];
        let rest = &mut EndianSlice::new(&buf, LittleEndian);

        match parse_unit_header(rest, DebugInfoOffset(0).into()) {
            Err(Error::UnknownVersion(1)) => assert!(true),
            otherwise => panic!("Unexpected result: {:?}", otherwise),
        };
    }

    #[test]
    fn test_unit_version_incomplete() {
        let buf = [0x01, 0x00, 0x00, 0x00, 0x04];
        let rest = &mut EndianSlice::new(&buf, LittleEndian);

        match parse_unit_header(rest, DebugInfoOffset(0).into()) {
            Err(Error::UnexpectedEof(_)) => assert!(true),
            otherwise => panic!("Unexpected result: {:?}", otherwise),
        };
    }

    #[test]
    fn test_parse_unit_header_32_ok() {
        let expected_rest = &[1, 2, 3, 4, 5, 6, 7, 8, 9];
        let encoding = Encoding {
            format: Format::Dwarf32,
            version: 4,
            address_size: 4,
        };
        let mut expected_unit = UnitHeader {
            encoding,
            unit_length: 0,
            unit_type: UnitType::Compilation,
            debug_abbrev_offset: DebugAbbrevOffset(0x0807_0605),
            unit_offset: DebugInfoOffset(0).into(),
            entries_buf: EndianSlice::new(expected_rest, LittleEndian),
        };
        let section = Section::with_endian(Endian::Little)
            .unit(&mut expected_unit)
            .append_bytes(expected_rest);
        let buf = section.get_contents().unwrap();
        let rest = &mut EndianSlice::new(&buf, LittleEndian);

        assert_eq!(
            parse_unit_header(rest, DebugInfoOffset(0).into()),
            Ok(expected_unit)
        );
        assert_eq!(*rest, EndianSlice::new(expected_rest, LittleEndian));
    }

    #[test]
    #[cfg(target_pointer_width = "64")]
    fn test_parse_unit_header_64_ok() {
        let expected_rest = &[1, 2, 3, 4, 5, 6, 7, 8, 9];
        let encoding = Encoding {
            format: Format::Dwarf64,
            version: 4,
            address_size: 8,
        };
        let mut expected_unit = UnitHeader {
            encoding,
            unit_length: 0,
            unit_type: UnitType::Compilation,
            debug_abbrev_offset: DebugAbbrevOffset(0x0102_0304_0506_0708),
            unit_offset: DebugInfoOffset(0).into(),
            entries_buf: EndianSlice::new(expected_rest, LittleEndian),
        };
        let section = Section::with_endian(Endian::Little)
            .unit(&mut expected_unit)
            .append_bytes(expected_rest);
        let buf = section.get_contents().unwrap();
        let rest = &mut EndianSlice::new(&buf, LittleEndian);

        assert_eq!(
            parse_unit_header(rest, DebugInfoOffset(0).into()),
            Ok(expected_unit)
        );
        assert_eq!(*rest, EndianSlice::new(expected_rest, LittleEndian));
    }

    #[test]
    fn test_parse_v5_unit_header_32_ok() {
        let expected_rest = &[1, 2, 3, 4, 5, 6, 7, 8, 9];
        let encoding = Encoding {
            format: Format::Dwarf32,
            version: 5,
            address_size: 4,
        };
        let mut expected_unit = UnitHeader {
            encoding,
            unit_length: 0,
            unit_type: UnitType::Compilation,
            debug_abbrev_offset: DebugAbbrevOffset(0x0807_0605),
            unit_offset: DebugInfoOffset(0).into(),
            entries_buf: EndianSlice::new(expected_rest, LittleEndian),
        };
        let section = Section::with_endian(Endian::Little)
            .unit(&mut expected_unit)
            .append_bytes(expected_rest);
        let buf = section.get_contents().unwrap();
        let rest = &mut EndianSlice::new(&buf, LittleEndian);

        assert_eq!(
            parse_unit_header(rest, DebugInfoOffset(0).into()),
            Ok(expected_unit)
        );
        assert_eq!(*rest, EndianSlice::new(expected_rest, LittleEndian));
    }

    #[test]
    #[cfg(target_pointer_width = "64")]
    fn test_parse_v5_unit_header_64_ok() {
        let expected_rest = &[1, 2, 3, 4, 5, 6, 7, 8, 9];
        let encoding = Encoding {
            format: Format::Dwarf64,
            version: 5,
            address_size: 8,
        };
        let mut expected_unit = UnitHeader {
            encoding,
            unit_length: 0,
            unit_type: UnitType::Compilation,
            debug_abbrev_offset: DebugAbbrevOffset(0x0102_0304_0506_0708),
            unit_offset: DebugInfoOffset(0).into(),
            entries_buf: EndianSlice::new(expected_rest, LittleEndian),
        };
        let section = Section::with_endian(Endian::Little)
            .unit(&mut expected_unit)
            .append_bytes(expected_rest);
        let buf = section.get_contents().unwrap();
        let rest = &mut EndianSlice::new(&buf, LittleEndian);

        assert_eq!(
            parse_unit_header(rest, DebugInfoOffset(0).into()),
            Ok(expected_unit)
        );
        assert_eq!(*rest, EndianSlice::new(expected_rest, LittleEndian));
    }

    #[test]
    fn test_parse_v5_partial_unit_header_32_ok() {
        let expected_rest = &[1, 2, 3, 4, 5, 6, 7, 8, 9];
        let encoding = Encoding {
            format: Format::Dwarf32,
            version: 5,
            address_size: 4,
        };
        let mut expected_unit = UnitHeader {
            encoding,
            unit_length: 0,
            unit_type: UnitType::Partial,
            debug_abbrev_offset: DebugAbbrevOffset(0x0807_0605),
            unit_offset: DebugInfoOffset(0).into(),
            entries_buf: EndianSlice::new(expected_rest, LittleEndian),
        };
        let section = Section::with_endian(Endian::Little)
            .unit(&mut expected_unit)
            .append_bytes(expected_rest);
        let buf = section.get_contents().unwrap();
        let rest = &mut EndianSlice::new(&buf, LittleEndian);

        assert_eq!(
            parse_unit_header(rest, DebugInfoOffset(0).into()),
            Ok(expected_unit)
        );
        assert_eq!(*rest, EndianSlice::new(expected_rest, LittleEndian));
    }

    #[test]
    #[cfg(target_pointer_width = "64")]
    fn test_parse_v5_partial_unit_header_64_ok() {
        let expected_rest = &[1, 2, 3, 4, 5, 6, 7, 8, 9];
        let encoding = Encoding {
            format: Format::Dwarf64,
            version: 5,
            address_size: 8,
        };
        let mut expected_unit = UnitHeader {
            encoding,
            unit_length: 0,
            unit_type: UnitType::Partial,
            debug_abbrev_offset: DebugAbbrevOffset(0x0102_0304_0506_0708),
            unit_offset: DebugInfoOffset(0).into(),
            entries_buf: EndianSlice::new(expected_rest, LittleEndian),
        };
        let section = Section::with_endian(Endian::Little)
            .unit(&mut expected_unit)
            .append_bytes(expected_rest);
        let buf = section.get_contents().unwrap();
        let rest = &mut EndianSlice::new(&buf, LittleEndian);

        assert_eq!(
            parse_unit_header(rest, DebugInfoOffset(0).into()),
            Ok(expected_unit)
        );
        assert_eq!(*rest, EndianSlice::new(expected_rest, LittleEndian));
    }

    #[test]
    fn test_parse_v5_skeleton_unit_header_32_ok() {
        let expected_rest = &[1, 2, 3, 4, 5, 6, 7, 8, 9];
        let encoding = Encoding {
            format: Format::Dwarf32,
            version: 5,
            address_size: 4,
        };
        let mut expected_unit = UnitHeader {
            encoding,
            unit_length: 0,
            unit_type: UnitType::Skeleton(DwoId(0x0706_5040_0302_1000)),
            debug_abbrev_offset: DebugAbbrevOffset(0x0807_0605),
            unit_offset: DebugInfoOffset(0).into(),
            entries_buf: EndianSlice::new(expected_rest, LittleEndian),
        };
        let section = Section::with_endian(Endian::Little)
            .unit(&mut expected_unit)
            .append_bytes(expected_rest);
        let buf = section.get_contents().unwrap();
        let rest = &mut EndianSlice::new(&buf, LittleEndian);

        assert_eq!(
            parse_unit_header(rest, DebugInfoOffset(0).into()),
            Ok(expected_unit)
        );
        assert_eq!(*rest, EndianSlice::new(expected_rest, LittleEndian));
    }

    #[test]
    #[cfg(target_pointer_width = "64")]
    fn test_parse_v5_skeleton_unit_header_64_ok() {
        let expected_rest = &[1, 2, 3, 4, 5, 6, 7, 8, 9];
        let encoding = Encoding {
            format: Format::Dwarf64,
            version: 5,
            address_size: 8,
        };
        let mut expected_unit = UnitHeader {
            encoding,
            unit_length: 0,
            unit_type: UnitType::Skeleton(DwoId(0x0706_5040_0302_1000)),
            debug_abbrev_offset: DebugAbbrevOffset(0x0102_0304_0506_0708),
            unit_offset: DebugInfoOffset(0).into(),
            entries_buf: EndianSlice::new(expected_rest, LittleEndian),
        };
        let section = Section::with_endian(Endian::Little)
            .unit(&mut expected_unit)
            .append_bytes(expected_rest);
        let buf = section.get_contents().unwrap();
        let rest = &mut EndianSlice::new(&buf, LittleEndian);

        assert_eq!(
            parse_unit_header(rest, DebugInfoOffset(0).into()),
            Ok(expected_unit)
        );
        assert_eq!(*rest, EndianSlice::new(expected_rest, LittleEndian));
    }

    #[test]
    fn test_parse_v5_split_compilation_unit_header_32_ok() {
        let expected_rest = &[1, 2, 3, 4, 5, 6, 7, 8, 9];
        let encoding = Encoding {
            format: Format::Dwarf32,
            version: 5,
            address_size: 4,
        };
        let mut expected_unit = UnitHeader {
            encoding,
            unit_length: 0,
            unit_type: UnitType::SplitCompilation(DwoId(0x0706_5040_0302_1000)),
            debug_abbrev_offset: DebugAbbrevOffset(0x0807_0605),
            unit_offset: DebugInfoOffset(0).into(),
            entries_buf: EndianSlice::new(expected_rest, LittleEndian),
        };
        let section = Section::with_endian(Endian::Little)
            .unit(&mut expected_unit)
            .append_bytes(expected_rest);
        let buf = section.get_contents().unwrap();
        let rest = &mut EndianSlice::new(&buf, LittleEndian);

        assert_eq!(
            parse_unit_header(rest, DebugInfoOffset(0).into()),
            Ok(expected_unit)
        );
        assert_eq!(*rest, EndianSlice::new(expected_rest, LittleEndian));
    }

    #[test]
    #[cfg(target_pointer_width = "64")]
    fn test_parse_v5_split_compilation_unit_header_64_ok() {
        let expected_rest = &[1, 2, 3, 4, 5, 6, 7, 8, 9];
        let encoding = Encoding {
            format: Format::Dwarf64,
            version: 5,
            address_size: 8,
        };
        let mut expected_unit = UnitHeader {
            encoding,
            unit_length: 0,
            unit_type: UnitType::SplitCompilation(DwoId(0x0706_5040_0302_1000)),
            debug_abbrev_offset: DebugAbbrevOffset(0x0102_0304_0506_0708),
            unit_offset: DebugInfoOffset(0).into(),
            entries_buf: EndianSlice::new(expected_rest, LittleEndian),
        };
        let section = Section::with_endian(Endian::Little)
            .unit(&mut expected_unit)
            .append_bytes(expected_rest);
        let buf = section.get_contents().unwrap();
        let rest = &mut EndianSlice::new(&buf, LittleEndian);

        assert_eq!(
            parse_unit_header(rest, DebugInfoOffset(0).into()),
            Ok(expected_unit)
        );
        assert_eq!(*rest, EndianSlice::new(expected_rest, LittleEndian));
    }

    #[test]
    fn test_parse_type_offset_32_ok() {
        let buf = [0x12, 0x34, 0x56, 0x78, 0x00];
        let rest = &mut EndianSlice::new(&buf, LittleEndian);

        match parse_type_offset(rest, Format::Dwarf32) {
            Ok(offset) => {
                assert_eq!(rest.len(), 1);
                assert_eq!(UnitOffset(0x7856_3412), offset);
            }
            otherwise => panic!("Unexpected result: {:?}", otherwise),
        }
    }

    #[test]
    #[cfg(target_pointer_width = "64")]
    fn test_parse_type_offset_64_ok() {
        let buf = [0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xff, 0x00];
        let rest = &mut EndianSlice::new(&buf, LittleEndian);

        match parse_type_offset(rest, Format::Dwarf64) {
            Ok(offset) => {
                assert_eq!(rest.len(), 1);
                assert_eq!(UnitOffset(0xffde_bc9a_7856_3412), offset);
            }
            otherwise => panic!("Unexpected result: {:?}", otherwise),
        }
    }

    #[test]
    fn test_parse_type_offset_incomplete() {
        // Need at least 4 bytes.
        let buf = [0xff, 0xff, 0xff];
        let rest = &mut EndianSlice::new(&buf, LittleEndian);

        match parse_type_offset(rest, Format::Dwarf32) {
            Err(Error::UnexpectedEof(_)) => assert!(true),
            otherwise => panic!("Unexpected result: {:?}", otherwise),
        };
    }

    #[test]
    fn test_parse_type_unit_header_32_ok() {
        let expected_rest = &[1, 2, 3, 4, 5, 6, 7, 8, 9];
        let encoding = Encoding {
            format: Format::Dwarf32,
            version: 4,
            address_size: 8,
        };
        let mut expected_unit = UnitHeader {
            encoding,
            unit_length: 0,
            unit_type: UnitType::Type {
                type_signature: DebugTypeSignature(0xdead_beef_dead_beef),
                type_offset: UnitOffset(0x7856_3412),
            },
            debug_abbrev_offset: DebugAbbrevOffset(0x0807_0605),
            unit_offset: DebugTypesOffset(0).into(),
            entries_buf: EndianSlice::new(expected_rest, LittleEndian),
        };
        let section = Section::with_endian(Endian::Little)
            .unit(&mut expected_unit)
            .append_bytes(expected_rest);
        let buf = section.get_contents().unwrap();
        let rest = &mut EndianSlice::new(&buf, LittleEndian);

        assert_eq!(
            parse_unit_header(rest, DebugTypesOffset(0).into()),
            Ok(expected_unit)
        );
        assert_eq!(*rest, EndianSlice::new(expected_rest, LittleEndian));
    }

    #[test]
    #[cfg(target_pointer_width = "64")]
    fn test_parse_type_unit_header_64_ok() {
        let expected_rest = &[1, 2, 3, 4, 5, 6, 7, 8, 9];
        let encoding = Encoding {
            format: Format::Dwarf64,
            version: 4,
            address_size: 8,
        };
        let mut expected_unit = UnitHeader {
            encoding,
            unit_length: 0,
            unit_type: UnitType::Type {
                type_signature: DebugTypeSignature(0xdead_beef_dead_beef),
                type_offset: UnitOffset(0x7856_3412_7856_3412),
            },
            debug_abbrev_offset: DebugAbbrevOffset(0x0807_0605),
            unit_offset: DebugTypesOffset(0).into(),
            entries_buf: EndianSlice::new(expected_rest, LittleEndian),
        };
        let section = Section::with_endian(Endian::Little)
            .unit(&mut expected_unit)
            .append_bytes(expected_rest);
        let buf = section.get_contents().unwrap();
        let rest = &mut EndianSlice::new(&buf, LittleEndian);

        assert_eq!(
            parse_unit_header(rest, DebugTypesOffset(0).into()),
            Ok(expected_unit)
        );
        assert_eq!(*rest, EndianSlice::new(expected_rest, LittleEndian));
    }

    #[test]
    fn test_parse_v5_type_unit_header_32_ok() {
        let expected_rest = &[1, 2, 3, 4, 5, 6, 7, 8, 9];
        let encoding = Encoding {
            format: Format::Dwarf32,
            version: 5,
            address_size: 8,
        };
        let mut expected_unit = UnitHeader {
            encoding,
            unit_length: 0,
            unit_type: UnitType::Type {
                type_signature: DebugTypeSignature(0xdead_beef_dead_beef),
                type_offset: UnitOffset(0x7856_3412),
            },
            debug_abbrev_offset: DebugAbbrevOffset(0x0807_0605),
            unit_offset: DebugInfoOffset(0).into(),
            entries_buf: EndianSlice::new(expected_rest, LittleEndian),
        };
        let section = Section::with_endian(Endian::Little)
            .unit(&mut expected_unit)
            .append_bytes(expected_rest);
        let buf = section.get_contents().unwrap();
        let rest = &mut EndianSlice::new(&buf, LittleEndian);

        assert_eq!(
            parse_unit_header(rest, DebugInfoOffset(0).into()),
            Ok(expected_unit)
        );
        assert_eq!(*rest, EndianSlice::new(expected_rest, LittleEndian));
    }

    #[test]
    #[cfg(target_pointer_width = "64")]
    fn test_parse_v5_type_unit_header_64_ok() {
        let expected_rest = &[1, 2, 3, 4, 5, 6, 7, 8, 9];
        let encoding = Encoding {
            format: Format::Dwarf64,
            version: 5,
            address_size: 8,
        };
        let mut expected_unit = UnitHeader {
            encoding,
            unit_length: 0,
            unit_type: UnitType::Type {
                type_signature: DebugTypeSignature(0xdead_beef_dead_beef),
                type_offset: UnitOffset(0x7856_3412_7856_3412),
            },
            debug_abbrev_offset: DebugAbbrevOffset(0x0807_0605),
            unit_offset: DebugInfoOffset(0).into(),
            entries_buf: EndianSlice::new(expected_rest, LittleEndian),
        };
        let section = Section::with_endian(Endian::Little)
            .unit(&mut expected_unit)
            .append_bytes(expected_rest);
        let buf = section.get_contents().unwrap();
        let rest = &mut EndianSlice::new(&buf, LittleEndian);

        assert_eq!(
            parse_unit_header(rest, DebugInfoOffset(0).into()),
            Ok(expected_unit)
        );
        assert_eq!(*rest, EndianSlice::new(expected_rest, LittleEndian));
    }

    #[test]
    fn test_parse_v5_split_type_unit_header_32_ok() {
        let expected_rest = &[1, 2, 3, 4, 5, 6, 7, 8, 9];
        let encoding = Encoding {
            format: Format::Dwarf32,
            version: 5,
            address_size: 8,
        };
        let mut expected_unit = UnitHeader {
            encoding,
            unit_length: 0,
            unit_type: UnitType::SplitType {
                type_signature: DebugTypeSignature(0xdead_beef_dead_beef),
                type_offset: UnitOffset(0x7856_3412),
            },
            debug_abbrev_offset: DebugAbbrevOffset(0x0807_0605),
            unit_offset: DebugInfoOffset(0).into(),
            entries_buf: EndianSlice::new(expected_rest, LittleEndian),
        };
        let section = Section::with_endian(Endian::Little)
            .unit(&mut expected_unit)
            .append_bytes(expected_rest);
        let buf = section.get_contents().unwrap();
        let rest = &mut EndianSlice::new(&buf, LittleEndian);

        assert_eq!(
            parse_unit_header(rest, DebugInfoOffset(0).into()),
            Ok(expected_unit)
        );
        assert_eq!(*rest, EndianSlice::new(expected_rest, LittleEndian));
    }

    #[test]
    #[cfg(target_pointer_width = "64")]
    fn test_parse_v5_split_type_unit_header_64_ok() {
        let expected_rest = &[1, 2, 3, 4, 5, 6, 7, 8, 9];
        let encoding = Encoding {
            format: Format::Dwarf64,
            version: 5,
            address_size: 8,
        };
        let mut expected_unit = UnitHeader {
            encoding,
            unit_length: 0,
            unit_type: UnitType::SplitType {
                type_signature: DebugTypeSignature(0xdead_beef_dead_beef),
                type_offset: UnitOffset(0x7856_3412_7856_3412),
            },
            debug_abbrev_offset: DebugAbbrevOffset(0x0807_0605),
            unit_offset: DebugInfoOffset(0).into(),
            entries_buf: EndianSlice::new(expected_rest, LittleEndian),
        };
        let section = Section::with_endian(Endian::Little)
            .unit(&mut expected_unit)
            .append_bytes(expected_rest);
        let buf = section.get_contents().unwrap();
        let rest = &mut EndianSlice::new(&buf, LittleEndian);

        assert_eq!(
            parse_unit_header(rest, DebugInfoOffset(0).into()),
            Ok(expected_unit)
        );
        assert_eq!(*rest, EndianSlice::new(expected_rest, LittleEndian));
    }

    fn section_contents<F>(f: F) -> Vec<u8>
    where
        F: Fn(Section) -> Section,
    {
        f(Section::with_endian(Endian::Little))
            .get_contents()
            .unwrap()
    }

    #[test]
    fn test_attribute_value() {
        let mut unit = test_parse_attribute_unit_default();
        let endian = unit.entries_buf.endian();

        let block_data = &[1, 2, 3, 4];
        let buf = section_contents(|s| s.uleb(block_data.len() as u64).append_bytes(block_data));
        let block = EndianSlice::new(&buf, endian);

        let buf = section_contents(|s| s.L32(0x0102_0304));
        let data4 = EndianSlice::new(&buf, endian);

        let buf = section_contents(|s| s.L64(0x0102_0304_0506_0708));
        let data8 = EndianSlice::new(&buf, endian);

        let tests = [
            (
                Format::Dwarf32,
                2,
                constants::DW_AT_data_member_location,
                constants::DW_FORM_block,
                block,
                AttributeValue::Block(EndianSlice::new(block_data, endian)),
                AttributeValue::Exprloc(Expression(EndianSlice::new(block_data, endian))),
            ),
            (
                Format::Dwarf32,
                2,
                constants::DW_AT_data_member_location,
                constants::DW_FORM_data4,
                data4,
                AttributeValue::SecOffset(0x0102_0304),
                AttributeValue::LocationListsRef(LocationListsOffset(0x0102_0304)),
            ),
            (
                Format::Dwarf64,
                2,
                constants::DW_AT_data_member_location,
                constants::DW_FORM_data4,
                data4,
                AttributeValue::Data4(0x0102_0304),
                AttributeValue::Udata(0x0102_0304),
            ),
            (
                Format::Dwarf32,
                4,
                constants::DW_AT_data_member_location,
                constants::DW_FORM_data4,
                data4,
                AttributeValue::Data4(0x0102_0304),
                AttributeValue::Udata(0x0102_0304),
            ),
            (
                Format::Dwarf32,
                2,
                constants::DW_AT_data_member_location,
                constants::DW_FORM_data8,
                data8,
                AttributeValue::Data8(0x0102_0304_0506_0708),
                AttributeValue::Udata(0x0102_0304_0506_0708),
            ),
            #[cfg(target_pointer_width = "64")]
            (
                Format::Dwarf64,
                2,
                constants::DW_AT_data_member_location,
                constants::DW_FORM_data8,
                data8,
                AttributeValue::SecOffset(0x0102_0304_0506_0708),
                AttributeValue::LocationListsRef(LocationListsOffset(0x0102_0304_0506_0708)),
            ),
            (
                Format::Dwarf64,
                4,
                constants::DW_AT_data_member_location,
                constants::DW_FORM_data8,
                data8,
                AttributeValue::Data8(0x0102_0304_0506_0708),
                AttributeValue::Udata(0x0102_0304_0506_0708),
            ),
            (
                Format::Dwarf32,
                4,
                constants::DW_AT_location,
                constants::DW_FORM_data4,
                data4,
                AttributeValue::SecOffset(0x0102_0304),
                AttributeValue::LocationListsRef(LocationListsOffset(0x0102_0304)),
            ),
            #[cfg(target_pointer_width = "64")]
            (
                Format::Dwarf64,
                4,
                constants::DW_AT_location,
                constants::DW_FORM_data8,
                data8,
                AttributeValue::SecOffset(0x0102_0304_0506_0708),
                AttributeValue::LocationListsRef(LocationListsOffset(0x0102_0304_0506_0708)),
            ),
            (
                Format::Dwarf32,
                4,
                constants::DW_AT_str_offsets_base,
                constants::DW_FORM_sec_offset,
                data4,
                AttributeValue::SecOffset(0x0102_0304),
                AttributeValue::DebugStrOffsetsBase(DebugStrOffsetsBase(0x0102_0304)),
            ),
            (
                Format::Dwarf32,
                4,
                constants::DW_AT_stmt_list,
                constants::DW_FORM_sec_offset,
                data4,
                AttributeValue::SecOffset(0x0102_0304),
                AttributeValue::DebugLineRef(DebugLineOffset(0x0102_0304)),
            ),
            (
                Format::Dwarf32,
                4,
                constants::DW_AT_addr_base,
                constants::DW_FORM_sec_offset,
                data4,
                AttributeValue::SecOffset(0x0102_0304),
                AttributeValue::DebugAddrBase(DebugAddrBase(0x0102_0304)),
            ),
            (
                Format::Dwarf32,
                4,
                constants::DW_AT_rnglists_base,
                constants::DW_FORM_sec_offset,
                data4,
                AttributeValue::SecOffset(0x0102_0304),
                AttributeValue::DebugRngListsBase(DebugRngListsBase(0x0102_0304)),
            ),
            (
                Format::Dwarf32,
                4,
                constants::DW_AT_loclists_base,
                constants::DW_FORM_sec_offset,
                data4,
                AttributeValue::SecOffset(0x0102_0304),
                AttributeValue::DebugLocListsBase(DebugLocListsBase(0x0102_0304)),
            ),
        ];

        for test in tests.iter() {
            let (format, version, name, form, mut input, expect_raw, expect_value) = *test;
            unit.encoding.format = format;
            unit.encoding.version = version;
            let spec = AttributeSpecification::new(name, form, None);
            let attribute =
                parse_attribute(&mut input, unit.encoding(), spec).expect("Should parse attribute");
            assert_eq!(attribute.raw_value(), expect_raw);
            assert_eq!(attribute.value(), expect_value);
        }
    }

    #[test]
    fn test_attribute_udata_sdata_value() {
        let tests: &[(
            AttributeValue<EndianSlice<LittleEndian>>,
            Option<u64>,
            Option<i64>,
        )] = &[
            (AttributeValue::Data1(1), Some(1), Some(1)),
            (
                AttributeValue::Data1(core::u8::MAX),
                Some(u64::from(std::u8::MAX)),
                Some(-1),
            ),
            (AttributeValue::Data2(1), Some(1), Some(1)),
            (
                AttributeValue::Data2(core::u16::MAX),
                Some(u64::from(std::u16::MAX)),
                Some(-1),
            ),
            (AttributeValue::Data4(1), Some(1), Some(1)),
            (
                AttributeValue::Data4(core::u32::MAX),
                Some(u64::from(std::u32::MAX)),
                Some(-1),
            ),
            (AttributeValue::Data8(1), Some(1), Some(1)),
            (
                AttributeValue::Data8(core::u64::MAX),
                Some(core::u64::MAX),
                Some(-1),
            ),
            (AttributeValue::Sdata(1), Some(1), Some(1)),
            (AttributeValue::Sdata(-1), None, Some(-1)),
            (AttributeValue::Udata(1), Some(1), Some(1)),
            (AttributeValue::Udata(1u64 << 63), Some(1u64 << 63), None),
        ];
        for test in tests.iter() {
            let (value, expect_udata, expect_sdata) = *test;
            let attribute = Attribute {
                name: DW_AT_data_member_location,
                value,
            };
            assert_eq!(attribute.udata_value(), expect_udata);
            assert_eq!(attribute.sdata_value(), expect_sdata);
        }
    }

    fn test_parse_attribute_unit<Endian>(
        address_size: u8,
        format: Format,
        endian: Endian,
    ) -> UnitHeader<EndianSlice<'static, Endian>>
    where
        Endian: Endianity,
    {
        let encoding = Encoding {
            format,
            version: 4,
            address_size,
        };
        UnitHeader::new(
            encoding,
            7,
            UnitType::Compilation,
            DebugAbbrevOffset(0x0807_0605),
            DebugInfoOffset(0).into(),
            EndianSlice::new(&[], endian),
        )
    }

    fn test_parse_attribute_unit_default() -> UnitHeader<EndianSlice<'static, LittleEndian>> {
        test_parse_attribute_unit(4, Format::Dwarf32, LittleEndian)
    }

    fn test_parse_attribute<'input, Endian>(
        buf: &'input [u8],
        len: usize,
        unit: &UnitHeader<EndianSlice<'input, Endian>>,
        form: constants::DwForm,
        value: AttributeValue<EndianSlice<'input, Endian>>,
    ) where
        Endian: Endianity,
    {
        let spec = AttributeSpecification::new(constants::DW_AT_low_pc, form, None);

        let expect = Attribute {
            name: constants::DW_AT_low_pc,
            value,
        };

        let rest = &mut EndianSlice::new(buf, Endian::default());
        match parse_attribute(rest, unit.encoding(), spec) {
            Ok(attr) => {
                assert_eq!(attr, expect);
                assert_eq!(*rest, EndianSlice::new(&buf[len..], Endian::default()));
                if let Some(size) = spec.size(unit) {
                    assert_eq!(rest.len() + size, buf.len());
                }
            }
            otherwise => {
                assert!(false, "Unexpected parse result = {:#?}", otherwise);
            }
        };
    }

    #[test]
    fn test_parse_attribute_addr() {
        let buf = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08];
        let unit = test_parse_attribute_unit(4, Format::Dwarf32, LittleEndian);
        let form = constants::DW_FORM_addr;
        let value = AttributeValue::Addr(0x0403_0201);
        test_parse_attribute(&buf, 4, &unit, form, value);
    }

    #[test]
    fn test_parse_attribute_addr8() {
        let buf = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08];
        let unit = test_parse_attribute_unit(8, Format::Dwarf32, LittleEndian);
        let form = constants::DW_FORM_addr;
        let value = AttributeValue::Addr(0x0807_0605_0403_0201);
        test_parse_attribute(&buf, 8, &unit, form, value);
    }

    #[test]
    fn test_parse_attribute_block1() {
        // Length of data (3), three bytes of data, two bytes of left over input.
        let buf = [0x03, 0x09, 0x09, 0x09, 0x00, 0x00];
        let unit = test_parse_attribute_unit_default();
        let form = constants::DW_FORM_block1;
        let value = AttributeValue::Block(EndianSlice::new(&buf[1..4], LittleEndian));
        test_parse_attribute(&buf, 4, &unit, form, value);
    }

    #[test]
    fn test_parse_attribute_block2() {
        // Two byte length of data (2), two bytes of data, two bytes of left over input.
        let buf = [0x02, 0x00, 0x09, 0x09, 0x00, 0x00];
        let unit = test_parse_attribute_unit_default();
        let form = constants::DW_FORM_block2;
        let value = AttributeValue::Block(EndianSlice::new(&buf[2..4], LittleEndian));
        test_parse_attribute(&buf, 4, &unit, form, value);
    }

    #[test]
    fn test_parse_attribute_block4() {
        // Four byte length of data (2), two bytes of data, no left over input.
        let buf = [0x02, 0x00, 0x00, 0x00, 0x99, 0x99];
        let unit = test_parse_attribute_unit_default();
        let form = constants::DW_FORM_block4;
        let value = AttributeValue::Block(EndianSlice::new(&buf[4..], LittleEndian));
        test_parse_attribute(&buf, 6, &unit, form, value);
    }

    #[test]
    fn test_parse_attribute_block() {
        // LEB length of data (2, one byte), two bytes of data, no left over input.
        let buf = [0x02, 0x99, 0x99];
        let unit = test_parse_attribute_unit_default();
        let form = constants::DW_FORM_block;
        let value = AttributeValue::Block(EndianSlice::new(&buf[1..], LittleEndian));
        test_parse_attribute(&buf, 3, &unit, form, value);
    }

    #[test]
    fn test_parse_attribute_data1() {
        let buf = [0x03];
        let unit = test_parse_attribute_unit_default();
        let form = constants::DW_FORM_data1;
        let value = AttributeValue::Data1(0x03);
        test_parse_attribute(&buf, 1, &unit, form, value);
    }

    #[test]
    fn test_parse_attribute_data2() {
        let buf = [0x02, 0x01, 0x0];
        let unit = test_parse_attribute_unit_default();
        let form = constants::DW_FORM_data2;
        let value = AttributeValue::Data2(0x0102);
        test_parse_attribute(&buf, 2, &unit, form, value);
    }

    #[test]
    fn test_parse_attribute_data4() {
        let buf = [0x01, 0x02, 0x03, 0x04, 0x99, 0x99];
        let unit = test_parse_attribute_unit_default();
        let form = constants::DW_FORM_data4;
        let value = AttributeValue::Data4(0x0403_0201);
        test_parse_attribute(&buf, 4, &unit, form, value);
    }

    #[test]
    fn test_parse_attribute_data8() {
        let buf = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x99, 0x99];
        let unit = test_parse_attribute_unit_default();
        let form = constants::DW_FORM_data8;
        let value = AttributeValue::Data8(0x0807_0605_0403_0201);
        test_parse_attribute(&buf, 8, &unit, form, value);
    }

    #[test]
    fn test_parse_attribute_udata() {
        let mut buf = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];

        let bytes_written = {
            let mut writable = &mut buf[..];
            leb128::write::unsigned(&mut writable, 4097).expect("should write ok")
        };

        let unit = test_parse_attribute_unit_default();
        let form = constants::DW_FORM_udata;
        let value = AttributeValue::Udata(4097);
        test_parse_attribute(&buf, bytes_written, &unit, form, value);
    }

    #[test]
    fn test_parse_attribute_sdata() {
        let mut buf = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];

        let bytes_written = {
            let mut writable = &mut buf[..];
            leb128::write::signed(&mut writable, -4097).expect("should write ok")
        };

        let unit = test_parse_attribute_unit_default();
        let form = constants::DW_FORM_sdata;
        let value = AttributeValue::Sdata(-4097);
        test_parse_attribute(&buf, bytes_written, &unit, form, value);
    }

    #[test]
    fn test_parse_attribute_exprloc() {
        // LEB length of data (2, one byte), two bytes of data, one byte left over input.
        let buf = [0x02, 0x99, 0x99, 0x11];
        let unit = test_parse_attribute_unit_default();
        let form = constants::DW_FORM_exprloc;
        let value = AttributeValue::Exprloc(Expression(EndianSlice::new(&buf[1..3], LittleEndian)));
        test_parse_attribute(&buf, 3, &unit, form, value);
    }

    #[test]
    fn test_parse_attribute_flag_true() {
        let buf = [0x42];
        let unit = test_parse_attribute_unit_default();
        let form = constants::DW_FORM_flag;
        let value = AttributeValue::Flag(true);
        test_parse_attribute(&buf, 1, &unit, form, value);
    }

    #[test]
    fn test_parse_attribute_flag_false() {
        let buf = [0x00];
        let unit = test_parse_attribute_unit_default();
        let form = constants::DW_FORM_flag;
        let value = AttributeValue::Flag(false);
        test_parse_attribute(&buf, 1, &unit, form, value);
    }

    #[test]
    fn test_parse_attribute_flag_present() {
        let buf = [0x01, 0x02, 0x03, 0x04];
        let unit = test_parse_attribute_unit_default();
        let form = constants::DW_FORM_flag_present;
        let value = AttributeValue::Flag(true);
        // DW_FORM_flag_present does not consume any bytes of the input stream.
        test_parse_attribute(&buf, 0, &unit, form, value);
    }

    #[test]
    fn test_parse_attribute_sec_offset_32() {
        let buf = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10];
        let unit = test_parse_attribute_unit(4, Format::Dwarf32, LittleEndian);
        let form = constants::DW_FORM_sec_offset;
        let value = AttributeValue::SecOffset(0x0403_0201);
        test_parse_attribute(&buf, 4, &unit, form, value);
    }

    #[test]
    #[cfg(target_pointer_width = "64")]
    fn test_parse_attribute_sec_offset_64() {
        let buf = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10];
        let unit = test_parse_attribute_unit(4, Format::Dwarf64, LittleEndian);
        let form = constants::DW_FORM_sec_offset;
        let value = AttributeValue::SecOffset(0x0807_0605_0403_0201);
        test_parse_attribute(&buf, 8, &unit, form, value);
    }

    #[test]
    fn test_parse_attribute_ref1() {
        let buf = [0x03];
        let unit = test_parse_attribute_unit_default();
        let form = constants::DW_FORM_ref1;
        let value = AttributeValue::UnitRef(UnitOffset(3));
        test_parse_attribute(&buf, 1, &unit, form, value);
    }

    #[test]
    fn test_parse_attribute_ref2() {
        let buf = [0x02, 0x01, 0x0];
        let unit = test_parse_attribute_unit_default();
        let form = constants::DW_FORM_ref2;
        let value = AttributeValue::UnitRef(UnitOffset(258));
        test_parse_attribute(&buf, 2, &unit, form, value);
    }

    #[test]
    fn test_parse_attribute_ref4() {
        let buf = [0x01, 0x02, 0x03, 0x04, 0x99, 0x99];
        let unit = test_parse_attribute_unit_default();
        let form = constants::DW_FORM_ref4;
        let value = AttributeValue::UnitRef(UnitOffset(0x0403_0201));
        test_parse_attribute(&buf, 4, &unit, form, value);
    }

    #[test]
    #[cfg(target_pointer_width = "64")]
    fn test_parse_attribute_ref8() {
        let buf = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x99, 0x99];
        let unit = test_parse_attribute_unit_default();
        let form = constants::DW_FORM_ref8;
        let value = AttributeValue::UnitRef(UnitOffset(0x0807_0605_0403_0201));
        test_parse_attribute(&buf, 8, &unit, form, value);
    }

    #[test]
    fn test_parse_attribute_ref_sup4() {
        let buf = [0x01, 0x02, 0x03, 0x04, 0x99, 0x99];
        let unit = test_parse_attribute_unit_default();
        let form = constants::DW_FORM_ref_sup4;
        let value = AttributeValue::DebugInfoRefSup(DebugInfoOffset(0x0403_0201));
        test_parse_attribute(&buf, 4, &unit, form, value);
    }

    #[test]
    #[cfg(target_pointer_width = "64")]
    fn test_parse_attribute_ref_sup8() {
        let buf = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x99, 0x99];
        let unit = test_parse_attribute_unit_default();
        let form = constants::DW_FORM_ref_sup8;
        let value = AttributeValue::DebugInfoRefSup(DebugInfoOffset(0x0807_0605_0403_0201));
        test_parse_attribute(&buf, 8, &unit, form, value);
    }

    #[test]
    fn test_parse_attribute_refudata() {
        let mut buf = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];

        let bytes_written = {
            let mut writable = &mut buf[..];
            leb128::write::unsigned(&mut writable, 4097).expect("should write ok")
        };

        let unit = test_parse_attribute_unit_default();
        let form = constants::DW_FORM_ref_udata;
        let value = AttributeValue::UnitRef(UnitOffset(4097));
        test_parse_attribute(&buf, bytes_written, &unit, form, value);
    }

    #[test]
    fn test_parse_attribute_refaddr_32() {
        let buf = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x99, 0x99];
        let unit = test_parse_attribute_unit(4, Format::Dwarf32, LittleEndian);
        let form = constants::DW_FORM_ref_addr;
        let value = AttributeValue::DebugInfoRef(DebugInfoOffset(0x0403_0201));
        test_parse_attribute(&buf, 4, &unit, form, value);
    }

    #[test]
    #[cfg(target_pointer_width = "64")]
    fn test_parse_attribute_refaddr_64() {
        let buf = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x99, 0x99];
        let unit = test_parse_attribute_unit(4, Format::Dwarf64, LittleEndian);
        let form = constants::DW_FORM_ref_addr;
        let value = AttributeValue::DebugInfoRef(DebugInfoOffset(0x0807_0605_0403_0201));
        test_parse_attribute(&buf, 8, &unit, form, value);
    }

    #[test]
    fn test_parse_attribute_refaddr_version2() {
        let buf = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x99, 0x99];
        let mut unit = test_parse_attribute_unit(4, Format::Dwarf32, LittleEndian);
        unit.encoding.version = 2;
        let form = constants::DW_FORM_ref_addr;
        let value = AttributeValue::DebugInfoRef(DebugInfoOffset(0x0403_0201));
        test_parse_attribute(&buf, 4, &unit, form, value);
    }

    #[test]
    #[cfg(target_pointer_width = "64")]
    fn test_parse_attribute_refaddr8_version2() {
        let buf = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x99, 0x99];
        let mut unit = test_parse_attribute_unit(8, Format::Dwarf32, LittleEndian);
        unit.encoding.version = 2;
        let form = constants::DW_FORM_ref_addr;
        let value = AttributeValue::DebugInfoRef(DebugInfoOffset(0x0807_0605_0403_0201));
        test_parse_attribute(&buf, 8, &unit, form, value);
    }

    #[test]
    fn test_parse_attribute_gnu_ref_alt_32() {
        let buf = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x99, 0x99];
        let unit = test_parse_attribute_unit(4, Format::Dwarf32, LittleEndian);
        let form = constants::DW_FORM_GNU_ref_alt;
        let value = AttributeValue::DebugInfoRefSup(DebugInfoOffset(0x0403_0201));
        test_parse_attribute(&buf, 4, &unit, form, value);
    }

    #[test]
    #[cfg(target_pointer_width = "64")]
    fn test_parse_attribute_gnu_ref_alt_64() {
        let buf = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x99, 0x99];
        let unit = test_parse_attribute_unit(4, Format::Dwarf64, LittleEndian);
        let form = constants::DW_FORM_GNU_ref_alt;
        let value = AttributeValue::DebugInfoRefSup(DebugInfoOffset(0x0807_0605_0403_0201));
        test_parse_attribute(&buf, 8, &unit, form, value);
    }

    #[test]
    fn test_parse_attribute_refsig8() {
        let buf = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x99, 0x99];
        let unit = test_parse_attribute_unit_default();
        let form = constants::DW_FORM_ref_sig8;
        let value = AttributeValue::DebugTypesRef(DebugTypeSignature(0x0807_0605_0403_0201));
        test_parse_attribute(&buf, 8, &unit, form, value);
    }

    #[test]
    fn test_parse_attribute_string() {
        let buf = [0x01, 0x02, 0x03, 0x04, 0x05, 0x0, 0x99, 0x99];
        let unit = test_parse_attribute_unit_default();
        let form = constants::DW_FORM_string;
        let value = AttributeValue::String(EndianSlice::new(&buf[..5], LittleEndian));
        test_parse_attribute(&buf, 6, &unit, form, value);
    }

    #[test]
    fn test_parse_attribute_strp_32() {
        let buf = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x99, 0x99];
        let unit = test_parse_attribute_unit(4, Format::Dwarf32, LittleEndian);
        let form = constants::DW_FORM_strp;
        let value = AttributeValue::DebugStrRef(DebugStrOffset(0x0403_0201));
        test_parse_attribute(&buf, 4, &unit, form, value);
    }

    #[test]
    #[cfg(target_pointer_width = "64")]
    fn test_parse_attribute_strp_64() {
        let buf = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x99, 0x99];
        let unit = test_parse_attribute_unit(4, Format::Dwarf64, LittleEndian);
        let form = constants::DW_FORM_strp;
        let value = AttributeValue::DebugStrRef(DebugStrOffset(0x0807_0605_0403_0201));
        test_parse_attribute(&buf, 8, &unit, form, value);
    }

    #[test]
    fn test_parse_attribute_strp_sup_32() {
        let buf = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x99, 0x99];
        let unit = test_parse_attribute_unit(4, Format::Dwarf32, LittleEndian);
        let form = constants::DW_FORM_strp_sup;
        let value = AttributeValue::DebugStrRefSup(DebugStrOffset(0x0403_0201));
        test_parse_attribute(&buf, 4, &unit, form, value);
    }

    #[test]
    #[cfg(target_pointer_width = "64")]
    fn test_parse_attribute_strp_sup_64() {
        let buf = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x99, 0x99];
        let unit = test_parse_attribute_unit(4, Format::Dwarf64, LittleEndian);
        let form = constants::DW_FORM_strp_sup;
        let value = AttributeValue::DebugStrRefSup(DebugStrOffset(0x0807_0605_0403_0201));
        test_parse_attribute(&buf, 8, &unit, form, value);
    }

    #[test]
    fn test_parse_attribute_gnu_strp_alt_32() {
        let buf = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x99, 0x99];
        let unit = test_parse_attribute_unit(4, Format::Dwarf32, LittleEndian);
        let form = constants::DW_FORM_GNU_strp_alt;
        let value = AttributeValue::DebugStrRefSup(DebugStrOffset(0x0403_0201));
        test_parse_attribute(&buf, 4, &unit, form, value);
    }

    #[test]
    #[cfg(target_pointer_width = "64")]
    fn test_parse_attribute_gnu_strp_alt_64() {
        let buf = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x99, 0x99];
        let unit = test_parse_attribute_unit(4, Format::Dwarf64, LittleEndian);
        let form = constants::DW_FORM_GNU_strp_alt;
        let value = AttributeValue::DebugStrRefSup(DebugStrOffset(0x0807_0605_0403_0201));
        test_parse_attribute(&buf, 8, &unit, form, value);
    }

    #[test]
    fn test_parse_attribute_strx() {
        let mut buf = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];

        let bytes_written = {
            let mut writable = &mut buf[..];
            leb128::write::unsigned(&mut writable, 4097).expect("should write ok")
        };

        let unit = test_parse_attribute_unit_default();
        let form = constants::DW_FORM_strx;
        let value = AttributeValue::DebugStrOffsetsIndex(DebugStrOffsetsIndex(4097));
        test_parse_attribute(&buf, bytes_written, &unit, form, value);
    }

    #[test]
    fn test_parse_attribute_strx1() {
        let buf = [0x01, 0x99, 0x99];
        let unit = test_parse_attribute_unit(4, Format::Dwarf64, LittleEndian);
        let form = constants::DW_FORM_strx1;
        let value = AttributeValue::DebugStrOffsetsIndex(DebugStrOffsetsIndex(0x01));
        test_parse_attribute(&buf, 1, &unit, form, value);
    }

    #[test]
    fn test_parse_attribute_strx2() {
        let buf = [0x01, 0x02, 0x99, 0x99];
        let unit = test_parse_attribute_unit(4, Format::Dwarf64, LittleEndian);
        let form = constants::DW_FORM_strx2;
        let value = AttributeValue::DebugStrOffsetsIndex(DebugStrOffsetsIndex(0x0201));
        test_parse_attribute(&buf, 2, &unit, form, value);
    }

    #[test]
    fn test_parse_attribute_strx3() {
        let buf = [0x01, 0x02, 0x03, 0x99, 0x99];
        let unit = test_parse_attribute_unit(4, Format::Dwarf64, LittleEndian);
        let form = constants::DW_FORM_strx3;
        let value = AttributeValue::DebugStrOffsetsIndex(DebugStrOffsetsIndex(0x03_0201));
        test_parse_attribute(&buf, 3, &unit, form, value);
    }

    #[test]
    fn test_parse_attribute_strx4() {
        let buf = [0x01, 0x02, 0x03, 0x04, 0x99, 0x99];
        let unit = test_parse_attribute_unit(4, Format::Dwarf64, LittleEndian);
        let form = constants::DW_FORM_strx4;
        let value = AttributeValue::DebugStrOffsetsIndex(DebugStrOffsetsIndex(0x0403_0201));
        test_parse_attribute(&buf, 4, &unit, form, value);
    }

    #[test]
    fn test_parse_attribute_addrx() {
        let mut buf = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];

        let bytes_written = {
            let mut writable = &mut buf[..];
            leb128::write::unsigned(&mut writable, 4097).expect("should write ok")
        };

        let unit = test_parse_attribute_unit_default();
        let form = constants::DW_FORM_addrx;
        let value = AttributeValue::DebugAddrIndex(DebugAddrIndex(4097));
        test_parse_attribute(&buf, bytes_written, &unit, form, value);
    }

    #[test]
    fn test_parse_attribute_addrx1() {
        let buf = [0x01, 0x99, 0x99];
        let unit = test_parse_attribute_unit(4, Format::Dwarf64, LittleEndian);
        let form = constants::DW_FORM_addrx1;
        let value = AttributeValue::DebugAddrIndex(DebugAddrIndex(0x01));
        test_parse_attribute(&buf, 1, &unit, form, value);
    }

    #[test]
    fn test_parse_attribute_addrx2() {
        let buf = [0x01, 0x02, 0x99, 0x99];
        let unit = test_parse_attribute_unit(4, Format::Dwarf64, LittleEndian);
        let form = constants::DW_FORM_addrx2;
        let value = AttributeValue::DebugAddrIndex(DebugAddrIndex(0x0201));
        test_parse_attribute(&buf, 2, &unit, form, value);
    }

    #[test]
    fn test_parse_attribute_addrx3() {
        let buf = [0x01, 0x02, 0x03, 0x99, 0x99];
        let unit = test_parse_attribute_unit(4, Format::Dwarf64, LittleEndian);
        let form = constants::DW_FORM_addrx3;
        let value = AttributeValue::DebugAddrIndex(DebugAddrIndex(0x03_0201));
        test_parse_attribute(&buf, 3, &unit, form, value);
    }

    #[test]
    fn test_parse_attribute_addrx4() {
        let buf = [0x01, 0x02, 0x03, 0x04, 0x99, 0x99];
        let unit = test_parse_attribute_unit(4, Format::Dwarf64, LittleEndian);
        let form = constants::DW_FORM_addrx4;
        let value = AttributeValue::DebugAddrIndex(DebugAddrIndex(0x0403_0201));
        test_parse_attribute(&buf, 4, &unit, form, value);
    }

    #[test]
    fn test_parse_attribute_loclistx() {
        let mut buf = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];

        let bytes_written = {
            let mut writable = &mut buf[..];
            leb128::write::unsigned(&mut writable, 4097).expect("should write ok")
        };

        let unit = test_parse_attribute_unit_default();
        let form = constants::DW_FORM_loclistx;
        let value = AttributeValue::DebugLocListsIndex(DebugLocListsIndex(4097));
        test_parse_attribute(&buf, bytes_written, &unit, form, value);
    }

    #[test]
    fn test_parse_attribute_rnglistx() {
        let mut buf = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];

        let bytes_written = {
            let mut writable = &mut buf[..];
            leb128::write::unsigned(&mut writable, 4097).expect("should write ok")
        };

        let unit = test_parse_attribute_unit_default();
        let form = constants::DW_FORM_rnglistx;
        let value = AttributeValue::DebugRngListsIndex(DebugRngListsIndex(4097));
        test_parse_attribute(&buf, bytes_written, &unit, form, value);
    }

    #[test]
    fn test_parse_attribute_indirect() {
        let mut buf = [0; 100];

        let bytes_written = {
            let mut writable = &mut buf[..];
            leb128::write::unsigned(&mut writable, constants::DW_FORM_udata.0.into())
                .expect("should write udata")
                + leb128::write::unsigned(&mut writable, 9_999_999).expect("should write value")
        };

        let unit = test_parse_attribute_unit_default();
        let form = constants::DW_FORM_indirect;
        let value = AttributeValue::Udata(9_999_999);
        test_parse_attribute(&buf, bytes_written, &unit, form, value);
    }

    #[test]
    fn test_parse_attribute_indirect_implicit_const() {
        let encoding = Encoding {
            format: Format::Dwarf32,
            version: 4,
            address_size: 4,
        };
        let mut buf = [0; 100];
        let mut writable = &mut buf[..];
        leb128::write::unsigned(&mut writable, constants::DW_FORM_implicit_const.0.into())
            .expect("should write implicit_const");

        let input = &mut EndianSlice::new(&buf, LittleEndian);
        let spec =
            AttributeSpecification::new(constants::DW_AT_low_pc, constants::DW_FORM_indirect, None);
        assert_eq!(
            parse_attribute(input, encoding, spec),
            Err(Error::InvalidImplicitConst)
        );
    }

    #[test]
    fn test_attrs_iter() {
        let encoding = Encoding {
            format: Format::Dwarf32,
            version: 4,
            address_size: 4,
        };
        let unit = UnitHeader::new(
            encoding,
            7,
            UnitType::Compilation,
            DebugAbbrevOffset(0x0807_0605),
            DebugInfoOffset(0).into(),
            EndianSlice::new(&[], LittleEndian),
        );

        let abbrev = Abbreviation::new(
            42,
            constants::DW_TAG_subprogram,
            constants::DW_CHILDREN_yes,
            vec![
                AttributeSpecification::new(constants::DW_AT_name, constants::DW_FORM_string, None),
                AttributeSpecification::new(constants::DW_AT_low_pc, constants::DW_FORM_addr, None),
                AttributeSpecification::new(
                    constants::DW_AT_high_pc,
                    constants::DW_FORM_addr,
                    None,
                ),
            ]
            .into(),
        );

        // "foo", 42, 1337, 4 dangling bytes of 0xaa where children would be
        let buf = [
            0x66, 0x6f, 0x6f, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x39, 0x05, 0x00, 0x00, 0xaa, 0xaa,
            0xaa, 0xaa,
        ];

        let entry = DebuggingInformationEntry {
            offset: UnitOffset(0),
            attrs_slice: EndianSlice::new(&buf, LittleEndian),
            attrs_len: Cell::new(None),
            abbrev: &abbrev,
            unit: &unit,
        };

        let mut attrs = AttrsIter {
            input: EndianSlice::new(&buf, LittleEndian),
            attributes: abbrev.attributes(),
            entry: &entry,
        };

        match attrs.next() {
            Ok(Some(attr)) => {
                assert_eq!(
                    attr,
                    Attribute {
                        name: constants::DW_AT_name,
                        value: AttributeValue::String(EndianSlice::new(b"foo", LittleEndian)),
                    }
                );
            }
            otherwise => {
                assert!(false, "Unexpected parse result = {:#?}", otherwise);
            }
        }

        assert!(entry.attrs_len.get().is_none());

        match attrs.next() {
            Ok(Some(attr)) => {
                assert_eq!(
                    attr,
                    Attribute {
                        name: constants::DW_AT_low_pc,
                        value: AttributeValue::Addr(0x2a),
                    }
                );
            }
            otherwise => {
                assert!(false, "Unexpected parse result = {:#?}", otherwise);
            }
        }

        assert!(entry.attrs_len.get().is_none());

        match attrs.next() {
            Ok(Some(attr)) => {
                assert_eq!(
                    attr,
                    Attribute {
                        name: constants::DW_AT_high_pc,
                        value: AttributeValue::Addr(0x539),
                    }
                );
            }
            otherwise => {
                assert!(false, "Unexpected parse result = {:#?}", otherwise);
            }
        }

        assert!(entry.attrs_len.get().is_none());

        assert!(attrs.next().expect("should parse next").is_none());
        assert!(entry.attrs_len.get().is_some());
        assert_eq!(
            entry.attrs_len.get().expect("should have entry.attrs_len"),
            buf.len() - 4
        )
    }

    #[test]
    fn test_attrs_iter_incomplete() {
        let encoding = Encoding {
            format: Format::Dwarf32,
            version: 4,
            address_size: 4,
        };
        let unit = UnitHeader::new(
            encoding,
            7,
            UnitType::Compilation,
            DebugAbbrevOffset(0x0807_0605),
            DebugInfoOffset(0).into(),
            EndianSlice::new(&[], LittleEndian),
        );

        let abbrev = Abbreviation::new(
            42,
            constants::DW_TAG_subprogram,
            constants::DW_CHILDREN_yes,
            vec![
                AttributeSpecification::new(constants::DW_AT_name, constants::DW_FORM_string, None),
                AttributeSpecification::new(constants::DW_AT_low_pc, constants::DW_FORM_addr, None),
                AttributeSpecification::new(
                    constants::DW_AT_high_pc,
                    constants::DW_FORM_addr,
                    None,
                ),
            ]
            .into(),
        );

        // "foo"
        let buf = [0x66, 0x6f, 0x6f, 0x00];

        let entry = DebuggingInformationEntry {
            offset: UnitOffset(0),
            attrs_slice: EndianSlice::new(&buf, LittleEndian),
            attrs_len: Cell::new(None),
            abbrev: &abbrev,
            unit: &unit,
        };

        let mut attrs = AttrsIter {
            input: EndianSlice::new(&buf, LittleEndian),
            attributes: abbrev.attributes(),
            entry: &entry,
        };

        match attrs.next() {
            Ok(Some(attr)) => {
                assert_eq!(
                    attr,
                    Attribute {
                        name: constants::DW_AT_name,
                        value: AttributeValue::String(EndianSlice::new(b"foo", LittleEndian)),
                    }
                );
            }
            otherwise => {
                assert!(false, "Unexpected parse result = {:#?}", otherwise);
            }
        }

        assert!(entry.attrs_len.get().is_none());

        // Return error for incomplete attribute.
        assert!(attrs.next().is_err());
        assert!(entry.attrs_len.get().is_none());

        // Return error for all subsequent calls.
        assert!(attrs.next().is_err());
        assert!(attrs.next().is_err());
        assert!(attrs.next().is_err());
        assert!(attrs.next().is_err());
        assert!(entry.attrs_len.get().is_none());
    }

    fn assert_entry_name<Endian>(entry: &DebuggingInformationEntry<EndianSlice<Endian>>, name: &str)
    where
        Endian: Endianity,
    {
        let value = entry
            .attr_value(constants::DW_AT_name)
            .expect("Should have parsed the name attribute")
            .expect("Should have found the name attribute");

        assert_eq!(
            value,
            AttributeValue::String(EndianSlice::new(name.as_bytes(), Endian::default()))
        );
    }

    fn assert_current_name<Endian>(cursor: &EntriesCursor<EndianSlice<Endian>>, name: &str)
    where
        Endian: Endianity,
    {
        let entry = cursor.current().expect("Should have an entry result");
        assert_entry_name(entry, name);
    }

    fn assert_next_entry<Endian>(cursor: &mut EntriesCursor<EndianSlice<Endian>>, name: &str)
    where
        Endian: Endianity,
    {
        cursor
            .next_entry()
            .expect("Should parse next entry")
            .expect("Should have an entry");
        assert_current_name(cursor, name);
    }

    fn assert_next_entry_null<Endian>(cursor: &mut EntriesCursor<EndianSlice<Endian>>)
    where
        Endian: Endianity,
    {
        cursor
            .next_entry()
            .expect("Should parse next entry")
            .expect("Should have an entry");
        assert!(cursor.current().is_none());
    }

    fn assert_next_dfs<Endian>(
        cursor: &mut EntriesCursor<EndianSlice<Endian>>,
        name: &str,
        depth: isize,
    ) where
        Endian: Endianity,
    {
        {
            let (val, entry) = cursor
                .next_dfs()
                .expect("Should parse next dfs")
                .expect("Should not be done with traversal");
            assert_eq!(val, depth);
            assert_entry_name(entry, name);
        }
        assert_current_name(cursor, name);
    }

    fn assert_next_sibling<Endian>(cursor: &mut EntriesCursor<EndianSlice<Endian>>, name: &str)
    where
        Endian: Endianity,
    {
        {
            let entry = cursor
                .next_sibling()
                .expect("Should parse next sibling")
                .expect("Should not be done with traversal");
            assert_entry_name(entry, name);
        }
        assert_current_name(cursor, name);
    }

    fn assert_valid_sibling_ptr<Endian>(cursor: &EntriesCursor<EndianSlice<Endian>>)
    where
        Endian: Endianity,
    {
        let sibling_ptr = cursor
            .current()
            .expect("Should have current entry")
            .attr_value(constants::DW_AT_sibling);
        match sibling_ptr {
            Ok(Some(AttributeValue::UnitRef(offset))) => {
                cursor
                    .unit
                    .range_from(offset..)
                    .expect("Sibling offset should be valid");
            }
            _ => panic!("Invalid sibling pointer {:?}", sibling_ptr),
        }
    }

    fn entries_cursor_tests_abbrev_buf() -> Vec<u8> {
        #[rustfmt::skip]
        let section = Section::with_endian(Endian::Little)
            .abbrev(1, DW_TAG_subprogram, DW_CHILDREN_yes)
                .abbrev_attr(DW_AT_name, DW_FORM_string)
                .abbrev_attr_null()
            .abbrev_null();
        section.get_contents().unwrap()
    }

    fn entries_cursor_tests_debug_info_buf() -> Vec<u8> {
        #[rustfmt::skip]
        let section = Section::with_endian(Endian::Little)
            .die(1, |s| s.attr_string("001"))
                .die(1, |s| s.attr_string("002"))
                    .die(1, |s| s.attr_string("003"))
                        .die_null()
                    .die_null()
                .die(1, |s| s.attr_string("004"))
                    .die(1, |s| s.attr_string("005"))
                        .die_null()
                    .die(1, |s| s.attr_string("006"))
                        .die_null()
                    .die_null()
                .die(1, |s| s.attr_string("007"))
                    .die(1, |s| s.attr_string("008"))
                        .die(1, |s| s.attr_string("009"))
                            .die_null()
                        .die_null()
                    .die_null()
                .die(1, |s| s.attr_string("010"))
                    .die_null()
                .die_null();
        let entries_buf = section.get_contents().unwrap();

        let encoding = Encoding {
            format: Format::Dwarf32,
            version: 4,
            address_size: 4,
        };
        let mut unit = UnitHeader {
            encoding,
            unit_length: 0,
            unit_type: UnitType::Compilation,
            debug_abbrev_offset: DebugAbbrevOffset(0),
            unit_offset: DebugInfoOffset(0).into(),
            entries_buf: EndianSlice::new(&entries_buf, LittleEndian),
        };
        let section = Section::with_endian(Endian::Little).unit(&mut unit);
        section.get_contents().unwrap()
    }

    #[test]
    fn test_cursor_next_entry_incomplete() {
        #[rustfmt::skip]
        let section = Section::with_endian(Endian::Little)
            .die(1, |s| s.attr_string("001"))
                .die(1, |s| s.attr_string("002"))
                    .die(1, |s| s);
        let entries_buf = section.get_contents().unwrap();

        let encoding = Encoding {
            format: Format::Dwarf32,
            version: 4,
            address_size: 4,
        };
        let mut unit = UnitHeader {
            encoding,
            unit_length: 0,
            unit_type: UnitType::Compilation,
            debug_abbrev_offset: DebugAbbrevOffset(0),
            unit_offset: DebugInfoOffset(0).into(),
            entries_buf: EndianSlice::new(&entries_buf, LittleEndian),
        };
        let section = Section::with_endian(Endian::Little).unit(&mut unit);
        let info_buf = &section.get_contents().unwrap();
        let debug_info = DebugInfo::new(info_buf, LittleEndian);

        let unit = debug_info
            .units()
            .next()
            .expect("should have a unit result")
            .expect("and it should be ok");

        let abbrevs_buf = &entries_cursor_tests_abbrev_buf();
        let debug_abbrev = DebugAbbrev::new(abbrevs_buf, LittleEndian);

        let abbrevs = unit
            .abbreviations(&debug_abbrev)
            .expect("Should parse abbreviations");

        let mut cursor = unit.entries(&abbrevs);

        assert_next_entry(&mut cursor, "001");
        assert_next_entry(&mut cursor, "002");

        {
            // Entry code is present, but none of the attributes.
            cursor
                .next_entry()
                .expect("Should parse next entry")
                .expect("Should have an entry");
            let entry = cursor.current().expect("Should have an entry result");
            assert!(entry.attrs().next().is_err());
        }

        assert!(cursor.next_entry().is_err());
        assert!(cursor.next_entry().is_err());
    }

    #[test]
    fn test_cursor_next_entry() {
        let info_buf = &entries_cursor_tests_debug_info_buf();
        let debug_info = DebugInfo::new(info_buf, LittleEndian);

        let unit = debug_info
            .units()
            .next()
            .expect("should have a unit result")
            .expect("and it should be ok");

        let abbrevs_buf = &entries_cursor_tests_abbrev_buf();
        let debug_abbrev = DebugAbbrev::new(abbrevs_buf, LittleEndian);

        let abbrevs = unit
            .abbreviations(&debug_abbrev)
            .expect("Should parse abbreviations");

        let mut cursor = unit.entries(&abbrevs);

        assert_next_entry(&mut cursor, "001");
        assert_next_entry(&mut cursor, "002");
        assert_next_entry(&mut cursor, "003");
        assert_next_entry_null(&mut cursor);
        assert_next_entry_null(&mut cursor);
        assert_next_entry(&mut cursor, "004");
        assert_next_entry(&mut cursor, "005");
        assert_next_entry_null(&mut cursor);
        assert_next_entry(&mut cursor, "006");
        assert_next_entry_null(&mut cursor);
        assert_next_entry_null(&mut cursor);
        assert_next_entry(&mut cursor, "007");
        assert_next_entry(&mut cursor, "008");
        assert_next_entry(&mut cursor, "009");
        assert_next_entry_null(&mut cursor);
        assert_next_entry_null(&mut cursor);
        assert_next_entry_null(&mut cursor);
        assert_next_entry(&mut cursor, "010");
        assert_next_entry_null(&mut cursor);
        assert_next_entry_null(&mut cursor);

        assert!(cursor
            .next_entry()
            .expect("Should parse next entry")
            .is_none());
        assert!(cursor.current().is_none());
    }

    #[test]
    fn test_cursor_next_dfs() {
        let info_buf = &entries_cursor_tests_debug_info_buf();
        let debug_info = DebugInfo::new(info_buf, LittleEndian);

        let unit = debug_info
            .units()
            .next()
            .expect("should have a unit result")
            .expect("and it should be ok");

        let abbrevs_buf = &entries_cursor_tests_abbrev_buf();
        let debug_abbrev = DebugAbbrev::new(abbrevs_buf, LittleEndian);

        let abbrevs = unit
            .abbreviations(&debug_abbrev)
            .expect("Should parse abbreviations");

        let mut cursor = unit.entries(&abbrevs);

        assert_next_dfs(&mut cursor, "001", 0);
        assert_next_dfs(&mut cursor, "002", 1);
        assert_next_dfs(&mut cursor, "003", 1);
        assert_next_dfs(&mut cursor, "004", -1);
        assert_next_dfs(&mut cursor, "005", 1);
        assert_next_dfs(&mut cursor, "006", 0);
        assert_next_dfs(&mut cursor, "007", -1);
        assert_next_dfs(&mut cursor, "008", 1);
        assert_next_dfs(&mut cursor, "009", 1);
        assert_next_dfs(&mut cursor, "010", -2);

        assert!(cursor.next_dfs().expect("Should parse next dfs").is_none());
        assert!(cursor.current().is_none());
    }

    #[test]
    fn test_cursor_next_sibling_no_sibling_ptr() {
        let info_buf = &entries_cursor_tests_debug_info_buf();
        let debug_info = DebugInfo::new(info_buf, LittleEndian);

        let unit = debug_info
            .units()
            .next()
            .expect("should have a unit result")
            .expect("and it should be ok");

        let abbrevs_buf = &entries_cursor_tests_abbrev_buf();
        let debug_abbrev = DebugAbbrev::new(abbrevs_buf, LittleEndian);

        let abbrevs = unit
            .abbreviations(&debug_abbrev)
            .expect("Should parse abbreviations");

        let mut cursor = unit.entries(&abbrevs);

        assert_next_dfs(&mut cursor, "001", 0);

        // Down to the first child of the root entry.

        assert_next_dfs(&mut cursor, "002", 1);

        // Now iterate all children of the root via `next_sibling`.

        assert_next_sibling(&mut cursor, "004");
        assert_next_sibling(&mut cursor, "007");
        assert_next_sibling(&mut cursor, "010");

        // There should be no more siblings.

        assert!(cursor
            .next_sibling()
            .expect("Should parse next sibling")
            .is_none());
        assert!(cursor.current().is_none());
    }

    #[test]
    fn test_cursor_next_sibling_continuation() {
        let info_buf = &entries_cursor_tests_debug_info_buf();
        let debug_info = DebugInfo::new(info_buf, LittleEndian);

        let unit = debug_info
            .units()
            .next()
            .expect("should have a unit result")
            .expect("and it should be ok");

        let abbrevs_buf = &entries_cursor_tests_abbrev_buf();
        let debug_abbrev = DebugAbbrev::new(abbrevs_buf, LittleEndian);

        let abbrevs = unit
            .abbreviations(&debug_abbrev)
            .expect("Should parse abbreviations");

        let mut cursor = unit.entries(&abbrevs);

        assert_next_dfs(&mut cursor, "001", 0);

        // Down to the first child of the root entry.

        assert_next_dfs(&mut cursor, "002", 1);

        // Get the next sibling, then iterate its children

        assert_next_sibling(&mut cursor, "004");
        assert_next_dfs(&mut cursor, "005", 1);
        assert_next_sibling(&mut cursor, "006");
        assert!(cursor
            .next_sibling()
            .expect("Should parse next sibling")
            .is_none());
        assert!(cursor
            .next_sibling()
            .expect("Should parse next sibling")
            .is_none());
        assert!(cursor
            .next_sibling()
            .expect("Should parse next sibling")
            .is_none());
        assert!(cursor
            .next_sibling()
            .expect("Should parse next sibling")
            .is_none());

        // And we should be able to continue with the children of the root entry.

        assert_next_dfs(&mut cursor, "007", -1);
        assert_next_sibling(&mut cursor, "010");

        // There should be no more siblings.

        assert!(cursor
            .next_sibling()
            .expect("Should parse next sibling")
            .is_none());
        assert!(cursor.current().is_none());
    }

    fn entries_cursor_sibling_abbrev_buf() -> Vec<u8> {
        #[rustfmt::skip]
        let section = Section::with_endian(Endian::Little)
            .abbrev(1, DW_TAG_subprogram, DW_CHILDREN_yes)
                .abbrev_attr(DW_AT_name, DW_FORM_string)
                .abbrev_attr(DW_AT_sibling, DW_FORM_ref1)
                .abbrev_attr_null()
            .abbrev(2, DW_TAG_subprogram, DW_CHILDREN_yes)
                .abbrev_attr(DW_AT_name, DW_FORM_string)
                .abbrev_attr_null()
                .abbrev_null();
        section.get_contents().unwrap()
    }

    fn entries_cursor_sibling_entries_buf(header_size: usize) -> Vec<u8> {
        let start = Label::new();
        let sibling004_ref = Label::new();
        let sibling004 = Label::new();
        let sibling009_ref = Label::new();
        let sibling009 = Label::new();

        #[rustfmt::skip]
        let section = Section::with_endian(Endian::Little)
            .mark(&start)
            .die(2, |s| s.attr_string("001"))
                // Valid sibling attribute.
                .die(1, |s| s.attr_string("002").D8(&sibling004_ref))
                    // Invalid code to ensure the sibling attribute was used.
                    .die(10, |s| s.attr_string("003"))
                        .die_null()
                    .die_null()
                .mark(&sibling004)
                // Invalid sibling attribute.
                .die(1, |s| s.attr_string("004").attr_ref1(255))
                    .die(2, |s| s.attr_string("005"))
                        .die_null()
                    .die_null()
                // Sibling attribute in child only.
                .die(2, |s| s.attr_string("006"))
                    // Valid sibling attribute.
                    .die(1, |s| s.attr_string("007").D8(&sibling009_ref))
                        // Invalid code to ensure the sibling attribute was used.
                        .die(10, |s| s.attr_string("008"))
                            .die_null()
                        .die_null()
                    .mark(&sibling009)
                    .die(2, |s| s.attr_string("009"))
                        .die_null()
                    .die_null()
                // No sibling attribute.
                .die(2, |s| s.attr_string("010"))
                    .die(2, |s| s.attr_string("011"))
                        .die_null()
                    .die_null()
                .die_null();

        let offset = header_size as u64 + (&sibling004 - &start) as u64;
        sibling004_ref.set_const(offset);

        let offset = header_size as u64 + (&sibling009 - &start) as u64;
        sibling009_ref.set_const(offset);

        section.get_contents().unwrap()
    }

    fn test_cursor_next_sibling_with_ptr(cursor: &mut EntriesCursor<EndianSlice<LittleEndian>>) {
        assert_next_dfs(cursor, "001", 0);

        // Down to the first child of the root.

        assert_next_dfs(cursor, "002", 1);

        // Now iterate all children of the root via `next_sibling`.

        assert_valid_sibling_ptr(&cursor);
        assert_next_sibling(cursor, "004");
        assert_next_sibling(cursor, "006");
        assert_next_sibling(cursor, "010");

        // There should be no more siblings.

        assert!(cursor
            .next_sibling()
            .expect("Should parse next sibling")
            .is_none());
        assert!(cursor.current().is_none());
    }

    #[test]
    fn test_debug_info_next_sibling_with_ptr() {
        let encoding = Encoding {
            format: Format::Dwarf32,
            version: 4,
            address_size: 4,
        };

        let mut unit = UnitHeader {
            encoding,
            unit_length: 0,
            unit_type: UnitType::Compilation,
            debug_abbrev_offset: DebugAbbrevOffset(0),
            unit_offset: DebugInfoOffset(0).into(),
            entries_buf: EndianSlice::new(&[], LittleEndian),
        };
        let header_size = unit.size_of_header();
        let entries_buf = entries_cursor_sibling_entries_buf(header_size);
        unit.entries_buf = EndianSlice::new(&entries_buf, LittleEndian);
        let section = Section::with_endian(Endian::Little).unit(&mut unit);
        let info_buf = section.get_contents().unwrap();
        let debug_info = DebugInfo::new(&info_buf, LittleEndian);

        let unit = debug_info
            .units()
            .next()
            .expect("should have a unit result")
            .expect("and it should be ok");

        let abbrev_buf = entries_cursor_sibling_abbrev_buf();
        let debug_abbrev = DebugAbbrev::new(&abbrev_buf, LittleEndian);

        let abbrevs = unit
            .abbreviations(&debug_abbrev)
            .expect("Should parse abbreviations");

        let mut cursor = unit.entries(&abbrevs);
        test_cursor_next_sibling_with_ptr(&mut cursor);
    }

    #[test]
    fn test_debug_types_next_sibling_with_ptr() {
        let encoding = Encoding {
            format: Format::Dwarf32,
            version: 4,
            address_size: 4,
        };
        let mut unit = UnitHeader {
            encoding,
            unit_length: 0,
            unit_type: UnitType::Type {
                type_signature: DebugTypeSignature(0),
                type_offset: UnitOffset(0),
            },
            debug_abbrev_offset: DebugAbbrevOffset(0),
            unit_offset: DebugTypesOffset(0).into(),
            entries_buf: EndianSlice::new(&[], LittleEndian),
        };
        let header_size = unit.size_of_header();
        let entries_buf = entries_cursor_sibling_entries_buf(header_size);
        unit.entries_buf = EndianSlice::new(&entries_buf, LittleEndian);
        let section = Section::with_endian(Endian::Little).unit(&mut unit);
        let info_buf = section.get_contents().unwrap();
        let debug_types = DebugTypes::new(&info_buf, LittleEndian);

        let unit = debug_types
            .units()
            .next()
            .expect("should have a unit result")
            .expect("and it should be ok");

        let abbrev_buf = entries_cursor_sibling_abbrev_buf();
        let debug_abbrev = DebugAbbrev::new(&abbrev_buf, LittleEndian);

        let abbrevs = unit
            .abbreviations(&debug_abbrev)
            .expect("Should parse abbreviations");

        let mut cursor = unit.entries(&abbrevs);
        test_cursor_next_sibling_with_ptr(&mut cursor);
    }

    #[test]
    fn test_entries_at_offset() {
        let info_buf = &entries_cursor_tests_debug_info_buf();
        let debug_info = DebugInfo::new(info_buf, LittleEndian);

        let unit = debug_info
            .units()
            .next()
            .expect("should have a unit result")
            .expect("and it should be ok");

        let abbrevs_buf = &entries_cursor_tests_abbrev_buf();
        let debug_abbrev = DebugAbbrev::new(abbrevs_buf, LittleEndian);

        let abbrevs = unit
            .abbreviations(&debug_abbrev)
            .expect("Should parse abbreviations");

        let mut cursor = unit
            .entries_at_offset(&abbrevs, UnitOffset(unit.header_size()))
            .unwrap();
        assert_next_entry(&mut cursor, "001");

        let cursor = unit.entries_at_offset(&abbrevs, UnitOffset(0));
        match cursor {
            Err(Error::OffsetOutOfBounds) => {}
            otherwise => {
                assert!(false, "Unexpected parse result = {:#?}", otherwise);
            }
        }
    }

    fn entries_tree_tests_debug_abbrevs_buf() -> Vec<u8> {
        #[rustfmt::skip]
        let section = Section::with_endian(Endian::Little)
            .abbrev(1, DW_TAG_subprogram, DW_CHILDREN_yes)
                .abbrev_attr(DW_AT_name, DW_FORM_string)
                .abbrev_attr_null()
            .abbrev(2, DW_TAG_subprogram, DW_CHILDREN_no)
                .abbrev_attr(DW_AT_name, DW_FORM_string)
                .abbrev_attr_null()
            .abbrev_null()
            .get_contents()
            .unwrap();
        section
    }

    fn entries_tree_tests_debug_info_buf(header_size: usize) -> (Vec<u8>, UnitOffset) {
        let start = Label::new();
        let entry2 = Label::new();
        #[rustfmt::skip]
        let section = Section::with_endian(Endian::Little)
            .mark(&start)
            .die(1, |s| s.attr_string("root"))
                .die(1, |s| s.attr_string("1"))
                    .die(1, |s| s.attr_string("1a"))
                        .die_null()
                    .die(2, |s| s.attr_string("1b"))
                    .die_null()
                .mark(&entry2)
                .die(1, |s| s.attr_string("2"))
                    .die(1, |s| s.attr_string("2a"))
                        .die(1, |s| s.attr_string("2a1"))
                            .die_null()
                        .die_null()
                    .die(1, |s| s.attr_string("2b"))
                        .die(2, |s| s.attr_string("2b1"))
                        .die_null()
                    .die_null()
                .die(1, |s| s.attr_string("3"))
                    .die(1, |s| s.attr_string("3a"))
                        .die(2, |s| s.attr_string("3a1"))
                        .die(2, |s| s.attr_string("3a2"))
                        .die_null()
                    .die(2, |s| s.attr_string("3b"))
                    .die_null()
                .die(2, |s| s.attr_string("final"))
                .die_null()
            .get_contents()
            .unwrap();
        let entry2 = UnitOffset(header_size + (&entry2 - &start) as usize);
        (section, entry2)
    }

    #[test]
    fn test_entries_tree() {
        fn assert_entry<'input, 'abbrev, 'unit, 'tree, Endian>(
            node: Result<
                Option<EntriesTreeNode<'abbrev, 'unit, 'tree, EndianSlice<'input, Endian>>>,
            >,
            name: &str,
        ) -> EntriesTreeIter<'abbrev, 'unit, 'tree, EndianSlice<'input, Endian>>
        where
            Endian: Endianity,
        {
            let node = node
                .expect("Should parse entry")
                .expect("Should have entry");
            assert_entry_name(node.entry(), name);
            node.children()
        }

        fn assert_null<E: Endianity>(node: Result<Option<EntriesTreeNode<EndianSlice<E>>>>) {
            match node {
                Ok(None) => {}
                otherwise => {
                    assert!(false, "Unexpected parse result = {:#?}", otherwise);
                }
            }
        }

        let abbrevs_buf = entries_tree_tests_debug_abbrevs_buf();
        let debug_abbrev = DebugAbbrev::new(&abbrevs_buf, LittleEndian);

        let encoding = Encoding {
            format: Format::Dwarf32,
            version: 4,
            address_size: 4,
        };
        let mut unit = UnitHeader {
            encoding,
            unit_length: 0,
            unit_type: UnitType::Compilation,
            debug_abbrev_offset: DebugAbbrevOffset(0),
            unit_offset: DebugInfoOffset(0).into(),
            entries_buf: EndianSlice::new(&[], LittleEndian),
        };
        let header_size = unit.size_of_header();
        let (entries_buf, entry2) = entries_tree_tests_debug_info_buf(header_size);
        unit.entries_buf = EndianSlice::new(&entries_buf, LittleEndian);
        let info_buf = Section::with_endian(Endian::Little)
            .unit(&mut unit)
            .get_contents()
            .unwrap();
        let debug_info = DebugInfo::new(&info_buf, LittleEndian);

        let unit = debug_info
            .units()
            .next()
            .expect("Should parse unit")
            .expect("and it should be some");
        let abbrevs = unit
            .abbreviations(&debug_abbrev)
            .expect("Should parse abbreviations");
        let mut tree = unit
            .entries_tree(&abbrevs, None)
            .expect("Should have entries tree");

        // Test we can restart iteration of the tree.
        {
            let mut iter = assert_entry(tree.root().map(Some), "root");
            assert_entry(iter.next(), "1");
        }
        {
            let mut iter = assert_entry(tree.root().map(Some), "root");
            assert_entry(iter.next(), "1");
        }

        let mut iter = assert_entry(tree.root().map(Some), "root");
        {
            // Test iteration with children.
            let mut iter = assert_entry(iter.next(), "1");
            {
                // Test iteration with children flag, but no children.
                let mut iter = assert_entry(iter.next(), "1a");
                assert_null(iter.next());
                assert_null(iter.next());
            }
            {
                // Test iteration without children flag.
                let mut iter = assert_entry(iter.next(), "1b");
                assert_null(iter.next());
                assert_null(iter.next());
            }
            assert_null(iter.next());
            assert_null(iter.next());
        }
        {
            // Test skipping over children.
            let mut iter = assert_entry(iter.next(), "2");
            assert_entry(iter.next(), "2a");
            assert_entry(iter.next(), "2b");
            assert_null(iter.next());
        }
        {
            // Test skipping after partial iteration.
            let mut iter = assert_entry(iter.next(), "3");
            {
                let mut iter = assert_entry(iter.next(), "3a");
                assert_entry(iter.next(), "3a1");
                // Parent iter should be able to skip over "3a2".
            }
            assert_entry(iter.next(), "3b");
            assert_null(iter.next());
        }
        assert_entry(iter.next(), "final");
        assert_null(iter.next());

        // Test starting at an offset.
        let mut tree = unit
            .entries_tree(&abbrevs, Some(entry2))
            .expect("Should have entries tree");
        let mut iter = assert_entry(tree.root().map(Some), "2");
        assert_entry(iter.next(), "2a");
        assert_entry(iter.next(), "2b");
        assert_null(iter.next());
    }

    #[test]
    fn test_entries_raw() {
        fn assert_abbrev<'input, 'abbrev, 'unit, Endian>(
            entries: &mut EntriesRaw<'abbrev, 'unit, EndianSlice<'input, Endian>>,
            tag: DwTag,
        ) -> &'abbrev Abbreviation
        where
            Endian: Endianity,
        {
            let abbrev = entries
                .read_abbreviation()
                .expect("Should parse abbrev")
                .expect("Should have abbrev");
            assert_eq!(abbrev.tag(), tag);
            abbrev
        }

        fn assert_null<'input, 'abbrev, 'unit, Endian>(
            entries: &mut EntriesRaw<'abbrev, 'unit, EndianSlice<'input, Endian>>,
        ) where
            Endian: Endianity,
        {
            match entries.read_abbreviation() {
                Ok(None) => {}
                otherwise => {
                    assert!(false, "Unexpected parse result = {:#?}", otherwise);
                }
            }
        }

        fn assert_attr<'input, 'abbrev, 'unit, Endian>(
            entries: &mut EntriesRaw<'abbrev, 'unit, EndianSlice<'input, Endian>>,
            spec: Option<AttributeSpecification>,
            name: DwAt,
            value: &str,
        ) where
            Endian: Endianity,
        {
            let spec = spec.expect("Should have attribute specification");
            let attr = entries
                .read_attribute(spec)
                .expect("Should parse attribute");
            assert_eq!(attr.name(), name);
            assert_eq!(
                attr.value(),
                AttributeValue::String(EndianSlice::new(value.as_bytes(), Endian::default()))
            );
        }

        #[rustfmt::skip]
        let section = Section::with_endian(Endian::Little)
            .abbrev(1, DW_TAG_subprogram, DW_CHILDREN_yes)
                .abbrev_attr(DW_AT_name, DW_FORM_string)
                .abbrev_attr(DW_AT_linkage_name, DW_FORM_string)
                .abbrev_attr_null()
            .abbrev(2, DW_TAG_variable, DW_CHILDREN_no)
                .abbrev_attr(DW_AT_name, DW_FORM_string)
                .abbrev_attr_null()
            .abbrev_null();
        let abbrevs_buf = section.get_contents().unwrap();
        let debug_abbrev = DebugAbbrev::new(&abbrevs_buf, LittleEndian);

        #[rustfmt::skip]
        let section = Section::with_endian(Endian::Little)
            .die(1, |s| s.attr_string("f1").attr_string("l1"))
                .die(2, |s| s.attr_string("v1"))
                .die(2, |s| s.attr_string("v2"))
                .die(1, |s| s.attr_string("f2").attr_string("l2"))
                    .die_null()
                .die_null();
        let entries_buf = section.get_contents().unwrap();

        let encoding = Encoding {
            format: Format::Dwarf32,
            version: 4,
            address_size: 4,
        };
        let mut unit = UnitHeader {
            encoding,
            unit_length: 0,
            unit_type: UnitType::Compilation,
            debug_abbrev_offset: DebugAbbrevOffset(0),
            unit_offset: DebugInfoOffset(0).into(),
            entries_buf: EndianSlice::new(&entries_buf, LittleEndian),
        };
        let section = Section::with_endian(Endian::Little).unit(&mut unit);
        let info_buf = section.get_contents().unwrap();
        let debug_info = DebugInfo::new(&info_buf, LittleEndian);

        let unit = debug_info
            .units()
            .next()
            .expect("should have a unit result")
            .expect("and it should be ok");

        let abbrevs = unit
            .abbreviations(&debug_abbrev)
            .expect("Should parse abbreviations");

        let mut entries = unit
            .entries_raw(&abbrevs, None)
            .expect("Should have entries");

        assert_eq!(entries.next_depth(), 0);
        let abbrev = assert_abbrev(&mut entries, DW_TAG_subprogram);
        let mut attrs = abbrev.attributes().iter().copied();
        assert_attr(&mut entries, attrs.next(), DW_AT_name, "f1");
        assert_attr(&mut entries, attrs.next(), DW_AT_linkage_name, "l1");
        assert!(attrs.next().is_none());

        assert_eq!(entries.next_depth(), 1);
        let abbrev = assert_abbrev(&mut entries, DW_TAG_variable);
        let mut attrs = abbrev.attributes().iter().copied();
        assert_attr(&mut entries, attrs.next(), DW_AT_name, "v1");
        assert!(attrs.next().is_none());

        assert_eq!(entries.next_depth(), 1);
        let abbrev = assert_abbrev(&mut entries, DW_TAG_variable);
        let mut attrs = abbrev.attributes().iter().copied();
        assert_attr(&mut entries, attrs.next(), DW_AT_name, "v2");
        assert!(attrs.next().is_none());

        assert_eq!(entries.next_depth(), 1);
        let abbrev = assert_abbrev(&mut entries, DW_TAG_subprogram);
        let mut attrs = abbrev.attributes().iter().copied();
        assert_attr(&mut entries, attrs.next(), DW_AT_name, "f2");
        assert_attr(&mut entries, attrs.next(), DW_AT_linkage_name, "l2");
        assert!(attrs.next().is_none());

        assert_eq!(entries.next_depth(), 2);
        assert_null(&mut entries);

        assert_eq!(entries.next_depth(), 1);
        assert_null(&mut entries);

        assert_eq!(entries.next_depth(), 0);
        assert!(entries.is_empty());
    }

    #[test]
    fn test_debug_info_offset() {
        let padding = &[0; 10];
        let entries = &[0; 20];
        let encoding = Encoding {
            format: Format::Dwarf32,
            version: 4,
            address_size: 4,
        };
        let mut unit = UnitHeader {
            encoding,
            unit_length: 0,
            unit_type: UnitType::Compilation,
            debug_abbrev_offset: DebugAbbrevOffset(0),
            unit_offset: DebugInfoOffset(0).into(),
            entries_buf: EndianSlice::new(entries, LittleEndian),
        };
        Section::with_endian(Endian::Little)
            .append_bytes(padding)
            .unit(&mut unit);
        let offset = padding.len();
        let header_length = unit.size_of_header();
        let length = unit.length_including_self();
        assert_eq!(DebugInfoOffset(0).to_unit_offset(&unit), None);
        assert_eq!(DebugInfoOffset(offset - 1).to_unit_offset(&unit), None);
        assert_eq!(DebugInfoOffset(offset).to_unit_offset(&unit), None);
        assert_eq!(
            DebugInfoOffset(offset + header_length - 1).to_unit_offset(&unit),
            None
        );
        assert_eq!(
            DebugInfoOffset(offset + header_length).to_unit_offset(&unit),
            Some(UnitOffset(header_length))
        );
        assert_eq!(
            DebugInfoOffset(offset + length - 1).to_unit_offset(&unit),
            Some(UnitOffset(length - 1))
        );
        assert_eq!(DebugInfoOffset(offset + length).to_unit_offset(&unit), None);
        assert_eq!(
            UnitOffset(header_length).to_debug_info_offset(&unit),
            Some(DebugInfoOffset(offset + header_length))
        );
        assert_eq!(
            UnitOffset(length - 1).to_debug_info_offset(&unit),
            Some(DebugInfoOffset(offset + length - 1))
        );
    }

    #[test]
    fn test_debug_types_offset() {
        let padding = &[0; 10];
        let entries = &[0; 20];
        let encoding = Encoding {
            format: Format::Dwarf32,
            version: 4,
            address_size: 4,
        };
        let mut unit = UnitHeader {
            encoding,
            unit_length: 0,
            unit_type: UnitType::Type {
                type_signature: DebugTypeSignature(0),
                type_offset: UnitOffset(0),
            },
            debug_abbrev_offset: DebugAbbrevOffset(0),
            unit_offset: DebugTypesOffset(0).into(),
            entries_buf: EndianSlice::new(entries, LittleEndian),
        };
        Section::with_endian(Endian::Little)
            .append_bytes(padding)
            .unit(&mut unit);
        let offset = padding.len();
        let header_length = unit.size_of_header();
        let length = unit.length_including_self();
        assert_eq!(DebugTypesOffset(0).to_unit_offset(&unit), None);
        assert_eq!(DebugTypesOffset(offset - 1).to_unit_offset(&unit), None);
        assert_eq!(DebugTypesOffset(offset).to_unit_offset(&unit), None);
        assert_eq!(
            DebugTypesOffset(offset + header_length - 1).to_unit_offset(&unit),
            None
        );
        assert_eq!(
            DebugTypesOffset(offset + header_length).to_unit_offset(&unit),
            Some(UnitOffset(header_length))
        );
        assert_eq!(
            DebugTypesOffset(offset + length - 1).to_unit_offset(&unit),
            Some(UnitOffset(length - 1))
        );
        assert_eq!(
            DebugTypesOffset(offset + length).to_unit_offset(&unit),
            None
        );
        assert_eq!(
            UnitOffset(header_length).to_debug_types_offset(&unit),
            Some(DebugTypesOffset(offset + header_length))
        );
        assert_eq!(
            UnitOffset(length - 1).to_debug_types_offset(&unit),
            Some(DebugTypesOffset(offset + length - 1))
        );
    }

    #[test]
    fn test_length_including_self() {
        let encoding = Encoding {
            format: Format::Dwarf32,
            version: 4,
            address_size: 4,
        };
        let mut unit = UnitHeader {
            encoding,
            unit_length: 0,
            unit_type: UnitType::Compilation,
            debug_abbrev_offset: DebugAbbrevOffset(0),
            unit_offset: DebugInfoOffset(0).into(),
            entries_buf: EndianSlice::new(&[], LittleEndian),
        };
        unit.encoding.format = Format::Dwarf32;
        assert_eq!(unit.length_including_self(), 4);
        unit.encoding.format = Format::Dwarf64;
        assert_eq!(unit.length_including_self(), 12);
        unit.unit_length = 10;
        assert_eq!(unit.length_including_self(), 22);
    }

    #[test]
    fn test_parse_type_unit_abbrevs() {
        let types_buf = [
            // Type unit header
            0x25, 0x00, 0x00, 0x00, // 32-bit unit length = 37
            0x04, 0x00, // Version 4
            0x00, 0x00, 0x00, 0x00, // debug_abbrev_offset
            0x04, // Address size
            0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, // Type signature
            0x01, 0x02, 0x03, 0x04, // Type offset
            // DIEs
            // Abbreviation code
            0x01, // Attribute of form DW_FORM_string = "foo\0"
            0x66, 0x6f, 0x6f, 0x00, // Children
            // Abbreviation code
            0x01, // Attribute of form DW_FORM_string = "foo\0"
            0x66, 0x6f, 0x6f, 0x00, // Children
            // Abbreviation code
            0x01, // Attribute of form DW_FORM_string = "foo\0"
            0x66, 0x6f, 0x6f, 0x00, // Children
            0x00, // End of children
            0x00, // End of children
            0x00, // End of children
        ];
        let debug_types = DebugTypes::new(&types_buf, LittleEndian);

        let abbrev_buf = [
            // Code
            0x01, // DW_TAG_subprogram
            0x2e, // DW_CHILDREN_yes
            0x01, // Begin attributes
            0x03, // Attribute name = DW_AT_name
            0x08, // Attribute form = DW_FORM_string
            0x00, 0x00, // End attributes
            0x00, // Null terminator
        ];

        let get_some_type_unit = || debug_types.units().next().unwrap().unwrap();

        let unit = get_some_type_unit();

        let read_debug_abbrev_section_somehow = || &abbrev_buf;
        let debug_abbrev = DebugAbbrev::new(read_debug_abbrev_section_somehow(), LittleEndian);
        let _abbrevs_for_unit = unit.abbreviations(&debug_abbrev).unwrap();
    }
}
