~taiite/protodump

a6c68980abe12cd53fe4a0ddb8a9b29e439f3906 — Hubert Hirtz 28 days ago 3d4a61d
Add doc comments
2 files changed, 45 insertions(+), 0 deletions(-)

M src/dwarf.rs
M src/types.rs
M src/dwarf.rs => src/dwarf.rs +7 -0
@@ 24,14 24,20 @@ pub struct Subprogram<R> {
    pub parameters: Vec<Parameter<R>>,
}

/// Iterator over the children of an entry.
pub struct EntryChildren<'e, R>
where
    R: gimli::Reader,
{
    entries: Option<gimli::EntriesCursor<'e, 'e, R>>,

    /// Whether the first child has been iterated over.
    init: bool,
}

/// Iterate over the children of an entry.
///
/// The given entry must be in the given unit.
pub fn entry_children<'e, R>(
    unit: &'e gimli::Unit<R>,
    entry: &'e gimli::DebuggingInformationEntry<R>,


@@ 40,6 46,7 @@ where
    R: gimli::Reader,
{
    let entries = if entry.has_children() {
        // TODO error should not happen since we give the correct unit for the entry.
        let mut cursor = unit.entries_at_offset(entry.offset())?;
        // somehow EntriesCursor behaves like this??
        let (delta, child) = cursor

M src/types.rs => src/types.rs +38 -0
@@ 7,6 7,9 @@ use std::fmt;
use std::rc::Rc;
use std::rc::Weak;

/// Description of how base types are encoded.
///
/// Enumeration version of `DW_AT_encoding` (see section 7.8).
#[derive(PartialEq)]
pub enum Encoding {
    Address,


@@ 55,43 58,62 @@ impl TryFrom<gimli::DwAte> for Encoding {
    }
}

/// Member/field of a structure or an union.
#[derive(PartialEq)]
pub struct Member<R> {
    /// The name of the field, or [None] if the field is an anonymous/unamed
    /// structure or union.
    name: Option<R>,

    /// Location of the member in bytes starting from the beginning of the
    /// structure.
    ///
    /// The location of union fields is always zero.
    location: u64,

    type_: InstancePtr<R>,
}

/// Variant of an enumeration.
#[derive(PartialEq)]
pub struct Enumerator<R> {
    name: R,
    value: u64,
}

/// Definition of a type.
#[derive(PartialEq)]
pub enum Definition<R> {
    /// A primitive type.
    Base {
        byte_size: u64,
        encoding: Encoding,
    },

    Enumeration {
        byte_size: u64,
        encoding: Encoding,
        enumerators: Vec<Enumerator<R>>,
    },

    /// A callback or function type.
    Subroutine {
        return_type: Option<InstancePtr<R>>,
        parameters: Vec<InstancePtr<R>>,
    },

    Structure {
        members: Vec<Member<R>>,
    },

    Union {
        members: Vec<Member<R>>,
    },
}

impl<R> Definition<R> {
    /// Convenience function to use when you want a value of type [Definition]
    /// but don't care about it.
    fn dummy() -> Definition<R> {
        Definition::Base {
            byte_size: 0,


@@ 100,13 122,18 @@ impl<R> Definition<R> {
    }
}

/// The information of a definition and its name.
///
/// The name might be [None] if the type is anonymous (e.g. defined where used)
pub struct Type<R> {
    name: Option<R>,
    definition: Definition<R>,
}

/// Pointer type for [Type] used through protodump in order to avoid copies.
pub type TypePtr<R> = Rc<RefCell<Type<R>>>;

/// Type modifier used in type [Instance]s.
// TODO add fields like pointer size, array count, etc.
#[derive(Copy, Clone, PartialEq)]
enum Modifier {


@@ 119,6 146,8 @@ enum Modifier {
}

impl Modifier {
    /// Whether a space must be added after the string representation of the
    /// modifier.
    pub fn needs_padding(self) -> bool {
        match self {
            Modifier::Array | Modifier::Pointer | Modifier::Reference => false,


@@ 127,12 156,14 @@ impl Modifier {
    }
}

/// An instance, appearance of a type with some modifiers.
pub struct Instance<R> {
    modifiers: Vec<Modifier>,
    underlying: Option<TypePtr<R>>,
    self_weak: Weak<RefCell<Instance<R>>>,
}

/// Pointer type for [Instance] used through protodump in order to avoid copies.
pub type InstancePtr<R> = Rc<RefCell<Instance<R>>>;

impl<R> PartialEq for Instance<R>


@@ 229,6 260,7 @@ where
}

impl<R> Instance<R> {
    /// Padding needed after the string representation of the instance.
    pub fn display_padding(&self) -> &'static str {
        let needs_padding = match self.modifiers.first() {
            Some(modifier) => modifier.needs_padding(),


@@ 242,12 274,18 @@ impl<R> Instance<R> {
    }
}

/// A type storage that holds all type instances and type definitions for a
/// single object file.
pub struct Cache<'a, R>
where
    R: gimli::Reader,
{
    dwarf: &'a gimli::Dwarf<R>,

    /// Map of type instances identified by where they appear in DWARF info.
    instances: HashMap<gimli::DebugInfoOffset<R::Offset>, InstancePtr<R>>,

    /// Map of type definitions identified by where they appear in DWARF info.
    definitions: HashMap<gimli::DebugInfoOffset<R::Offset>, TypePtr<R>>,
}