use alloc::vec::Vec;
use std::ops::{Deref, DerefMut};
use std::{slice, usize};

use crate::common::{
    DebugAbbrevOffset, DebugInfoOffset, DebugLineOffset, DebugMacinfoOffset, DebugMacroOffset,
    DebugStrOffset, DebugTypeSignature, Encoding, Format, SectionId,
};
use crate::constants;
use crate::leb128::write::{sleb128_size, uleb128_size};
use crate::write::{
    Abbreviation, AbbreviationTable, Address, AttributeSpecification, BaseId, DebugLineStrOffsets,
    DebugStrOffsets, Error, Expression, FileId, LineProgram, LineStringId, LocationListId,
    LocationListOffsets, LocationListTable, RangeListId, RangeListOffsets, RangeListTable,
    Reference, Result, Section, Sections, StringId, Writer,
};

define_id!(UnitId, "An identifier for a unit in a `UnitTable`.");

define_id!(UnitEntryId, "An identifier for an entry in a `Unit`.");

/// A table of units that will be stored in the `.debug_info` section.
#[derive(Debug, Default)]
pub struct UnitTable {
    base_id: BaseId,
    units: Vec<Unit>,
}

impl UnitTable {
    /// Create a new unit and add it to the table.
    ///
    /// `address_size` must be in bytes.
    ///
    /// Returns the `UnitId` of the new unit.
    #[inline]
    pub fn add(&mut self, unit: Unit) -> UnitId {
        let id = UnitId::new(self.base_id, self.units.len());
        self.units.push(unit);
        id
    }

    /// Return the number of units.
    #[inline]
    pub fn count(&self) -> usize {
        self.units.len()
    }

    /// Return the id of a unit.
    ///
    /// # Panics
    ///
    /// Panics if `index >= self.count()`.
    #[inline]
    pub fn id(&self, index: usize) -> UnitId {
        assert!(index < self.count());
        UnitId::new(self.base_id, index)
    }

    /// Get a reference to a unit.
    ///
    /// # Panics
    ///
    /// Panics if `id` is invalid.
    #[inline]
    pub fn get(&self, id: UnitId) -> &Unit {
        debug_assert_eq!(self.base_id, id.base_id);
        &self.units[id.index]
    }

    /// Get a mutable reference to a unit.
    ///
    /// # Panics
    ///
    /// Panics if `id` is invalid.
    #[inline]
    pub fn get_mut(&mut self, id: UnitId) -> &mut Unit {
        debug_assert_eq!(self.base_id, id.base_id);
        &mut self.units[id.index]
    }

    /// Write the units to the given sections.
    ///
    /// `strings` must contain the `.debug_str` offsets of the corresponding
    /// `StringTable`.
    pub fn write<W: Writer>(
        &mut self,
        sections: &mut Sections<W>,
        line_strings: &DebugLineStrOffsets,
        strings: &DebugStrOffsets,
    ) -> Result<DebugInfoOffsets> {
        let mut offsets = DebugInfoOffsets {
            base_id: self.base_id,
            units: Vec::new(),
        };
        for unit in &mut self.units {
            // TODO: maybe share abbreviation tables
            let abbrev_offset = sections.debug_abbrev.offset();
            let mut abbrevs = AbbreviationTable::default();

            offsets.units.push(unit.write(
                sections,
                abbrev_offset,
                &mut abbrevs,
                line_strings,
                strings,
            )?);

            abbrevs.write(&mut sections.debug_abbrev)?;
        }

        write_section_refs(
            &mut sections.debug_info_refs,
            &mut sections.debug_info.0,
            &offsets,
        )?;
        write_section_refs(
            &mut sections.debug_loc_refs,
            &mut sections.debug_loc.0,
            &offsets,
        )?;
        write_section_refs(
            &mut sections.debug_loclists_refs,
            &mut sections.debug_loclists.0,
            &offsets,
        )?;

        Ok(offsets)
    }
}

fn write_section_refs<W: Writer>(
    references: &mut Vec<DebugInfoReference>,
    w: &mut W,
    offsets: &DebugInfoOffsets,
) -> Result<()> {
    for r in references.drain(..) {
        let entry_offset = offsets.entry(r.unit, r.entry).0;
        debug_assert_ne!(entry_offset, 0);
        w.write_offset_at(r.offset, entry_offset, SectionId::DebugInfo, r.size)?;
    }
    Ok(())
}

/// A unit's debugging information.
#[derive(Debug)]
pub struct Unit {
    base_id: BaseId,
    /// The encoding parameters for this unit.
    encoding: Encoding,
    /// The line number program for this unit.
    pub line_program: LineProgram,
    /// A table of range lists used by this unit.
    pub ranges: RangeListTable,
    /// A table of location lists used by this unit.
    pub locations: LocationListTable,
    /// All entries in this unit. The order is unrelated to the tree order.
    // Requirements:
    // - entries form a tree
    // - entries can be added in any order
    // - entries have a fixed id
    // - able to quickly lookup an entry from its id
    // Limitations of current implementation:
    // - mutable iteration of children is messy due to borrow checker
    entries: Vec<DebuggingInformationEntry>,
    /// The index of the root entry in entries.
    root: UnitEntryId,
}

impl Unit {
    /// Create a new `Unit`.
    pub fn new(encoding: Encoding, line_program: LineProgram) -> Self {
        let base_id = BaseId::default();
        let ranges = RangeListTable::default();
        let locations = LocationListTable::default();
        let mut entries = Vec::new();
        let root = DebuggingInformationEntry::new(
            base_id,
            &mut entries,
            None,
            constants::DW_TAG_compile_unit,
        );
        Unit {
            base_id,
            encoding,
            line_program,
            ranges,
            locations,
            entries,
            root,
        }
    }

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

    /// Return the DWARF version for this unit.
    #[inline]
    pub fn version(&self) -> u16 {
        self.encoding.version
    }

    /// Return the address size in bytes for this unit.
    #[inline]
    pub fn address_size(&self) -> u8 {
        self.encoding.address_size
    }

    /// Return the DWARF format for this unit.
    #[inline]
    pub fn format(&self) -> Format {
        self.encoding.format
    }

    /// Return the number of `DebuggingInformationEntry`s created for this unit.
    ///
    /// This includes entries that no longer have a parent.
    #[inline]
    pub fn count(&self) -> usize {
        self.entries.len()
    }

    /// Return the id of the root entry.
    #[inline]
    pub fn root(&self) -> UnitEntryId {
        self.root
    }

    /// Add a new `DebuggingInformationEntry` to this unit and return its id.
    ///
    /// The `parent` must be within the same unit.
    ///
    /// # Panics
    ///
    /// Panics if `parent` is invalid.
    #[inline]
    pub fn add(&mut self, parent: UnitEntryId, tag: constants::DwTag) -> UnitEntryId {
        debug_assert_eq!(self.base_id, parent.base_id);
        DebuggingInformationEntry::new(self.base_id, &mut self.entries, Some(parent), tag)
    }

    /// Get a reference to an entry.
    ///
    /// # Panics
    ///
    /// Panics if `id` is invalid.
    #[inline]
    pub fn get(&self, id: UnitEntryId) -> &DebuggingInformationEntry {
        debug_assert_eq!(self.base_id, id.base_id);
        &self.entries[id.index]
    }

    /// Get a mutable reference to an entry.
    ///
    /// # Panics
    ///
    /// Panics if `id` is invalid.
    #[inline]
    pub fn get_mut(&mut self, id: UnitEntryId) -> &mut DebuggingInformationEntry {
        debug_assert_eq!(self.base_id, id.base_id);
        &mut self.entries[id.index]
    }

    /// Return true if `self.line_program` is used by a DIE.
    fn line_program_in_use(&self) -> bool {
        if self.line_program.is_none() {
            return false;
        }
        if !self.line_program.is_empty() {
            return true;
        }

        for entry in &self.entries {
            for attr in &entry.attrs {
                if let AttributeValue::FileIndex(Some(_)) = attr.value {
                    return true;
                }
            }
        }

        false
    }

    /// Write the unit to the given sections.
    pub(crate) fn write<W: Writer>(
        &mut self,
        sections: &mut Sections<W>,
        abbrev_offset: DebugAbbrevOffset,
        abbrevs: &mut AbbreviationTable,
        line_strings: &DebugLineStrOffsets,
        strings: &DebugStrOffsets,
    ) -> Result<UnitOffsets> {
        let line_program = if self.line_program_in_use() {
            self.entries[self.root.index]
                .set(constants::DW_AT_stmt_list, AttributeValue::LineProgramRef);
            Some(self.line_program.write(
                &mut sections.debug_line,
                self.encoding,
                line_strings,
                strings,
            )?)
        } else {
            self.entries[self.root.index].delete(constants::DW_AT_stmt_list);
            None
        };

        // TODO: use .debug_types for type units in DWARF v4.
        let w = &mut sections.debug_info;

        let mut offsets = UnitOffsets {
            base_id: self.base_id,
            unit: w.offset(),
            // Entries can be written in any order, so create the complete vec now.
            entries: vec![EntryOffset::none(); self.entries.len()],
        };

        let length_offset = w.write_initial_length(self.format())?;
        let length_base = w.len();

        w.write_u16(self.version())?;
        if 2 <= self.version() && self.version() <= 4 {
            w.write_offset(
                abbrev_offset.0,
                SectionId::DebugAbbrev,
                self.format().word_size(),
            )?;
            w.write_u8(self.address_size())?;
        } else if self.version() == 5 {
            w.write_u8(constants::DW_UT_compile.0)?;
            w.write_u8(self.address_size())?;
            w.write_offset(
                abbrev_offset.0,
                SectionId::DebugAbbrev,
                self.format().word_size(),
            )?;
        } else {
            return Err(Error::UnsupportedVersion(self.version()));
        }

        // Calculate all DIE offsets, so that we are able to output references to them.
        // However, references to base types in expressions use ULEB128, so base types
        // must be moved to the front before we can calculate offsets.
        self.reorder_base_types();
        let mut offset = w.len();
        self.entries[self.root.index].calculate_offsets(
            self,
            &mut offset,
            &mut offsets,
            abbrevs,
        )?;

        let range_lists = self.ranges.write(sections, self.encoding)?;
        // Location lists can't be written until we have DIE offsets.
        let loc_lists = self
            .locations
            .write(sections, self.encoding, Some(&offsets))?;

        let w = &mut sections.debug_info;
        let mut unit_refs = Vec::new();
        self.entries[self.root.index].write(
            w,
            &mut sections.debug_info_refs,
            &mut unit_refs,
            self,
            &mut offsets,
            line_program,
            line_strings,
            strings,
            &range_lists,
            &loc_lists,
        )?;

        let length = (w.len() - length_base) as u64;
        w.write_initial_length_at(length_offset, length, self.format())?;

        for (offset, entry) in unit_refs {
            // This does not need relocation.
            w.write_udata_at(
                offset.0,
                offsets.unit_offset(entry),
                self.format().word_size(),
            )?;
        }

        Ok(offsets)
    }

    /// Reorder base types to come first so that typed stack operations
    /// can get their offset.
    fn reorder_base_types(&mut self) {
        let root = &self.entries[self.root.index];
        let mut root_children = Vec::with_capacity(root.children.len());
        for entry in &root.children {
            if self.entries[entry.index].tag == constants::DW_TAG_base_type {
                root_children.push(*entry);
            }
        }
        for entry in &root.children {
            if self.entries[entry.index].tag != constants::DW_TAG_base_type {
                root_children.push(*entry);
            }
        }
        self.entries[self.root.index].children = root_children;
    }
}

/// A Debugging Information Entry (DIE).
///
/// DIEs have a set of attributes and optionally have children DIEs as well.
///
/// DIEs form a tree without any cycles. This is enforced by specifying the
/// parent when creating a DIE, and disallowing changes of parent.
#[derive(Debug)]
pub struct DebuggingInformationEntry {
    id: UnitEntryId,
    parent: Option<UnitEntryId>,
    tag: constants::DwTag,
    /// Whether to emit `DW_AT_sibling`.
    sibling: bool,
    attrs: Vec<Attribute>,
    children: Vec<UnitEntryId>,
}

impl DebuggingInformationEntry {
    /// Create a new `DebuggingInformationEntry`.
    ///
    /// # Panics
    ///
    /// Panics if `parent` is invalid.
    #[allow(clippy::new_ret_no_self)]
    fn new(
        base_id: BaseId,
        entries: &mut Vec<DebuggingInformationEntry>,
        parent: Option<UnitEntryId>,
        tag: constants::DwTag,
    ) -> UnitEntryId {
        let id = UnitEntryId::new(base_id, entries.len());
        entries.push(DebuggingInformationEntry {
            id,
            parent,
            tag,
            sibling: false,
            attrs: Vec::new(),
            children: Vec::new(),
        });
        if let Some(parent) = parent {
            debug_assert_eq!(base_id, parent.base_id);
            assert_ne!(parent, id);
            entries[parent.index].children.push(id);
        }
        id
    }

    /// Return the id of this entry.
    #[inline]
    pub fn id(&self) -> UnitEntryId {
        self.id
    }

    /// Return the parent of this entry.
    #[inline]
    pub fn parent(&self) -> Option<UnitEntryId> {
        self.parent
    }

    /// Return the tag of this entry.
    #[inline]
    pub fn tag(&self) -> constants::DwTag {
        self.tag
    }

    /// Return `true` if a `DW_AT_sibling` attribute will be emitted.
    #[inline]
    pub fn sibling(&self) -> bool {
        self.sibling
    }

