~taiite/protodump

dd2d08354305536fd8e2df5d9081c195662469f3 — Hubert Hirtz 28 days ago a6c6898
Handle enumerations that don't have DW_AT_encoding

e.g. rust's std::cmp::Ordering

... and fetch the encoding from the underlying type, if it's a base
type.

Handling underlying types that are not base type is TODO (?), yet to be
found in the wild.
1 files changed, 27 insertions(+), 8 deletions(-)

M src/types.rs
M src/types.rs => src/types.rs +27 -8
@@ 10,7 10,7 @@ use std::rc::Weak;
/// Description of how base types are encoded.
///
/// Enumeration version of `DW_AT_encoding` (see section 7.8).
#[derive(PartialEq)]
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum Encoding {
    Address,
    Boolean,


@@ 59,7 59,7 @@ impl TryFrom<gimli::DwAte> for Encoding {
}

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


@@ 75,14 75,14 @@ pub struct Member<R> {
}

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

/// Definition of a type.
#[derive(PartialEq)]
#[derive(Debug, PartialEq)]
pub enum Definition<R> {
    /// A primitive type.
    Base {


@@ 125,6 125,7 @@ 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)
#[derive(Debug)]
pub struct Type<R> {
    name: Option<R>,
    definition: Definition<R>,


@@ 135,7 136,7 @@ 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)]
#[derive(Copy, Clone, Debug, PartialEq)]
enum Modifier {
    Array,
    Const,


@@ 157,6 158,7 @@ impl Modifier {
}

/// An instance, appearance of a type with some modifiers.
#[derive(Debug)]
pub struct Instance<R> {
    modifiers: Vec<Modifier>,
    underlying: Option<TypePtr<R>>,


@@ 317,9 319,26 @@ where
        entry: &gimli::DebuggingInformationEntry<R>,
    ) -> gimli::Result<Definition<R>> {
        let byte_size = crate::dwarf::entry_byte_size(entry)?.unwrap();
        let encoding = crate::dwarf::entry_encoding(entry)?.unwrap();

        // TODO also get underlying type?
        let encoding = match crate::dwarf::entry_encoding(entry)? {
            None => match crate::dwarf::entry_type(self, unit, entry)? {
                None => {
                    assert_eq!(byte_size, 1);
                    Encoding::Unsigned
                }
                Some(type_) => match &type_
                    .borrow()
                    .underlying
                    .as_ref()
                    .unwrap()
                    .borrow()
                    .definition
                {
                    Definition::Base { encoding, .. } => *encoding,
                    unexpected => panic!("unexpected underlying type for enum: {:?}", unexpected),
                },
            },
            Some(encoding) => encoding,
        };

        let mut enumerators = Vec::new();
        let mut children = crate::dwarf::entry_children(unit, entry)?;