1 // SPDX-License-Identifier: GPL-2.0 2 #include <elf.h> 3 #include <errno.h> 4 #include <string.h> 5 #include "dwarf-regs.h" 6 #include "perf_regs.h" 7 #include "util/sample.h" 8 #include "debug.h" 9 10 int __weak arch_sdt_arg_parse_op(char *old_op __maybe_unused, 11 char **new_op __maybe_unused) 12 { 13 return SDT_ARG_SKIP; 14 } 15 16 uint64_t __weak arch__intr_reg_mask(void) 17 { 18 return 0; 19 } 20 21 uint64_t __weak arch__user_reg_mask(void) 22 { 23 return 0; 24 } 25 26 const char *perf_reg_name(int id, uint16_t e_machine, uint32_t e_flags) 27 { 28 const char *reg_name = NULL; 29 30 switch (e_machine) { 31 case EM_ARM: 32 reg_name = __perf_reg_name_arm(id); 33 break; 34 case EM_AARCH64: 35 reg_name = __perf_reg_name_arm64(id); 36 break; 37 case EM_CSKY: 38 reg_name = __perf_reg_name_csky(id, e_flags); 39 break; 40 case EM_LOONGARCH: 41 reg_name = __perf_reg_name_loongarch(id); 42 break; 43 case EM_MIPS: 44 reg_name = __perf_reg_name_mips(id); 45 break; 46 case EM_PPC: 47 case EM_PPC64: 48 reg_name = __perf_reg_name_powerpc(id); 49 break; 50 case EM_RISCV: 51 reg_name = __perf_reg_name_riscv(id); 52 break; 53 case EM_S390: 54 reg_name = __perf_reg_name_s390(id); 55 break; 56 case EM_386: 57 case EM_X86_64: 58 reg_name = __perf_reg_name_x86(id); 59 break; 60 default: 61 break; 62 } 63 if (reg_name) 64 return reg_name; 65 66 pr_debug("Failed to find register %d for ELF machine type %u\n", id, e_machine); 67 return "unknown"; 68 } 69 70 int perf_reg_value(u64 *valp, struct regs_dump *regs, int id) 71 { 72 int i, idx = 0; 73 u64 mask = regs->mask; 74 75 if ((u64)id >= PERF_SAMPLE_REGS_CACHE_SIZE) 76 return -EINVAL; 77 78 if (regs->cache_mask & (1ULL << id)) 79 goto out; 80 81 if (!(mask & (1ULL << id))) 82 return -EINVAL; 83 84 for (i = 0; i < id; i++) { 85 if (mask & (1ULL << i)) 86 idx++; 87 } 88 89 regs->cache_mask |= (1ULL << id); 90 regs->cache_regs[id] = regs->regs[idx]; 91 92 out: 93 *valp = regs->cache_regs[id]; 94 return 0; 95 } 96 97 uint64_t perf_arch_reg_ip(uint16_t e_machine) 98 { 99 switch (e_machine) { 100 case EM_ARM: 101 return __perf_reg_ip_arm(); 102 case EM_AARCH64: 103 return __perf_reg_ip_arm64(); 104 case EM_CSKY: 105 return __perf_reg_ip_csky(); 106 case EM_LOONGARCH: 107 return __perf_reg_ip_loongarch(); 108 case EM_MIPS: 109 return __perf_reg_ip_mips(); 110 case EM_PPC: 111 case EM_PPC64: 112 return __perf_reg_ip_powerpc(); 113 case EM_RISCV: 114 return __perf_reg_ip_riscv(); 115 case EM_S390: 116 return __perf_reg_ip_s390(); 117 case EM_386: 118 case EM_X86_64: 119 return __perf_reg_ip_x86(); 120 default: 121 pr_err("Failed to find IP register for ELF machine type %u\n", e_machine); 122 return 0; 123 } 124 } 125 126 uint64_t perf_arch_reg_sp(uint16_t e_machine) 127 { 128 switch (e_machine) { 129 case EM_ARM: 130 return __perf_reg_sp_arm(); 131 case EM_AARCH64: 132 return __perf_reg_sp_arm64(); 133 case EM_CSKY: 134 return __perf_reg_sp_csky(); 135 case EM_LOONGARCH: 136 return __perf_reg_sp_loongarch(); 137 case EM_MIPS: 138 return __perf_reg_sp_mips(); 139 case EM_PPC: 140 case EM_PPC64: 141 return __perf_reg_sp_powerpc(); 142 case EM_RISCV: 143 return __perf_reg_sp_riscv(); 144 case EM_S390: 145 return __perf_reg_sp_s390(); 146 case EM_386: 147 case EM_X86_64: 148 return __perf_reg_sp_x86(); 149 default: 150 pr_err("Failed to find SP register for ELF machine type %u\n", e_machine); 151 return 0; 152 } 153 } 154