diff options
Diffstat (limited to 'tools/perf/util/perf_regs.c')
| -rw-r--r-- | tools/perf/util/perf_regs.c | 227 |
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; + } } |
