From cf7c7f12042b9e9dfb7e63c9c3180b6af1860b2b Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Fri, 16 Jan 2026 21:28:39 -0800 Subject: [PATCH] perf dwarf-regs: Add basic get_dwarf_regnum() for most architectures MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Add a basic get_dwarf_regnum() implementation for most architectures by using the get_dwarf_regstr() tables and returning the index of the name within the table. Some minor name and constification clean up for csky. Signed-off-by: Ian Rogers Cc: Aditya Bodkhe Cc: Adrian Hunter Cc: Albert Ou Cc: Alexandre Ghiti Cc: Andi Kleen Cc: Athira Rajeev Cc: Chun-Tse Shao Cc: Dmitriy Vyukov Cc: Dr. David Alan Gilbert Cc: Guo Ren Cc: Haibo Xu Cc: Howard Chu Cc: Ingo Molnar Cc: James Clark Cc: Jiri Olsa Cc: John Garry Cc: Krzysztof Łopatowski Cc: Leo Yan Cc: Mark Wielaard Cc: Namhyung Kim Cc: Palmer Dabbelt Cc: Paul Walmsley Cc: Peter Zijlstra Cc: Sergei Trofimovich Cc: Shimin Guo Cc: Stephen Brennan Cc: Thomas Falcon Cc: Will Deacon Signed-off-by: Arnaldo Carvalho de Melo --- .../util/dwarf-regs-arch/dwarf-regs-csky.c | 24 +++++++- tools/perf/util/dwarf-regs.c | 58 +++++++++++++++++-- tools/perf/util/include/dwarf-regs.h | 5 +- 3 files changed, 78 insertions(+), 9 deletions(-) diff --git a/tools/perf/util/dwarf-regs-arch/dwarf-regs-csky.c b/tools/perf/util/dwarf-regs-arch/dwarf-regs-csky.c index d38ef1f07f3e3..86394ed46397d 100644 --- a/tools/perf/util/dwarf-regs-arch/dwarf-regs-csky.c +++ b/tools/perf/util/dwarf-regs-arch/dwarf-regs-csky.c @@ -2,11 +2,12 @@ // Copyright (C) 2019 Hangzhou C-SKY Microsystems co.,ltd. // Mapping of DWARF debug register numbers into register names. +#include #include #include #define CSKY_ABIV2_MAX_REGS 73 -const char *csky_dwarf_regs_table_abiv2[CSKY_ABIV2_MAX_REGS] = { +static const char * const csky_dwarf_regs_table_abiv2[CSKY_ABIV2_MAX_REGS] = { /* r0 ~ r8 */ "%a0", "%a1", "%a2", "%a3", "%regs0", "%regs1", "%regs2", "%regs3", /* r9 ~ r15 */ @@ -27,7 +28,7 @@ const char *csky_dwarf_regs_table_abiv2[CSKY_ABIV2_MAX_REGS] = { }; #define CSKY_ABIV1_MAX_REGS 57 -const char *csky_dwarf_regs_table_abiv1[CSKY_ABIV1_MAX_REGS] = { +static const char * const csky_dwarf_regs_table_abiv1[CSKY_ABIV1_MAX_REGS] = { /* r0 ~ r8 */ "%sp", "%regs9", "%a0", "%a1", "%a2", "%a3", "%regs0", "%regs1", /* r9 ~ r15 */ @@ -41,10 +42,27 @@ const char *csky_dwarf_regs_table_abiv1[CSKY_ABIV1_MAX_REGS] = { "%epc", }; -const char *get_csky_regstr(unsigned int n, unsigned int flags) +const char *__get_csky_regstr(unsigned int n, unsigned int flags) { if (flags & EF_CSKY_ABIV2) return (n < CSKY_ABIV2_MAX_REGS) ? csky_dwarf_regs_table_abiv2[n] : NULL; return (n < CSKY_ABIV1_MAX_REGS) ? csky_dwarf_regs_table_abiv1[n] : NULL; } + +static int __get_dwarf_regnum(const char *const *regstr, size_t num_regstr, const char *name) +{ + for (size_t i = 0; i < num_regstr; i++) { + if (regstr[i] && !strcmp(regstr[i], name)) + return i; + } + return -ENOENT; +} + +int __get_csky_regnum(const char *name, unsigned int flags) +{ + if (flags & EF_CSKY_ABIV2) + return __get_dwarf_regnum(csky_dwarf_regs_table_abiv2, CSKY_ABIV2_MAX_REGS, name); + + return __get_dwarf_regnum(csky_dwarf_regs_table_abiv1, CSKY_ABIV1_MAX_REGS, name); +} diff --git a/tools/perf/util/dwarf-regs.c b/tools/perf/util/dwarf-regs.c index 1f7d892612dfe..dffa0c8bdd145 100644 --- a/tools/perf/util/dwarf-regs.c +++ b/tools/perf/util/dwarf-regs.c @@ -27,11 +27,11 @@ #include "../arch/mips/include/dwarf-regs-table.h" #include "../arch/loongarch/include/dwarf-regs-table.h" -#define __get_dwarf_regstr(tbl, n) (((n) < ARRAY_SIZE(tbl)) ? (tbl)[(n)] : NULL) - /* Return architecture dependent register string (for kprobe-tracer) */ const char *get_dwarf_regstr(unsigned int n, unsigned int machine, unsigned int flags) { + #define __get_dwarf_regstr(tbl, n) (((n) < ARRAY_SIZE(tbl)) ? (tbl)[(n)] : NULL) + if (machine == EM_NONE) { /* Generic arch - use host arch */ machine = EM_HOST; @@ -46,7 +46,7 @@ const char *get_dwarf_regstr(unsigned int n, unsigned int machine, unsigned int case EM_AARCH64: return __get_dwarf_regstr(aarch64_regstr_tbl, n); case EM_CSKY: - return get_csky_regstr(n, flags); + return __get_csky_regstr(n, flags); case EM_SH: return __get_dwarf_regstr(sh_regstr_tbl, n); case EM_S390: @@ -69,15 +69,28 @@ const char *get_dwarf_regstr(unsigned int n, unsigned int machine, unsigned int pr_err("ELF MACHINE %x is not supported.\n", machine); } return NULL; + + #undef __get_dwarf_regstr +} + +static int __get_dwarf_regnum(const char *const *regstr, size_t num_regstr, const char *name) +{ + for (size_t i = 0; i < num_regstr; i++) { + if (regstr[i] && !strcmp(regstr[i], name)) + return i; + } + return -ENOENT; } /* Return DWARF register number from architecture register name */ -int get_dwarf_regnum(const char *name, unsigned int machine, unsigned int flags __maybe_unused) +int get_dwarf_regnum(const char *name, unsigned int machine, unsigned int flags) { char *regname = strdup(name); int reg = -1; char *p; + #define _get_dwarf_regnum(tbl, name) __get_dwarf_regnum(tbl, ARRAY_SIZE(tbl), name) + if (regname == NULL) return -EINVAL; @@ -97,11 +110,48 @@ int get_dwarf_regnum(const char *name, unsigned int machine, unsigned int flags case EM_386: reg = __get_dwarf_regnum_i386(name); break; + case EM_ARM: + reg = _get_dwarf_regnum(arm_regstr_tbl, name); + break; + case EM_AARCH64: + reg = _get_dwarf_regnum(aarch64_regstr_tbl, name); + break; + case EM_CSKY: + reg = __get_csky_regnum(name, flags); + break; + case EM_SH: + reg = _get_dwarf_regnum(sh_regstr_tbl, name); + break; + case EM_S390: + reg = _get_dwarf_regnum(s390_regstr_tbl, name); + break; + case EM_PPC: + case EM_PPC64: + reg = _get_dwarf_regnum(powerpc_regstr_tbl, name); + break; + case EM_RISCV: + reg = _get_dwarf_regnum(riscv_regstr_tbl, name); + break; + case EM_SPARC: + case EM_SPARCV9: + reg = _get_dwarf_regnum(sparc_regstr_tbl, name); + break; + case EM_XTENSA: + reg = _get_dwarf_regnum(xtensa_regstr_tbl, name); + break; + case EM_MIPS: + reg = _get_dwarf_regnum(mips_regstr_tbl, name); + break; + case EM_LOONGARCH: + reg = _get_dwarf_regnum(loongarch_regstr_tbl, name); + break; default: pr_err("ELF MACHINE %x is not supported.\n", machine); } free(regname); return reg; + + #undef _get_dwarf_regnum } static int get_libdw_frame_nregs(unsigned int machine, unsigned int flags __maybe_unused) diff --git a/tools/perf/util/include/dwarf-regs.h b/tools/perf/util/include/dwarf-regs.h index 00881f1d45d6f..a120c97a5fac8 100644 --- a/tools/perf/util/include/dwarf-regs.h +++ b/tools/perf/util/include/dwarf-regs.h @@ -89,8 +89,6 @@ #define DWARF_REG_FB 0xd3affb /* random number */ #ifdef HAVE_LIBDW_SUPPORT -const char *get_csky_regstr(unsigned int n, unsigned int flags); - /** * get_dwarf_regstr() - Returns ftrace register string from DWARF regnum. * @n: DWARF register number. @@ -99,6 +97,9 @@ const char *get_csky_regstr(unsigned int n, unsigned int flags); */ const char *get_dwarf_regstr(unsigned int n, unsigned int machine, unsigned int flags); +const char *__get_csky_regstr(unsigned int n, unsigned int flags); +int __get_csky_regnum(const char *name, unsigned int flags); + int __get_dwarf_regnum_i386(const char *name); int __get_dwarf_regnum_x86_64(const char *name); int __get_dwarf_regnum_for_perf_regnum_i386(int perf_regnum); -- 2.47.3