    /// Set whether a `DW_AT_sibling` attribute will be emitted.
    ///
    /// The attribute will only be emitted if the DIE has children.
    #[inline]
    pub fn set_sibling(&mut self, sibling: bool) {
        self.sibling = sibling;
    }

    /// Iterate over the attributes of this entry.
    #[inline]
    pub fn attrs(&self) -> slice::Iter<Attribute> {
        self.attrs.iter()
    }

    /// Iterate over the attributes of this entry for modification.
    #[inline]
    pub fn attrs_mut(&mut self) -> slice::IterMut<Attribute> {
        self.attrs.iter_mut()
    }

    /// Get an attribute.
    pub fn get(&self, name: constants::DwAt) -> Option<&AttributeValue> {
        self.attrs
            .iter()
            .find(|attr| attr.name == name)
            .map(|attr| &attr.value)
    }

    /// Get an attribute for modification.
    pub fn get_mut(&mut self, name: constants::DwAt) -> Option<&mut AttributeValue> {
        self.attrs
            .iter_mut()
            .find(|attr| attr.name == name)
            .map(|attr| &mut attr.value)
    }

    /// Set an attribute.
    ///
    /// Replaces any existing attribute with the same name.
    ///
    /// # Panics
    ///
    /// Panics if `name` is `DW_AT_sibling`. Use `set_sibling` instead.
    pub fn set(&mut self, name: constants::DwAt, value: AttributeValue) {
        assert_ne!(name, constants::DW_AT_sibling);
        if let Some(attr) = self.attrs.iter_mut().find(|attr| attr.name == name) {
            attr.value = value;
            return;
        }
        self.attrs.push(Attribute { name, value });
    }

    /// Delete an attribute.
    ///
    /// Replaces any existing attribute with the same name.
    pub fn delete(&mut self, name: constants::DwAt) {
        self.attrs.retain(|x| x.name != name);
    }

    /// Iterate over the children of this entry.
    ///
    /// Note: use `Unit::add` to add a new child to this entry.
    #[inline]
    pub fn children(&self) -> slice::Iter<UnitEntryId> {
        self.children.iter()
    }

    /// Delete a child entry and all of its children.
    pub fn delete_child(&mut self, id: UnitEntryId) {
        self.children.retain(|&child| child != id);
    }

    /// Return the type abbreviation for this DIE.
    fn abbreviation(&self, encoding: Encoding) -> Result<Abbreviation> {
        let mut attrs = Vec::new();

        if self.sibling && !self.children.is_empty() {
            let form = match encoding.format {
                Format::Dwarf32 => constants::DW_FORM_ref4,
                Format::Dwarf64 => constants::DW_FORM_ref8,
            };
            attrs.push(AttributeSpecification::new(constants::DW_AT_sibling, form));
        }

        for attr in &self.attrs {
            attrs.push(attr.specification(encoding)?);
        }

        Ok(Abbreviation::new(
            self.tag,
            !self.children.is_empty(),
            attrs,
        ))
    }

    fn calculate_offsets(
        &self,
        unit: &Unit,
        offset: &mut usize,
        offsets: &mut UnitOffsets,
        abbrevs: &mut AbbreviationTable,
    ) -> Result<()> {
        offsets.entries[self.id.index].offset = DebugInfoOffset(*offset);
        offsets.entries[self.id.index].abbrev = abbrevs.add(self.abbreviation(unit.encoding())?);
        *offset += self.size(unit, offsets);
        if !self.children.is_empty() {
            for child in &self.children {
                unit.entries[child.index].calculate_offsets(unit, offset, offsets, abbrevs)?;
            }
            // Null child
            *offset += 1;
        }
        Ok(())
    }

    fn size(&self, unit: &Unit, offsets: &UnitOffsets) -> usize {
        let mut size = uleb128_size(offsets.abbrev(self.id));
        if self.sibling && !self.children.is_empty() {
            size += unit.format().word_size() as usize;
        }
        for attr in &self.attrs {
            size += attr.value.size(unit, offsets);
        }
        size
    }

    /// Write the entry to the given sections.
    fn write<W: Writer>(
        &self,
        w: &mut DebugInfo<W>,
        debug_info_refs: &mut Vec<DebugInfoReference>,
        unit_refs: &mut Vec<(DebugInfoOffset, UnitEntryId)>,
        unit: &Unit,
        offsets: &mut UnitOffsets,
        line_program: Option<DebugLineOffset>,
        line_strings: &DebugLineStrOffsets,
        strings: &DebugStrOffsets,
        range_lists: &RangeListOffsets,
        loc_lists: &LocationListOffsets,
    ) -> Result<()> {
        debug_assert_eq!(offsets.debug_info_offset(self.id), w.offset());
        w.write_uleb128(offsets.abbrev(self.id))?;

        let sibling_offset = if self.sibling && !self.children.is_empty() {
            let offset = w.offset();
            w.write_udata(0, unit.format().word_size())?;
            Some(offset)
        } else {
            None
        };

        for attr in &self.attrs {
            attr.value.write(
                w,
                debug_info_refs,
                unit_refs,
                unit,
                offsets,
                line_program,
                line_strings,
                strings,
                range_lists,
                loc_lists,
            )?;
        }

        if !self.children.is_empty() {
            for child in &self.children {
                unit.entries[child.index].write(
                    w,
                    debug_info_refs,
                    unit_refs,
                    unit,
                    offsets,
                    line_program,
                    line_strings,
                    strings,
                    range_lists,
                    loc_lists,
                )?;
            }
            // Null child
            w.write_u8(0)?;
        }

        if let Some(offset) = sibling_offset {
            let next_offset = (w.offset().0 - offsets.unit.0) as u64;
            // This does not need relocation.
            w.write_udata_at(offset.0, next_offset, unit.format().word_size())?;
        }
        Ok(())
    }
}

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

impl Attribute {
    /// Get the name of this attribute.
    #[inline]
    pub fn name(&self) -> constants::DwAt {
        self.name
    }

    /// Get the value of this attribute.
    #[inline]
    pub fn get(&self) -> &AttributeValue {
        &self.value
    }

    /// Set the value of this attribute.
    #[inline]
    pub fn set(&mut self, value: AttributeValue) {
        self.value = value;
    }

    /// Return the type specification for this attribute.
    fn specification(&self, encoding: Encoding) -> Result<AttributeSpecification> {
        Ok(AttributeSpecification::new(
            self.name,
            self.value.form(encoding)?,
        ))
    }
}

/// The value of an attribute in a `DebuggingInformationEntry`.
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum AttributeValue {
    /// "Refers to some location in the address space of the described program."
    Address(Address),

    /// A slice of an arbitrary number of bytes.
    Block(Vec<u8>),

    /// 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.
    ///
    /// This value will be converted to the target endian before writing.
    ///
    /// 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.
    ///
    /// This value will be converted to the target endian before writing.
    ///
    /// 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.
    ///
    /// This value will be converted to the target endian before writing.
    ///
    /// 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),

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

    /// An attribute that is always present.
    FlagPresent,

    /// A reference to a `DebuggingInformationEntry` in this unit.
    UnitRef(UnitEntryId),

    /// A reference to a `DebuggingInformationEntry` in a potentially different unit.
    DebugInfoRef(Reference),

    /// An offset into the `.debug_info` section of the supplementary object file.
    ///
    /// The API does not currently assist with generating this offset.
    /// This variant will be removed from the API once support for writing
    /// supplementary object files is implemented.
    DebugInfoRefSup(DebugInfoOffset),

    /// A reference to a line number program.
    LineProgramRef,

    /// A reference to a location list.
    LocationListRef(LocationListId),

    /// An offset into the `.debug_macinfo` section.
    ///
    /// The API does not currently assist with generating this offset.
    /// This variant will be removed from the API once support for writing
    /// `.debug_macinfo` sections is implemented.
    DebugMacinfoRef(DebugMacinfoOffset),

    /// An offset into the `.debug_macro` section.
    ///
    /// The API does not currently assist with generating this offset.
    /// This variant will be removed from the API once support for writing
    /// `.debug_macro` sections is implemented.
    DebugMacroRef(DebugMacroOffset),

    /// A reference to a range list.
    RangeListRef(RangeListId),

    /// A type signature.
    ///
    /// The API does not currently assist with generating this signature.
    /// This variant will be removed from the API once support for writing
    /// `.debug_types` sections is implemented.
    DebugTypesRef(DebugTypeSignature),

    /// A reference to a string in the `.debug_str` section.
    StringRef(StringId),

    /// An offset into the `.debug_str` section of the supplementary object file.
    ///
    /// The API does not currently assist with generating this offset.
    /// This variant will be removed from the API once support for writing
    /// supplementary object files is implemented.
    DebugStrRefSup(DebugStrOffset),

    /// A reference to a string in the `.debug_line_str` section.
    LineStringRef(LineStringId),

    /// A slice of bytes representing a string. Must not include null bytes.
    /// Not guaranteed to be UTF-8 or anything like that.
    String(Vec<u8>),

    /// 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 unit containing this value.
    FileIndex(Option<FileId>),
}

impl AttributeValue {
    /// Return the form that will be used to encode this value.
    pub fn form(&self, encoding: Encoding) -> Result<constants::DwForm> {
        // TODO: missing forms:
        // - DW_FORM_indirect
        // - DW_FORM_implicit_const
        // - FW_FORM_block1/block2/block4
        // - DW_FORM_str/strx1/strx2/strx3/strx4
        // - DW_FORM_addrx/addrx1/addrx2/addrx3/addrx4
        // - DW_FORM_data16
        // - DW_FORM_line_strp
        // - DW_FORM_loclistx
        // - DW_FORM_rnglistx
        let form = match *self {
            AttributeValue::Address(_) => constants::DW_FORM_addr,
            AttributeValue::Block(_) => constants::DW_FORM_block,
            AttributeValue::Data1(_) => constants::DW_FORM_data1,
            AttributeValue::Data2(_) => constants::DW_FORM_data2,
            AttributeValue::Data4(_) => constants::DW_FORM_data4,
            AttributeValue::Data8(_) => constants::DW_FORM_data8,
            AttributeValue::Exprloc(_) => constants::DW_FORM_exprloc,
            AttributeValue::Flag(_) => constants::DW_FORM_flag,
            AttributeValue::FlagPresent => constants::DW_FORM_flag_present,
            AttributeValue::UnitRef(_) => {
                // Using a fixed size format lets us write a placeholder before we know
                // the value.
                match encoding.format {
                    Format::Dwarf32 => constants::DW_FORM_ref4,
                    Format::Dwarf64 => constants::DW_FORM_ref8,
                }
            }
            AttributeValue::DebugInfoRef(_) => constants::DW_FORM_ref_addr,
            AttributeValue::DebugInfoRefSup(_) => {
                // TODO: should this depend on the size of supplementary section?
                match encoding.format {
                    Format::Dwarf32 => constants::DW_FORM_ref_sup4,
                    Format::Dwarf64 => constants::DW_FORM_ref_sup8,
                }
            }
            AttributeValue::LineProgramRef
            | AttributeValue::LocationListRef(_)
            | AttributeValue::DebugMacinfoRef(_)
            | AttributeValue::DebugMacroRef(_)
            | AttributeValue::RangeListRef(_) => {
                if encoding.version == 2 || encoding.version == 3 {
                    match encoding.format {
                        Format::Dwarf32 => constants::DW_FORM_data4,
                        Format::Dwarf64 => constants::DW_FORM_data8,
                    }
                } else {
                    constants::DW_FORM_sec_offset
                }
            }
            AttributeValue::DebugTypesRef(_) => constants::DW_FORM_ref_sig8,
            AttributeValue::StringRef(_) => constants::DW_FORM_strp,
            AttributeValue::DebugStrRefSup(_) => constants::DW_FORM_strp_sup,
            AttributeValue::LineStringRef(_) => constants::DW_FORM_line_strp,
            AttributeValue::String(_) => constants::DW_FORM_string,
            AttributeValue::Encoding(_)
            | AttributeValue::DecimalSign(_)
            | AttributeValue::Endianity(_)
            | AttributeValue::Accessibility(_)
            | AttributeValue::Visibility(_)
            | AttributeValue::Virtuality(_)
            | AttributeValue::Language(_)
            | AttributeValue::AddressClass(_)
            | AttributeValue::IdentifierCase(_)
            | AttributeValue::CallingConvention(_)
            | AttributeValue::Inline(_)
            | AttributeValue::Ordering(_)
            | AttributeValue::FileIndex(_)
            | AttributeValue::Udata(_) => constants::DW_FORM_udata,
            AttributeValue::Sdata(_) => constants::DW_FORM_sdata,
        };
        Ok(form)
    }

