1 /* SPDX-License-Identifier: GPL-2.0 */
3 * Convert sample address to data type using DWARF debug info.
5 * Written by Namhyung Kim <namhyung@kernel.org>
11 #include <linux/zalloc.h>
14 #include "annotate-data.h"
15 #include "debuginfo.h"
18 #include "dwarf-regs.h"
22 #include "map_symbol.h"
26 #include "symbol_conf.h"
29 /* register number of the stack pointer */
32 static void delete_var_types(struct die_var_type
*var_types
);
34 #define pr_debug_dtp(fmt, ...) \
36 if (debug_type_profile) \
37 pr_info(fmt, ##__VA_ARGS__); \
39 pr_debug3(fmt, ##__VA_ARGS__); \
42 void pr_debug_type_name(Dwarf_Die
*die
, enum type_state_kind kind
)
48 if (!debug_type_profile
&& verbose
< 3)
52 case TSR_KIND_INVALID
:
55 case TSR_KIND_PERCPU_BASE
:
56 pr_info(" percpu base\n");
59 pr_info(" constant\n");
61 case TSR_KIND_POINTER
:
63 /* it also prints the type info */
66 pr_info(" stack canary\n");
73 dwarf_aggregate_size(die
, &size
);
76 die_get_typename_from_type(die
, &sb
);
77 str
= strbuf_detach(&sb
, NULL
);
78 pr_info(" type='%s' size=%#lx (die:%#lx)\n",
79 str
, (long)size
, (long)dwarf_dieoffset(die
));
83 static void pr_debug_location(Dwarf_Die
*die
, u64 pc
, int reg
)
87 Dwarf_Addr base
, start
, end
;
91 if (!debug_type_profile
&& verbose
< 3)
94 if (dwarf_attr(die
, DW_AT_location
, &attr
) == NULL
)
97 while ((off
= dwarf_getlocations(&attr
, off
, &base
, &start
, &end
, &ops
, &nops
)) > 0) {
98 if (reg
!= DWARF_REG_PC
&& end
<= pc
)
100 if (reg
!= DWARF_REG_PC
&& start
> pc
)
103 pr_info(" variable location: ");
105 case DW_OP_reg0
...DW_OP_reg31
:
106 pr_info("reg%d\n", ops
->atom
- DW_OP_reg0
);
108 case DW_OP_breg0
...DW_OP_breg31
:
109 pr_info("base=reg%d, offset=%#lx\n",
110 ops
->atom
- DW_OP_breg0
, (long)ops
->number
);
113 pr_info("reg%ld\n", (long)ops
->number
);
116 pr_info("base=reg%ld, offset=%#lx\n",
117 (long)ops
->number
, (long)ops
->number2
);
120 pr_info("use frame base, offset=%#lx\n", (long)ops
->number
);
123 pr_info("address=%#lx\n", (long)ops
->number
);
126 pr_info("unknown: code=%#x, number=%#lx\n",
127 ops
->atom
, (long)ops
->number
);
134 static void pr_debug_scope(Dwarf_Die
*scope_die
)
138 if (!debug_type_profile
&& verbose
< 3)
141 pr_info("(die:%lx) ", (long)dwarf_dieoffset(scope_die
));
143 tag
= dwarf_tag(scope_die
);
144 if (tag
== DW_TAG_subprogram
)
145 pr_info("[function] %s\n", dwarf_diename(scope_die
));
146 else if (tag
== DW_TAG_inlined_subroutine
)
147 pr_info("[inlined] %s\n", dwarf_diename(scope_die
));
148 else if (tag
== DW_TAG_lexical_block
)
149 pr_info("[block]\n");
151 pr_info("[unknown] tag=%x\n", tag
);
154 bool has_reg_type(struct type_state
*state
, int reg
)
156 return (unsigned)reg
< ARRAY_SIZE(state
->regs
);
159 static void init_type_state(struct type_state
*state
, struct arch
*arch
)
161 memset(state
, 0, sizeof(*state
));
162 INIT_LIST_HEAD(&state
->stack_vars
);
164 if (arch__is(arch
, "x86")) {
165 state
->regs
[0].caller_saved
= true;
166 state
->regs
[1].caller_saved
= true;
167 state
->regs
[2].caller_saved
= true;
168 state
->regs
[4].caller_saved
= true;
169 state
->regs
[5].caller_saved
= true;
170 state
->regs
[8].caller_saved
= true;
171 state
->regs
[9].caller_saved
= true;
172 state
->regs
[10].caller_saved
= true;
173 state
->regs
[11].caller_saved
= true;
175 state
->stack_reg
= X86_REG_SP
;
179 static void exit_type_state(struct type_state
*state
)
181 struct type_state_stack
*stack
, *tmp
;
183 list_for_each_entry_safe(stack
, tmp
, &state
->stack_vars
, list
) {
184 list_del(&stack
->list
);
190 * Compare type name and size to maintain them in a tree.
191 * I'm not sure if DWARF would have information of a single type in many
192 * different places (compilation units). If not, it could compare the
193 * offset of the type entry in the .debug_info section.
195 static int data_type_cmp(const void *_key
, const struct rb_node
*node
)
197 const struct annotated_data_type
*key
= _key
;
198 struct annotated_data_type
*type
;
200 type
= rb_entry(node
, struct annotated_data_type
, node
);
202 if (key
->self
.size
!= type
->self
.size
)
203 return key
->self
.size
- type
->self
.size
;
204 return strcmp(key
->self
.type_name
, type
->self
.type_name
);
207 static bool data_type_less(struct rb_node
*node_a
, const struct rb_node
*node_b
)
209 struct annotated_data_type
*a
, *b
;
211 a
= rb_entry(node_a
, struct annotated_data_type
, node
);
212 b
= rb_entry(node_b
, struct annotated_data_type
, node
);
214 if (a
->self
.size
!= b
->self
.size
)
215 return a
->self
.size
< b
->self
.size
;
216 return strcmp(a
->self
.type_name
, b
->self
.type_name
) < 0;
219 /* Recursively add new members for struct/union */
220 static int __add_member_cb(Dwarf_Die
*die
, void *arg
)
222 struct annotated_member
*parent
= arg
;
223 struct annotated_member
*member
;
224 Dwarf_Die member_type
, die_mem
;
225 Dwarf_Word size
, loc
, bit_size
= 0;
226 Dwarf_Attribute attr
;
230 if (dwarf_tag(die
) != DW_TAG_member
)
231 return DIE_FIND_CB_SIBLING
;
233 member
= zalloc(sizeof(*member
));
235 return DIE_FIND_CB_END
;
237 strbuf_init(&sb
, 32);
238 die_get_typename(die
, &sb
);
240 __die_get_real_type(die
, &member_type
);
241 if (dwarf_tag(&member_type
) == DW_TAG_typedef
)
242 die_get_real_type(&member_type
, &die_mem
);
244 die_mem
= member_type
;
246 if (dwarf_aggregate_size(&die_mem
, &size
) < 0)
249 if (dwarf_attr_integrate(die
, DW_AT_data_member_location
, &attr
))
250 dwarf_formudata(&attr
, &loc
);
252 /* bitfield member */
253 if (dwarf_attr_integrate(die
, DW_AT_data_bit_offset
, &attr
) &&
254 dwarf_formudata(&attr
, &loc
) == 0)
259 if (dwarf_attr_integrate(die
, DW_AT_bit_size
, &attr
) &&
260 dwarf_formudata(&attr
, &bit_size
) == 0)
261 size
= (bit_size
+ 7) / 8;
264 member
->type_name
= strbuf_detach(&sb
, NULL
);
265 /* member->var_name can be NULL */
266 if (dwarf_diename(die
)) {
268 if (asprintf(&member
->var_name
, "%s:%ld",
269 dwarf_diename(die
), (long)bit_size
) < 0)
270 member
->var_name
= NULL
;
272 member
->var_name
= strdup(dwarf_diename(die
));
275 if (member
->var_name
== NULL
) {
277 return DIE_FIND_CB_END
;
281 member
->offset
= loc
+ parent
->offset
;
282 INIT_LIST_HEAD(&member
->children
);
283 list_add_tail(&member
->node
, &parent
->children
);
285 tag
= dwarf_tag(&die_mem
);
287 case DW_TAG_structure_type
:
288 case DW_TAG_union_type
:
289 die_find_child(&die_mem
, __add_member_cb
, member
, &die_mem
);
294 return DIE_FIND_CB_SIBLING
;
297 static void add_member_types(struct annotated_data_type
*parent
, Dwarf_Die
*type
)
301 die_find_child(type
, __add_member_cb
, &parent
->self
, &die_mem
);
304 static void delete_members(struct annotated_member
*member
)
306 struct annotated_member
*child
, *tmp
;
308 list_for_each_entry_safe(child
, tmp
, &member
->children
, node
) {
309 list_del(&child
->node
);
310 delete_members(child
);
311 zfree(&child
->type_name
);
312 zfree(&child
->var_name
);
317 static struct annotated_data_type
*dso__findnew_data_type(struct dso
*dso
,
320 struct annotated_data_type
*result
= NULL
;
321 struct annotated_data_type key
;
322 struct rb_node
*node
;
327 strbuf_init(&sb
, 32);
328 if (die_get_typename_from_type(type_die
, &sb
) < 0)
329 strbuf_add(&sb
, "(unknown type)", 14);
330 type_name
= strbuf_detach(&sb
, NULL
);
332 if (dwarf_tag(type_die
) == DW_TAG_typedef
)
333 die_get_real_type(type_die
, type_die
);
335 dwarf_aggregate_size(type_die
, &size
);
337 /* Check existing nodes in dso->data_types tree */
338 key
.self
.type_name
= type_name
;
339 key
.self
.size
= size
;
340 node
= rb_find(&key
, dso__data_types(dso
), data_type_cmp
);
342 result
= rb_entry(node
, struct annotated_data_type
, node
);
347 /* If not, add a new one */
348 result
= zalloc(sizeof(*result
));
349 if (result
== NULL
) {
354 result
->self
.type_name
= type_name
;
355 result
->self
.size
= size
;
356 INIT_LIST_HEAD(&result
->self
.children
);
358 if (symbol_conf
.annotate_data_member
)
359 add_member_types(result
, type_die
);
361 rb_add(&result
->node
, dso__data_types(dso
), data_type_less
);
365 static bool find_cu_die(struct debuginfo
*di
, u64 pc
, Dwarf_Die
*cu_die
)
367 Dwarf_Off off
, next_off
;
370 if (dwarf_addrdie(di
->dbg
, pc
, cu_die
) != NULL
)
374 * There are some kernels don't have full aranges and contain only a few
375 * aranges entries. Fallback to iterate all CU entries in .debug_info
376 * in case it's missing.
379 while (dwarf_nextcu(di
->dbg
, off
, &next_off
, &header_size
,
380 NULL
, NULL
, NULL
) == 0) {
381 if (dwarf_offdie(di
->dbg
, off
+ header_size
, cu_die
) &&
382 dwarf_haspc(cu_die
, pc
))
390 enum type_match_result
{
391 PERF_TMR_UNKNOWN
= 0,
400 static const char *match_result_str(enum type_match_result tmr
)
405 case PERF_TMR_NO_TYPE
:
406 return "no type information";
407 case PERF_TMR_NO_POINTER
:
408 return "no/void pointer";
409 case PERF_TMR_NO_SIZE
:
410 return "type size is unknown";
411 case PERF_TMR_BAD_OFFSET
:
412 return "offset bigger than size";
413 case PERF_TMR_UNKNOWN
:
414 case PERF_TMR_BAIL_OUT
:
416 return "invalid state";
420 static bool is_pointer_type(Dwarf_Die
*type_die
)
422 int tag
= dwarf_tag(type_die
);
424 return tag
== DW_TAG_pointer_type
|| tag
== DW_TAG_array_type
;
427 static bool is_compound_type(Dwarf_Die
*type_die
)
429 int tag
= dwarf_tag(type_die
);
431 return tag
== DW_TAG_structure_type
|| tag
== DW_TAG_union_type
;
434 /* returns if Type B has better information than Type A */
435 static bool is_better_type(Dwarf_Die
*type_a
, Dwarf_Die
*type_b
)
437 Dwarf_Word size_a
, size_b
;
438 Dwarf_Die die_a
, die_b
;
440 /* pointer type is preferred */
441 if (is_pointer_type(type_a
) != is_pointer_type(type_b
))
442 return is_pointer_type(type_b
);
444 if (is_pointer_type(type_b
)) {
446 * We want to compare the target type, but 'void *' can fail to
447 * get the target type.
449 if (die_get_real_type(type_a
, &die_a
) == NULL
)
451 if (die_get_real_type(type_b
, &die_b
) == NULL
)
458 /* bigger type is preferred */
459 if (dwarf_aggregate_size(type_a
, &size_a
) < 0 ||
460 dwarf_aggregate_size(type_b
, &size_b
) < 0)
463 if (size_a
!= size_b
)
464 return size_a
< size_b
;
466 /* struct or union is preferred */
467 if (is_compound_type(type_a
) != is_compound_type(type_b
))
468 return is_compound_type(type_b
);
470 /* typedef is preferred */
471 if (dwarf_tag(type_b
) == DW_TAG_typedef
)
477 /* The type info will be saved in @type_die */
478 static enum type_match_result
check_variable(struct data_loc_info
*dloc
,
480 Dwarf_Die
*type_die
, int reg
,
481 int offset
, bool is_fbreg
)
484 bool needs_pointer
= true;
485 Dwarf_Die sized_type
;
487 if (reg
== DWARF_REG_PC
)
488 needs_pointer
= false;
489 else if (reg
== dloc
->fbreg
|| is_fbreg
)
490 needs_pointer
= false;
491 else if (arch__is(dloc
->arch
, "x86") && reg
== X86_REG_SP
)
492 needs_pointer
= false;
494 /* Get the type of the variable */
495 if (__die_get_real_type(var_die
, type_die
) == NULL
)
496 return PERF_TMR_NO_TYPE
;
499 * Usually it expects a pointer type for a memory access.
500 * Convert to a real type it points to. But global variables
501 * and local variables are accessed directly without a pointer.
504 if (!is_pointer_type(type_die
) ||
505 __die_get_real_type(type_die
, type_die
) == NULL
)
506 return PERF_TMR_NO_POINTER
;
509 if (dwarf_tag(type_die
) == DW_TAG_typedef
)
510 die_get_real_type(type_die
, &sized_type
);
512 sized_type
= *type_die
;
514 /* Get the size of the actual type */
515 if (dwarf_aggregate_size(&sized_type
, &size
) < 0)
516 return PERF_TMR_NO_SIZE
;
518 /* Minimal sanity check */
519 if ((unsigned)offset
>= size
)
520 return PERF_TMR_BAD_OFFSET
;
525 struct type_state_stack
*find_stack_state(struct type_state
*state
,
528 struct type_state_stack
*stack
;
530 list_for_each_entry(stack
, &state
->stack_vars
, list
) {
531 if (offset
== stack
->offset
)
534 if (stack
->compound
&& stack
->offset
< offset
&&
535 offset
< stack
->offset
+ stack
->size
)
541 void set_stack_state(struct type_state_stack
*stack
, int offset
, u8 kind
,
547 if (dwarf_aggregate_size(type_die
, &size
) < 0)
550 tag
= dwarf_tag(type_die
);
552 stack
->type
= *type_die
;
554 stack
->offset
= offset
;
558 case DW_TAG_structure_type
:
559 case DW_TAG_union_type
:
560 stack
->compound
= (kind
!= TSR_KIND_POINTER
);
563 stack
->compound
= false;
568 struct type_state_stack
*findnew_stack_state(struct type_state
*state
,
572 struct type_state_stack
*stack
= find_stack_state(state
, offset
);
575 set_stack_state(stack
, offset
, kind
, type_die
);
579 stack
= malloc(sizeof(*stack
));
581 set_stack_state(stack
, offset
, kind
, type_die
);
582 list_add(&stack
->list
, &state
->stack_vars
);
587 /* Maintain a cache for quick global variable lookup */
588 struct global_var_entry
{
596 static int global_var_cmp(const void *_key
, const struct rb_node
*node
)
598 const u64 addr
= (uintptr_t)_key
;
599 struct global_var_entry
*gvar
;
601 gvar
= rb_entry(node
, struct global_var_entry
, node
);
603 if (gvar
->start
<= addr
&& addr
< gvar
->end
)
605 return gvar
->start
> addr
? -1 : 1;
608 static bool global_var_less(struct rb_node
*node_a
, const struct rb_node
*node_b
)
610 struct global_var_entry
*gvar_a
, *gvar_b
;
612 gvar_a
= rb_entry(node_a
, struct global_var_entry
, node
);
613 gvar_b
= rb_entry(node_b
, struct global_var_entry
, node
);
615 return gvar_a
->start
< gvar_b
->start
;
618 static struct global_var_entry
*global_var__find(struct data_loc_info
*dloc
, u64 addr
)
620 struct dso
*dso
= map__dso(dloc
->ms
->map
);
621 struct rb_node
*node
;
623 node
= rb_find((void *)(uintptr_t)addr
, dso__global_vars(dso
), global_var_cmp
);
627 return rb_entry(node
, struct global_var_entry
, node
);
630 static bool global_var__add(struct data_loc_info
*dloc
, u64 addr
,
631 const char *name
, Dwarf_Die
*type_die
)
633 struct dso
*dso
= map__dso(dloc
->ms
->map
);
634 struct global_var_entry
*gvar
;
637 if (dwarf_aggregate_size(type_die
, &size
) < 0)
640 gvar
= malloc(sizeof(*gvar
));
644 gvar
->name
= name
? strdup(name
) : NULL
;
645 if (name
&& gvar
->name
== NULL
) {
651 gvar
->end
= addr
+ size
;
652 gvar
->die_offset
= dwarf_dieoffset(type_die
);
654 rb_add(&gvar
->node
, dso__global_vars(dso
), global_var_less
);
658 void global_var_type__tree_delete(struct rb_root
*root
)
660 struct global_var_entry
*gvar
;
662 while (!RB_EMPTY_ROOT(root
)) {
663 struct rb_node
*node
= rb_first(root
);
665 rb_erase(node
, root
);
666 gvar
= rb_entry(node
, struct global_var_entry
, node
);
672 bool get_global_var_info(struct data_loc_info
*dloc
, u64 addr
,
673 const char **var_name
, int *var_offset
)
675 struct addr_location al
;
679 /* Kernel symbols might be relocated */
680 mem_addr
= addr
+ map__reloc(dloc
->ms
->map
);
682 addr_location__init(&al
);
683 sym
= thread__find_symbol_fb(dloc
->thread
, dloc
->cpumode
,
686 *var_name
= sym
->name
;
687 /* Calculate type offset from the start of variable */
688 *var_offset
= mem_addr
- map__unmap_ip(al
.map
, sym
->start
);
692 addr_location__exit(&al
);
693 if (*var_name
== NULL
)
699 static void global_var__collect(struct data_loc_info
*dloc
)
701 Dwarf
*dwarf
= dloc
->di
->dbg
;
702 Dwarf_Off off
, next_off
;
703 Dwarf_Die cu_die
, type_die
;
706 /* Iterate all CU and collect global variables that have no location in a register. */
708 while (dwarf_nextcu(dwarf
, off
, &next_off
, &header_size
,
709 NULL
, NULL
, NULL
) == 0) {
710 struct die_var_type
*var_types
= NULL
;
711 struct die_var_type
*pos
;
713 if (dwarf_offdie(dwarf
, off
+ header_size
, &cu_die
) == NULL
) {
718 die_collect_global_vars(&cu_die
, &var_types
);
720 for (pos
= var_types
; pos
; pos
= pos
->next
) {
721 const char *var_name
= NULL
;
727 if (!dwarf_offdie(dwarf
, pos
->die_off
, &type_die
))
730 if (!get_global_var_info(dloc
, pos
->addr
, &var_name
,
737 global_var__add(dloc
, pos
->addr
, var_name
, &type_die
);
740 delete_var_types(var_types
);
746 bool get_global_var_type(Dwarf_Die
*cu_die
, struct data_loc_info
*dloc
,
747 u64 ip
, u64 var_addr
, int *var_offset
,
752 const char *var_name
= NULL
;
753 struct global_var_entry
*gvar
;
754 struct dso
*dso
= map__dso(dloc
->ms
->map
);
757 if (RB_EMPTY_ROOT(dso__global_vars(dso
)))
758 global_var__collect(dloc
);
760 gvar
= global_var__find(dloc
, var_addr
);
762 if (!dwarf_offdie(dloc
->di
->dbg
, gvar
->die_offset
, type_die
))
765 *var_offset
= var_addr
- gvar
->start
;
769 /* Try to get the variable by address first */
770 if (die_find_variable_by_addr(cu_die
, var_addr
, &var_die
, &offset
) &&
771 check_variable(dloc
, &var_die
, type_die
, DWARF_REG_PC
, offset
,
772 /*is_fbreg=*/false) == PERF_TMR_OK
) {
773 var_name
= dwarf_diename(&var_die
);
774 *var_offset
= offset
;
778 if (!get_global_var_info(dloc
, var_addr
, &var_name
, var_offset
))
781 pc
= map__rip_2objdump(dloc
->ms
->map
, ip
);
783 /* Try to get the name of global variable */
784 if (die_find_variable_at(cu_die
, var_name
, pc
, &var_die
) &&
785 check_variable(dloc
, &var_die
, type_die
, DWARF_REG_PC
, *var_offset
,
786 /*is_fbreg=*/false) == PERF_TMR_OK
)
792 /* The address should point to the start of the variable */
793 global_var__add(dloc
, var_addr
- *var_offset
, var_name
, type_die
);
797 static bool die_is_same(Dwarf_Die
*die_a
, Dwarf_Die
*die_b
)
799 return (die_a
->cu
== die_b
->cu
) && (die_a
->addr
== die_b
->addr
);
803 * update_var_state - Update type state using given variables
804 * @state: type state table
805 * @dloc: data location info
806 * @addr: instruction address to match with variable
807 * @insn_offset: instruction offset (for debug)
808 * @var_types: list of variables with type info
810 * This function fills the @state table using @var_types info. Each variable
811 * is used only at the given location and updates an entry in the table.
813 static void update_var_state(struct type_state
*state
, struct data_loc_info
*dloc
,
814 u64 addr
, u64 insn_offset
, struct die_var_type
*var_types
)
817 struct die_var_type
*var
;
818 int fbreg
= dloc
->fbreg
;
822 if (die_get_cfa(dloc
->di
->dbg
, addr
, &fbreg
, &fb_offset
) < 0)
826 for (var
= var_types
; var
!= NULL
; var
= var
->next
) {
827 if (var
->addr
!= addr
)
829 /* Get the type DIE using the offset */
830 if (!dwarf_offdie(dloc
->di
->dbg
, var
->die_off
, &mem_die
))
833 if (var
->reg
== DWARF_REG_FB
|| var
->reg
== fbreg
) {
834 int offset
= var
->offset
;
835 struct type_state_stack
*stack
;
837 if (var
->reg
!= DWARF_REG_FB
)
840 stack
= find_stack_state(state
, offset
);
841 if (stack
&& stack
->kind
== TSR_KIND_TYPE
&&
842 !is_better_type(&stack
->type
, &mem_die
))
845 findnew_stack_state(state
, offset
, TSR_KIND_TYPE
,
848 pr_debug_dtp("var [%"PRIx64
"] -%#x(stack)",
849 insn_offset
, -offset
);
850 pr_debug_type_name(&mem_die
, TSR_KIND_TYPE
);
851 } else if (has_reg_type(state
, var
->reg
) && var
->offset
== 0) {
852 struct type_state_reg
*reg
;
855 reg
= &state
->regs
[var
->reg
];
857 if (reg
->ok
&& reg
->kind
== TSR_KIND_TYPE
&&
858 !is_better_type(®
->type
, &mem_die
))
861 orig_type
= reg
->type
;
864 reg
->kind
= TSR_KIND_TYPE
;
867 pr_debug_dtp("var [%"PRIx64
"] reg%d",
868 insn_offset
, var
->reg
);
869 pr_debug_type_name(&mem_die
, TSR_KIND_TYPE
);
872 * If this register is directly copied from another and it gets a
873 * better type, also update the type of the source register. This
874 * is usually the case of container_of() macro with offset of 0.
876 if (has_reg_type(state
, reg
->copied_from
)) {
877 struct type_state_reg
*copy_reg
;
879 copy_reg
= &state
->regs
[reg
->copied_from
];
881 /* TODO: check if type is compatible or embedded */
882 if (!copy_reg
->ok
|| (copy_reg
->kind
!= TSR_KIND_TYPE
) ||
883 !die_is_same(©_reg
->type
, &orig_type
) ||
884 !is_better_type(©_reg
->type
, &mem_die
))
887 copy_reg
->type
= mem_die
;
889 pr_debug_dtp("var [%"PRIx64
"] copyback reg%d",
890 insn_offset
, reg
->copied_from
);
891 pr_debug_type_name(&mem_die
, TSR_KIND_TYPE
);
898 * update_insn_state - Update type state for an instruction
899 * @state: type state table
900 * @dloc: data location info
901 * @cu_die: compile unit debug entry
902 * @dl: disasm line for the instruction
904 * This function updates the @state table for the target operand of the
905 * instruction at @dl if it transfers the type like MOV on x86. Since it
906 * tracks the type, it won't care about the values like in arithmetic
907 * instructions like ADD/SUB/MUL/DIV and INC/DEC.
909 * Note that ops->reg2 is only available when both mem_ref and multi_regs
912 static void update_insn_state(struct type_state
*state
, struct data_loc_info
*dloc
,
913 Dwarf_Die
*cu_die
, struct disasm_line
*dl
)
915 if (dloc
->arch
->update_insn_state
)
916 dloc
->arch
->update_insn_state(state
, dloc
, cu_die
, dl
);
920 * Prepend this_blocks (from the outer scope) to full_blocks, removing
921 * duplicate disasm line.
923 static void prepend_basic_blocks(struct list_head
*this_blocks
,
924 struct list_head
*full_blocks
)
926 struct annotated_basic_block
*first_bb
, *last_bb
;
928 last_bb
= list_last_entry(this_blocks
, typeof(*last_bb
), list
);
929 first_bb
= list_first_entry(full_blocks
, typeof(*first_bb
), list
);
931 if (list_empty(full_blocks
))
934 /* Last insn in this_blocks should be same as first insn in full_blocks */
935 if (last_bb
->end
!= first_bb
->begin
) {
936 pr_debug("prepend basic blocks: mismatched disasm line %"PRIx64
" -> %"PRIx64
"\n",
937 last_bb
->end
->al
.offset
, first_bb
->begin
->al
.offset
);
941 /* Is the basic block have only one disasm_line? */
942 if (last_bb
->begin
== last_bb
->end
) {
943 list_del(&last_bb
->list
);
948 /* Point to the insn before the last when adding this block to full_blocks */
949 last_bb
->end
= list_prev_entry(last_bb
->end
, al
.node
);
952 list_splice(this_blocks
, full_blocks
);
955 static void delete_basic_blocks(struct list_head
*basic_blocks
)
957 struct annotated_basic_block
*bb
, *tmp
;
959 list_for_each_entry_safe(bb
, tmp
, basic_blocks
, list
) {
965 /* Make sure all variables have a valid start address */
966 static void fixup_var_address(struct die_var_type
*var_types
, u64 addr
)
970 * Some variables have no address range meaning it's always
971 * available in the whole scope. Let's adjust the start
972 * address to the start of the scope.
974 if (var_types
->addr
== 0)
975 var_types
->addr
= addr
;
977 var_types
= var_types
->next
;
981 static void delete_var_types(struct die_var_type
*var_types
)
984 struct die_var_type
*next
= var_types
->next
;
991 /* should match to is_stack_canary() in util/annotate.c */
992 static void setup_stack_canary(struct data_loc_info
*dloc
)
994 if (arch__is(dloc
->arch
, "x86")) {
995 dloc
->op
->segment
= INSN_SEG_X86_GS
;
996 dloc
->op
->imm
= true;
997 dloc
->op
->offset
= 40;
1002 * It's at the target address, check if it has a matching type.
1003 * It returns PERF_TMR_BAIL_OUT when it looks up per-cpu variables which
1004 * are similar to global variables and no additional info is needed.
1006 static enum type_match_result
check_matching_type(struct type_state
*state
,
1007 struct data_loc_info
*dloc
,
1009 struct disasm_line
*dl
,
1010 Dwarf_Die
*type_die
)
1013 u32 insn_offset
= dl
->al
.offset
;
1014 int reg
= dloc
->op
->reg1
;
1015 int offset
= dloc
->op
->offset
;
1016 const char *offset_sign
= "";
1025 pr_debug_dtp("chk [%x] reg%d offset=%s%#x ok=%d kind=%d ",
1026 insn_offset
, reg
, offset_sign
, offset
,
1027 state
->regs
[reg
].ok
, state
->regs
[reg
].kind
);
1029 if (!state
->regs
[reg
].ok
)
1030 goto check_non_register
;
1032 if (state
->regs
[reg
].kind
== TSR_KIND_TYPE
) {
1033 Dwarf_Die sized_type
;
1036 strbuf_init(&sb
, 32);
1037 die_get_typename_from_type(&state
->regs
[reg
].type
, &sb
);
1038 pr_debug_dtp("(%s)", sb
.buf
);
1039 strbuf_release(&sb
);
1042 * Normal registers should hold a pointer (or array) to
1043 * dereference a memory location.
1045 if (!is_pointer_type(&state
->regs
[reg
].type
)) {
1046 if (dloc
->op
->offset
< 0 && reg
!= state
->stack_reg
)
1049 return PERF_TMR_NO_POINTER
;
1052 /* Remove the pointer and get the target type */
1053 if (__die_get_real_type(&state
->regs
[reg
].type
, type_die
) == NULL
)
1054 return PERF_TMR_NO_POINTER
;
1056 dloc
->type_offset
= dloc
->op
->offset
;
1058 if (dwarf_tag(type_die
) == DW_TAG_typedef
)
1059 die_get_real_type(type_die
, &sized_type
);
1061 sized_type
= *type_die
;
1063 /* Get the size of the actual type */
1064 if (dwarf_aggregate_size(&sized_type
, &size
) < 0 ||
1065 (unsigned)dloc
->type_offset
>= size
)
1066 return PERF_TMR_BAD_OFFSET
;
1071 if (state
->regs
[reg
].kind
== TSR_KIND_POINTER
) {
1072 pr_debug_dtp("percpu ptr");
1075 * It's actaully pointer but the address was calculated using
1076 * some arithmetic. So it points to the actual type already.
1078 *type_die
= state
->regs
[reg
].type
;
1080 dloc
->type_offset
= dloc
->op
->offset
;
1082 /* Get the size of the actual type */
1083 if (dwarf_aggregate_size(type_die
, &size
) < 0 ||
1084 (unsigned)dloc
->type_offset
>= size
)
1085 return PERF_TMR_BAIL_OUT
;
1090 if (state
->regs
[reg
].kind
== TSR_KIND_CANARY
) {
1091 pr_debug_dtp("stack canary");
1094 * This is a saved value of the stack canary which will be handled
1095 * in the outer logic when it returns failure here. Pretend it's
1096 * from the stack canary directly.
1098 setup_stack_canary(dloc
);
1100 return PERF_TMR_BAIL_OUT
;
1103 if (state
->regs
[reg
].kind
== TSR_KIND_PERCPU_BASE
) {
1104 u64 var_addr
= dloc
->op
->offset
;
1107 pr_debug_dtp("percpu var");
1109 if (dloc
->op
->multi_regs
) {
1110 int reg2
= dloc
->op
->reg2
;
1112 if (dloc
->op
->reg2
== reg
)
1113 reg2
= dloc
->op
->reg1
;
1115 if (has_reg_type(state
, reg2
) && state
->regs
[reg2
].ok
&&
1116 state
->regs
[reg2
].kind
== TSR_KIND_CONST
)
1117 var_addr
+= state
->regs
[reg2
].imm_value
;
1120 if (get_global_var_type(cu_die
, dloc
, dloc
->ip
, var_addr
,
1121 &var_offset
, type_die
)) {
1122 dloc
->type_offset
= var_offset
;
1125 /* No need to retry per-cpu (global) variables */
1126 return PERF_TMR_BAIL_OUT
;
1130 if (reg
== dloc
->fbreg
) {
1131 struct type_state_stack
*stack
;
1133 pr_debug_dtp("fbreg");
1135 stack
= find_stack_state(state
, dloc
->type_offset
);
1136 if (stack
== NULL
) {
1138 pr_debug_dtp(" : retry\n");
1141 /* update type info it's the first store to the stack */
1142 update_insn_state(state
, dloc
, cu_die
, dl
);
1145 return PERF_TMR_NO_TYPE
;
1148 if (stack
->kind
== TSR_KIND_CANARY
) {
1149 setup_stack_canary(dloc
);
1150 return PERF_TMR_BAIL_OUT
;
1153 if (stack
->kind
!= TSR_KIND_TYPE
)
1154 return PERF_TMR_NO_TYPE
;
1156 *type_die
= stack
->type
;
1157 /* Update the type offset from the start of slot */
1158 dloc
->type_offset
-= stack
->offset
;
1164 struct type_state_stack
*stack
;
1165 u64 pc
= map__rip_2objdump(dloc
->ms
->map
, dloc
->ip
);
1168 pr_debug_dtp("cfa");
1170 if (die_get_cfa(dloc
->di
->dbg
, pc
, &fbreg
, &fboff
) < 0)
1174 return PERF_TMR_NO_TYPE
;
1176 stack
= find_stack_state(state
, dloc
->type_offset
- fboff
);
1177 if (stack
== NULL
) {
1179 pr_debug_dtp(" : retry\n");
1182 /* update type info it's the first store to the stack */
1183 update_insn_state(state
, dloc
, cu_die
, dl
);
1186 return PERF_TMR_NO_TYPE
;
1189 if (stack
->kind
== TSR_KIND_CANARY
) {
1190 setup_stack_canary(dloc
);
1191 return PERF_TMR_BAIL_OUT
;
1194 if (stack
->kind
!= TSR_KIND_TYPE
)
1195 return PERF_TMR_NO_TYPE
;
1197 *type_die
= stack
->type
;
1198 /* Update the type offset from the start of slot */
1199 dloc
->type_offset
-= fboff
+ stack
->offset
;
1205 if (dso__kernel(map__dso(dloc
->ms
->map
))) {
1208 /* Direct this-cpu access like "%gs:0x34740" */
1209 if (dloc
->op
->segment
== INSN_SEG_X86_GS
&& dloc
->op
->imm
&&
1210 arch__is(dloc
->arch
, "x86")) {
1211 pr_debug_dtp("this-cpu var");
1213 addr
= dloc
->op
->offset
;
1215 if (get_global_var_type(cu_die
, dloc
, dloc
->ip
, addr
,
1216 &offset
, type_die
)) {
1217 dloc
->type_offset
= offset
;
1220 return PERF_TMR_BAIL_OUT
;
1223 /* Access to global variable like "-0x7dcf0500(,%rdx,8)" */
1224 if (dloc
->op
->offset
< 0 && reg
!= state
->stack_reg
) {
1225 addr
= (s64
) dloc
->op
->offset
;
1227 if (get_global_var_type(cu_die
, dloc
, dloc
->ip
, addr
,
1228 &offset
, type_die
)) {
1229 pr_debug_dtp("global var");
1231 dloc
->type_offset
= offset
;
1234 return PERF_TMR_BAIL_OUT
;
1238 return PERF_TMR_UNKNOWN
;
1241 /* Iterate instructions in basic blocks and update type table */
1242 static enum type_match_result
find_data_type_insn(struct data_loc_info
*dloc
,
1243 struct list_head
*basic_blocks
,
1244 struct die_var_type
*var_types
,
1246 Dwarf_Die
*type_die
)
1248 struct type_state state
;
1249 struct symbol
*sym
= dloc
->ms
->sym
;
1250 struct annotation
*notes
= symbol__annotation(sym
);
1251 struct annotated_basic_block
*bb
;
1252 enum type_match_result ret
= PERF_TMR_UNKNOWN
;
1254 init_type_state(&state
, dloc
->arch
);
1256 list_for_each_entry(bb
, basic_blocks
, list
) {
1257 struct disasm_line
*dl
= bb
->begin
;
1259 BUG_ON(bb
->begin
->al
.offset
== -1 || bb
->end
->al
.offset
== -1);
1261 pr_debug_dtp("bb: [%"PRIx64
" - %"PRIx64
"]\n",
1262 bb
->begin
->al
.offset
, bb
->end
->al
.offset
);
1264 list_for_each_entry_from(dl
, ¬es
->src
->source
, al
.node
) {
1265 u64 this_ip
= sym
->start
+ dl
->al
.offset
;
1266 u64 addr
= map__rip_2objdump(dloc
->ms
->map
, this_ip
);
1268 /* Skip comment or debug info lines */
1269 if (dl
->al
.offset
== -1)
1272 /* Update variable type at this address */
1273 update_var_state(&state
, dloc
, addr
, dl
->al
.offset
, var_types
);
1275 if (this_ip
== dloc
->ip
) {
1276 ret
= check_matching_type(&state
, dloc
,
1277 cu_die
, dl
, type_die
);
1278 pr_debug_dtp(" : %s\n", match_result_str(ret
));
1282 /* Update type table after processing the instruction */
1283 update_insn_state(&state
, dloc
, cu_die
, dl
);
1290 exit_type_state(&state
);
1294 static int arch_supports_insn_tracking(struct data_loc_info
*dloc
)
1296 if ((arch__is(dloc
->arch
, "x86")) || (arch__is(dloc
->arch
, "powerpc")))
1302 * Construct a list of basic blocks for each scope with variables and try to find
1303 * the data type by updating a type state table through instructions.
1305 static enum type_match_result
find_data_type_block(struct data_loc_info
*dloc
,
1309 Dwarf_Die
*type_die
)
1311 LIST_HEAD(basic_blocks
);
1312 struct die_var_type
*var_types
= NULL
;
1313 u64 src_ip
, dst_ip
, prev_dst_ip
;
1314 enum type_match_result ret
= PERF_TMR_UNKNOWN
;
1316 /* TODO: other architecture support */
1317 if (!arch_supports_insn_tracking(dloc
))
1318 return PERF_TMR_BAIL_OUT
;
1320 prev_dst_ip
= dst_ip
= dloc
->ip
;
1321 for (int i
= nr_scopes
- 1; i
>= 0; i
--) {
1322 Dwarf_Addr base
, start
, end
;
1323 LIST_HEAD(this_blocks
);
1325 if (dwarf_ranges(&scopes
[i
], 0, &base
, &start
, &end
) < 0)
1328 pr_debug_dtp("scope: [%d/%d] ", i
+ 1, nr_scopes
);
1329 pr_debug_scope(&scopes
[i
]);
1331 src_ip
= map__objdump_2rip(dloc
->ms
->map
, start
);
1334 /* Get basic blocks for this scope */
1335 if (annotate_get_basic_blocks(dloc
->ms
->sym
, src_ip
, dst_ip
,
1336 &this_blocks
) < 0) {
1337 /* Try previous block if they are not connected */
1338 if (prev_dst_ip
!= dst_ip
) {
1339 dst_ip
= prev_dst_ip
;
1343 pr_debug_dtp("cannot find a basic block from %"PRIx64
" to %"PRIx64
"\n",
1344 src_ip
- dloc
->ms
->sym
->start
,
1345 dst_ip
- dloc
->ms
->sym
->start
);
1348 prepend_basic_blocks(&this_blocks
, &basic_blocks
);
1350 /* Get variable info for this scope and add to var_types list */
1351 die_collect_vars(&scopes
[i
], &var_types
);
1352 fixup_var_address(var_types
, start
);
1354 /* Find from start of this scope to the target instruction */
1355 ret
= find_data_type_insn(dloc
, &basic_blocks
, var_types
,
1357 if (ret
== PERF_TMR_OK
) {
1359 int offset
= dloc
->op
->offset
;
1360 const char *offset_sign
= "";
1367 if (dloc
->op
->multi_regs
)
1368 snprintf(buf
, sizeof(buf
), "reg%d, reg%d",
1369 dloc
->op
->reg1
, dloc
->op
->reg2
);
1371 snprintf(buf
, sizeof(buf
), "reg%d", dloc
->op
->reg1
);
1373 pr_debug_dtp("found by insn track: %s%#x(%s) type-offset=%#x\n",
1374 offset_sign
, offset
, buf
, dloc
->type_offset
);
1378 if (ret
== PERF_TMR_BAIL_OUT
)
1381 /* Go up to the next scope and find blocks to the start */
1382 prev_dst_ip
= dst_ip
;
1386 delete_basic_blocks(&basic_blocks
);
1387 delete_var_types(var_types
);
1391 /* The result will be saved in @type_die */
1392 static int find_data_type_die(struct data_loc_info
*dloc
, Dwarf_Die
*type_die
)
1394 struct annotated_op_loc
*loc
= dloc
->op
;
1395 Dwarf_Die cu_die
, var_die
;
1396 Dwarf_Die
*scopes
= NULL
;
1397 int reg
, offset
= loc
->offset
;
1402 bool is_fbreg
= false;
1406 enum type_match_result result
= PERF_TMR_UNKNOWN
;
1407 const char *offset_sign
= "";
1409 if (dloc
->op
->multi_regs
)
1410 snprintf(buf
, sizeof(buf
), "reg%d, reg%d", dloc
->op
->reg1
, dloc
->op
->reg2
);
1411 else if (dloc
->op
->reg1
== DWARF_REG_PC
)
1412 snprintf(buf
, sizeof(buf
), "PC");
1414 snprintf(buf
, sizeof(buf
), "reg%d", dloc
->op
->reg1
);
1421 pr_debug_dtp("-----------------------------------------------------------\n");
1422 pr_debug_dtp("find data type for %s%#x(%s) at %s+%#"PRIx64
"\n",
1423 offset_sign
, offset
, buf
,
1424 dloc
->ms
->sym
->name
, dloc
->ip
- dloc
->ms
->sym
->start
);
1427 * IP is a relative instruction address from the start of the map, as
1428 * it can be randomized/relocated, it needs to translate to PC which is
1429 * a file address for DWARF processing.
1431 pc
= map__rip_2objdump(dloc
->ms
->map
, dloc
->ip
);
1433 /* Get a compile_unit for this address */
1434 if (!find_cu_die(dloc
->di
, pc
, &cu_die
)) {
1435 pr_debug_dtp("cannot find CU for address %"PRIx64
"\n", pc
);
1436 ann_data_stat
.no_cuinfo
++;
1441 offset
= loc
->offset
;
1443 pr_debug_dtp("CU for %s (die:%#lx)\n",
1444 dwarf_diename(&cu_die
), (long)dwarf_dieoffset(&cu_die
));
1446 if (reg
== DWARF_REG_PC
) {
1447 if (get_global_var_type(&cu_die
, dloc
, dloc
->ip
, dloc
->var_addr
,
1448 &offset
, type_die
)) {
1449 dloc
->type_offset
= offset
;
1451 pr_debug_dtp("found by addr=%#"PRIx64
" type_offset=%#x\n",
1452 dloc
->var_addr
, offset
);
1453 pr_debug_type_name(type_die
, TSR_KIND_TYPE
);
1459 /* Get a list of nested scopes - i.e. (inlined) functions and blocks. */
1460 nr_scopes
= die_get_scopes(&cu_die
, pc
, &scopes
);
1462 if (reg
!= DWARF_REG_PC
&& dwarf_hasattr(&scopes
[0], DW_AT_frame_base
)) {
1463 Dwarf_Attribute attr
;
1466 /* Check if the 'reg' is assigned as frame base register */
1467 if (dwarf_attr(&scopes
[0], DW_AT_frame_base
, &attr
) != NULL
&&
1468 dwarf_formblock(&attr
, &block
) == 0 && block
.length
== 1) {
1469 switch (*block
.data
) {
1470 case DW_OP_reg0
... DW_OP_reg31
:
1471 fbreg
= dloc
->fbreg
= *block
.data
- DW_OP_reg0
;
1473 case DW_OP_call_frame_cfa
:
1474 dloc
->fb_cfa
= true;
1475 if (die_get_cfa(dloc
->di
->dbg
, pc
, &fbreg
,
1483 pr_debug_dtp("frame base: cfa=%d fbreg=%d\n",
1484 dloc
->fb_cfa
, fbreg
);
1489 is_fbreg
= (reg
== fbreg
);
1491 offset
= loc
->offset
- fb_offset
;
1493 /* Search from the inner-most scope to the outer */
1494 for (i
= nr_scopes
- 1; i
>= 0; i
--) {
1496 int type_offset
= offset
;
1498 if (reg
== DWARF_REG_PC
) {
1499 if (!die_find_variable_by_addr(&scopes
[i
], dloc
->var_addr
,
1500 &var_die
, &type_offset
))
1503 /* Look up variables/parameters in this scope */
1504 if (!die_find_variable_by_reg(&scopes
[i
], pc
, reg
,
1505 &type_offset
, is_fbreg
, &var_die
))
1509 pr_debug_dtp("found \"%s\" (die: %#lx) in scope=%d/%d (die: %#lx) ",
1510 dwarf_diename(&var_die
), (long)dwarf_dieoffset(&var_die
),
1511 i
+1, nr_scopes
, (long)dwarf_dieoffset(&scopes
[i
]));
1513 /* Found a variable, see if it's correct */
1514 result
= check_variable(dloc
, &var_die
, &mem_die
, reg
, type_offset
, is_fbreg
);
1515 if (result
== PERF_TMR_OK
) {
1516 if (reg
== DWARF_REG_PC
) {
1517 pr_debug_dtp("addr=%#"PRIx64
" type_offset=%#x\n",
1518 dloc
->var_addr
, type_offset
);
1519 } else if (reg
== DWARF_REG_FB
|| is_fbreg
) {
1520 pr_debug_dtp("stack_offset=%#x type_offset=%#x\n",
1521 fb_offset
, type_offset
);
1523 pr_debug_dtp("type_offset=%#x\n", type_offset
);
1526 if (!found
|| is_better_type(type_die
, &mem_die
)) {
1527 *type_die
= mem_die
;
1528 dloc
->type_offset
= type_offset
;
1532 pr_debug_dtp("failed: %s\n", match_result_str(result
));
1535 pr_debug_location(&var_die
, pc
, reg
);
1536 pr_debug_type_name(&mem_die
, TSR_KIND_TYPE
);
1539 if (!found
&& loc
->multi_regs
&& reg
== loc
->reg1
&& loc
->reg1
!= loc
->reg2
) {
1544 if (!found
&& reg
!= DWARF_REG_PC
) {
1545 result
= find_data_type_block(dloc
, &cu_die
, scopes
,
1546 nr_scopes
, type_die
);
1547 if (result
== PERF_TMR_OK
) {
1548 ann_data_stat
.insn_track
++;
1554 pr_debug_dtp("final result: ");
1556 pr_debug_type_name(type_die
, TSR_KIND_TYPE
);
1560 case PERF_TMR_NO_TYPE
:
1561 case PERF_TMR_NO_POINTER
:
1562 pr_debug_dtp("%s\n", match_result_str(result
));
1563 ann_data_stat
.no_typeinfo
++;
1565 case PERF_TMR_NO_SIZE
:
1566 pr_debug_dtp("%s\n", match_result_str(result
));
1567 ann_data_stat
.invalid_size
++;
1569 case PERF_TMR_BAD_OFFSET
:
1570 pr_debug_dtp("%s\n", match_result_str(result
));
1571 ann_data_stat
.bad_offset
++;
1573 case PERF_TMR_UNKNOWN
:
1574 case PERF_TMR_BAIL_OUT
:
1575 case PERF_TMR_OK
: /* should not reach here */
1577 pr_debug_dtp("no variable found\n");
1578 ann_data_stat
.no_var
++;
1589 * find_data_type - Return a data type at the location
1590 * @dloc: data location
1592 * This functions searches the debug information of the binary to get the data
1593 * type it accesses. The exact location is expressed by (ip, reg, offset)
1594 * for pointer variables or (ip, addr) for global variables. Note that global
1595 * variables might update the @dloc->type_offset after finding the start of the
1596 * variable. If it cannot find a global variable by address, it tried to find
1597 * a declaration of the variable using var_name. In that case, @dloc->offset
1600 * It return %NULL if not found.
1602 struct annotated_data_type
*find_data_type(struct data_loc_info
*dloc
)
1604 struct dso
*dso
= map__dso(dloc
->ms
->map
);
1608 * The type offset is the same as instruction offset by default.
1609 * But when finding a global variable, the offset won't be valid.
1611 dloc
->type_offset
= dloc
->op
->offset
;
1615 if (find_data_type_die(dloc
, &type_die
) < 0)
1618 return dso__findnew_data_type(dso
, &type_die
);
1621 static int alloc_data_type_histograms(struct annotated_data_type
*adt
, int nr_entries
)
1624 size_t sz
= sizeof(struct type_hist
);
1626 sz
+= sizeof(struct type_hist_entry
) * adt
->self
.size
;
1628 /* Allocate a table of pointers for each event */
1629 adt
->histograms
= calloc(nr_entries
, sizeof(*adt
->histograms
));
1630 if (adt
->histograms
== NULL
)
1634 * Each histogram is allocated for the whole size of the type.
1635 * TODO: Probably we can move the histogram to members.
1637 for (i
= 0; i
< nr_entries
; i
++) {
1638 adt
->histograms
[i
] = zalloc(sz
);
1639 if (adt
->histograms
[i
] == NULL
)
1643 adt
->nr_histograms
= nr_entries
;
1648 zfree(&(adt
->histograms
[i
]));
1649 zfree(&adt
->histograms
);
1653 static void delete_data_type_histograms(struct annotated_data_type
*adt
)
1655 for (int i
= 0; i
< adt
->nr_histograms
; i
++)
1656 zfree(&(adt
->histograms
[i
]));
1658 zfree(&adt
->histograms
);
1659 adt
->nr_histograms
= 0;
1662 void annotated_data_type__tree_delete(struct rb_root
*root
)
1664 struct annotated_data_type
*pos
;
1666 while (!RB_EMPTY_ROOT(root
)) {
1667 struct rb_node
*node
= rb_first(root
);
1669 rb_erase(node
, root
);
1670 pos
= rb_entry(node
, struct annotated_data_type
, node
);
1671 delete_members(&pos
->self
);
1672 delete_data_type_histograms(pos
);
1673 zfree(&pos
->self
.type_name
);
1679 * annotated_data_type__update_samples - Update histogram
1680 * @adt: Data type to update
1681 * @evsel: Event to update
1682 * @offset: Offset in the type
1683 * @nr_samples: Number of samples at this offset
1684 * @period: Event count at this offset
1686 * This function updates type histogram at @ofs for @evsel. Samples are
1687 * aggregated before calling this function so it can be called with more
1688 * than one samples at a certain offset.
1690 int annotated_data_type__update_samples(struct annotated_data_type
*adt
,
1691 struct evsel
*evsel
, int offset
,
1692 int nr_samples
, u64 period
)
1694 struct type_hist
*h
;
1699 if (adt
->histograms
== NULL
) {
1700 int nr
= evsel
->evlist
->core
.nr_entries
;
1702 if (alloc_data_type_histograms(adt
, nr
) < 0)
1706 if (offset
< 0 || offset
>= adt
->self
.size
)
1709 h
= adt
->histograms
[evsel
->core
.idx
];
1711 h
->nr_samples
+= nr_samples
;
1712 h
->addr
[offset
].nr_samples
+= nr_samples
;
1713 h
->period
+= period
;
1714 h
->addr
[offset
].period
+= period
;
1718 static void print_annotated_data_header(struct hist_entry
*he
, struct evsel
*evsel
)
1720 struct dso
*dso
= map__dso(he
->ms
.map
);
1722 int nr_samples
= he
->stat
.nr_events
;
1724 const char *val_hdr
= "Percent";
1726 if (evsel__is_group_event(evsel
)) {
1727 struct hist_entry
*pair
;
1729 list_for_each_entry(pair
, &he
->pairs
.head
, pairs
.node
)
1730 nr_samples
+= pair
->stat
.nr_events
;
1733 printf("Annotate type: '%s' in %s (%d samples):\n",
1734 he
->mem_type
->self
.type_name
, dso__name(dso
), nr_samples
);
1736 if (evsel__is_group_event(evsel
)) {
1741 for_each_group_evsel(pos
, evsel
) {
1742 if (symbol_conf
.skip_empty
&&
1743 evsel__hists(pos
)->stats
.nr_samples
== 0)
1746 printf(" event[%d] = %s\n", i
++, pos
->name
);
1751 if (symbol_conf
.show_total_period
) {
1754 } else if (symbol_conf
.show_nr_samples
) {
1756 val_hdr
= "Samples";
1759 printf("============================================================================\n");
1760 printf("%*s %10s %10s %s\n", (width
+ 1) * nr_members
, val_hdr
,
1761 "offset", "size", "field");
1764 static void print_annotated_data_value(struct type_hist
*h
, u64 period
, int nr_samples
)
1766 double percent
= h
->period
? (100.0 * period
/ h
->period
) : 0;
1767 const char *color
= get_percent_color(percent
);
1769 if (symbol_conf
.show_total_period
)
1770 color_fprintf(stdout
, color
, " %11" PRIu64
, period
);
1771 else if (symbol_conf
.show_nr_samples
)
1772 color_fprintf(stdout
, color
, " %7d", nr_samples
);
1774 color_fprintf(stdout
, color
, " %7.2f", percent
);
1777 static void print_annotated_data_type(struct annotated_data_type
*mem_type
,
1778 struct annotated_member
*member
,
1779 struct evsel
*evsel
, int indent
)
1781 struct annotated_member
*child
;
1782 struct type_hist
*h
= mem_type
->histograms
[evsel
->core
.idx
];
1783 int i
, nr_events
= 0, samples
= 0;
1785 int width
= symbol_conf
.show_total_period
? 11 : 7;
1788 for_each_group_evsel(pos
, evsel
) {
1789 h
= mem_type
->histograms
[pos
->core
.idx
];
1791 if (symbol_conf
.skip_empty
&&
1792 evsel__hists(pos
)->stats
.nr_samples
== 0)
1797 for (i
= 0; i
< member
->size
; i
++) {
1798 samples
+= h
->addr
[member
->offset
+ i
].nr_samples
;
1799 period
+= h
->addr
[member
->offset
+ i
].period
;
1801 print_annotated_data_value(h
, period
, samples
);
1805 printf(" %#10x %#10x %*s%s\t%s",
1806 member
->offset
, member
->size
, indent
, "", member
->type_name
,
1807 member
->var_name
?: "");
1809 if (!list_empty(&member
->children
))
1812 list_for_each_entry(child
, &member
->children
, node
)
1813 print_annotated_data_type(mem_type
, child
, evsel
, indent
+ 4);
1815 if (!list_empty(&member
->children
))
1816 printf("%*s}", (width
+ 1) * nr_events
+ 24 + indent
, "");
1820 int hist_entry__annotate_data_tty(struct hist_entry
*he
, struct evsel
*evsel
)
1822 print_annotated_data_header(he
, evsel
);
1823 print_annotated_data_type(he
->mem_type
, &he
->mem_type
->self
, evsel
, 0);
1826 /* move to the next entry */