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 static const struct sample_reg sample_reg_masks[] = { 27 SMPL_REG_END 28 }; 29 30 const struct sample_reg * __weak arch__sample_reg_masks(void) 31 { 32 return sample_reg_masks; 33 } 34 35 const char *perf_reg_name(int id, uint16_t e_machine) 36 { 37 const char *reg_name = NULL; 38 39 switch (e_machine) { 40 case EM_ARM: 41 reg_name = __perf_reg_name_arm(id); 42 break; 43 case EM_AARCH64: 44 reg_name = __perf_reg_name_arm64(id); 45 break; 46 case EM_CSKY: 47 reg_name = __perf_reg_name_csky(id); 48 break; 49 case EM_LOONGARCH: 50 reg_name = __perf_reg_name_loongarch(id); 51 break; 52 case EM_MIPS: 53 reg_name = __perf_reg_name_mips(id); 54 break; 55 case EM_PPC: 56 case EM_PPC64: 57 reg_name = __perf_reg_name_powerpc(id); 58 break; 59 case EM_RISCV: 60 reg_name = __perf_reg_name_riscv(id); 61 break; 62 case EM_S390: 63 reg_name = __perf_reg_name_s390(id); 64 break; 65 case EM_386: 66 case EM_X86_64: 67 reg_name = __perf_reg_name_x86(id); 68 break; 69 default: 70 break; 71 } 72 if (reg_name) 73 return reg_name; 74 75 pr_debug("Failed to find register %d for ELF machine type %u\n", id, e_machine); 76 return "unknown"; 77 } 78 79 int perf_reg_value(u64 *valp, struct regs_dump *regs, int id) 80 { 81 int i, idx = 0; 82 u64 mask = regs->mask; 83 84 if ((u64)id >= PERF_SAMPLE_REGS_CACHE_SIZE) 85 return -EINVAL; 86 87 if (regs->cache_mask & (1ULL << id)) 88 goto out; 89 90 if (!(mask & (1ULL << id))) 91 return -EINVAL; 92 93 for (i = 0; i < id; i++) { 94 if (mask & (1ULL << i)) 95 idx++; 96 } 97 98 regs->cache_mask |= (1ULL << id); 99 regs->cache_regs[id] = regs->regs[idx]; 100 101 out: 102 *valp = regs->cache_regs[id]; 103 return 0; 104 } 105 106 uint64_t perf_arch_reg_ip(uint16_t e_machine) 107 { 108 switch (e_machine) { 109 case EM_ARM: 110 return __perf_reg_ip_arm(); 111 case EM_AARCH64: 112 return __perf_reg_ip_arm64(); 113 case EM_CSKY: 114 return __perf_reg_ip_csky(); 115 case EM_LOONGARCH: 116 return __perf_reg_ip_loongarch(); 117 case EM_MIPS: 118 return __perf_reg_ip_mips(); 119 case EM_PPC: 120 case EM_PPC64: 121 return __perf_reg_ip_powerpc(); 122 case EM_RISCV: 123 return __perf_reg_ip_riscv(); 124 case EM_S390: 125 return __perf_reg_ip_s390(); 126 case EM_386: 127 case EM_X86_64: 128 return __perf_reg_ip_x86(); 129 default: 130 pr_err("Failed to find IP register for ELF machine type %u\n", e_machine); 131 return 0; 132 } 133 } 134 135 uint64_t perf_arch_reg_sp(uint16_t e_machine) 136 { 137 switch (e_machine) { 138 case EM_ARM: 139 return __perf_reg_sp_arm(); 140 case EM_AARCH64: 141 return __perf_reg_sp_arm64(); 142 case EM_CSKY: 143 return __perf_reg_sp_csky(); 144 case EM_LOONGARCH: 145 return __perf_reg_sp_loongarch(); 146 case EM_MIPS: 147 return __perf_reg_sp_mips(); 148 case EM_PPC: 149 case EM_PPC64: 150 return __perf_reg_sp_powerpc(); 151 case EM_RISCV: 152 return __perf_reg_sp_riscv(); 153 case EM_S390: 154 return __perf_reg_sp_s390(); 155 case EM_386: 156 case EM_X86_64: 157 return __perf_reg_sp_x86(); 158 default: 159 pr_err("Failed to find SP register for ELF machine type %u\n", e_machine); 160 return 0; 161 } 162 } 163