    fn size(&self, unit: &Unit, offsets: &UnitOffsets) -> usize {
        macro_rules! debug_assert_form {
            ($form:expr) => {
                debug_assert_eq!(self.form(unit.encoding()).unwrap(), $form)
            };
        }
        match *self {
            AttributeValue::Address(_) => {
                debug_assert_form!(constants::DW_FORM_addr);
                unit.address_size() as usize
            }
            AttributeValue::Block(ref val) => {
                debug_assert_form!(constants::DW_FORM_block);
                uleb128_size(val.len() as u64) + val.len()
            }
            AttributeValue::Data1(_) => {
                debug_assert_form!(constants::DW_FORM_data1);
                1
            }
            AttributeValue::Data2(_) => {
                debug_assert_form!(constants::DW_FORM_data2);
                2
            }
            AttributeValue::Data4(_) => {
                debug_assert_form!(constants::DW_FORM_data4);
                4
            }
            AttributeValue::Data8(_) => {
                debug_assert_form!(constants::DW_FORM_data8);
                8
            }
            AttributeValue::Sdata(val) => {
                debug_assert_form!(constants::DW_FORM_sdata);
                sleb128_size(val)
            }
            AttributeValue::Udata(val) => {
                debug_assert_form!(constants::DW_FORM_udata);
                uleb128_size(val)
            }
            AttributeValue::Exprloc(ref val) => {
                debug_assert_form!(constants::DW_FORM_exprloc);
                let size = val.size(unit.encoding(), Some(offsets));
                uleb128_size(size as u64) + size
            }
            AttributeValue::Flag(_) => {
                debug_assert_form!(constants::DW_FORM_flag);
                1
            }
            AttributeValue::FlagPresent => {
                debug_assert_form!(constants::DW_FORM_flag_present);
                0
            }
            AttributeValue::UnitRef(_) => {
                match unit.format() {
                    Format::Dwarf32 => debug_assert_form!(constants::DW_FORM_ref4),
                    Format::Dwarf64 => debug_assert_form!(constants::DW_FORM_ref8),
                }
                unit.format().word_size() as usize
            }
            AttributeValue::DebugInfoRef(_) => {
                debug_assert_form!(constants::DW_FORM_ref_addr);
                if unit.version() == 2 {
                    unit.address_size() as usize
                } else {
                    unit.format().word_size() as usize
                }
            }
            AttributeValue::DebugInfoRefSup(_) => {
                match unit.format() {
                    Format::Dwarf32 => debug_assert_form!(constants::DW_FORM_ref_sup4),
                    Format::Dwarf64 => debug_assert_form!(constants::DW_FORM_ref_sup8),
                }
                unit.format().word_size() as usize
            }
            AttributeValue::LineProgramRef => {
                if unit.version() >= 4 {
                    debug_assert_form!(constants::DW_FORM_sec_offset);
                }
                unit.format().word_size() as usize
            }
            AttributeValue::LocationListRef(_) => {
                if unit.version() >= 4 {
                    debug_assert_form!(constants::DW_FORM_sec_offset);
                }
                unit.format().word_size() as usize
            }
            AttributeValue::DebugMacinfoRef(_) => {
                if unit.version() >= 4 {
                    debug_assert_form!(constants::DW_FORM_sec_offset);
                }
                unit.format().word_size() as usize
            }
            AttributeValue::DebugMacroRef(_) => {
                if unit.version() >= 4 {
                    debug_assert_form!(constants::DW_FORM_sec_offset);
                }
                unit.format().word_size() as usize
            }
            AttributeValue::RangeListRef(_) => {
                if unit.version() >= 4 {
                    debug_assert_form!(constants::DW_FORM_sec_offset);
                }
                unit.format().word_size() as usize
            }
            AttributeValue::DebugTypesRef(_) => {
                debug_assert_form!(constants::DW_FORM_ref_sig8);
                8
            }
            AttributeValue::StringRef(_) => {
                debug_assert_form!(constants::DW_FORM_strp);
                unit.format().word_size() as usize
            }
            AttributeValue::DebugStrRefSup(_) => {
                debug_assert_form!(constants::DW_FORM_strp_sup);
                unit.format().word_size() as usize
            }
            AttributeValue::LineStringRef(_) => {
                debug_assert_form!(constants::DW_FORM_line_strp);
                unit.format().word_size() as usize
            }
            AttributeValue::String(ref val) => {
                debug_assert_form!(constants::DW_FORM_string);
                val.len() + 1
            }
            AttributeValue::Encoding(val) => {
                debug_assert_form!(constants::DW_FORM_udata);
                uleb128_size(val.0 as u64)
            }
            AttributeValue::DecimalSign(val) => {
                debug_assert_form!(constants::DW_FORM_udata);
                uleb128_size(val.0 as u64)
            }
            AttributeValue::Endianity(val) => {
                debug_assert_form!(constants::DW_FORM_udata);
                uleb128_size(val.0 as u64)
            }
            AttributeValue::Accessibility(val) => {
                debug_assert_form!(constants::DW_FORM_udata);
                uleb128_size(val.0 as u64)
            }
            AttributeValue::Visibility(val) => {
                debug_assert_form!(constants::DW_FORM_udata);
                uleb128_size(val.0 as u64)
            }
            AttributeValue::Virtuality(val) => {
                debug_assert_form!(constants::DW_FORM_udata);
                uleb128_size(val.0 as u64)
            }
            AttributeValue::Language(val) => {
                debug_assert_form!(constants::DW_FORM_udata);
                uleb128_size(val.0 as u64)
            }
            AttributeValue::AddressClass(val) => {
                debug_assert_form!(constants::DW_FORM_udata);
                uleb128_size(val.0 as u64)
            }
            AttributeValue::IdentifierCase(val) => {
                debug_assert_form!(constants::DW_FORM_udata);
                uleb128_size(val.0 as u64)
            }
            AttributeValue::CallingConvention(val) => {
                debug_assert_form!(constants::DW_FORM_udata);
                uleb128_size(val.0 as u64)
            }
            AttributeValue::Inline(val) => {
                debug_assert_form!(constants::DW_FORM_udata);
                uleb128_size(val.0 as u64)
            }
            AttributeValue::Ordering(val) => {
                debug_assert_form!(constants::DW_FORM_udata);
                uleb128_size(val.0 as u64)
            }
            AttributeValue::FileIndex(val) => {
                debug_assert_form!(constants::DW_FORM_udata);
                uleb128_size(val.map(FileId::raw).unwrap_or(0))
            }
        }
    }

    /// Write the attribute value to the given sections.
    fn write<W: Writer>(
        &self,
        w: &mut DebugInfo<W>,
        debug_info_refs: &mut Vec<DebugInfoReference>,
        unit_refs: &mut Vec<(DebugInfoOffset, UnitEntryId)>,
        unit: &Unit,
        offsets: &UnitOffsets,
        line_program: Option<DebugLineOffset>,
        line_strings: &DebugLineStrOffsets,
        strings: &DebugStrOffsets,
        range_lists: &RangeListOffsets,
        loc_lists: &LocationListOffsets,
    ) -> Result<()> {
        macro_rules! debug_assert_form {
            ($form:expr) => {
                debug_assert_eq!(self.form(unit.encoding()).unwrap(), $form)
            };
        }
        match *self {
            AttributeValue::Address(val) => {
                debug_assert_form!(constants::DW_FORM_addr);
                w.write_address(val, unit.address_size())?;
            }
            AttributeValue::Block(ref val) => {
                debug_assert_form!(constants::DW_FORM_block);
                w.write_uleb128(val.len() as u64)?;
                w.write(val)?;
            }
            AttributeValue::Data1(val) => {
                debug_assert_form!(constants::DW_FORM_data1);
                w.write_u8(val)?;
            }
            AttributeValue::Data2(val) => {
                debug_assert_form!(constants::DW_FORM_data2);
                w.write_u16(val)?;
            }
            AttributeValue::Data4(val) => {
                debug_assert_form!(constants::DW_FORM_data4);
                w.write_u32(val)?;
            }
            AttributeValue::Data8(val) => {
                debug_assert_form!(constants::DW_FORM_data8);
                w.write_u64(val)?;
            }
            AttributeValue::Sdata(val) => {
                debug_assert_form!(constants::DW_FORM_sdata);
                w.write_sleb128(val)?;
            }
            AttributeValue::Udata(val) => {
                debug_assert_form!(constants::DW_FORM_udata);
                w.write_uleb128(val)?;
            }
            AttributeValue::Exprloc(ref val) => {
                debug_assert_form!(constants::DW_FORM_exprloc);
                w.write_uleb128(val.size(unit.encoding(), Some(offsets)) as u64)?;
                val.write(
                    &mut w.0,
                    Some(debug_info_refs),
                    unit.encoding(),
                    Some(offsets),
                )?;
            }
            AttributeValue::Flag(val) => {
                debug_assert_form!(constants::DW_FORM_flag);
                w.write_u8(val as u8)?;
            }
            AttributeValue::FlagPresent => {
                debug_assert_form!(constants::DW_FORM_flag_present);
            }
            AttributeValue::UnitRef(id) => {
                match unit.format() {
                    Format::Dwarf32 => debug_assert_form!(constants::DW_FORM_ref4),
                    Format::Dwarf64 => debug_assert_form!(constants::DW_FORM_ref8),
                }
                unit_refs.push((w.offset(), id));
                w.write_udata(0, unit.format().word_size())?;
            }
            AttributeValue::DebugInfoRef(reference) => {
                debug_assert_form!(constants::DW_FORM_ref_addr);
                let size = if unit.version() == 2 {
                    unit.address_size()
                } else {
                    unit.format().word_size()
                };
                match reference {
                    Reference::Symbol(symbol) => w.write_reference(symbol, size)?,
                    Reference::Entry(unit, entry) => {
                        debug_info_refs.push(DebugInfoReference {
                            offset: w.len(),
                            unit,
                            entry,
                            size,
                        });
                        w.write_udata(0, size)?;
                    }
                }
            }
            AttributeValue::DebugInfoRefSup(val) => {
                match unit.format() {
                    Format::Dwarf32 => debug_assert_form!(constants::DW_FORM_ref_sup4),
                    Format::Dwarf64 => debug_assert_form!(constants::DW_FORM_ref_sup8),
                }
                w.write_udata(val.0 as u64, unit.format().word_size())?;
            }
            AttributeValue::LineProgramRef => {
                if unit.version() >= 4 {
                    debug_assert_form!(constants::DW_FORM_sec_offset);
                }
                match line_program {
                    Some(line_program) => {
                        w.write_offset(
                            line_program.0,
                            SectionId::DebugLine,
                            unit.format().word_size(),
                        )?;
                    }
                    None => return Err(Error::InvalidAttributeValue),
                }
            }
            AttributeValue::LocationListRef(val) => {
                if unit.version() >= 4 {
                    debug_assert_form!(constants::DW_FORM_sec_offset);
                }
                let section = if unit.version() <= 4 {
                    SectionId::DebugLoc
                } else {
                    SectionId::DebugLocLists
                };
                w.write_offset(loc_lists.get(val).0, section, unit.format().word_size())?;
            }
            AttributeValue::DebugMacinfoRef(val) => {
                if unit.version() >= 4 {
                    debug_assert_form!(constants::DW_FORM_sec_offset);
                }
                w.write_offset(val.0, SectionId::DebugMacinfo, unit.format().word_size())?;
            }
            AttributeValue::DebugMacroRef(val) => {
                if unit.version() >= 4 {
                    debug_assert_form!(constants::DW_FORM_sec_offset);
                }
                w.write_offset(val.0, SectionId::DebugMacro, unit.format().word_size())?;
            }
            AttributeValue::RangeListRef(val) => {
                if unit.version() >= 4 {
                    debug_assert_form!(constants::DW_FORM_sec_offset);
                }
                let section = if unit.version() <= 4 {
                    SectionId::DebugRanges
                } else {
                    SectionId::DebugRngLists
                };
                w.write_offset(range_lists.get(val).0, section, unit.format().word_size())?;
            }
            AttributeValue::DebugTypesRef(val) => {
                debug_assert_form!(constants::DW_FORM_ref_sig8);
                w.write_u64(val.0)?;
            }
            AttributeValue::StringRef(val) => {
                debug_assert_form!(constants::DW_FORM_strp);
                w.write_offset(
                    strings.get(val).0,
                    SectionId::DebugStr,
                    unit.format().word_size(),
                )?;
            }
            AttributeValue::DebugStrRefSup(val) => {
                debug_assert_form!(constants::DW_FORM_strp_sup);
                w.write_udata(val.0 as u64, unit.format().word_size())?;
            }
            AttributeValue::LineStringRef(val) => {
                debug_assert_form!(constants::DW_FORM_line_strp);
                w.write_offset(
                    line_strings.get(val).0,
                    SectionId::DebugLineStr,
                    unit.format().word_size(),
                )?;
            }
            AttributeValue::String(ref val) => {
                debug_assert_form!(constants::DW_FORM_string);
                w.write(val)?;
                w.write_u8(0)?;
            }
            AttributeValue::Encoding(val) => {
                debug_assert_form!(constants::DW_FORM_udata);
                w.write_uleb128(u64::from(val.0))?;
            }
            AttributeValue::DecimalSign(val) => {
                debug_assert_form!(constants::DW_FORM_udata);
                w.write_uleb128(u64::from(val.0))?;
            }
            AttributeValue::Endianity(val) => {
                debug_assert_form!(constants::DW_FORM_udata);
                w.write_uleb128(u64::from(val.0))?;
            }
            AttributeValue::Accessibility(val) => {
                debug_assert_form!(constants::DW_FORM_udata);
                w.write_uleb128(u64::from(val.0))?;
            }
            AttributeValue::Visibility(val) => {
                debug_assert_form!(constants::DW_FORM_udata);
                w.write_uleb128(u64::from(val.0))?;
            }
            AttributeValue::Virtuality(val) => {
                debug_assert_form!(constants::DW_FORM_udata);
                w.write_uleb128(u64::from(val.0))?;
            }
            AttributeValue::Language(val) => {
                debug_assert_form!(constants::DW_FORM_udata);
                w.write_uleb128(u64::from(val.0))?;
            }
            AttributeValue::AddressClass(val) => {
                debug_assert_form!(constants::DW_FORM_udata);
                w.write_uleb128(val.0)?;
            }
            AttributeValue::IdentifierCase(val) => {
                debug_assert_form!(constants::DW_FORM_udata);
                w.write_uleb128(u64::from(val.0))?;
            }
            AttributeValue::CallingConvention(val) => {
                debug_assert_form!(constants::DW_FORM_udata);
                w.write_uleb128(u64::from(val.0))?;
            }
            AttributeValue::Inline(val) => {
                debug_assert_form!(constants::DW_FORM_udata);
                w.write_uleb128(u64::from(val.0))?;
            }
            AttributeValue::Ordering(val) => {
                debug_assert_form!(constants::DW_FORM_udata);
                w.write_uleb128(u64::from(val.0))?;
            }
            AttributeValue::FileIndex(val) => {
                debug_assert_form!(constants::DW_FORM_udata);
                w.write_uleb128(val.map(FileId::raw).unwrap_or(0))?;
            }
        }
        Ok(())
    }
}

