[PATCH v2 06/16] perf dwarf-regs: Adapt get_dwarf_regnum() for arm64
From: Tengda Wu
Date: Fri Apr 03 2026 - 05:54:10 EST
The current arm64 DWARF register lookup relies on 'aarch64_regstr_tbl',
a static string table. While this works for kprobe-tracer where register
names start with '%', it is insufficient for parsing register numbers
directly from raw instructions (e.g., extracting '6' from 'x6' or 'w6')
during annotation.
Since get_dwarf_regnum() is currently used only by 'perf annotate' and
does not affect kprobe-tracer, replace the limited table-based lookup
with a programmatic implementation in __get_dwarf_regnum_arm64(). This
allows resolving arm64 register names (x0-x30, w0-w30, sp, etc.) directly
into their corresponding DWARF register numbers.
Signed-off-by: Tengda Wu <wutengda@xxxxxxxxxxxxxxx>
---
.../util/dwarf-regs-arch/dwarf-regs-arm64.c | 20 +++++++++++++++++++
tools/perf/util/dwarf-regs.c | 2 +-
tools/perf/util/include/dwarf-regs.h | 1 +
3 files changed, 22 insertions(+), 1 deletion(-)
diff --git a/tools/perf/util/dwarf-regs-arch/dwarf-regs-arm64.c b/tools/perf/util/dwarf-regs-arch/dwarf-regs-arm64.c
index 593ca7d4fccc..be55fc2a4f38 100644
--- a/tools/perf/util/dwarf-regs-arch/dwarf-regs-arm64.c
+++ b/tools/perf/util/dwarf-regs-arch/dwarf-regs-arm64.c
@@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
#include <errno.h>
+#include <ctype.h>
#include <dwarf-regs.h>
#include "../../../arch/arm64/include/uapi/asm/perf_regs.h"
@@ -10,3 +11,22 @@ int __get_dwarf_regnum_for_perf_regnum_arm64(int perf_regnum)
return perf_regnum;
}
+
+int __get_dwarf_regnum_arm64(const char *name)
+{
+ int reg;
+
+ if (!strcmp(name, "sp") || !strcmp(name, "wzr") || !strcmp(name, "xzr"))
+ return 31;
+
+ if (*name != 'x' && *name != 'w')
+ return -ENOENT;
+
+ name++;
+ if (!isdigit(*name))
+ return -ENOENT;
+
+ reg = strtol(name, NULL, 10);
+
+ return reg >= 0 && reg <= 30 ? reg : -ENOENT;
+}
diff --git a/tools/perf/util/dwarf-regs.c b/tools/perf/util/dwarf-regs.c
index 797f455eba0d..bacf5c13c3bc 100644
--- a/tools/perf/util/dwarf-regs.c
+++ b/tools/perf/util/dwarf-regs.c
@@ -114,7 +114,7 @@ int get_dwarf_regnum(const char *name, unsigned int machine, unsigned int flags)
reg = _get_dwarf_regnum(arm_regstr_tbl, name);
break;
case EM_AARCH64:
- reg = _get_dwarf_regnum(aarch64_regstr_tbl, name);
+ reg = __get_dwarf_regnum_arm64(name);
break;
case EM_CSKY:
reg = __get_csky_regnum(name, flags);
diff --git a/tools/perf/util/include/dwarf-regs.h b/tools/perf/util/include/dwarf-regs.h
index 46a764cf322f..a25f038bbff2 100644
--- a/tools/perf/util/include/dwarf-regs.h
+++ b/tools/perf/util/include/dwarf-regs.h
@@ -105,6 +105,7 @@ int __get_dwarf_regnum_x86_64(const char *name);
int __get_dwarf_regnum_for_perf_regnum_i386(int perf_regnum);
int __get_dwarf_regnum_for_perf_regnum_x86_64(int perf_regnum);
+int __get_dwarf_regnum_arm64(const char *name);
int __get_dwarf_regnum_for_perf_regnum_arm(int perf_regnum);
int __get_dwarf_regnum_for_perf_regnum_arm64(int perf_regnum);
--
2.34.1