Mirror of strace – the linux syscall tracer
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

perf_ioctl.c 2.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. /*
  2. * Copyright (c) 2018 The strace developers.
  3. * All rights reserved.
  4. *
  5. * SPDX-License-Identifier: LGPL-2.1-or-later
  6. */
  7. #include "defs.h"
  8. #include <linux/ioctl.h>
  9. #include "perf_event_struct.h"
  10. #define XLAT_MACROS_ONLY
  11. #include "xlat/perf_ioctl_cmds.h"
  12. #undef XLAT_MACROS_ONLY
  13. #include "xlat/perf_ioctl_flags.h"
  14. #include MPERS_DEFS
  15. static int
  16. perf_ioctl_query_bpf(struct tcb *const tcp, const kernel_ulong_t arg)
  17. {
  18. uint32_t info;
  19. if (entering(tcp)) {
  20. tprints(", ");
  21. if (umove_or_printaddr(tcp, arg, &info))
  22. return RVAL_IOCTL_DECODED;
  23. tprintf("{ids_len=%u, ", info);
  24. return 0;
  25. }
  26. if (syserror(tcp) ||
  27. umove(tcp, arg + offsetof(struct perf_event_query_bpf, prog_cnt),
  28. &info)) {
  29. tprints("...}");
  30. return RVAL_IOCTL_DECODED;
  31. }
  32. tprintf("prog_cnt=%u, ids=", info);
  33. print_array(tcp, arg + offsetof(struct perf_event_query_bpf, ids), info,
  34. &info, sizeof(info),
  35. tfetch_mem, print_uint32_array_member, NULL);
  36. tprints("}");
  37. return RVAL_IOCTL_DECODED;
  38. }
  39. static int
  40. perf_ioctl_modify_attributes(struct tcb *const tcp, const kernel_ulong_t arg)
  41. {
  42. tprints(", ");
  43. if (!fetch_perf_event_attr(tcp, arg))
  44. print_perf_event_attr(tcp, arg);
  45. return RVAL_IOCTL_DECODED;
  46. }
  47. MPERS_PRINTER_DECL(int, perf_ioctl,
  48. struct tcb *const tcp, const unsigned int code,
  49. const kernel_ulong_t arg)
  50. {
  51. switch (code) {
  52. case PERF_EVENT_IOC_ENABLE:
  53. case PERF_EVENT_IOC_DISABLE:
  54. case PERF_EVENT_IOC_RESET:
  55. tprints(", ");
  56. printflags(perf_ioctl_flags, arg, "PERF_IOC_FLAG_???");
  57. return RVAL_IOCTL_DECODED;
  58. case PERF_EVENT_IOC_REFRESH:
  59. tprintf(", %d", (int) arg);
  60. return RVAL_IOCTL_DECODED;
  61. case PERF_EVENT_IOC_PERIOD:
  62. tprints(", ");
  63. printnum_int64(tcp, arg, "%" PRIu64);
  64. return RVAL_IOCTL_DECODED;
  65. case PERF_EVENT_IOC_SET_OUTPUT:
  66. case PERF_EVENT_IOC_SET_BPF:
  67. tprintf(", ");
  68. printfd(tcp, (int) arg);
  69. return RVAL_IOCTL_DECODED;
  70. case PERF_EVENT_IOC_PAUSE_OUTPUT:
  71. tprintf(", %" PRI_klu, arg);
  72. return RVAL_IOCTL_DECODED;
  73. /*
  74. * The following ioctl requests are personality-specific
  75. * due to the pointer size.
  76. */
  77. case PERF_EVENT_IOC_SET_FILTER:
  78. tprints(", ");
  79. printstr_ex(tcp, arg, get_pagesize(), QUOTE_0_TERMINATED);
  80. return RVAL_IOCTL_DECODED;
  81. case PERF_EVENT_IOC_ID:
  82. if (entering(tcp)) {
  83. tprints(", ");
  84. return 0;
  85. }
  86. printnum_int64(tcp, arg, "%" PRIu64);
  87. return RVAL_IOCTL_DECODED;
  88. case PERF_EVENT_IOC_QUERY_BPF:
  89. return perf_ioctl_query_bpf(tcp, arg);
  90. case PERF_EVENT_IOC_MODIFY_ATTRIBUTES:
  91. return perf_ioctl_modify_attributes(tcp, arg);
  92. default:
  93. return RVAL_DECODED;
  94. }
  95. }