aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tools/perf/util/annotate-data.c27
1 files changed, 19 insertions, 8 deletions
diff --git a/tools/perf/util/annotate-data.c b/tools/perf/util/annotate-data.c
index e53d66c46c54..12d5faff3b7a 100644
--- a/tools/perf/util/annotate-data.c
+++ b/tools/perf/util/annotate-data.c
@@ -25,6 +25,9 @@
#include "symbol_conf.h"
#include "thread.h"
+/* register number of the stack pointer */
+#define X86_REG_SP 7
+
enum type_state_kind {
TSR_KIND_INVALID = 0,
TSR_KIND_TYPE,
@@ -197,7 +200,7 @@ static void init_type_state(struct type_state *state, struct arch *arch)
state->regs[10].caller_saved = true;
state->regs[11].caller_saved = true;
state->ret_reg = 0;
- state->stack_reg = 7;
+ state->stack_reg = X86_REG_SP;
}
}
@@ -382,10 +385,18 @@ static bool find_cu_die(struct debuginfo *di, u64 pc, Dwarf_Die *cu_die)
}
/* The type info will be saved in @type_die */
-static int check_variable(Dwarf_Die *var_die, Dwarf_Die *type_die, int offset,
- bool is_pointer)
+static int check_variable(struct data_loc_info *dloc, Dwarf_Die *var_die,
+ Dwarf_Die *type_die, int reg, int offset, bool is_fbreg)
{
Dwarf_Word size;
+ bool is_pointer = true;
+
+ if (reg == DWARF_REG_PC)
+ is_pointer = false;
+ else if (reg == dloc->fbreg || is_fbreg)
+ is_pointer = false;
+ else if (arch__is(dloc->arch, "x86") && reg == X86_REG_SP)
+ is_pointer = false;
/* Get the type of the variable */
if (die_get_real_type(var_die, type_die) == NULL) {
@@ -607,7 +618,6 @@ static bool get_global_var_type(Dwarf_Die *cu_die, struct data_loc_info *dloc,
{
u64 pc;
int offset;
- bool is_pointer = false;
const char *var_name = NULL;
struct global_var_entry *gvar;
Dwarf_Die var_die;
@@ -623,7 +633,8 @@ static bool get_global_var_type(Dwarf_Die *cu_die, struct data_loc_info *dloc,
/* Try to get the variable by address first */
if (die_find_variable_by_addr(cu_die, var_addr, &var_die, &offset) &&
- check_variable(&var_die, type_die, offset, is_pointer) == 0) {
+ check_variable(dloc, &var_die, type_die, DWARF_REG_PC, offset,
+ /*is_fbreg=*/false) == 0) {
var_name = dwarf_diename(&var_die);
*var_offset = offset;
goto ok;
@@ -636,7 +647,8 @@ static bool get_global_var_type(Dwarf_Die *cu_die, struct data_loc_info *dloc,
/* Try to get the name of global variable */
if (die_find_variable_at(cu_die, var_name, pc, &var_die) &&
- check_variable(&var_die, type_die, *var_offset, is_pointer) == 0)
+ check_variable(dloc, &var_die, type_die, DWARF_REG_PC, *var_offset,
+ /*is_fbreg=*/false) == 0)
goto ok;
return false;
@@ -1587,8 +1599,7 @@ retry:
}
/* Found a variable, see if it's correct */
- ret = check_variable(&var_die, type_die, offset,
- reg != DWARF_REG_PC && !is_fbreg);
+ ret = check_variable(dloc, &var_die, type_die, reg, offset, is_fbreg);
if (ret == 0) {
pr_debug_dtp("found \"%s\" in scope=%d/%d (die: %#lx) ",
dwarf_diename(&var_die), i+1, nr_scopes,