stackdump_trace/variables/type_value_tree_building/
enumeration.rs1use crate::{
2 error::TraceError,
3 get_entry_type_reference_tree_recursive,
4 gimli_extensions::{AttributeExt, DebuggingInformationEntryExt},
5 type_value_tree::{
6 value::Value,
7 variable_type::{Archetype, VariableType},
8 TypeValue, TypeValueTree,
9 },
10 variables::{build_type_value_tree, get_entry_name},
11 DefaultReader,
12};
13use gimli::{Abbreviations, DebugInfoOffset, Dwarf, Unit};
14use std::collections::HashMap;
15
16pub fn build_enumeration<W: funty::Integral>(
17 dwarf: &Dwarf<DefaultReader>,
18 unit: &Unit<DefaultReader, usize>,
19 abbreviations: &Abbreviations,
20 node: gimli::EntriesTreeNode<DefaultReader>,
21 type_cache: &mut HashMap<DebugInfoOffset, Result<TypeValueTree<W>, TraceError>>,
22) -> Result<TypeValueTree<W>, TraceError> {
23 let mut type_value_tree = TypeValueTree::new(TypeValue::default());
24 let mut type_value = type_value_tree.root_mut();
25 let entry = node.entry();
26
27 let name = get_entry_name(dwarf, unit, entry)?;
32
33 get_entry_type_reference_tree_recursive!(
34 underlying_type_tree = (dwarf, unit, abbreviations, entry)
35 );
36 let mut underlying_type_tree = underlying_type_tree.map(|mut type_tree| {
37 type_tree
38 .root()
39 .map(|root| build_type_value_tree(dwarf, unit, abbreviations, root, type_cache))
40 })???;
41 underlying_type_tree.root_mut().data_mut().name = "base".into();
42 let underlying_type_bitrange = underlying_type_tree.root().data().bit_range.clone();
43
44 type_value.data_mut().variable_type.name = name;
45 type_value.data_mut().variable_type.archetype = Archetype::Enumeration;
46 type_value.data_mut().bit_range = underlying_type_bitrange.clone();
47
48 type_value.push_back(underlying_type_tree);
49
50 let mut children = node.children();
51 while let Ok(Some(child)) = children.next() {
52 let enumerator_entry = child.entry();
53
54 if enumerator_entry.tag() != gimli::constants::DW_TAG_enumerator {
56 continue;
57 }
58
59 let enumerator_name = get_entry_name(dwarf, unit, enumerator_entry)?;
64 let const_value = enumerator_entry
65 .required_attr(&unit.header, gimli::constants::DW_AT_const_value)?
66 .required_sdata_value()?;
67
68 type_value.push_back(TypeValueTree::new(TypeValue {
69 name: enumerator_name,
70 variable_type: VariableType {
71 archetype: Archetype::Enumerator,
72 ..Default::default()
73 },
74 bit_range: underlying_type_bitrange.clone(),
75 variable_value: Ok(Value::Int(const_value as i128)),
76 }));
77 }
78
79 Ok(type_value_tree)
80}