perf annotate-data: Handle direct use of stack pointer without fbreg

Sometimes compiler generates code to use the stack pointer register
without frame pointer.  As we know RSP is the stack register on x86,
let's treat it as same as fbreg.  But the offset would be opposite
direction so update the debug message accordingly.

Reported-by: Blake Jones <blakejones@google.com>
Link: https://lore.kernel.org/r/20250126210242.1181225-1-namhyung@kernel.org
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
This commit is contained in:
Namhyung Kim 2025-01-26 13:02:42 -08:00
parent c40aa8d98d
commit f4dc5a3355
2 changed files with 26 additions and 11 deletions

View File

@ -410,7 +410,7 @@ static void update_insn_state_x86(struct type_state *state,
retry:
/* Check stack variables with offset */
if (sreg == fbreg) {
if (sreg == fbreg || sreg == state->stack_reg) {
struct type_state_stack *stack;
int offset = src->offset - fboff;
@ -433,8 +433,13 @@ static void update_insn_state_x86(struct type_state *state,
return;
}
pr_debug_dtp("mov [%x] -%#x(stack) -> reg%d",
insn_offset, -offset, dst->reg1);
if (sreg == fbreg) {
pr_debug_dtp("mov [%x] -%#x(stack) -> reg%d",
insn_offset, -offset, dst->reg1);
} else {
pr_debug_dtp("mov [%x] %#x(reg%d) -> reg%d",
insn_offset, offset, sreg, dst->reg1);
}
pr_debug_type_name(&tsr->type, tsr->kind);
}
/* And then dereference the pointer if it has one */
@ -561,7 +566,7 @@ static void update_insn_state_x86(struct type_state *state,
return;
/* Check stack variables with offset */
if (dst->reg1 == fbreg) {
if (dst->reg1 == fbreg || dst->reg1 == state->stack_reg) {
struct type_state_stack *stack;
int offset = dst->offset - fboff;
@ -584,8 +589,13 @@ static void update_insn_state_x86(struct type_state *state,
&tsr->type);
}
pr_debug_dtp("mov [%x] reg%d -> -%#x(stack)",
insn_offset, src->reg1, -offset);
if (dst->reg1 == fbreg) {
pr_debug_dtp("mov [%x] reg%d -> -%#x(stack)",
insn_offset, src->reg1, -offset);
} else {
pr_debug_dtp("mov [%x] reg%d -> %#x(reg%d)",
insn_offset, src->reg1, offset, dst->reg1);
}
pr_debug_type_name(&tsr->type, tsr->kind);
}
/*

View File

@ -830,7 +830,7 @@ static void update_var_state(struct type_state *state, struct data_loc_info *dlo
if (!dwarf_offdie(dloc->di->dbg, var->die_off, &mem_die))
continue;
if (var->reg == DWARF_REG_FB || var->reg == fbreg) {
if (var->reg == DWARF_REG_FB || var->reg == fbreg || var->reg == state->stack_reg) {
int offset = var->offset;
struct type_state_stack *stack;
@ -845,8 +845,13 @@ static void update_var_state(struct type_state *state, struct data_loc_info *dlo
findnew_stack_state(state, offset, TSR_KIND_TYPE,
&mem_die);
pr_debug_dtp("var [%"PRIx64"] -%#x(stack)",
insn_offset, -offset);
if (var->reg == state->stack_reg) {
pr_debug_dtp("var [%"PRIx64"] %#x(reg%d)",
insn_offset, offset, state->stack_reg);
} else {
pr_debug_dtp("var [%"PRIx64"] -%#x(stack)",
insn_offset, -offset);
}
pr_debug_type_name(&mem_die, TSR_KIND_TYPE);
} else if (has_reg_type(state, var->reg) && var->offset == 0) {
struct type_state_reg *reg;
@ -1127,10 +1132,10 @@ static enum type_match_result check_matching_type(struct type_state *state,
}
check_non_register:
if (reg == dloc->fbreg) {
if (reg == dloc->fbreg || reg == state->stack_reg) {
struct type_state_stack *stack;
pr_debug_dtp("fbreg");
pr_debug_dtp("%s", reg == dloc->fbreg ? "fbreg" : "stack");
stack = find_stack_state(state, dloc->type_offset);
if (stack == NULL) {