diff options
author | Leo Yan <leo.yan@linaro.org> | 2023-06-06 09:45:55 +0800 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2023-08-16 08:46:45 -0300 |
commit | 34af56afacd82ed585ad9cfc51a3a783ad371b26 (patch) | |
tree | 96fb0d911fe0e7c5ca35be55cf7b5f277b33217e /tools/perf/util/perf_regs.c | |
parent | perf parse-regs: Refactor arch register parsing functions (diff) | |
download | linux-34af56afacd82ed585ad9cfc51a3a783ad371b26.tar.gz linux-34af56afacd82ed585ad9cfc51a3a783ad371b26.tar.bz2 linux-34af56afacd82ed585ad9cfc51a3a783ad371b26.zip |
perf parse-regs: Introduce functions perf_arch_reg_{ip|sp}()
The current code uses macros PERF_REG_IP and PERF_REG_SP for parsing
registers and we build perf with these macros statically, which means it
only can correctly analyze CPU registers for the native architecture and
fails to support cross analysis (e.g. we build perf on x86 and cannot
analyze Arm64's registers).
We need to generalize util/perf_regs.c for support multi architectures,
as a first step, this commit introduces new functions perf_arch_reg_ip()
and perf_arch_reg_sp(), these two functions dynamically return IP and SP
register index respectively according to the parameter "arch".
Every architecture has its own functions (like __perf_reg_ip_arm64 and
__perf_reg_sp_arm64), these architecture specific functions are defined
in each arch source file under folder util/perf-regs-arch; at the end
all of them are built into the tool for cross analysis.
Committer notes:
Make DWARF_MINIMAL_REGS() an inline function, so that we can use the
__maybe_unused attribute for the 'arch' parameter, as this will avoid a
build failure when that variable is unused in the callers. That happens
when building on unsupported architectures, the ones without
HAVE_PERF_REGS_SUPPORT defined.
Signed-off-by: Leo Yan <leo.yan@linaro.org>
Acked-by: Ian Rogers <irogers@google.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Albert Ou <aou@eecs.berkeley.edu>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Eric Lin <eric.lin@sifive.com>
Cc: Fangrui Song <maskray@google.com>
Cc: Guo Ren <guoren@kernel.org>
Cc: Huacai Chen <chenhuacai@kernel.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Ivan Babrou <ivan@cloudflare.com>
Cc: James Clark <james.clark@arm.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: John Garry <john.g.garry@oracle.com>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Mike Leach <mike.leach@linaro.org>
Cc: Ming Wang <wangming01@loongson.cn>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Palmer Dabbelt <palmer@dabbelt.com>
Cc: Paul Walmsley <paul.walmsley@sifive.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Sandipan Das <sandipan.das@amd.com>
Cc: Will Deacon <will@kernel.org>
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-csky@vger.kernel.org
Cc: linux-riscv@lists.infradead.org
Link: https://lore.kernel.org/r/20230606014559.21783-3-leo.yan@linaro.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/util/perf_regs.c')
-rw-r--r-- | tools/perf/util/perf_regs.c | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/tools/perf/util/perf_regs.c b/tools/perf/util/perf_regs.c index 5af1b95c3d01..23584efd4886 100644 --- a/tools/perf/util/perf_regs.c +++ b/tools/perf/util/perf_regs.c @@ -3,6 +3,7 @@ #include <string.h> #include "perf_regs.h" #include "util/sample.h" +#include "debug.h" int __weak arch_sdt_arg_parse_op(char *old_op __maybe_unused, char **new_op __maybe_unused) @@ -74,4 +75,55 @@ out: *valp = regs->cache_regs[id]; return 0; } + +uint64_t perf_arch_reg_ip(const char *arch) +{ + if (!strcmp(arch, "arm")) + return __perf_reg_ip_arm(); + else if (!strcmp(arch, "arm64")) + return __perf_reg_ip_arm64(); + else if (!strcmp(arch, "csky")) + return __perf_reg_ip_csky(); + else if (!strcmp(arch, "loongarch")) + return __perf_reg_ip_loongarch(); + else if (!strcmp(arch, "mips")) + return __perf_reg_ip_mips(); + else if (!strcmp(arch, "powerpc")) + return __perf_reg_ip_powerpc(); + else if (!strcmp(arch, "riscv")) + return __perf_reg_ip_riscv(); + else if (!strcmp(arch, "s390")) + return __perf_reg_ip_s390(); + else if (!strcmp(arch, "x86")) + return __perf_reg_ip_x86(); + + pr_err("Fail to find IP register for arch %s, returns 0\n", arch); + return 0; +} + +uint64_t perf_arch_reg_sp(const char *arch) +{ + if (!strcmp(arch, "arm")) + return __perf_reg_sp_arm(); + else if (!strcmp(arch, "arm64")) + return __perf_reg_sp_arm64(); + else if (!strcmp(arch, "csky")) + return __perf_reg_sp_csky(); + else if (!strcmp(arch, "loongarch")) + return __perf_reg_sp_loongarch(); + else if (!strcmp(arch, "mips")) + return __perf_reg_sp_mips(); + else if (!strcmp(arch, "powerpc")) + return __perf_reg_sp_powerpc(); + else if (!strcmp(arch, "riscv")) + return __perf_reg_sp_riscv(); + else if (!strcmp(arch, "s390")) + return __perf_reg_sp_s390(); + else if (!strcmp(arch, "x86")) + return __perf_reg_sp_x86(); + + pr_err("Fail to find SP register for arch %s, returns 0\n", arch); + return 0; +} + #endif |