define_section!(
    DebugInfo,
    DebugInfoOffset,
    "A writable `.debug_info` section."
);

/// The section offsets of all elements within a `.debug_info` section.
#[derive(Debug, Default)]
pub struct DebugInfoOffsets {
    base_id: BaseId,
    units: Vec<UnitOffsets>,
}

impl DebugInfoOffsets {
    #[cfg(test)]
    #[cfg(feature = "read")]
    pub(crate) fn unit_offsets(&self, unit: UnitId) -> &UnitOffsets {
        debug_assert_eq!(self.base_id, unit.base_id);
        &self.units[unit.index]
    }

    /// Get the `.debug_info` section offset for the given unit.
    #[inline]
    pub fn unit(&self, unit: UnitId) -> DebugInfoOffset {
        debug_assert_eq!(self.base_id, unit.base_id);
        self.units[unit.index].unit
    }

    /// Get the `.debug_info` section offset for the given entry.
    #[inline]
    pub fn entry(&self, unit: UnitId, entry: UnitEntryId) -> DebugInfoOffset {
        debug_assert_eq!(self.base_id, unit.base_id);
        self.units[unit.index].debug_info_offset(entry)
    }
}

/// The section offsets of all elements of a unit within a `.debug_info` section.
#[derive(Debug)]
pub(crate) struct UnitOffsets {
    base_id: BaseId,
    unit: DebugInfoOffset,
    entries: Vec<EntryOffset>,
}

impl UnitOffsets {
    #[cfg(test)]
    #[cfg(feature = "read")]
    fn none() -> Self {
        UnitOffsets {
            base_id: BaseId::default(),
            unit: DebugInfoOffset(0),
            entries: Vec::new(),
        }
    }

    /// Get the .debug_info offset for the given entry.
    #[inline]
    pub(crate) fn debug_info_offset(&self, entry: UnitEntryId) -> DebugInfoOffset {
        debug_assert_eq!(self.base_id, entry.base_id);
        let offset = self.entries[entry.index].offset;
        debug_assert_ne!(offset.0, 0);
        offset
    }

    /// Get the unit offset for the given entry.
    #[inline]
    pub(crate) fn unit_offset(&self, entry: UnitEntryId) -> u64 {
        let offset = self.debug_info_offset(entry);
        (offset.0 - self.unit.0) as u64
    }

    /// Get the abbreviation code for the given entry.
    #[inline]
    pub(crate) fn abbrev(&self, entry: UnitEntryId) -> u64 {
        debug_assert_eq!(self.base_id, entry.base_id);
        self.entries[entry.index].abbrev
    }
}

#[derive(Debug, Clone, Copy)]
pub(crate) struct EntryOffset {
    offset: DebugInfoOffset,
    abbrev: u64,
}

impl EntryOffset {
    fn none() -> Self {
        EntryOffset {
            offset: DebugInfoOffset(0),
            abbrev: 0,
        }
    }
}

/// A reference to a `.debug_info` entry that has yet to be resolved.
#[derive(Debug, Clone, Copy)]
pub(crate) struct DebugInfoReference {
    /// The offset within the section of the reference.
    pub offset: usize,
    /// The size of the reference.
    pub size: u8,
    /// The unit containing the entry.
    pub unit: UnitId,
    /// The entry being referenced.
    pub entry: UnitEntryId,
}

#[cfg(feature = "read")]
pub(crate) mod convert {
    use super::*;
    use crate::common::{DwoId, UnitSectionOffset};
    use crate::read::{self, Reader};
    use crate::write::{self, ConvertError, ConvertResult, LocationList, RangeList};
    use std::collections::HashMap;

    pub(crate) struct ConvertUnit<R: Reader<Offset = usize>> {
        from_unit: read::Unit<R>,
        base_id: BaseId,
        encoding: Encoding,
        entries: Vec<DebuggingInformationEntry>,
        entry_offsets: Vec<read::UnitOffset>,
        root: UnitEntryId,
    }

    pub(crate) struct ConvertUnitContext<'a, R: Reader<Offset = usize>> {
        pub dwarf: &'a read::Dwarf<R>,
        pub unit: &'a read::Unit<R>,
        pub line_strings: &'a mut write::LineStringTable,
        pub strings: &'a mut write::StringTable,
        pub ranges: &'a mut write::RangeListTable,
        pub locations: &'a mut write::LocationListTable,
        pub convert_address: &'a dyn Fn(u64) -> Option<Address>,
        pub base_address: Address,
        pub line_program_offset: Option<DebugLineOffset>,
        pub line_program_files: Vec<FileId>,
        pub entry_ids: &'a HashMap<UnitSectionOffset, (UnitId, UnitEntryId)>,
    }

    impl UnitTable {
        /// Create a unit table by reading the data in the given sections.
        ///
        /// This also updates the given tables with the values that are referenced from
        /// attributes in this section.
        ///
        /// `convert_address` is a function to convert read addresses into the `Address`
        /// type. For non-relocatable addresses, this function may simply return
        /// `Address::Constant(address)`. For relocatable addresses, it is the caller's
        /// responsibility to determine the symbol and addend corresponding to the address
        /// and return `Address::Symbol { symbol, addend }`.
        pub fn from<R: Reader<Offset = usize>>(
            dwarf: &read::Dwarf<R>,
            line_strings: &mut write::LineStringTable,
            strings: &mut write::StringTable,
            convert_address: &dyn Fn(u64) -> Option<Address>,
        ) -> ConvertResult<UnitTable> {
            let base_id = BaseId::default();
            let mut unit_entries = Vec::new();
            let mut entry_ids = HashMap::new();

            let mut from_units = dwarf.units();
            while let Some(from_unit) = from_units.next()? {
                let unit_id = UnitId::new(base_id, unit_entries.len());
                unit_entries.push(Unit::convert_entries(
                    from_unit,
                    unit_id,
                    &mut entry_ids,
                    dwarf,
                )?);
            }

            // Attributes must be converted in a separate pass so that we can handle
            // references to other compilation units.
            let mut units = Vec::new();
            for unit_entries in unit_entries.drain(..) {
                units.push(Unit::convert_attributes(
                    unit_entries,
                    &entry_ids,
                    dwarf,
                    line_strings,
                    strings,
                    convert_address,
                )?);
            }

            Ok(UnitTable { base_id, units })
        }
    }

    impl Unit {
        /// Create a unit by reading the data in the input sections.
        ///
        /// Does not add entry attributes.
        pub(crate) fn convert_entries<R: Reader<Offset = usize>>(
            from_header: read::UnitHeader<R>,
            unit_id: UnitId,
            entry_ids: &mut HashMap<UnitSectionOffset, (UnitId, UnitEntryId)>,
            dwarf: &read::Dwarf<R>,
        ) -> ConvertResult<ConvertUnit<R>> {
            match from_header.type_() {
                read::UnitType::Compilation => (),
                _ => return Err(ConvertError::UnsupportedUnitType),
            }
            let base_id = BaseId::default();

            let from_unit = dwarf.unit(from_header)?;
            let encoding = from_unit.encoding();

            let mut entries = Vec::new();
            let mut entry_offsets = Vec::new();

            let mut from_tree = from_unit.entries_tree(None)?;
            let from_root = from_tree.root()?;
            let root = DebuggingInformationEntry::convert_entry(
                from_root,
                &from_unit,
                base_id,
                &mut entries,
                &mut entry_offsets,
                entry_ids,
                None,
                unit_id,
            )?;

            Ok(ConvertUnit {
                from_unit,
                base_id,
                encoding,
                entries,
                entry_offsets,
                root,
            })
        }

        /// Create entry attributes by reading the data in the input sections.
        fn convert_attributes<R: Reader<Offset = usize>>(
            unit: ConvertUnit<R>,
            entry_ids: &HashMap<UnitSectionOffset, (UnitId, UnitEntryId)>,
            dwarf: &read::Dwarf<R>,
            line_strings: &mut write::LineStringTable,
            strings: &mut write::StringTable,
            convert_address: &dyn Fn(u64) -> Option<Address>,
        ) -> ConvertResult<Unit> {
            let from_unit = unit.from_unit;
            let base_address =
                convert_address(from_unit.low_pc).ok_or(ConvertError::InvalidAddress)?;

            let (line_program_offset, line_program, line_program_files) =
                match from_unit.line_program {
                    Some(ref from_program) => {
                        let from_program = from_program.clone();
                        let line_program_offset = from_program.header().offset();
                        let (line_program, line_program_files) = LineProgram::from(
                            from_program,
                            dwarf,
                            line_strings,
                            strings,
                            convert_address,
                        )?;
                        (Some(line_program_offset), line_program, line_program_files)
                    }
                    None => (None, LineProgram::none(), Vec::new()),
                };

            let mut ranges = RangeListTable::default();
            let mut locations = LocationListTable::default();

            let mut context = ConvertUnitContext {
                entry_ids,
                dwarf,
                unit: &from_unit,
                line_strings,
                strings,
                ranges: &mut ranges,
                locations: &mut locations,
                convert_address,
                base_address,
                line_program_offset,
                line_program_files,
            };

            let mut entries = unit.entries;
            for entry in &mut entries {
                entry.convert_attributes(&mut context, &unit.entry_offsets)?;
            }

            Ok(Unit {
                base_id: unit.base_id,
                encoding: unit.encoding,
                line_program,
                ranges,
                locations,
                entries,
                root: unit.root,
            })
        }
    }

    impl DebuggingInformationEntry {
        /// Create an entry by reading the data in the input sections.
        ///
        /// Does not add the entry attributes.
        fn convert_entry<R: Reader<Offset = usize>>(
            from: read::EntriesTreeNode<R>,
            from_unit: &read::Unit<R>,
            base_id: BaseId,
            entries: &mut Vec<DebuggingInformationEntry>,
            entry_offsets: &mut Vec<read::UnitOffset>,
            entry_ids: &mut HashMap<UnitSectionOffset, (UnitId, UnitEntryId)>,
            parent: Option<UnitEntryId>,
            unit_id: UnitId,
        ) -> ConvertResult<UnitEntryId> {
            let from_entry = from.entry();
            let id = DebuggingInformationEntry::new(base_id, entries, parent, from_entry.tag());
            let offset = from_entry.offset();
            entry_offsets.push(offset);
            entry_ids.insert(offset.to_unit_section_offset(from_unit), (unit_id, id));

            let mut from_children = from.children();
            while let Some(from_child) = from_children.next()? {
                DebuggingInformationEntry::convert_entry(
                    from_child,
                    from_unit,
                    base_id,
                    entries,
                    entry_offsets,
                    entry_ids,
                    Some(id),
                    unit_id,
                )?;
            }
            Ok(id)
        }

        /// Create an entry's attributes by reading the data in the input sections.
        fn convert_attributes<R: Reader<Offset = usize>>(
            &mut self,
            context: &mut ConvertUnitContext<R>,
            entry_offsets: &[read::UnitOffset],
        ) -> ConvertResult<()> {
            let offset = entry_offsets[self.id.index];
            let from = context.unit.entry(offset)?;
            let mut from_attrs = from.attrs();
            while let Some(from_attr) = from_attrs.next()? {
                if from_attr.name() == constants::DW_AT_sibling {
                    // This may point to a null entry, so we have to treat it differently.
                    self.set_sibling(true);
                } else if let Some(attr) = Attribute::from(context, &from_attr)? {
                    self.set(attr.name, attr.value);
                }
            }
            Ok(())
        }
    }

    impl Attribute {
        /// Create an attribute by reading the data in the given sections.
        pub(crate) fn from<R: Reader<Offset = usize>>(
            context: &mut ConvertUnitContext<R>,
            from: &read::Attribute<R>,
        ) -> ConvertResult<Option<Attribute>> {
            let value = AttributeValue::from(context, from.value())?;
            Ok(value.map(|value| Attribute {
                name: from.name(),
                value,
            }))
        }
    }

    impl AttributeValue {
        /// Create an attribute value by reading the data in the given sections.
        pub(crate) fn from<R: Reader<Offset = usize>>(
            context: &mut ConvertUnitContext<R>,
            from: read::AttributeValue<R>,
        ) -> ConvertResult<Option<AttributeValue>> {
            let to = match from {
                read::AttributeValue::Addr(val) => match (context.convert_address)(val) {
                    Some(val) => AttributeValue::Address(val),
                    None => return Err(ConvertError::InvalidAddress),
                },
                read::AttributeValue::Block(r) => AttributeValue::Block(r.to_slice()?.into()),
                read::AttributeValue::Data1(val) => AttributeValue::Data1(val),
                read::AttributeValue::Data2(val) => AttributeValue::Data2(val),
                read::AttributeValue::Data4(val) => AttributeValue::Data4(val),
                read::AttributeValue::Data8(val) => AttributeValue::Data8(val),
                read::AttributeValue::Sdata(val) => AttributeValue::Sdata(val),
                read::AttributeValue::Udata(val) => AttributeValue::Udata(val),
                read::AttributeValue::Exprloc(expression) => {
                    let expression = Expression::from(
                        expression,
                        context.unit.encoding(),
                        Some(context.dwarf),
                        Some(context.unit),
                        Some(context.entry_ids),
                        context.convert_address,
                    )?;
                    AttributeValue::Exprloc(expression)
                }
                // TODO: it would be nice to preserve the flag form.
                read::AttributeValue::Flag(val) => AttributeValue::Flag(val),
                read::AttributeValue::DebugAddrBase(_base) => {
                    // We convert all address indices to addresses,
                    // so this is unneeded.
                    return Ok(None);
                }
                read::AttributeValue::DebugAddrIndex(index) => {
                    let val = context.dwarf.address(context.unit, index)?;
                    match (context.convert_address)(val) {
                        Some(val) => AttributeValue::Address(val),
                        None => return Err(ConvertError::InvalidAddress),
                    }
                }
                read::AttributeValue::UnitRef(val) => {
                    if !context.unit.header.is_valid_offset(val) {
                        return Err(ConvertError::InvalidUnitRef);
                    }
                    let id = context
                        .entry_ids
                        .get(&val.to_unit_section_offset(context.unit))
                        .ok_or(ConvertError::InvalidUnitRef)?;
                    AttributeValue::UnitRef(id.1)
                }
                read::AttributeValue::DebugInfoRef(val) => {
                    // TODO: support relocation of this value
                    let id = context
                        .entry_ids
                        .get(&UnitSectionOffset::DebugInfoOffset(val))
                        .ok_or(ConvertError::InvalidDebugInfoRef)?;
                    AttributeValue::DebugInfoRef(Reference::Entry(id.0, id.1))
                }
                read::AttributeValue::DebugInfoRefSup(val) => AttributeValue::DebugInfoRefSup(val),
                read::AttributeValue::DebugLineRef(val) => {
                    // There should only be the line program in the CU DIE which we've already
                    // converted, so check if it matches that.
                    if Some(val) == context.line_program_offset {
                        AttributeValue::LineProgramRef
                    } else {
                        return Err(ConvertError::InvalidLineRef);
                    }
                }
                read::AttributeValue::DebugMacinfoRef(val) => AttributeValue::DebugMacinfoRef(val),
                read::AttributeValue::DebugMacroRef(val) => AttributeValue::DebugMacroRef(val),
                read::AttributeValue::LocationListsRef(val) => {
                    let iter = context
                        .dwarf
                        .locations
                        .raw_locations(val, context.unit.encoding())?;
                    let loc_list = LocationList::from(iter, context)?;
                    let loc_id = context.locations.add(loc_list);
                    AttributeValue::LocationListRef(loc_id)
                }
                read::AttributeValue::DebugLocListsBase(_base) => {
                    // We convert all location list indices to offsets,
                    // so this is unneeded.
                    return Ok(None);
                }
                read::AttributeValue::DebugLocListsIndex(index) => {
                    let offset = context.dwarf.locations_offset(context.unit, index)?;
                    let iter = context
                        .dwarf
                        .locations
                        .raw_locations(offset, context.unit.encoding())?;
                    let loc_list = LocationList::from(iter, context)?;
                    let loc_id = context.locations.add(loc_list);
                    AttributeValue::LocationListRef(loc_id)
                }
                read::AttributeValue::RangeListsRef(offset) => {
                    let offset = context.dwarf.ranges_offset_from_raw(context.unit, offset);
                    let iter = context.dwarf.raw_ranges(context.unit, offset)?;
                    let range_list = RangeList::from(iter, context)?;
                    let range_id = context.ranges.add(range_list);
                    AttributeValue::RangeListRef(range_id)
                }
                read::AttributeValue::DebugRngListsBase(_base) => {
                    // We convert all range list indices to offsets,
                    // so this is unneeded.
                    return Ok(None);
                }
                read::AttributeValue::DebugRngListsIndex(index) => {
                    let offset = context.dwarf.ranges_offset(context.unit, index)?;
                    let iter = context
                        .dwarf
                        .ranges
                        .raw_ranges(offset, context.unit.encoding())?;
                    let range_list = RangeList::from(iter, context)?;
                    let range_id = context.ranges.add(range_list);
                    AttributeValue::RangeListRef(range_id)
                }
                read::AttributeValue::DebugTypesRef(val) => AttributeValue::DebugTypesRef(val),
                read::AttributeValue::DebugStrRef(offset) => {
                    let r = context.dwarf.string(offset)?;
                    let id = context.strings.add(r.to_slice()?);
                    AttributeValue::StringRef(id)
                }
                read::AttributeValue::DebugStrRefSup(val) => AttributeValue::DebugStrRefSup(val),
                read::AttributeValue::DebugStrOffsetsBase(_base) => {
                    // We convert all string offsets to `.debug_str` references,
                    // so this is unneeded.
                    return Ok(None);
                }
                read::AttributeValue::DebugStrOffsetsIndex(index) => {
                    let offset = context.dwarf.string_offset(context.unit, index)?;
                    let r = context.dwarf.string(offset)?;
                    let id = context.strings.add(r.to_slice()?);
                    AttributeValue::StringRef(id)
                }
                read::AttributeValue::DebugLineStrRef(offset) => {
                    let r = context.dwarf.line_string(offset)?;
                    let id = context.line_strings.add(r.to_slice()?);
                    AttributeValue::LineStringRef(id)
                }
                read::AttributeValue::String(r) => AttributeValue::String(r.to_slice()?.into()),
                read::AttributeValue::Encoding(val) => AttributeValue::Encoding(val),
                read::AttributeValue::DecimalSign(val) => AttributeValue::DecimalSign(val),
                read::AttributeValue::Endianity(val) => AttributeValue::Endianity(val),
                read::AttributeValue::Accessibility(val) => AttributeValue::Accessibility(val),
                read::AttributeValue::Visibility(val) => AttributeValue::Visibility(val),
                read::AttributeValue::Virtuality(val) => AttributeValue::Virtuality(val),
                read::AttributeValue::Language(val) => AttributeValue::Language(val),
                read::AttributeValue::AddressClass(val) => AttributeValue::AddressClass(val),
                read::AttributeValue::IdentifierCase(val) => AttributeValue::IdentifierCase(val),
                read::AttributeValue::CallingConvention(val) => {
                    AttributeValue::CallingConvention(val)
                }
                read::AttributeValue::Inline(val) => AttributeValue::Inline(val),
                read::AttributeValue::Ordering(val) => AttributeValue::Ordering(val),
                read::AttributeValue::FileIndex(val) => {
                    if val == 0 {
                        // 0 means not specified, even for version 5.
                        AttributeValue::FileIndex(None)
                    } else {
                        match context.line_program_files.get(val as usize) {
                            Some(id) => AttributeValue::FileIndex(Some(*id)),
                            None => return Err(ConvertError::InvalidFileIndex),
                        }
                    }
                }
                // Should always be a more specific section reference.
                read::AttributeValue::SecOffset(_) => {
                    return Err(ConvertError::InvalidAttributeValue);
                }
                read::AttributeValue::DwoId(DwoId(val)) => AttributeValue::Udata(val),
            };
            Ok(Some(to))
        }
    }
}

