[RFC PATCH v1 4/5] perf annotate: Wire up ARM64 data type profiling infrastructure
From: Shuai Xue
Date: Tue Jun 23 2026 - 09:07:59 EST
Add ARM64 support to the core dispatch and initialization points:
1. annotate_get_insn_location(): Add an arm64 branch alongside the
existing powerpc branch to call get_arm64_regs() for extracting
register numbers and memory offsets from raw instructions.
2. arch_supports_insn_tracking(): Include arm64 so that
find_data_type_block() can perform instruction-level type state
tracking on ARM64.
3. init_type_state(): Add arm64 branch to set caller-saved registers
(x0-x18 per AAPCS64) and stack register (SP, DWARF reg 31).
Without this, stack_reg defaults to 0 (x0) after memset, causing
x0-based memory accesses to be misidentified as stack accesses.
Signed-off-by: Shuai Xue <xueshuai@xxxxxxxxxxxxxxxxx>
---
tools/perf/util/annotate-data.c | 18 +++++++++++++++++-
tools/perf/util/annotate.c | 12 ++++++++----
2 files changed, 25 insertions(+), 5 deletions(-)
diff --git a/tools/perf/util/annotate-data.c b/tools/perf/util/annotate-data.c
index 1eff0a27237d..c04ad66ff077 100644
--- a/tools/perf/util/annotate-data.c
+++ b/tools/perf/util/annotate-data.c
@@ -29,6 +29,11 @@
/* register number of the stack pointer */
#define X86_REG_SP 7
+/* ARM64 DWARF register numbers: x0-x30=0-30, SP=31 */
+#define ARM64_REG_SP 31
+#define ARM64_REG_LR 30
+#define ARM64_REG_FP 29
+
static void delete_var_types(struct die_var_type *var_types);
#define pr_debug_dtp(fmt, ...) \
@@ -178,6 +183,16 @@ static void init_type_state(struct type_state *state, const struct arch *arch)
state->ret_reg = 0;
state->stack_reg = X86_REG_SP;
}
+
+ if (arch__is_arm64(arch)) {
+ int i;
+
+ /* ARM64 ABI: x0-x18 are caller-saved */
+ for (i = 0; i <= 18; i++)
+ state->regs[i].caller_saved = true;
+ state->ret_reg = 0;
+ state->stack_reg = ARM64_REG_SP;
+ }
}
static void exit_type_state(struct type_state *state)
@@ -1421,7 +1436,8 @@ static enum type_match_result find_data_type_insn(struct data_loc_info *dloc,
static int arch_supports_insn_tracking(struct data_loc_info *dloc)
{
- if ((arch__is_x86(dloc->arch)) || (arch__is_powerpc(dloc->arch)))
+ if ((arch__is_x86(dloc->arch)) || (arch__is_powerpc(dloc->arch)) ||
+ (arch__is_arm64(dloc->arch)))
return 1;
return 0;
}
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index e745f3034a0e..bd734826538d 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -2574,19 +2574,23 @@ int annotate_get_insn_location(const struct arch *arch, struct disasm_line *dl,
op_loc->reg2 = -1;
if (insn_str == NULL) {
- if (!arch__is_powerpc(arch))
+ if (!arch__is_powerpc(arch) && !arch__is_arm64(arch))
continue;
}
/*
- * For powerpc, call get_powerpc_regs function which extracts the
- * required fields for op_loc, ie reg1, reg2, offset from the
- * raw instruction.
+ * For powerpc and arm64, call arch-specific functions to
+ * extract the required fields for op_loc (reg1, reg2, offset)
+ * from the raw instruction.
*/
if (arch__is_powerpc(arch)) {
op_loc->mem_ref = mem_ref;
op_loc->multi_regs = multi_regs;
get_powerpc_regs(dl->raw.raw_insn, !i, op_loc);
+ } else if (arch__is_arm64(arch)) {
+ op_loc->mem_ref = mem_ref;
+ op_loc->multi_regs = multi_regs;
+ get_arm64_regs(dl->raw.raw_insn, !i, op_loc);
} else if (strchr(insn_str, arch->objdump.memory_ref_char)) {
op_loc->mem_ref = true;
op_loc->multi_regs = multi_regs;
--
2.51.2.612.gdc70283dfc