summaryrefslogtreecommitdiff
path: root/tools/perf/util/perf_regs.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/perf_regs.c')
-rw-r--r--tools/perf/util/perf_regs.c227
1 files changed, 172 insertions, 55 deletions
diff --git a/tools/perf/util/perf_regs.c b/tools/perf/util/perf_regs.c
index 44b90bbf2d07..f52b0e1f7fc7 100644
--- a/tools/perf/util/perf_regs.c
+++ b/tools/perf/util/perf_regs.c
@@ -1,59 +1,168 @@
// SPDX-License-Identifier: GPL-2.0
+#include <elf.h>
#include <errno.h>
#include <string.h>
+#include "dwarf-regs.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)
+int perf_sdt_arg_parse_op(uint16_t e_machine, char *old_op, char **new_op)
{
- return SDT_ARG_SKIP;
-}
+ int ret = SDT_ARG_SKIP;
+
+ switch (e_machine) {
+ case EM_AARCH64:
+ ret = __perf_sdt_arg_parse_op_arm64(old_op, new_op);
+ break;
+ case EM_PPC:
+ case EM_PPC64:
+ ret = __perf_sdt_arg_parse_op_powerpc(old_op, new_op);
+ break;
+ case EM_386:
+ case EM_X86_64:
+ ret = __perf_sdt_arg_parse_op_x86(old_op, new_op);
+ break;
+ case EM_S390:
+ ret = __perf_sdt_arg_parse_op_s390(old_op, new_op);
+ break;
+ default:
+ pr_debug("Unknown ELF machine %d, standard arguments parse will be skipped.\n",
+ e_machine);
+ break;
+ }
-uint64_t __weak arch__intr_reg_mask(void)
-{
- return 0;
+ return ret;
}
-uint64_t __weak arch__user_reg_mask(void)
+uint64_t perf_intr_reg_mask(uint16_t e_machine)
{
- return 0;
-}
+ uint64_t mask = 0;
+
+ switch (e_machine) {
+ case EM_ARM:
+ mask = __perf_reg_mask_arm(/*intr=*/true);
+ break;
+ case EM_AARCH64:
+ mask = __perf_reg_mask_arm64(/*intr=*/true);
+ break;
+ case EM_CSKY:
+ mask = __perf_reg_mask_csky(/*intr=*/true);
+ break;
+ case EM_LOONGARCH:
+ mask = __perf_reg_mask_loongarch(/*intr=*/true);
+ break;
+ case EM_MIPS:
+ mask = __perf_reg_mask_mips(/*intr=*/true);
+ break;
+ case EM_PPC:
+ case EM_PPC64:
+ mask = __perf_reg_mask_powerpc(/*intr=*/true);
+ break;
+ case EM_RISCV:
+ mask = __perf_reg_mask_riscv(/*intr=*/true);
+ break;
+ case EM_S390:
+ mask = __perf_reg_mask_s390(/*intr=*/true);
+ break;
+ case EM_386:
+ case EM_X86_64:
+ mask = __perf_reg_mask_x86(/*intr=*/true);
+ break;
+ default:
+ pr_debug("Unknown ELF machine %d, interrupt sampling register mask will be empty.\n",
+ e_machine);
+ break;
+ }
-static const struct sample_reg sample_reg_masks[] = {
- SMPL_REG_END
-};
+ return mask;
+}
-const struct sample_reg * __weak arch__sample_reg_masks(void)
+uint64_t perf_user_reg_mask(uint16_t e_machine)
{
- return sample_reg_masks;
+ uint64_t mask = 0;
+
+ switch (e_machine) {
+ case EM_ARM:
+ mask = __perf_reg_mask_arm(/*intr=*/false);
+ break;
+ case EM_AARCH64:
+ mask = __perf_reg_mask_arm64(/*intr=*/false);
+ break;
+ case EM_CSKY:
+ mask = __perf_reg_mask_csky(/*intr=*/false);
+ break;
+ case EM_LOONGARCH:
+ mask = __perf_reg_mask_loongarch(/*intr=*/false);
+ break;
+ case EM_MIPS:
+ mask = __perf_reg_mask_mips(/*intr=*/false);
+ break;
+ case EM_PPC:
+ case EM_PPC64:
+ mask = __perf_reg_mask_powerpc(/*intr=*/false);
+ break;
+ case EM_RISCV:
+ mask = __perf_reg_mask_riscv(/*intr=*/false);
+ break;
+ case EM_S390:
+ mask = __perf_reg_mask_s390(/*intr=*/false);
+ break;
+ case EM_386:
+ case EM_X86_64:
+ mask = __perf_reg_mask_x86(/*intr=*/false);
+ break;
+ default:
+ pr_debug("Unknown ELF machine %d, user sampling register mask will be empty.\n",
+ e_machine);
+ break;
+ }
+
+ return mask;
}
-const char *perf_reg_name(int id, const char *arch)
+const char *perf_reg_name(int id, uint16_t e_machine, uint32_t e_flags)
{
const char *reg_name = NULL;
- if (!strcmp(arch, "csky"))
- reg_name = __perf_reg_name_csky(id);
- else if (!strcmp(arch, "loongarch"))
+ switch (e_machine) {
+ case EM_ARM:
+ reg_name = __perf_reg_name_arm(id);
+ break;
+ case EM_AARCH64:
+ reg_name = __perf_reg_name_arm64(id);
+ break;
+ case EM_CSKY:
+ reg_name = __perf_reg_name_csky(id, e_flags);
+ break;
+ case EM_LOONGARCH:
reg_name = __perf_reg_name_loongarch(id);
- else if (!strcmp(arch, "mips"))
+ break;
+ case EM_MIPS:
reg_name = __perf_reg_name_mips(id);
- else if (!strcmp(arch, "powerpc"))
+ break;
+ case EM_PPC:
+ case EM_PPC64:
reg_name = __perf_reg_name_powerpc(id);
- else if (!strcmp(arch, "riscv"))
+ break;
+ case EM_RISCV:
reg_name = __perf_reg_name_riscv(id);
- else if (!strcmp(arch, "s390"))
+ break;
+ case EM_S390:
reg_name = __perf_reg_name_s390(id);
- else if (!strcmp(arch, "x86"))
+ break;
+ case EM_386:
+ case EM_X86_64:
reg_name = __perf_reg_name_x86(id);
- else if (!strcmp(arch, "arm"))
- reg_name = __perf_reg_name_arm(id);
- else if (!strcmp(arch, "arm64"))
- reg_name = __perf_reg_name_arm64(id);
+ break;
+ default:
+ break;
+ }
+ if (reg_name)
+ return reg_name;
- return reg_name ?: "unknown";
+ pr_debug("Failed to find register %d for ELF machine type %u\n", id, e_machine);
+ return "unknown";
}
int perf_reg_value(u64 *valp, struct regs_dump *regs, int id)
@@ -83,52 +192,60 @@ out:
return 0;
}
-uint64_t perf_arch_reg_ip(const char *arch)
+uint64_t perf_arch_reg_ip(uint16_t e_machine)
{
- if (!strcmp(arch, "arm"))
+ switch (e_machine) {
+ case EM_ARM:
return __perf_reg_ip_arm();
- else if (!strcmp(arch, "arm64"))
+ case EM_AARCH64:
return __perf_reg_ip_arm64();
- else if (!strcmp(arch, "csky"))
+ case EM_CSKY:
return __perf_reg_ip_csky();
- else if (!strcmp(arch, "loongarch"))
+ case EM_LOONGARCH:
return __perf_reg_ip_loongarch();
- else if (!strcmp(arch, "mips"))
+ case EM_MIPS:
return __perf_reg_ip_mips();
- else if (!strcmp(arch, "powerpc"))
+ case EM_PPC:
+ case EM_PPC64:
return __perf_reg_ip_powerpc();
- else if (!strcmp(arch, "riscv"))
+ case EM_RISCV:
return __perf_reg_ip_riscv();
- else if (!strcmp(arch, "s390"))
+ case EM_S390:
return __perf_reg_ip_s390();
- else if (!strcmp(arch, "x86"))
+ case EM_386:
+ case EM_X86_64:
return __perf_reg_ip_x86();
-
- pr_err("Fail to find IP register for arch %s, returns 0\n", arch);
- return 0;
+ default:
+ pr_err("Failed to find IP register for ELF machine type %u\n", e_machine);
+ return 0;
+ }
}
-uint64_t perf_arch_reg_sp(const char *arch)
+uint64_t perf_arch_reg_sp(uint16_t e_machine)
{
- if (!strcmp(arch, "arm"))
+ switch (e_machine) {
+ case EM_ARM:
return __perf_reg_sp_arm();
- else if (!strcmp(arch, "arm64"))
+ case EM_AARCH64:
return __perf_reg_sp_arm64();
- else if (!strcmp(arch, "csky"))
+ case EM_CSKY:
return __perf_reg_sp_csky();
- else if (!strcmp(arch, "loongarch"))
+ case EM_LOONGARCH:
return __perf_reg_sp_loongarch();
- else if (!strcmp(arch, "mips"))
+ case EM_MIPS:
return __perf_reg_sp_mips();
- else if (!strcmp(arch, "powerpc"))
+ case EM_PPC:
+ case EM_PPC64:
return __perf_reg_sp_powerpc();
- else if (!strcmp(arch, "riscv"))
+ case EM_RISCV:
return __perf_reg_sp_riscv();
- else if (!strcmp(arch, "s390"))
+ case EM_S390:
return __perf_reg_sp_s390();
- else if (!strcmp(arch, "x86"))
+ case EM_386:
+ case EM_X86_64:
return __perf_reg_sp_x86();
-
- pr_err("Fail to find SP register for arch %s, returns 0\n", arch);
- return 0;
+ default:
+ pr_err("Failed to find SP register for ELF machine type %u\n", e_machine);
+ return 0;
+ }
}