#[cfg(test)]
#[cfg(feature = "read")]
mod tests {
    use super::*;
    use crate::common::{
        DebugAddrBase, DebugLocListsBase, DebugRngListsBase, DebugStrOffsetsBase, LineEncoding,
    };
    use crate::constants;
    use crate::read;
    use crate::write::{
        DebugLine, DebugLineStr, DebugStr, DwarfUnit, EndianVec, LineString, LineStringTable,
        Location, LocationList, LocationListTable, Range, RangeList, RangeListOffsets,
        RangeListTable, StringTable,
    };
    use crate::LittleEndian;
    use std::collections::HashMap;
    use std::mem;
    use std::sync::Arc;

    #[test]
    fn test_unit_table() {
        let mut strings = StringTable::default();

        let mut units = UnitTable::default();
        let unit_id1 = units.add(Unit::new(
            Encoding {
                version: 4,
                address_size: 8,
                format: Format::Dwarf32,
            },
            LineProgram::none(),
        ));
        let unit2 = units.add(Unit::new(
            Encoding {
                version: 2,
                address_size: 4,
                format: Format::Dwarf64,
            },
            LineProgram::none(),
        ));
        let unit3 = units.add(Unit::new(
            Encoding {
                version: 5,
                address_size: 4,
                format: Format::Dwarf32,
            },
            LineProgram::none(),
        ));
        assert_eq!(units.count(), 3);
        {
            let unit1 = units.get_mut(unit_id1);
            assert_eq!(unit1.version(), 4);
            assert_eq!(unit1.address_size(), 8);
            assert_eq!(unit1.format(), Format::Dwarf32);
            assert_eq!(unit1.count(), 1);

            let root_id = unit1.root();
            assert_eq!(root_id, UnitEntryId::new(unit1.base_id, 0));
            {
                let root = unit1.get_mut(root_id);
                assert_eq!(root.id(), root_id);
                assert!(root.parent().is_none());
                assert_eq!(root.tag(), constants::DW_TAG_compile_unit);

                // Test get/get_mut
                assert!(root.get(constants::DW_AT_producer).is_none());
                assert!(root.get_mut(constants::DW_AT_producer).is_none());
                let mut producer = AttributeValue::String(b"root"[..].into());
                root.set(constants::DW_AT_producer, producer.clone());
                assert_eq!(root.get(constants::DW_AT_producer), Some(&producer));
                assert_eq!(root.get_mut(constants::DW_AT_producer), Some(&mut producer));

                // Test attrs
                let mut attrs = root.attrs();
                let attr = attrs.next().unwrap();
                assert_eq!(attr.name(), constants::DW_AT_producer);
                assert_eq!(attr.get(), &producer);
                assert!(attrs.next().is_none());
            }

            let child1 = unit1.add(root_id, constants::DW_TAG_subprogram);
            assert_eq!(child1, UnitEntryId::new(unit1.base_id, 1));
            {
                let child1 = unit1.get_mut(child1);
                assert_eq!(child1.parent(), Some(root_id));

                let tmp = AttributeValue::String(b"tmp"[..].into());
                child1.set(constants::DW_AT_name, tmp.clone());
                assert_eq!(child1.get(constants::DW_AT_name), Some(&tmp));

                // Test attrs_mut
                let name = AttributeValue::StringRef(strings.add(&b"child1"[..]));
                {
                    let attr = child1.attrs_mut().next().unwrap();
                    assert_eq!(attr.name(), constants::DW_AT_name);
                    attr.set(name.clone());
                }
                assert_eq!(child1.get(constants::DW_AT_name), Some(&name));
            }

            let child2 = unit1.add(root_id, constants::DW_TAG_subprogram);
            assert_eq!(child2, UnitEntryId::new(unit1.base_id, 2));
            {
                let child2 = unit1.get_mut(child2);
                assert_eq!(child2.parent(), Some(root_id));

                let tmp = AttributeValue::String(b"tmp"[..].into());
                child2.set(constants::DW_AT_name, tmp.clone());
                assert_eq!(child2.get(constants::DW_AT_name), Some(&tmp));

                // Test replace
                let name = AttributeValue::StringRef(strings.add(&b"child2"[..]));
                child2.set(constants::DW_AT_name, name.clone());
                assert_eq!(child2.get(constants::DW_AT_name), Some(&name));
            }

            {
                let root = unit1.get(root_id);
                assert_eq!(
                    root.children().cloned().collect::<Vec<_>>(),
                    vec![child1, child2]
                );
            }
        }
        {
            let unit2 = units.get(unit2);
            assert_eq!(unit2.version(), 2);
            assert_eq!(unit2.address_size(), 4);
            assert_eq!(unit2.format(), Format::Dwarf64);
            assert_eq!(unit2.count(), 1);

            let root = unit2.root();
            assert_eq!(root, UnitEntryId::new(unit2.base_id, 0));
            let root = unit2.get(root);
            assert_eq!(root.id(), UnitEntryId::new(unit2.base_id, 0));
            assert!(root.parent().is_none());
            assert_eq!(root.tag(), constants::DW_TAG_compile_unit);
        }

        let mut sections = Sections::new(EndianVec::new(LittleEndian));
        let debug_line_str_offsets = DebugLineStrOffsets::none();
        let debug_str_offsets = strings.write(&mut sections.debug_str).unwrap();
        units
            .write(&mut sections, &debug_line_str_offsets, &debug_str_offsets)
            .unwrap();

        println!("{:?}", sections.debug_str);
        println!("{:?}", sections.debug_info);
        println!("{:?}", sections.debug_abbrev);

        let dwarf = read::Dwarf {
            debug_abbrev: read::DebugAbbrev::new(sections.debug_abbrev.slice(), LittleEndian),
            debug_info: read::DebugInfo::new(sections.debug_info.slice(), LittleEndian),
            debug_str: read::DebugStr::new(sections.debug_str.slice(), LittleEndian),
            ..Default::default()
        };
        let mut read_units = dwarf.units();

        {
            let read_unit1 = read_units.next().unwrap().unwrap();
            let unit1 = units.get(unit_id1);
            assert_eq!(unit1.version(), read_unit1.version());
            assert_eq!(unit1.address_size(), read_unit1.address_size());
            assert_eq!(unit1.format(), read_unit1.format());

            let read_unit1 = dwarf.unit(read_unit1).unwrap();
            let mut read_entries = read_unit1.entries();

            let root = unit1.get(unit1.root());
            {
                let (depth, read_root) = read_entries.next_dfs().unwrap().unwrap();
                assert_eq!(depth, 0);
                assert_eq!(root.tag(), read_root.tag());
                assert!(read_root.has_children());

                let producer = match root.get(constants::DW_AT_producer).unwrap() {
                    AttributeValue::String(ref producer) => &**producer,
                    otherwise => panic!("unexpected {:?}", otherwise),
                };
                assert_eq!(producer, b"root");
                let read_producer = read_root
                    .attr_value(constants::DW_AT_producer)
                    .unwrap()
                    .unwrap();
                assert_eq!(
                    dwarf
                        .attr_string(&read_unit1, read_producer)
                        .unwrap()
                        .slice(),
                    producer
                );
            }

            let mut children = root.children().cloned();

            {
                let child = children.next().unwrap();
                assert_eq!(child, UnitEntryId::new(unit1.base_id, 1));
                let child = unit1.get(child);
                let (depth, read_child) = read_entries.next_dfs().unwrap().unwrap();
                assert_eq!(depth, 1);
                assert_eq!(child.tag(), read_child.tag());
                assert!(!read_child.has_children());

                let name = match child.get(constants::DW_AT_name).unwrap() {
                    AttributeValue::StringRef(name) => *name,
                    otherwise => panic!("unexpected {:?}", otherwise),
                };
                let name = strings.get(name);
                assert_eq!(name, b"child1");
                let read_name = read_child
                    .attr_value(constants::DW_AT_name)
                    .unwrap()
                    .unwrap();
                assert_eq!(
                    dwarf.attr_string(&read_unit1, read_name).unwrap().slice(),
                    name
                );
            }

            {
                let child = children.next().unwrap();
                assert_eq!(child, UnitEntryId::new(unit1.base_id, 2));
                let child = unit1.get(child);
                let (depth, read_child) = read_entries.next_dfs().unwrap().unwrap();
                assert_eq!(depth, 0);
                assert_eq!(child.tag(), read_child.tag());
                assert!(!read_child.has_children());

                let name = match child.get(constants::DW_AT_name).unwrap() {
                    AttributeValue::StringRef(name) => *name,
                    otherwise => panic!("unexpected {:?}", otherwise),
                };
                let name = strings.get(name);
                assert_eq!(name, b"child2");
                let read_name = read_child
                    .attr_value(constants::DW_AT_name)
                    .unwrap()
                    .unwrap();
                assert_eq!(
                    dwarf.attr_string(&read_unit1, read_name).unwrap().slice(),
                    name
                );
            }

            assert!(read_entries.next_dfs().unwrap().is_none());
        }

        {
            let read_unit2 = read_units.next().unwrap().unwrap();
            let unit2 = units.get(unit2);
            assert_eq!(unit2.version(), read_unit2.version());
            assert_eq!(unit2.address_size(), read_unit2.address_size());
            assert_eq!(unit2.format(), read_unit2.format());

            let abbrevs = dwarf.abbreviations(&read_unit2).unwrap();
            let mut read_entries = read_unit2.entries(&abbrevs);

            {
                let root = unit2.get(unit2.root());
                let (depth, read_root) = read_entries.next_dfs().unwrap().unwrap();
                assert_eq!(depth, 0);
                assert_eq!(root.tag(), read_root.tag());
                assert!(!read_root.has_children());
            }

            assert!(read_entries.next_dfs().unwrap().is_none());
        }

        {
            let read_unit3 = read_units.next().unwrap().unwrap();
            let unit3 = units.get(unit3);
            assert_eq!(unit3.version(), read_unit3.version());
            assert_eq!(unit3.address_size(), read_unit3.address_size());
            assert_eq!(unit3.format(), read_unit3.format());

            let abbrevs = dwarf.abbreviations(&read_unit3).unwrap();
            let mut read_entries = read_unit3.entries(&abbrevs);

            {
                let root = unit3.get(unit3.root());
                let (depth, read_root) = read_entries.next_dfs().unwrap().unwrap();
                assert_eq!(depth, 0);
                assert_eq!(root.tag(), read_root.tag());
                assert!(!read_root.has_children());
            }

            assert!(read_entries.next_dfs().unwrap().is_none());
        }

        assert!(read_units.next().unwrap().is_none());

        let mut convert_line_strings = LineStringTable::default();
        let mut convert_strings = StringTable::default();
        let convert_units = UnitTable::from(
            &dwarf,
            &mut convert_line_strings,
            &mut convert_strings,
            &|address| Some(Address::Constant(address)),
        )
        .unwrap();
        assert_eq!(convert_units.count(), units.count());

        for i in 0..convert_units.count() {
            let unit_id = units.id(i);
            let unit = units.get(unit_id);
            let convert_unit_id = convert_units.id(i);
            let convert_unit = convert_units.get(convert_unit_id);
            assert_eq!(convert_unit.version(), unit.version());
            assert_eq!(convert_unit.address_size(), unit.address_size());
            assert_eq!(convert_unit.format(), unit.format());
            assert_eq!(convert_unit.count(), unit.count());

            let root = unit.get(unit.root());
            let convert_root = convert_unit.get(convert_unit.root());
            assert_eq!(convert_root.tag(), root.tag());
            for (convert_attr, attr) in convert_root.attrs().zip(root.attrs()) {
                assert_eq!(convert_attr, attr);
            }
        }
    }

