95 lines · c
1// SPDX-License-Identifier: LGPL-2.12#ifndef PERF_FLAG_FD_NO_GROUP3# define PERF_FLAG_FD_NO_GROUP (1UL << 0)4#endif5 6#ifndef PERF_FLAG_FD_OUTPUT7# define PERF_FLAG_FD_OUTPUT (1UL << 1)8#endif9 10#ifndef PERF_FLAG_PID_CGROUP11# define PERF_FLAG_PID_CGROUP (1UL << 2) /* pid=cgroup id, per-cpu mode only */12#endif13 14#ifndef PERF_FLAG_FD_CLOEXEC15# define PERF_FLAG_FD_CLOEXEC (1UL << 3) /* O_CLOEXEC */16#endif17 18static 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_FLAG39 40 if (flags)41 printed += scnprintf(bf + printed, size - printed, "%s%#x", printed ? "|" : "", flags);42 43 return printed;44}45 46#define SCA_PERF_FLAGS syscall_arg__scnprintf_perf_flags47 48struct attr_fprintf_args {49 size_t size, printed;50 char *bf;51 bool first;52};53 54static 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(args->bf + args->printed , args->size - args->printed, "%s%s: %s", args->first ? "" : ", ", name, val);58 59 args->first = false;60 args->printed += printed;61 return printed;62}63 64static 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(bf, size, "{ "),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(bf + args.printed, size - args.printed, " }");75}76 77static 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((void *)arg->augmented.args->value, bf, size, arg->trace->show_zeros);80}81 82static 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(bf, size, "%#lx", arg->val);88}89 90#define SCA_PERF_ATTR syscall_arg__scnprintf_perf_event_attr91// 'argname' is just documentational at this point, to remove the previous comment with that info92#define SCA_PERF_ATTR_FROM_USER(argname) \93 { .scnprintf = SCA_PERF_ATTR, \94 .from_user = true, }95