From 7c132a86ec56a6974875aeae7b350635b94b3a13 Mon Sep 17 00:00:00 2001 From: Tengda Wu Date: Tue, 20 Oct 2026 13:45:00 +0000 Subject: [PATCH] perf annotate-arm64: Track return type after call instructions Enable data type profiling to track function return values in arm64 annotations by looking up the DWARF return type of called functions. Reviewed-by: Ian Rogers Reviewed-by: Namhyung Kim Signed-off-by: Tengda Wu Signed-off-by: Arnaldo Carvalho de Melo --- .../perf/util/annotate-arch/annotate-arm64.c | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/tools/perf/util/annotate-arch/annotate-arm64.c b/tools/perf/util/annotate-arch/annotate-arm64.c index d591d556ad40..c4cc8bca85cc 100644 --- a/tools/perf/util/annotate-arch/annotate-arm64.c +++ b/tools/perf/util/annotate-arch/annotate-arm64.c @@ -463,12 +463,14 @@ static bool is_readonly_insn(const char *name) } static void update_call_insn_state(struct type_state *state, - struct data_loc_info *dloc, + struct data_loc_info *dloc, Dwarf_Die *cu_die, struct disasm_line *dl) { struct symbol *func = dl->ops.target.sym; const char *call_name; u64 call_addr; + struct type_state_reg *tsr; + Dwarf_Die type_die; u32 insn_offset = dl->al.offset; call_name = func ? func->name : dl->ops.target.name; @@ -487,6 +489,19 @@ static void update_call_insn_state(struct type_state *state, continue; invalidate_reg_state(reg); } + + /* Update register with the return type (if any) */ + if (call_name && die_find_func_rettype(cu_die, call_name, &type_die)) { + tsr = &state->regs[state->ret_reg]; + invalidate_reg_state(tsr); + tsr->type = type_die; + tsr->kind = TSR_KIND_TYPE; + tsr->offset = 0; + tsr->ok = true; + + pr_debug_dtp("call [%x] return -> reg%d", insn_offset, state->ret_reg); + pr_debug_type_name(&type_die, tsr->kind); + } } /* Invalidate registers explicitly written by an unhandled instruction. */ @@ -513,7 +528,7 @@ static void invalidate_unhandled_insn_regs(struct type_state *state, } static void update_insn_state_arm64(struct type_state *state, - struct data_loc_info *dloc, Dwarf_Die *cu_die __maybe_unused, + struct data_loc_info *dloc, Dwarf_Die *cu_die, struct disasm_line *dl) { struct annotated_insn_loc loc; @@ -526,7 +541,7 @@ static void update_insn_state_arm64(struct type_state *state, return; if (ins__is_call(&dl->ins)) - update_call_insn_state(state, dloc, dl); + update_call_insn_state(state, dloc, cu_die, dl); else invalidate_unhandled_insn_regs(state, dl, dst); }