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