@@ -31,9 +31,9 @@ static int data_type_cmp(const void *_key, const struct rb_node *node)
31
31
32
32
type = rb_entry (node , struct annotated_data_type , node );
33
33
34
- if (key -> type_size != type -> type_size )
35
- return key -> type_size - type -> type_size ;
36
- return strcmp (key -> type_name , type -> type_name );
34
+ if (key -> self . size != type -> self . size )
35
+ return key -> self . size - type -> self . size ;
36
+ return strcmp (key -> self . type_name , type -> self . type_name );
37
37
}
38
38
39
39
static bool data_type_less (struct rb_node * node_a , const struct rb_node * node_b )
@@ -43,9 +43,80 @@ static bool data_type_less(struct rb_node *node_a, const struct rb_node *node_b)
43
43
a = rb_entry (node_a , struct annotated_data_type , node );
44
44
b = rb_entry (node_b , struct annotated_data_type , node );
45
45
46
- if (a -> type_size != b -> type_size )
47
- return a -> type_size < b -> type_size ;
48
- return strcmp (a -> type_name , b -> type_name ) < 0 ;
46
+ if (a -> self .size != b -> self .size )
47
+ return a -> self .size < b -> self .size ;
48
+ return strcmp (a -> self .type_name , b -> self .type_name ) < 0 ;
49
+ }
50
+
51
+ /* Recursively add new members for struct/union */
52
+ static int __add_member_cb (Dwarf_Die * die , void * arg )
53
+ {
54
+ struct annotated_member * parent = arg ;
55
+ struct annotated_member * member ;
56
+ Dwarf_Die member_type , die_mem ;
57
+ Dwarf_Word size , loc ;
58
+ Dwarf_Attribute attr ;
59
+ struct strbuf sb ;
60
+ int tag ;
61
+
62
+ if (dwarf_tag (die ) != DW_TAG_member )
63
+ return DIE_FIND_CB_SIBLING ;
64
+
65
+ member = zalloc (sizeof (* member ));
66
+ if (member == NULL )
67
+ return DIE_FIND_CB_END ;
68
+
69
+ strbuf_init (& sb , 32 );
70
+ die_get_typename (die , & sb );
71
+
72
+ die_get_real_type (die , & member_type );
73
+ if (dwarf_aggregate_size (& member_type , & size ) < 0 )
74
+ size = 0 ;
75
+
76
+ if (!dwarf_attr_integrate (die , DW_AT_data_member_location , & attr ))
77
+ loc = 0 ;
78
+ else
79
+ dwarf_formudata (& attr , & loc );
80
+
81
+ member -> type_name = strbuf_detach (& sb , NULL );
82
+ /* member->var_name can be NULL */
83
+ if (dwarf_diename (die ))
84
+ member -> var_name = strdup (dwarf_diename (die ));
85
+ member -> size = size ;
86
+ member -> offset = loc + parent -> offset ;
87
+ INIT_LIST_HEAD (& member -> children );
88
+ list_add_tail (& member -> node , & parent -> children );
89
+
90
+ tag = dwarf_tag (& member_type );
91
+ switch (tag ) {
92
+ case DW_TAG_structure_type :
93
+ case DW_TAG_union_type :
94
+ die_find_child (& member_type , __add_member_cb , member , & die_mem );
95
+ break ;
96
+ default :
97
+ break ;
98
+ }
99
+ return DIE_FIND_CB_SIBLING ;
100
+ }
101
+
102
+ static void add_member_types (struct annotated_data_type * parent , Dwarf_Die * type )
103
+ {
104
+ Dwarf_Die die_mem ;
105
+
106
+ die_find_child (type , __add_member_cb , & parent -> self , & die_mem );
107
+ }
108
+
109
+ static void delete_members (struct annotated_member * member )
110
+ {
111
+ struct annotated_member * child , * tmp ;
112
+
113
+ list_for_each_entry_safe (child , tmp , & member -> children , node ) {
114
+ list_del (& child -> node );
115
+ delete_members (child );
116
+ free (child -> type_name );
117
+ free (child -> var_name );
118
+ free (child );
119
+ }
49
120
}
50
121
51
122
static struct annotated_data_type * dso__findnew_data_type (struct dso * dso ,
@@ -65,8 +136,8 @@ static struct annotated_data_type *dso__findnew_data_type(struct dso *dso,
65
136
dwarf_aggregate_size (type_die , & size );
66
137
67
138
/* Check existing nodes in dso->data_types tree */
68
- key .type_name = type_name ;
69
- key .type_size = size ;
139
+ key .self . type_name = type_name ;
140
+ key .self . size = size ;
70
141
node = rb_find (& key , & dso -> data_types , data_type_cmp );
71
142
if (node ) {
72
143
result = rb_entry (node , struct annotated_data_type , node );
@@ -81,8 +152,15 @@ static struct annotated_data_type *dso__findnew_data_type(struct dso *dso,
81
152
return NULL ;
82
153
}
83
154
84
- result -> type_name = type_name ;
85
- result -> type_size = size ;
155
+ result -> self .type_name = type_name ;
156
+ result -> self .size = size ;
157
+ INIT_LIST_HEAD (& result -> self .children );
158
+
159
+ /*
160
+ * Fill member info unconditionally for now,
161
+ * later perf annotate would need it.
162
+ */
163
+ add_member_types (result , type_die );
86
164
87
165
rb_add (& result -> node , & dso -> data_types , data_type_less );
88
166
return result ;
@@ -233,7 +311,8 @@ void annotated_data_type__tree_delete(struct rb_root *root)
233
311
234
312
rb_erase (node , root );
235
313
pos = rb_entry (node , struct annotated_data_type , node );
236
- free (pos -> type_name );
314
+ delete_members (& pos -> self );
315
+ free (pos -> self .type_name );
237
316
free (pos );
238
317
}
239
318
}
0 commit comments