aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorNamhyung Kim <namhyung@kernel.org>2025-01-26 13:02:42 -0800
committerNamhyung Kim <namhyung@kernel.org>2025-02-26 13:42:49 -0800
commitf4dc5a3355a84f53ff3287d496728c7b77160069 (patch)
treeb9f060a407c2f1398fdbaf33eef241d4916df9dd
parentperf report: Fix sample number stats for branch entry mode (diff)
downloadwireguard-linux-f4dc5a3355a84f53ff3287d496728c7b77160069.tar.xz
wireguard-linux-f4dc5a3355a84f53ff3287d496728c7b77160069.zip
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>
-rw-r--r--tools/perf/arch/x86/annotate/instructions.c22
-rw-r--r--tools/perf/util/annotate-data.c15
2 files changed, 26 insertions, 11 deletions
diff --git a/tools/perf/arch/x86/annotate/instructions.c b/tools/perf/arch/x86/annotate/instructions.c
index ae94b1f0b9cc..c6d403eae744 100644
--- a/tools/perf/arch/x86/annotate/instructions.c
+++ b/tools/perf/arch/x86/annotate/instructions.c
@@ -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 @@ retry:
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 @@ retry:
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 @@ retry:
&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);
}
/*
diff --git a/tools/perf/util/annotate-data.c b/tools/perf/util/annotate-data.c
index 976abedca09e..eaf96fa80c83 100644
--- a/tools/perf/util/annotate-data.c
+++ b/tools/perf/util/annotate-data.c
@@ -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 @@ again:
}
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) {