Thread (73 messages) 73 messages, 5 authors, 19d ago

Re: [PATCH v5 13/26] perf annotate-arm64: Enable instruction tracking support

From: Tengda Wu <hidden>
Date: 2026-09-10 09:20:14
Also in: sashiko-reviews


On 2026/9/8 21:18, sashiko-bot@kernel.org wrote:
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] Incomplete initialization of ARM64 caller-saved registers in init_type_state() misses x30 (Link Register) and x18. According to the ARM64 AAPCS64 ABI, x30 is intrinsically caller-saved (it is clobbered by function calls to store the return address), and x18 is also a temporary/caller-saved register (unless strictly reserved by a platform ABI). Because these registers are omitted during initialization, their `caller_saved` flags remain `false`. Consequently, their data type states are not invalidated across function calls, allowing stale type info to erroneously propagate.
--

commit 7f29650747bf4bd656328dd491ef0f827ab60d8c
Author: Tengda Wu [off-list ref]

perf annotate-arm64: Enable instruction tracking support

Enable basic instruction tracking for arm64 by implementing three
essential functions in the find_data_type_block() call path. This
allows arm64 to support basic variable type inference during
instruction tracking.
quoted
diff --git a/tools/perf/util/annotate-arch/annotate-arm64.c b/tools/perf/util/annotate-arch/annotate-arm64.c
index d8a5904359b1a..8fda4d4d68887 100644
--- a/tools/perf/util/annotate-arch/annotate-arm64.c
+++ b/tools/perf/util/annotate-arch/annotate-arm64.c
[ ... ]
quoted
@@ -442,6 +446,77 @@ static void extract_op_location_arm64(const struct arch *arch,
[ ... ]
quoted
+	if (ins__is_call(&dl->ins)) {
+		struct symbol *func = dl->ops.target.sym;
+		const char *call_name;
+		u64 call_addr;
+
+		call_name = func ? func->name : dl->ops.target.name;
+		pr_debug_dtp("call [%x] %s\n", insn_offset, call_name ?: "<unknown>");
+
+		/* Invalidate caller-saved registers after call */
+		call_addr = map__rip_2objdump(dloc->ms->map,
+					      dloc->ms->sym->start + dl->al.offset);
+		for (unsigned int i = 0; i < ARRAY_SIZE(state->regs); i++) {
+			struct type_state_reg *reg = &state->regs[i];
+
+			if (!reg->caller_saved)
+				continue;
[Severity: Medium]
Because x30 and x18 are omitted from being marked as caller-saved during type
state initialization, their caller_saved flags will be false.

Are these registers unintentionally skipped here, preventing them from being
invalidated across function calls?
quoted
+			/* Keep register valid within DWARF location lifetime */
+			if (reg->lifetime_active && call_addr < reg->lifetime_end)
+				continue;
+			invalidate_reg_state(reg);
+		}
+		return;
+	}
[ ... ]
quoted
diff --git a/tools/perf/util/annotate-data.c b/tools/perf/util/annotate-data.c
index 104b80d471f1b..c51b20a7af9b6 100644
--- a/tools/perf/util/annotate-data.c
+++ b/tools/perf/util/annotate-data.c
[ ... ]
quoted
@@ -178,6 +179,13 @@ static void init_type_state(struct type_state *state, const struct arch *arch)
 		state->regs[11].caller_saved = true;
 		state->ret_reg = 0;
 		state->stack_reg = X86_REG_SP;
+	} else if (arch__is_arm64(arch)) {
+		int i;
+
+		for (i = 0; i < 18; i++)
+			state->regs[i].caller_saved = true;
[Severity: Medium]
According to the ARM64 AAPCS64 ABI, x30 (Link Register) is intrinsically
caller-saved since it is clobbered by function calls to store the return
address.

x18 is also typically a temporary/caller-saved register unless strictly reserved
by a platform ABI.

This loop halts at 17, failing to set the caller_saved flag for x18 and x30.

Could this omission allow stale data type information for these registers to
erroneously propagate across function calls?
x18 does need to be set as caller-saved, but x30 is not really necessary, because
it generally serves as LR and is not used to carry data type information.
So I'm going to add only x18.

Thanks,
Tengda
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help