    #[test]
    fn test_attribute_value() {
        // Create a string table and a string with a non-zero id/offset.
        let mut strings = StringTable::default();
        strings.add("string one");
        let string_id = strings.add("string two");
        let mut debug_str = DebugStr::from(EndianVec::new(LittleEndian));
        let debug_str_offsets = strings.write(&mut debug_str).unwrap();
        let read_debug_str = read::DebugStr::new(debug_str.slice(), LittleEndian);

        let mut line_strings = LineStringTable::default();
        line_strings.add("line string one");
        let line_string_id = line_strings.add("line string two");
        let mut debug_line_str = DebugLineStr::from(EndianVec::new(LittleEndian));
        let debug_line_str_offsets = line_strings.write(&mut debug_line_str).unwrap();
        let read_debug_line_str =
            read::DebugLineStr::from(read::EndianSlice::new(debug_line_str.slice(), LittleEndian));

        let data = vec![1, 2, 3, 4];
        let read_data = read::EndianSlice::new(&[1, 2, 3, 4], LittleEndian);

        let mut expression = Expression::new();
        expression.op_constu(57);
        let read_expression = read::Expression(read::EndianSlice::new(
            &[constants::DW_OP_constu.0, 57],
            LittleEndian,
        ));

        let mut ranges = RangeListTable::default();
        let range_id = ranges.add(RangeList(vec![Range::StartEnd {
            begin: Address::Constant(0x1234),
            end: Address::Constant(0x2345),
        }]));

        let mut locations = LocationListTable::default();
        let loc_id = locations.add(LocationList(vec![Location::StartEnd {
            begin: Address::Constant(0x1234),
            end: Address::Constant(0x2345),
            data: expression.clone(),
        }]));

        for &version in &[2, 3, 4, 5] {
            for &address_size in &[4, 8] {
                for &format in &[Format::Dwarf32, Format::Dwarf64] {
                    let encoding = Encoding {
                        format,
                        version,
                        address_size,
                    };

                    let mut sections = Sections::new(EndianVec::new(LittleEndian));
                    let range_list_offsets = ranges.write(&mut sections, encoding).unwrap();
                    let loc_list_offsets = locations.write(&mut sections, encoding, None).unwrap();

                    let read_debug_ranges =
                        read::DebugRanges::new(sections.debug_ranges.slice(), LittleEndian);
                    let read_debug_rnglists =
                        read::DebugRngLists::new(sections.debug_rnglists.slice(), LittleEndian);

                    let read_debug_loc =
                        read::DebugLoc::new(sections.debug_loc.slice(), LittleEndian);
                    let read_debug_loclists =
                        read::DebugLocLists::new(sections.debug_loclists.slice(), LittleEndian);

                    let mut units = UnitTable::default();
                    let unit = units.add(Unit::new(encoding, LineProgram::none()));
                    let unit = units.get(unit);
                    let encoding = Encoding {
                        format,
                        version,
                        address_size,
                    };
                    let from_unit = read::UnitHeader::new(
                        encoding,
                        0,
                        read::UnitType::Compilation,
                        DebugAbbrevOffset(0),
                        DebugInfoOffset(0).into(),
                        read::EndianSlice::new(&[], LittleEndian),
                    );

                    for &(ref name, ref value, ref expect_value) in &[
                        (
                            constants::DW_AT_name,
                            AttributeValue::Address(Address::Constant(0x1234)),
                            read::AttributeValue::Addr(0x1234),
                        ),
                        (
                            constants::DW_AT_name,
                            AttributeValue::Block(data.clone()),
                            read::AttributeValue::Block(read_data),
                        ),
                        (
                            constants::DW_AT_name,
                            AttributeValue::Data1(0x12),
                            read::AttributeValue::Data1(0x12),
                        ),
                        (
                            constants::DW_AT_name,
                            AttributeValue::Data2(0x1234),
                            read::AttributeValue::Data2(0x1234),
                        ),
                        (
                            constants::DW_AT_name,
                            AttributeValue::Data4(0x1234),
                            read::AttributeValue::Data4(0x1234),
                        ),
                        (
                            constants::DW_AT_name,
                            AttributeValue::Data8(0x1234),
                            read::AttributeValue::Data8(0x1234),
                        ),
                        (
                            constants::DW_AT_name,
                            AttributeValue::Sdata(0x1234),
                            read::AttributeValue::Sdata(0x1234),
                        ),
                        (
                            constants::DW_AT_name,
                            AttributeValue::Udata(0x1234),
                            read::AttributeValue::Udata(0x1234),
                        ),
                        (
                            constants::DW_AT_name,
                            AttributeValue::Exprloc(expression.clone()),
                            read::AttributeValue::Exprloc(read_expression),
                        ),
                        (
                            constants::DW_AT_name,
                            AttributeValue::Flag(false),
                            read::AttributeValue::Flag(false),
                        ),
                        /*
                        (
                            constants::DW_AT_name,
                            AttributeValue::FlagPresent,
                            read::AttributeValue::Flag(true),
                        ),
                        */
                        (
                            constants::DW_AT_name,
                            AttributeValue::DebugInfoRefSup(DebugInfoOffset(0x1234)),
                            read::AttributeValue::DebugInfoRefSup(DebugInfoOffset(0x1234)),
                        ),
                        (
                            constants::DW_AT_location,
                            AttributeValue::LocationListRef(loc_id),
                            read::AttributeValue::SecOffset(loc_list_offsets.get(loc_id).0),
                        ),
                        (
                            constants::DW_AT_macro_info,
                            AttributeValue::DebugMacinfoRef(DebugMacinfoOffset(0x1234)),
                            read::AttributeValue::SecOffset(0x1234),
                        ),
                        (
                            constants::DW_AT_macros,
                            AttributeValue::DebugMacroRef(DebugMacroOffset(0x1234)),
                            read::AttributeValue::SecOffset(0x1234),
                        ),
                        (
                            constants::DW_AT_ranges,
                            AttributeValue::RangeListRef(range_id),
                            read::AttributeValue::SecOffset(range_list_offsets.get(range_id).0),
                        ),
                        (
                            constants::DW_AT_name,
                            AttributeValue::DebugTypesRef(DebugTypeSignature(0x1234)),
                            read::AttributeValue::DebugTypesRef(DebugTypeSignature(0x1234)),
                        ),
                        (
                            constants::DW_AT_name,
                            AttributeValue::StringRef(string_id),
                            read::AttributeValue::DebugStrRef(debug_str_offsets.get(string_id)),
                        ),
                        (
                            constants::DW_AT_name,
                            AttributeValue::DebugStrRefSup(DebugStrOffset(0x1234)),
                            read::AttributeValue::DebugStrRefSup(DebugStrOffset(0x1234)),
                        ),
                        (
                            constants::DW_AT_name,
                            AttributeValue::LineStringRef(line_string_id),
                            read::AttributeValue::DebugLineStrRef(
                                debug_line_str_offsets.get(line_string_id),
                            ),
                        ),
                        (
                            constants::DW_AT_name,
                            AttributeValue::String(data.clone()),
                            read::AttributeValue::String(read_data),
                        ),
                        (
                            constants::DW_AT_encoding,
                            AttributeValue::Encoding(constants::DwAte(0x12)),
                            read::AttributeValue::Udata(0x12),
                        ),
                        (
                            constants::DW_AT_decimal_sign,
                            AttributeValue::DecimalSign(constants::DwDs(0x12)),
                            read::AttributeValue::Udata(0x12),
                        ),
                        (
                            constants::DW_AT_endianity,
                            AttributeValue::Endianity(constants::DwEnd(0x12)),
                            read::AttributeValue::Udata(0x12),
                        ),
                        (
                            constants::DW_AT_accessibility,
                            AttributeValue::Accessibility(constants::DwAccess(0x12)),
                            read::AttributeValue::Udata(0x12),
                        ),
                        (
                            constants::DW_AT_visibility,
                            AttributeValue::Visibility(constants::DwVis(0x12)),
                            read::AttributeValue::Udata(0x12),
                        ),
                        (
                            constants::DW_AT_virtuality,
                            AttributeValue::Virtuality(constants::DwVirtuality(0x12)),
                            read::AttributeValue::Udata(0x12),
                        ),
                        (
                            constants::DW_AT_language,
                            AttributeValue::Language(constants::DwLang(0x12)),
                            read::AttributeValue::Udata(0x12),
                        ),
                        (
                            constants::DW_AT_address_class,
                            AttributeValue::AddressClass(constants::DwAddr(0x12)),
                            read::AttributeValue::Udata(0x12),
                        ),
                        (
                            constants::DW_AT_identifier_case,
                            AttributeValue::IdentifierCase(constants::DwId(0x12)),
                            read::AttributeValue::Udata(0x12),
                        ),
                        (
                            constants::DW_AT_calling_convention,
                            AttributeValue::CallingConvention(constants::DwCc(0x12)),
                            read::AttributeValue::Udata(0x12),
                        ),
                        (
                            constants::DW_AT_ordering,
                            AttributeValue::Ordering(constants::DwOrd(0x12)),
                            read::AttributeValue::Udata(0x12),
                        ),
                        (
                            constants::DW_AT_inline,
                            AttributeValue::Inline(constants::DwInl(0x12)),
                            read::AttributeValue::Udata(0x12),
                        ),
                    ][..]
                    {
                        let form = value.form(encoding).unwrap();
                        let attr = Attribute {
                            name: *name,
                            value: value.clone(),
                        };

                        let offsets = UnitOffsets::none();
                        let line_program_offset = None;
                        let mut debug_info_refs = Vec::new();
                        let mut unit_refs = Vec::new();
                        let mut debug_info = DebugInfo::from(EndianVec::new(LittleEndian));
                        attr.value
                            .write(
                                &mut debug_info,
                                &mut debug_info_refs,
                                &mut unit_refs,
                                &unit,
                                &offsets,
                                line_program_offset,
                                &debug_line_str_offsets,
                                &debug_str_offsets,
                                &range_list_offsets,
                                &loc_list_offsets,
                            )
                            .unwrap();

                        let spec = read::AttributeSpecification::new(*name, form, None);
                        let mut r = read::EndianSlice::new(debug_info.slice(), LittleEndian);
                        let read_attr = read::parse_attribute(&mut r, encoding, spec).unwrap();
                        let read_value = &read_attr.raw_value();
                        // read::AttributeValue is invariant in the lifetime of R.
                        // The lifetimes here are all okay, so transmute it.
                        let read_value = unsafe {
                            mem::transmute::<
                                &read::AttributeValue<read::EndianSlice<LittleEndian>>,
                                &read::AttributeValue<read::EndianSlice<LittleEndian>>,
                            >(read_value)
                        };
                        assert_eq!(read_value, expect_value);

                        let dwarf = read::Dwarf {
                            debug_str: read_debug_str.clone(),
                            debug_line_str: read_debug_line_str.clone(),
                            ranges: read::RangeLists::new(read_debug_ranges, read_debug_rnglists),
                            locations: read::LocationLists::new(
                                read_debug_loc,
                                read_debug_loclists,
                            ),
                            ..Default::default()
                        };

                        let unit = read::Unit {
                            header: from_unit,
                            abbreviations: Arc::new(read::Abbreviations::default()),
                            name: None,
                            comp_dir: None,
                            low_pc: 0,
                            str_offsets_base: DebugStrOffsetsBase(0),
                            addr_base: DebugAddrBase(0),
                            loclists_base: DebugLocListsBase(0),
                            rnglists_base: DebugRngListsBase(0),
                            line_program: None,
                            dwo_id: None,
                        };

                        let mut context = convert::ConvertUnitContext {
                            dwarf: &dwarf,
                            unit: &unit,
                            line_strings: &mut line_strings,
                            strings: &mut strings,
                            ranges: &mut ranges,
                            locations: &mut locations,
                            convert_address: &|address| Some(Address::Constant(address)),
                            base_address: Address::Constant(0),
                            line_program_offset: None,
                            line_program_files: Vec::new(),
                            entry_ids: &HashMap::new(),
                        };

                        let convert_attr =
                            Attribute::from(&mut context, &read_attr).unwrap().unwrap();
                        assert_eq!(convert_attr, attr);
                    }
                }
            }
        }
    }

