summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/perf/util/annotate-data.c39
-rw-r--r--tools/perf/util/dwarf-aux.c2
-rw-r--r--tools/perf/util/dwarf-aux.h2
3 files changed, 33 insertions, 10 deletions
diff --git a/tools/perf/util/annotate-data.c b/tools/perf/util/annotate-data.c
index f125ac5f0bda..c18272092a6b 100644
--- a/tools/perf/util/annotate-data.c
+++ b/tools/perf/util/annotate-data.c
@@ -217,8 +217,13 @@ static int __add_member_cb(Dwarf_Die *die, void *arg)
strbuf_init(&sb, 32);
die_get_typename(die, &sb);
- die_get_real_type(die, &member_type);
- if (dwarf_aggregate_size(&member_type, &size) < 0)
+ __die_get_real_type(die, &member_type);
+ if (dwarf_tag(&member_type) == DW_TAG_typedef)
+ die_get_real_type(&member_type, &die_mem);
+ else
+ die_mem = member_type;
+
+ if (dwarf_aggregate_size(&die_mem, &size) < 0)
size = 0;
if (!dwarf_attr_integrate(die, DW_AT_data_member_location, &attr))
@@ -235,11 +240,11 @@ static int __add_member_cb(Dwarf_Die *die, void *arg)
INIT_LIST_HEAD(&member->children);
list_add_tail(&member->node, &parent->children);
- tag = dwarf_tag(&member_type);
+ tag = dwarf_tag(&die_mem);
switch (tag) {
case DW_TAG_structure_type:
case DW_TAG_union_type:
- die_find_child(&member_type, __add_member_cb, member, &die_mem);
+ die_find_child(&die_mem, __add_member_cb, member, &die_mem);
break;
default:
break;
@@ -281,6 +286,10 @@ static struct annotated_data_type *dso__findnew_data_type(struct dso *dso,
if (die_get_typename_from_type(type_die, &sb) < 0)
strbuf_add(&sb, "(unknown type)", 14);
type_name = strbuf_detach(&sb, NULL);
+
+ if (dwarf_tag(type_die) == DW_TAG_typedef)
+ die_get_real_type(type_die, type_die);
+
dwarf_aggregate_size(type_die, &size);
/* Check existing nodes in dso->data_types tree */
@@ -342,6 +351,7 @@ static int check_variable(struct data_loc_info *dloc, Dwarf_Die *var_die,
{
Dwarf_Word size;
bool is_pointer = true;
+ Dwarf_Die sized_type;
if (reg == DWARF_REG_PC)
is_pointer = false;
@@ -351,7 +361,7 @@ static int check_variable(struct data_loc_info *dloc, Dwarf_Die *var_die,
is_pointer = false;
/* Get the type of the variable */
- if (die_get_real_type(var_die, type_die) == NULL) {
+ if (__die_get_real_type(var_die, type_die) == NULL) {
pr_debug_dtp("variable has no type\n");
ann_data_stat.no_typeinfo++;
return -1;
@@ -365,15 +375,20 @@ static int check_variable(struct data_loc_info *dloc, Dwarf_Die *var_die,
if (is_pointer) {
if ((dwarf_tag(type_die) != DW_TAG_pointer_type &&
dwarf_tag(type_die) != DW_TAG_array_type) ||
- die_get_real_type(type_die, type_die) == NULL) {
+ __die_get_real_type(type_die, type_die) == NULL) {
pr_debug_dtp("no pointer or no type\n");
ann_data_stat.no_typeinfo++;
return -1;
}
}
+ if (dwarf_tag(type_die) == DW_TAG_typedef)
+ die_get_real_type(type_die, &sized_type);
+ else
+ sized_type = *type_die;
+
/* Get the size of the actual type */
- if (dwarf_aggregate_size(type_die, &size) < 0) {
+ if (dwarf_aggregate_size(&sized_type, &size) < 0) {
pr_debug_dtp("type size is unknown\n");
ann_data_stat.invalid_size++;
return -1;
@@ -846,6 +861,7 @@ static int check_matching_type(struct type_state *state,
if (state->regs[reg].ok && state->regs[reg].kind == TSR_KIND_TYPE) {
int tag = dwarf_tag(&state->regs[reg].type);
+ Dwarf_Die sized_type;
/*
* Normal registers should hold a pointer (or array) to
@@ -862,13 +878,18 @@ static int check_matching_type(struct type_state *state,
pr_debug_dtp("\n");
/* Remove the pointer and get the target type */
- if (die_get_real_type(&state->regs[reg].type, type_die) == NULL)
+ if (__die_get_real_type(&state->regs[reg].type, type_die) == NULL)
return -1;
dloc->type_offset = dloc->op->offset;
+ if (dwarf_tag(type_die) == DW_TAG_typedef)
+ die_get_real_type(type_die, &sized_type);
+ else
+ sized_type = *type_die;
+
/* Get the size of the actual type */
- if (dwarf_aggregate_size(type_die, &size) < 0 ||
+ if (dwarf_aggregate_size(&sized_type, &size) < 0 ||
(unsigned)dloc->type_offset >= size)
return -1;
diff --git a/tools/perf/util/dwarf-aux.c b/tools/perf/util/dwarf-aux.c
index 44ef968a7ad3..5e080d7e22c2 100644
--- a/tools/perf/util/dwarf-aux.c
+++ b/tools/perf/util/dwarf-aux.c
@@ -267,7 +267,7 @@ Dwarf_Die *die_get_type(Dwarf_Die *vr_die, Dwarf_Die *die_mem)
}
/* Get a type die, but skip qualifiers */
-static Dwarf_Die *__die_get_real_type(Dwarf_Die *vr_die, Dwarf_Die *die_mem)
+Dwarf_Die *__die_get_real_type(Dwarf_Die *vr_die, Dwarf_Die *die_mem)
{
int tag;
diff --git a/tools/perf/util/dwarf-aux.h b/tools/perf/util/dwarf-aux.h
index 24446412b869..336a3a183a78 100644
--- a/tools/perf/util/dwarf-aux.h
+++ b/tools/perf/util/dwarf-aux.h
@@ -56,6 +56,8 @@ const char *die_get_decl_file(Dwarf_Die *dw_die);
/* Get type die */
Dwarf_Die *die_get_type(Dwarf_Die *vr_die, Dwarf_Die *die_mem);
+/* Get a type die, but skip qualifiers */
+Dwarf_Die *__die_get_real_type(Dwarf_Die *vr_die, Dwarf_Die *die_mem);
/* Get a type die, but skip qualifiers and typedef */
Dwarf_Die *die_get_real_type(Dwarf_Die *vr_die, Dwarf_Die *die_mem);