1 | // SPDX-License-Identifier: LGPL-2.1 |
2 | #ifndef PERF_FLAG_FD_NO_GROUP |
3 | # define PERF_FLAG_FD_NO_GROUP (1UL << 0) |
4 | #endif |
5 | |
6 | #ifndef PERF_FLAG_FD_OUTPUT |
7 | # define PERF_FLAG_FD_OUTPUT (1UL << 1) |
8 | #endif |
9 | |
10 | #ifndef PERF_FLAG_PID_CGROUP |
11 | # define PERF_FLAG_PID_CGROUP (1UL << 2) /* pid=cgroup id, per-cpu mode only */ |
12 | #endif |
13 | |
14 | #ifndef PERF_FLAG_FD_CLOEXEC |
15 | # define PERF_FLAG_FD_CLOEXEC (1UL << 3) /* O_CLOEXEC */ |
16 | #endif |
17 | |
18 | static size_t syscall_arg__scnprintf_perf_flags(char *bf, size_t size, |
19 | struct syscall_arg *arg) |
20 | { |
21 | bool show_prefix = arg->show_string_prefix; |
22 | const char *prefix = "PERF_" ; |
23 | int printed = 0, flags = arg->val; |
24 | |
25 | if (flags == 0) |
26 | return 0; |
27 | |
28 | #define P_FLAG(n) \ |
29 | if (flags & PERF_FLAG_##n) { \ |
30 | printed += scnprintf(bf + printed, size - printed, "%s%s%s", printed ? "|" : "", show_prefix ? prefix : "", #n); \ |
31 | flags &= ~PERF_FLAG_##n; \ |
32 | } |
33 | |
34 | P_FLAG(FD_NO_GROUP); |
35 | P_FLAG(FD_OUTPUT); |
36 | P_FLAG(PID_CGROUP); |
37 | P_FLAG(FD_CLOEXEC); |
38 | #undef P_FLAG |
39 | |
40 | if (flags) |
41 | printed += scnprintf(buf: bf + printed, size: size - printed, fmt: "%s%#x" , printed ? "|" : "" , flags); |
42 | |
43 | return printed; |
44 | } |
45 | |
46 | #define SCA_PERF_FLAGS syscall_arg__scnprintf_perf_flags |
47 | |
48 | struct attr_fprintf_args { |
49 | size_t size, printed; |
50 | char *bf; |
51 | bool first; |
52 | }; |
53 | |
54 | static int attr__fprintf(FILE *fp __maybe_unused, const char *name, const char *val, void *priv) |
55 | { |
56 | struct attr_fprintf_args *args = priv; |
57 | size_t printed = scnprintf(buf: args->bf + args->printed , size: args->size - args->printed, fmt: "%s%s: %s" , args->first ? "" : ", " , name, val); |
58 | |
59 | args->first = false; |
60 | args->printed += printed; |
61 | return printed; |
62 | } |
63 | |
64 | static size_t perf_event_attr___scnprintf(struct perf_event_attr *attr, char *bf, size_t size, bool show_zeros __maybe_unused) |
65 | { |
66 | struct attr_fprintf_args args = { |
67 | .printed = scnprintf(buf: bf, size, fmt: "{ " ), |
68 | .size = size, |
69 | .first = true, |
70 | .bf = bf, |
71 | }; |
72 | |
73 | perf_event_attr__fprintf(stdout, attr, attr__fprintf, &args); |
74 | return args.printed + scnprintf(buf: bf + args.printed, size: size - args.printed, fmt: " }" ); |
75 | } |
76 | |
77 | static size_t syscall_arg__scnprintf_augmented_perf_event_attr(struct syscall_arg *arg, char *bf, size_t size) |
78 | { |
79 | return perf_event_attr___scnprintf(attr: (void *)arg->augmented.args, bf, size, show_zeros: arg->trace->show_zeros); |
80 | } |
81 | |
82 | static size_t syscall_arg__scnprintf_perf_event_attr(char *bf, size_t size, struct syscall_arg *arg) |
83 | { |
84 | if (arg->augmented.args) |
85 | return syscall_arg__scnprintf_augmented_perf_event_attr(arg, bf, size); |
86 | |
87 | return scnprintf(buf: bf, size, fmt: "%#lx" , arg->val); |
88 | } |
89 | |
90 | #define SCA_PERF_ATTR syscall_arg__scnprintf_perf_event_attr |
91 | |