    #[test]
    fn test_unit_ref() {
        let mut units = UnitTable::default();
        let unit_id1 = units.add(Unit::new(
            Encoding {
                version: 4,
                address_size: 8,
                format: Format::Dwarf32,
            },
            LineProgram::none(),
        ));
        assert_eq!(unit_id1, units.id(0));
        let unit_id2 = units.add(Unit::new(
            Encoding {
                version: 2,
                address_size: 4,
                format: Format::Dwarf64,
            },
            LineProgram::none(),
        ));
        assert_eq!(unit_id2, units.id(1));
        let unit1_child1 = UnitEntryId::new(units.get(unit_id1).base_id, 1);
        let unit1_child2 = UnitEntryId::new(units.get(unit_id1).base_id, 2);
        let unit2_child1 = UnitEntryId::new(units.get(unit_id2).base_id, 1);
        let unit2_child2 = UnitEntryId::new(units.get(unit_id2).base_id, 2);
        {
            let unit1 = units.get_mut(unit_id1);
            let root = unit1.root();
            let child_id1 = unit1.add(root, constants::DW_TAG_subprogram);
            assert_eq!(child_id1, unit1_child1);
            let child_id2 = unit1.add(root, constants::DW_TAG_subprogram);
            assert_eq!(child_id2, unit1_child2);
            {
                let child1 = unit1.get_mut(child_id1);
                child1.set(constants::DW_AT_type, AttributeValue::UnitRef(child_id2));
            }
            {
                let child2 = unit1.get_mut(child_id2);
                child2.set(
                    constants::DW_AT_type,
                    AttributeValue::DebugInfoRef(Reference::Entry(unit_id2, unit2_child1)),
                );
            }
        }
        {
            let unit2 = units.get_mut(unit_id2);
            let root = unit2.root();
            let child_id1 = unit2.add(root, constants::DW_TAG_subprogram);
            assert_eq!(child_id1, unit2_child1);
            let child_id2 = unit2.add(root, constants::DW_TAG_subprogram);
            assert_eq!(child_id2, unit2_child2);
            {
                let child1 = unit2.get_mut(child_id1);
                child1.set(constants::DW_AT_type, AttributeValue::UnitRef(child_id2));
            }
            {
                let child2 = unit2.get_mut(child_id2);
                child2.set(
                    constants::DW_AT_type,
                    AttributeValue::DebugInfoRef(Reference::Entry(unit_id1, unit1_child1)),
                );
            }
        }

        let debug_line_str_offsets = DebugLineStrOffsets::none();
        let debug_str_offsets = DebugStrOffsets::none();
        let mut sections = Sections::new(EndianVec::new(LittleEndian));
        let debug_info_offsets = units
            .write(&mut sections, &debug_line_str_offsets, &debug_str_offsets)
            .unwrap();

        println!("{:?}", sections.debug_info);
        println!("{:?}", sections.debug_abbrev);

        let dwarf = read::Dwarf {
            debug_abbrev: read::DebugAbbrev::new(sections.debug_abbrev.slice(), LittleEndian),
            debug_info: read::DebugInfo::new(sections.debug_info.slice(), LittleEndian),
            ..Default::default()
        };

        let mut read_units = dwarf.units();
        {
            let read_unit1 = read_units.next().unwrap().unwrap();
            assert_eq!(
                read_unit1.offset(),
                debug_info_offsets.unit(unit_id1).into()
            );

            let abbrevs = dwarf.abbreviations(&read_unit1).unwrap();
            let mut read_entries = read_unit1.entries(&abbrevs);
            {
                let (_, _read_root) = read_entries.next_dfs().unwrap().unwrap();
            }
            {
                let (_, read_child1) = read_entries.next_dfs().unwrap().unwrap();
                let offset = debug_info_offsets
                    .entry(unit_id1, unit1_child2)
                    .to_unit_offset(&read_unit1)
                    .unwrap();
                assert_eq!(
                    read_child1.attr_value(constants::DW_AT_type).unwrap(),
                    Some(read::AttributeValue::UnitRef(offset))
                );
            }
            {
                let (_, read_child2) = read_entries.next_dfs().unwrap().unwrap();
                let offset = debug_info_offsets.entry(unit_id2, unit2_child1);
                assert_eq!(
                    read_child2.attr_value(constants::DW_AT_type).unwrap(),
                    Some(read::AttributeValue::DebugInfoRef(offset))
                );
            }
        }
        {
            let read_unit2 = read_units.next().unwrap().unwrap();
            assert_eq!(
                read_unit2.offset(),
                debug_info_offsets.unit(unit_id2).into()
            );

            let abbrevs = dwarf.abbreviations(&read_unit2).unwrap();
            let mut read_entries = read_unit2.entries(&abbrevs);
            {
                let (_, _read_root) = read_entries.next_dfs().unwrap().unwrap();
            }
            {
                let (_, read_child1) = read_entries.next_dfs().unwrap().unwrap();
                let offset = debug_info_offsets
                    .entry(unit_id2, unit2_child2)
                    .to_unit_offset(&read_unit2)
                    .unwrap();
                assert_eq!(
                    read_child1.attr_value(constants::DW_AT_type).unwrap(),
                    Some(read::AttributeValue::UnitRef(offset))
                );
            }
            {
                let (_, read_child2) = read_entries.next_dfs().unwrap().unwrap();
                let offset = debug_info_offsets.entry(unit_id1, unit1_child1);
                assert_eq!(
                    read_child2.attr_value(constants::DW_AT_type).unwrap(),
                    Some(read::AttributeValue::DebugInfoRef(offset))
                );
            }
        }

        let mut convert_line_strings = LineStringTable::default();
        let mut convert_strings = StringTable::default();
        let convert_units = UnitTable::from(
            &dwarf,
            &mut convert_line_strings,
            &mut convert_strings,
            &|address| Some(Address::Constant(address)),
        )
        .unwrap();
        assert_eq!(convert_units.count(), units.count());

        for i in 0..convert_units.count() {
            let unit = units.get(units.id(i));
            let convert_unit = convert_units.get(convert_units.id(i));
            assert_eq!(convert_unit.version(), unit.version());
            assert_eq!(convert_unit.address_size(), unit.address_size());
            assert_eq!(convert_unit.format(), unit.format());
            assert_eq!(convert_unit.count(), unit.count());

            let root = unit.get(unit.root());
            let convert_root = convert_unit.get(convert_unit.root());
            assert_eq!(convert_root.tag(), root.tag());
            for (convert_attr, attr) in convert_root.attrs().zip(root.attrs()) {
                assert_eq!(convert_attr, attr);
            }

            let child1 = unit.get(UnitEntryId::new(unit.base_id, 1));
            let convert_child1 = convert_unit.get(UnitEntryId::new(convert_unit.base_id, 1));
            assert_eq!(convert_child1.tag(), child1.tag());
            for (convert_attr, attr) in convert_child1.attrs().zip(child1.attrs()) {
                assert_eq!(convert_attr.name, attr.name);
                match (convert_attr.value.clone(), attr.value.clone()) {
                    (
                        AttributeValue::DebugInfoRef(Reference::Entry(convert_unit, convert_entry)),
                        AttributeValue::DebugInfoRef(Reference::Entry(unit, entry)),
                    ) => {
                        assert_eq!(convert_unit.index, unit.index);
                        assert_eq!(convert_entry.index, entry.index);
                    }
                    (AttributeValue::UnitRef(convert_id), AttributeValue::UnitRef(id)) => {
                        assert_eq!(convert_id.index, id.index);
                    }
                    (convert_value, value) => assert_eq!(convert_value, value),
                }
            }

            let child2 = unit.get(UnitEntryId::new(unit.base_id, 2));
            let convert_child2 = convert_unit.get(UnitEntryId::new(convert_unit.base_id, 2));
            assert_eq!(convert_child2.tag(), child2.tag());
            for (convert_attr, attr) in convert_child2.attrs().zip(child2.attrs()) {
                assert_eq!(convert_attr.name, attr.name);
                match (convert_attr.value.clone(), attr.value.clone()) {
                    (
                        AttributeValue::DebugInfoRef(Reference::Entry(convert_unit, convert_entry)),
                        AttributeValue::DebugInfoRef(Reference::Entry(unit, entry)),
                    ) => {
                        assert_eq!(convert_unit.index, unit.index);
                        assert_eq!(convert_entry.index, entry.index);
                    }
                    (AttributeValue::UnitRef(convert_id), AttributeValue::UnitRef(id)) => {
                        assert_eq!(convert_id.index, id.index);
                    }
                    (convert_value, value) => assert_eq!(convert_value, value),
                }
            }
        }
    }

