perf_regs.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  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. int perf_sdt_arg_parse_op(uint16_t e_machine, char *old_op, char **new_op)
  10. {
  11. int ret = SDT_ARG_SKIP;
  12. switch (e_machine) {
  13. case EM_AARCH64:
  14. ret = __perf_sdt_arg_parse_op_arm64(old_op, new_op);
  15. break;
  16. case EM_PPC:
  17. case EM_PPC64:
  18. ret = __perf_sdt_arg_parse_op_powerpc(old_op, new_op);
  19. break;
  20. case EM_386:
  21. case EM_X86_64:
  22. ret = __perf_sdt_arg_parse_op_x86(old_op, new_op);
  23. break;
  24. default:
  25. pr_debug("Unknown ELF machine %d, standard arguments parse will be skipped.\n",
  26. e_machine);
  27. break;
  28. }
  29. return ret;
  30. }
  31. uint64_t perf_intr_reg_mask(uint16_t e_machine)
  32. {
  33. uint64_t mask = 0;
  34. switch (e_machine) {
  35. case EM_ARM:
  36. mask = __perf_reg_mask_arm(/*intr=*/true);
  37. break;
  38. case EM_AARCH64:
  39. mask = __perf_reg_mask_arm64(/*intr=*/true);
  40. break;
  41. case EM_CSKY:
  42. mask = __perf_reg_mask_csky(/*intr=*/true);
  43. break;
  44. case EM_LOONGARCH:
  45. mask = __perf_reg_mask_loongarch(/*intr=*/true);
  46. break;
  47. case EM_MIPS:
  48. mask = __perf_reg_mask_mips(/*intr=*/true);
  49. break;
  50. case EM_PPC:
  51. case EM_PPC64:
  52. mask = __perf_reg_mask_powerpc(/*intr=*/true);
  53. break;
  54. case EM_RISCV:
  55. mask = __perf_reg_mask_riscv(/*intr=*/true);
  56. break;
  57. case EM_S390:
  58. mask = __perf_reg_mask_s390(/*intr=*/true);
  59. break;
  60. case EM_386:
  61. case EM_X86_64:
  62. mask = __perf_reg_mask_x86(/*intr=*/true);
  63. break;
  64. default:
  65. pr_debug("Unknown ELF machine %d, interrupt sampling register mask will be empty.\n",
  66. e_machine);
  67. break;
  68. }
  69. return mask;
  70. }
  71. uint64_t perf_user_reg_mask(uint16_t e_machine)
  72. {
  73. uint64_t mask = 0;
  74. switch (e_machine) {
  75. case EM_ARM:
  76. mask = __perf_reg_mask_arm(/*intr=*/false);
  77. break;
  78. case EM_AARCH64:
  79. mask = __perf_reg_mask_arm64(/*intr=*/false);
  80. break;
  81. case EM_CSKY:
  82. mask = __perf_reg_mask_csky(/*intr=*/false);
  83. break;
  84. case EM_LOONGARCH:
  85. mask = __perf_reg_mask_loongarch(/*intr=*/false);
  86. break;
  87. case EM_MIPS:
  88. mask = __perf_reg_mask_mips(/*intr=*/false);
  89. break;
  90. case EM_PPC:
  91. case EM_PPC64:
  92. mask = __perf_reg_mask_powerpc(/*intr=*/false);
  93. break;
  94. case EM_RISCV:
  95. mask = __perf_reg_mask_riscv(/*intr=*/false);
  96. break;
  97. case EM_S390:
  98. mask = __perf_reg_mask_s390(/*intr=*/false);
  99. break;
  100. case EM_386:
  101. case EM_X86_64:
  102. mask = __perf_reg_mask_x86(/*intr=*/false);
  103. break;
  104. default:
  105. pr_debug("Unknown ELF machine %d, user sampling register mask will be empty.\n",
  106. e_machine);
  107. break;
  108. }
  109. return mask;
  110. }
  111. const char *perf_reg_name(int id, uint16_t e_machine, uint32_t e_flags)
  112. {
  113. const char *reg_name = NULL;
  114. switch (e_machine) {
  115. case EM_ARM:
  116. reg_name = __perf_reg_name_arm(id);
  117. break;
  118. case EM_AARCH64:
  119. reg_name = __perf_reg_name_arm64(id);
  120. break;
  121. case EM_CSKY:
  122. reg_name = __perf_reg_name_csky(id, e_flags);
  123. break;
  124. case EM_LOONGARCH:
  125. reg_name = __perf_reg_name_loongarch(id);
  126. break;
  127. case EM_MIPS:
  128. reg_name = __perf_reg_name_mips(id);
  129. break;
  130. case EM_PPC:
  131. case EM_PPC64:
  132. reg_name = __perf_reg_name_powerpc(id);
  133. break;
  134. case EM_RISCV:
  135. reg_name = __perf_reg_name_riscv(id);
  136. break;
  137. case EM_S390:
  138. reg_name = __perf_reg_name_s390(id);
  139. break;
  140. case EM_386:
  141. case EM_X86_64:
  142. reg_name = __perf_reg_name_x86(id);
  143. break;
  144. default:
  145. break;
  146. }
  147. if (reg_name)
  148. return reg_name;
  149. pr_debug("Failed to find register %d for ELF machine type %u\n", id, e_machine);
  150. return "unknown";
  151. }
  152. int perf_reg_value(u64 *valp, struct regs_dump *regs, int id)
  153. {
  154. int i, idx = 0;
  155. u64 mask = regs->mask;
  156. if ((u64)id >= PERF_SAMPLE_REGS_CACHE_SIZE)
  157. return -EINVAL;
  158. if (regs->cache_mask & (1ULL << id))
  159. goto out;
  160. if (!(mask & (1ULL << id)))
  161. return -EINVAL;
  162. for (i = 0; i < id; i++) {
  163. if (mask & (1ULL << i))
  164. idx++;
  165. }
  166. regs->cache_mask |= (1ULL << id);
  167. regs->cache_regs[id] = regs->regs[idx];
  168. out:
  169. *valp = regs->cache_regs[id];
  170. return 0;
  171. }
  172. uint64_t perf_arch_reg_ip(uint16_t e_machine)
  173. {
  174. switch (e_machine) {
  175. case EM_ARM:
  176. return __perf_reg_ip_arm();
  177. case EM_AARCH64:
  178. return __perf_reg_ip_arm64();
  179. case EM_CSKY:
  180. return __perf_reg_ip_csky();
  181. case EM_LOONGARCH:
  182. return __perf_reg_ip_loongarch();
  183. case EM_MIPS:
  184. return __perf_reg_ip_mips();
  185. case EM_PPC:
  186. case EM_PPC64:
  187. return __perf_reg_ip_powerpc();
  188. case EM_RISCV:
  189. return __perf_reg_ip_riscv();
  190. case EM_S390:
  191. return __perf_reg_ip_s390();
  192. case EM_386:
  193. case EM_X86_64:
  194. return __perf_reg_ip_x86();
  195. default:
  196. pr_err("Failed to find IP register for ELF machine type %u\n", e_machine);
  197. return 0;
  198. }
  199. }
  200. uint64_t perf_arch_reg_sp(uint16_t e_machine)
  201. {
  202. switch (e_machine) {
  203. case EM_ARM:
  204. return __perf_reg_sp_arm();
  205. case EM_AARCH64:
  206. return __perf_reg_sp_arm64();
  207. case EM_CSKY:
  208. return __perf_reg_sp_csky();
  209. case EM_LOONGARCH:
  210. return __perf_reg_sp_loongarch();
  211. case EM_MIPS:
  212. return __perf_reg_sp_mips();
  213. case EM_PPC:
  214. case EM_PPC64:
  215. return __perf_reg_sp_powerpc();
  216. case EM_RISCV:
  217. return __perf_reg_sp_riscv();
  218. case EM_S390:
  219. return __perf_reg_sp_s390();
  220. case EM_386:
  221. case EM_X86_64:
  222. return __perf_reg_sp_x86();
  223. default:
  224. pr_err("Failed to find SP register for ELF machine type %u\n", e_machine);
  225. return 0;
  226. }
  227. }