From 109218718de2f7173fabdd507cc6786e79ad1690 Mon Sep 17 00:00:00 2001 From: Zecheng Li Date: Mon, 13 Oct 2025 18:16:01 +0000 Subject: [PATCH] perf annotate: Save pointer offset in stack state The tracked pointer offset was not being preserved in the stack state, which could lead to incorrect type analysis. This change adds a ptr_offset field to the type_state_stack struct and passes it to set_stack_state and findnew_stack_state to ensure the offset is preserved after the pointer is loaded from a stack location. It improves the type annotation coverage and quality. Signed-off-by: Zecheng Li Signed-off-by: Namhyung Kim --- tools/perf/arch/x86/annotate/instructions.c | 6 +++--- tools/perf/util/annotate-data.c | 12 +++++++----- tools/perf/util/annotate-data.h | 7 +++++-- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/tools/perf/arch/x86/annotate/instructions.c b/tools/perf/arch/x86/annotate/instructions.c index def7729a394c9..0c87e42ca3dc2 100644 --- a/tools/perf/arch/x86/annotate/instructions.c +++ b/tools/perf/arch/x86/annotate/instructions.c @@ -541,7 +541,7 @@ retry: } else if (!stack->compound) { tsr->type = stack->type; tsr->kind = stack->kind; - tsr->offset = 0; + tsr->offset = stack->ptr_offset; tsr->ok = true; } else if (die_get_member_type(&stack->type, offset - stack->offset, @@ -724,10 +724,10 @@ retry: */ if (!stack->compound) set_stack_state(stack, offset, tsr->kind, - &tsr->type); + &tsr->type, tsr->offset); } else { findnew_stack_state(state, offset, tsr->kind, - &tsr->type); + &tsr->type, tsr->offset); } if (dst->reg1 == fbreg) { diff --git a/tools/perf/util/annotate-data.c b/tools/perf/util/annotate-data.c index 4204a7956ee5a..e183c6104d594 100644 --- a/tools/perf/util/annotate-data.c +++ b/tools/perf/util/annotate-data.c @@ -577,7 +577,7 @@ struct type_state_stack *find_stack_state(struct type_state *state, } void set_stack_state(struct type_state_stack *stack, int offset, u8 kind, - Dwarf_Die *type_die) + Dwarf_Die *type_die, int ptr_offset) { int tag; Dwarf_Word size; @@ -592,6 +592,7 @@ void set_stack_state(struct type_state_stack *stack, int offset, u8 kind, stack->type = *type_die; stack->size = size; stack->offset = offset; + stack->ptr_offset = ptr_offset; stack->kind = kind; if (kind == TSR_KIND_POINTER) { @@ -614,18 +615,19 @@ void set_stack_state(struct type_state_stack *stack, int offset, u8 kind, struct type_state_stack *findnew_stack_state(struct type_state *state, int offset, u8 kind, - Dwarf_Die *type_die) + Dwarf_Die *type_die, + int ptr_offset) { struct type_state_stack *stack = find_stack_state(state, offset); if (stack) { - set_stack_state(stack, offset, kind, type_die); + set_stack_state(stack, offset, kind, type_die, ptr_offset); return stack; } stack = malloc(sizeof(*stack)); if (stack) { - set_stack_state(stack, offset, kind, type_die); + set_stack_state(stack, offset, kind, type_die, ptr_offset); list_add(&stack->list, &state->stack_vars); } return stack; @@ -895,7 +897,7 @@ static void update_var_state(struct type_state *state, struct data_loc_info *dlo continue; findnew_stack_state(state, offset, TSR_KIND_TYPE, - &mem_die); + &mem_die, /*ptr_offset=*/0); if (var->reg == state->stack_reg) { pr_debug_dtp("var [%"PRIx64"] %#x(reg%d)", diff --git a/tools/perf/util/annotate-data.h b/tools/perf/util/annotate-data.h index 14655b76db65a..869307c7f1300 100644 --- a/tools/perf/util/annotate-data.h +++ b/tools/perf/util/annotate-data.h @@ -191,6 +191,8 @@ struct type_state_stack { struct list_head list; Dwarf_Die type; int offset; + /* pointer offset, saves tsr->offset on the stack state */ + int ptr_offset; int size; bool compound; u8 kind; @@ -247,9 +249,10 @@ int annotated_data_type__get_member_name(struct annotated_data_type *adt, bool has_reg_type(struct type_state *state, int reg); struct type_state_stack *findnew_stack_state(struct type_state *state, int offset, u8 kind, - Dwarf_Die *type_die); + Dwarf_Die *type_die, + int ptr_offset); void set_stack_state(struct type_state_stack *stack, int offset, u8 kind, - Dwarf_Die *type_die); + Dwarf_Die *type_die, int ptr_offset); struct type_state_stack *find_stack_state(struct type_state *state, int offset); bool get_global_var_type(Dwarf_Die *cu_die, struct data_loc_info *dloc, -- 2.47.3