    #[test]
    fn test_sibling() {
        fn add_child(
            unit: &mut Unit,
            parent: UnitEntryId,
            tag: constants::DwTag,
            name: &str,
        ) -> UnitEntryId {
            let id = unit.add(parent, tag);
            let child = unit.get_mut(id);
            child.set(constants::DW_AT_name, AttributeValue::String(name.into()));
            child.set_sibling(true);
            id
        }

        fn add_children(units: &mut UnitTable, unit_id: UnitId) {
            let unit = units.get_mut(unit_id);
            let root = unit.root();
            let child1 = add_child(unit, root, constants::DW_TAG_subprogram, "child1");
            add_child(unit, child1, constants::DW_TAG_variable, "grandchild1");
            add_child(unit, root, constants::DW_TAG_subprogram, "child2");
            add_child(unit, root, constants::DW_TAG_subprogram, "child3");
        }

        fn next_child<R: read::Reader<Offset = usize>>(
            entries: &mut read::EntriesCursor<R>,
        ) -> (read::UnitOffset, Option<read::UnitOffset>) {
            let (_, entry) = entries.next_dfs().unwrap().unwrap();
            let offset = entry.offset();
            let sibling =
                entry
                    .attr_value(constants::DW_AT_sibling)
                    .unwrap()
                    .map(|attr| match attr {
                        read::AttributeValue::UnitRef(offset) => offset,
                        _ => panic!("bad sibling value"),
                    });
            (offset, sibling)
        }

        fn check_sibling<R: read::Reader<Offset = usize>>(
            unit: &read::UnitHeader<R>,
            debug_abbrev: &read::DebugAbbrev<R>,
        ) {
            let abbrevs = unit.abbreviations(debug_abbrev).unwrap();
            let mut entries = unit.entries(&abbrevs);
            // root
            entries.next_dfs().unwrap().unwrap();
            // child1
            let (_, sibling1) = next_child(&mut entries);
            // grandchild1
            entries.next_dfs().unwrap().unwrap();
            // child2
            let (offset2, sibling2) = next_child(&mut entries);
            // child3
            let (_, _) = next_child(&mut entries);
            assert_eq!(sibling1, Some(offset2));
            assert_eq!(sibling2, None);
        }

        let encoding = Encoding {
            format: Format::Dwarf32,
            version: 4,
            address_size: 8,
        };
        let mut units = UnitTable::default();
        let unit_id1 = units.add(Unit::new(encoding, LineProgram::none()));
        add_children(&mut units, unit_id1);
        let unit_id2 = units.add(Unit::new(encoding, LineProgram::none()));
        add_children(&mut units, unit_id2);

        let debug_line_str_offsets = DebugLineStrOffsets::none();
        let debug_str_offsets = DebugStrOffsets::none();
        let mut sections = Sections::new(EndianVec::new(LittleEndian));
        units
            .write(&mut sections, &debug_line_str_offsets, &debug_str_offsets)
            .unwrap();

        println!("{:?}", sections.debug_info);
        println!("{:?}", sections.debug_abbrev);

        let read_debug_info = read::DebugInfo::new(sections.debug_info.slice(), LittleEndian);
        let read_debug_abbrev = read::DebugAbbrev::new(sections.debug_abbrev.slice(), LittleEndian);
        let mut read_units = read_debug_info.units();
        check_sibling(&read_units.next().unwrap().unwrap(), &read_debug_abbrev);
        check_sibling(&read_units.next().unwrap().unwrap(), &read_debug_abbrev);
    }

    #[test]
    fn test_line_ref() {
        for &version in &[2, 3, 4, 5] {
            for &address_size in &[4, 8] {
                for &format in &[Format::Dwarf32, Format::Dwarf64] {
                    let encoding = Encoding {
                        format,
                        version,
                        address_size,
                    };

                    // The line program we'll be referencing.
                    let mut line_program = LineProgram::new(
                        encoding,
                        LineEncoding::default(),
                        LineString::String(b"comp_dir".to_vec()),
                        LineString::String(b"comp_name".to_vec()),
                        None,
                    );
                    let dir = line_program.default_directory();
                    let file1 =
                        line_program.add_file(LineString::String(b"file1".to_vec()), dir, None);
                    let file2 =
                        line_program.add_file(LineString::String(b"file2".to_vec()), dir, None);

                    // Write, read, and convert the line program, so that we have the info
                    // required to convert the attributes.
                    let line_strings = DebugLineStrOffsets::none();
                    let strings = DebugStrOffsets::none();
                    let mut debug_line = DebugLine::from(EndianVec::new(LittleEndian));
                    let line_program_offset = line_program
                        .write(&mut debug_line, encoding, &line_strings, &strings)
                        .unwrap();
                    let read_debug_line = read::DebugLine::new(debug_line.slice(), LittleEndian);
                    let read_line_program = read_debug_line
                        .program(
                            line_program_offset,
                            address_size,
                            Some(read::EndianSlice::new(b"comp_dir", LittleEndian)),
                            Some(read::EndianSlice::new(b"comp_name", LittleEndian)),
                        )
                        .unwrap();
                    let dwarf = read::Dwarf::default();
                    let mut convert_line_strings = LineStringTable::default();
                    let mut convert_strings = StringTable::default();
                    let (_, line_program_files) = LineProgram::from(
                        read_line_program,
                        &dwarf,
                        &mut convert_line_strings,
                        &mut convert_strings,
                        &|address| Some(Address::Constant(address)),
                    )
                    .unwrap();

                    // Fake the unit.
                    let mut units = UnitTable::default();
                    let unit = units.add(Unit::new(encoding, LineProgram::none()));
                    let unit = units.get(unit);
                    let from_unit = read::UnitHeader::new(
                        encoding,
                        0,
                        read::UnitType::Compilation,
                        DebugAbbrevOffset(0),
                        DebugInfoOffset(0).into(),
                        read::EndianSlice::new(&[], LittleEndian),
                    );

                    for &(ref name, ref value, ref expect_value) in &[
                        (
                            constants::DW_AT_stmt_list,
                            AttributeValue::LineProgramRef,
                            read::AttributeValue::SecOffset(line_program_offset.0),
                        ),
                        (
                            constants::DW_AT_decl_file,
                            AttributeValue::FileIndex(Some(file1)),
                            read::AttributeValue::Udata(file1.raw()),
                        ),
                        (
                            constants::DW_AT_decl_file,
                            AttributeValue::FileIndex(Some(file2)),
                            read::AttributeValue::Udata(file2.raw()),
                        ),
                    ][..]
                    {
                        let mut ranges = RangeListTable::default();
                        let mut locations = LocationListTable::default();
                        let mut strings = StringTable::default();
                        let mut line_strings = LineStringTable::default();

                        let form = value.form(encoding).unwrap();
                        let attr = Attribute {
                            name: *name,
                            value: value.clone(),
                        };

                        let mut debug_info_refs = Vec::new();
                        let mut unit_refs = Vec::new();
                        let mut debug_info = DebugInfo::from(EndianVec::new(LittleEndian));
                        let offsets = UnitOffsets::none();
                        let debug_line_str_offsets = DebugLineStrOffsets::none();
                        let debug_str_offsets = DebugStrOffsets::none();
                        let range_list_offsets = RangeListOffsets::none();
                        let loc_list_offsets = LocationListOffsets::none();
                        attr.value
                            .write(
                                &mut debug_info,
                                &mut debug_info_refs,
                                &mut unit_refs,
                                &unit,
                                &offsets,
                                Some(line_program_offset),
                                &debug_line_str_offsets,
                                &debug_str_offsets,
                                &range_list_offsets,
                                &loc_list_offsets,
                            )
                            .unwrap();

                        let spec = read::AttributeSpecification::new(*name, form, None);
                        let mut r = read::EndianSlice::new(debug_info.slice(), LittleEndian);
                        let read_attr = read::parse_attribute(&mut r, encoding, spec).unwrap();
                        let read_value = &read_attr.raw_value();
                        // read::AttributeValue is invariant in the lifetime of R.
                        // The lifetimes here are all okay, so transmute it.
                        let read_value = unsafe {
                            mem::transmute::<
                                &read::AttributeValue<read::EndianSlice<LittleEndian>>,
                                &read::AttributeValue<read::EndianSlice<LittleEndian>>,
                            >(read_value)
                        };
                        assert_eq!(read_value, expect_value);

                        let unit = read::Unit {
                            header: from_unit,
                            abbreviations: Arc::new(read::Abbreviations::default()),
                            name: None,
                            comp_dir: None,
                            low_pc: 0,
                            str_offsets_base: DebugStrOffsetsBase(0),
                            addr_base: DebugAddrBase(0),
                            loclists_base: DebugLocListsBase(0),
                            rnglists_base: DebugRngListsBase(0),
                            line_program: None,
                            dwo_id: None,
                        };

                        let mut context = convert::ConvertUnitContext {
                            dwarf: &dwarf,
                            unit: &unit,
                            line_strings: &mut line_strings,
                            strings: &mut strings,
                            ranges: &mut ranges,
                            locations: &mut locations,
                            convert_address: &|address| Some(Address::Constant(address)),
                            base_address: Address::Constant(0),
                            line_program_offset: Some(line_program_offset),
                            line_program_files: line_program_files.clone(),
                            entry_ids: &HashMap::new(),
                        };

                        let convert_attr =
                            Attribute::from(&mut context, &read_attr).unwrap().unwrap();
                        assert_eq!(convert_attr, attr);
                    }
                }
            }
        }
    }

    #[test]
    fn test_line_program_used() {
        for used in vec![false, true] {
            let encoding = Encoding {
                format: Format::Dwarf32,
                version: 5,
                address_size: 8,
            };

            let line_program = LineProgram::new(
                encoding,
                LineEncoding::default(),
                LineString::String(b"comp_dir".to_vec()),
                LineString::String(b"comp_name".to_vec()),
                None,
            );

            let mut unit = Unit::new(encoding, line_program);
            let file_id = if used { Some(FileId::new(0)) } else { None };
            let root = unit.root();
            unit.get_mut(root).set(
                constants::DW_AT_decl_file,
                AttributeValue::FileIndex(file_id),
            );

            let mut units = UnitTable::default();
            units.add(unit);

            let debug_line_str_offsets = DebugLineStrOffsets::none();
            let debug_str_offsets = DebugStrOffsets::none();
            let mut sections = Sections::new(EndianVec::new(LittleEndian));
            units
                .write(&mut sections, &debug_line_str_offsets, &debug_str_offsets)
                .unwrap();
            assert_eq!(!used, sections.debug_line.slice().is_empty());
        }
    }

    #[test]
    fn test_delete_child() {
        fn set_name(unit: &mut Unit, id: UnitEntryId, name: &str) {
            let entry = unit.get_mut(id);
            entry.set(constants::DW_AT_name, AttributeValue::String(name.into()));
        }
        fn check_name<R: read::Reader>(
            entry: &read::DebuggingInformationEntry<R>,
            debug_str: &read::DebugStr<R>,
            name: &str,
        ) {
            let name_attr = entry.attr(constants::DW_AT_name).unwrap().unwrap();
            let entry_name = name_attr.string_value(debug_str).unwrap();
            let entry_name_str = entry_name.to_string().unwrap();
            assert_eq!(entry_name_str, name);
        }
        let encoding = Encoding {
            format: Format::Dwarf32,
            version: 4,
            address_size: 8,
        };
        let mut dwarf = DwarfUnit::new(encoding);
        let root = dwarf.unit.root();

        // Add and delete entries in the root unit
        let child1 = dwarf.unit.add(root, constants::DW_TAG_subprogram);
        set_name(&mut dwarf.unit, child1, "child1");
        let grandchild1 = dwarf.unit.add(child1, constants::DW_TAG_variable);
        set_name(&mut dwarf.unit, grandchild1, "grandchild1");
        let child2 = dwarf.unit.add(root, constants::DW_TAG_subprogram);
        set_name(&mut dwarf.unit, child2, "child2");
        // This deletes both `child1` and its child `grandchild1`
        dwarf.unit.get_mut(root).delete_child(child1);
        let child3 = dwarf.unit.add(root, constants::DW_TAG_subprogram);
        set_name(&mut dwarf.unit, child3, "child3");
        let child4 = dwarf.unit.add(root, constants::DW_TAG_subprogram);
        set_name(&mut dwarf.unit, child4, "child4");
        let grandchild4 = dwarf.unit.add(child4, constants::DW_TAG_variable);
        set_name(&mut dwarf.unit, grandchild4, "grandchild4");
        dwarf.unit.get_mut(child4).delete_child(grandchild4);

        let mut sections = Sections::new(EndianVec::new(LittleEndian));

        // Write DWARF data which should only include `child2`, `child3` and `child4`
        dwarf.write(&mut sections).unwrap();

        let read_debug_info = read::DebugInfo::new(sections.debug_info.slice(), LittleEndian);
        let read_debug_abbrev = read::DebugAbbrev::new(sections.debug_abbrev.slice(), LittleEndian);
        let read_debug_str = read::DebugStr::new(sections.debug_str.slice(), LittleEndian);
        let read_unit = read_debug_info.units().next().unwrap().unwrap();
        let abbrevs = read_unit.abbreviations(&read_debug_abbrev).unwrap();
        let mut entries = read_unit.entries(&abbrevs);
        // root
        entries.next_dfs().unwrap().unwrap();
        // child2
        let (_, read_child2) = entries.next_dfs().unwrap().unwrap();
        check_name(read_child2, &read_debug_str, "child2");
        // child3
        let (_, read_child3) = entries.next_dfs().unwrap().unwrap();
        check_name(read_child3, &read_debug_str, "child3");
        // child4
        let (_, read_child4) = entries.next_dfs().unwrap().unwrap();
        check_name(read_child4, &read_debug_str, "child4");
        // There should be no more entries
        assert!(entries.next_dfs().unwrap().is_none());
    }
}
