//! 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 OSX, 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.
    #[allow(clippy::inline_always)]
    #[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 let Some(_) = attrs.next()? {}
            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.
    #[allow(clippy::inline_always)]
    #[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".
    #[allow(clippy::cyclomatic_complexity)]
    #[allow(clippy::match_same_arms)]
    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<'unit, 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<'unit, 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`.
    #[allow(clippy::inline_always)]
    #[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());
    /// ```
    #[allow(clippy::type_complexity)]
    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 OSX, 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.into()).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() {
        #[allow(clippy::type_complexity)]
        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();
    }
}
