2 * Check verbose decoding of perf_event_open syscall.
4 * Copyright (c) 2016 Eugene Syromyatnikov <evgsyr@gmail.com>
5 * Copyright (c) 2016-2017 The strace developers.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 #include <asm/unistd.h>
34 #if defined(__NR_perf_event_open) && defined(HAVE_LINUX_PERF_EVENT_H)
36 # include <inttypes.h>
45 # include <linux/perf_event.h>
48 # include "xlat/perf_event_open_flags.h"
49 # include "xlat/perf_attr_size.h"
51 # if ULONG_MAX > UINT_MAX /* Poor man's "whether long is 8 bytes?" */
52 # define LONG_STR_PREFIX "ffffffff"
53 # else /* !(ULONG_MAX > UINT_MAX) */
54 # define LONG_STR_PREFIX ""
55 # endif /* ULONG_MAX > UINT_MAX */
57 # ifndef PERF_TYPE_BREAKPOINT
58 # define PERF_TYPE_BREAKPOINT 5
76 /* In order to avoid endianness-specific hackery. */
98 exclude_callchain_kernel :1,
99 exclude_callchain_user :1,
111 static char buf[sizeof("0x") + sizeof(void *) * 2];
116 snprintf(buf, sizeof(buf), "%#lx", (unsigned long)ptr);
125 * config - 13 IDs (0..11 + random), depends on type
126 * sample type - bitmask, up to 20 bits
127 * read_format - 5 IDs
128 * bp_type - 6, weird semantics (invalid/unknown)
129 * branch_sample_type - bitmask, 16 bits
130 * clockid - 13 values
133 * sample_period/sample_freq
134 * wakeup_event/wakeup_watermark
140 * The main idea behind all those numerous ifdefs is checking against version of
141 * structure provided in kernel headers and not use one defined in strace
142 * headers (assume the case when suddenly we add flag without proper update of
143 * __reserved_1 field or something like this).
146 print_event_attr(struct perf_event_attr *attr_ptr, size_t size,
147 const char *type, const char *config, const char *sample_type,
148 const char *read_format, const char *precise_ip_desc,
149 const char *bp_type, const char *branch_sample_type,
150 const char *clockid, uint32_t available_size)
153 * Currently, strace supports version 5 of the structure, which is
157 STRACE_PEA_ABBREV_SIZE =
158 offsetof(struct perf_event_attr, config) +
159 sizeof(attr_ptr->config),
160 STRACE_PEA_SIZE = 112,
164 struct perf_event_attr *attr;
168 uint64_t use_clockid;
170 struct pea_flags flags;
177 STRACE_PEA_ABBREV_SIZE;
179 size < STRACE_PEA_SIZE ?
180 (size ? size : PERF_ATTR_SIZE_VER0) : STRACE_PEA_SIZE;
183 if (read_size > available_size) {
184 printf("%s", printaddr(attr_ptr));
189 * Replicate kernel's behaviour regarding copying structure from
192 attr = calloc(1, STRACE_PEA_SIZE);
195 error_msg_and_fail("calloc");
198 memcpy(attr, attr_ptr, read_size);
200 if (size && (size < PERF_ATTR_SIZE_VER0)) {
201 printf("%s", printaddr(attr_ptr));
206 printf("{type=%s, size=", type);
207 if (size != attr->size) {
208 printxval(perf_attr_size, size, "PERF_ATTR_SIZE_???");
211 printxval(perf_attr_size, attr->size, "PERF_ATTR_SIZE_???");
212 printf(", config=%s, ", config);
215 size = PERF_ATTR_SIZE_VER0;
219 # else /* !VERBOSE */
220 printf("%s=%" PRI__u64", sample_type=%s, read_format=%s",
221 attr->freq ? "sample_freq" : "sample_period",
222 attr->freq ? attr->sample_freq : attr->sample_period,
223 sample_type, read_format);
225 printf(", disabled=%u"
229 ", exclusive_user=%u"
230 ", exclude_kernel=%u"
237 ", enable_on_exec=%u"
245 attr->exclude_kernel,
252 attr->enable_on_exec,
256 flags_data.raw = ((uint64_t *) attr)[5];
259 # ifdef HAVE_STRUCT_PERF_EVENT_ATTR_PRECISE_IP
262 flags_data.flags.precise_ip;
264 printf(", precise_ip=%" PRIu64 " /* %s */", val, precise_ip_desc);
267 # ifdef HAVE_STRUCT_PERF_EVENT_ATTR_MMAP_DATA
270 flags_data.flags.mmap_data;
272 printf(", mmap_data=%" PRIu64, val);
275 # ifdef HAVE_STRUCT_PERF_EVENT_ATTR_SAMPLE_ID_ALL
278 flags_data.flags.sample_id_all;
280 printf(", sample_id_all=%" PRIu64, val);
283 # ifdef HAVE_STRUCT_PERF_EVENT_ATTR_EXCLUDE_HOST
286 flags_data.flags.exclude_host;
288 printf(", exclude_host=%" PRIu64, val);
291 # ifdef HAVE_STRUCT_PERF_EVENT_ATTR_EXCLUDE_GUEST
294 flags_data.flags.exclude_guest;
296 printf(", exclude_guest=%" PRIu64, val);
299 # ifdef HAVE_STRUCT_PERF_EVENT_ATTR_EXCLUDE_CALLCHAIN_KERNEL
300 attr->exclude_callchain_kernel;
302 flags_data.flags.exclude_callchain_kernel;
304 printf(", exclude_callchain_kernel=%" PRIu64, val);
307 # ifdef HAVE_STRUCT_PERF_EVENT_ATTR_EXCLUDE_CALLCHAIN_USER
308 attr->exclude_callchain_user;
310 flags_data.flags.exclude_callchain_user;
312 printf(", exclude_callchain_user=%" PRIu64, val);
315 # ifdef HAVE_STRUCT_PERF_EVENT_ATTR_MMAP2
318 flags_data.flags.mmap2;
320 printf(", mmap2=%" PRIu64, val);
323 # ifdef HAVE_STRUCT_PERF_EVENT_ATTR_COMM_EXEC
326 flags_data.flags.comm_exec;
328 printf(", comm_exec=%" PRIu64, val);
331 # ifdef HAVE_STRUCT_PERF_EVENT_ATTR_USE_CLOCKID
334 flags_data.flags.use_clockid;
336 printf(", use_clockid=%" PRIu64, val);
339 # ifdef HAVE_STRUCT_PERF_EVENT_ATTR_CONTEXT_SWITCH
340 attr->context_switch;
342 flags_data.flags.context_switch;
344 printf(", context_switch=%" PRIu64, val);
347 # ifdef HAVE_STRUCT_PERF_EVENT_ATTR_WRITE_BACKWARD
348 attr->write_backward;
350 flags_data.flags.write_backward;
352 printf(", write_backward=%" PRIu64, val);
354 val = flags_data.flags.__reserved_1;
356 printf(", __reserved_1=%#" PRIx64 " /* Bits 63..28 */", val);
359 attr->watermark ? "wakeup_watermark" : "wakeup_events",
360 attr->watermark ? attr->wakeup_watermark : attr->wakeup_events);
362 if (attr->type == PERF_TYPE_BREAKPOINT)
363 printf(", bp_type=%s", bp_type);
366 # ifdef HAVE_STRUCT_PERF_EVENT_ATTR_CONFIG1
369 ((uint64_t *) attr)[56 / sizeof(uint64_t)];
371 printf(", %s=%#" PRIx64,
372 attr->type == PERF_TYPE_BREAKPOINT ? "bp_addr" : "config1",
375 /* End of version 0 of the structure */
382 # ifdef HAVE_STRUCT_PERF_EVENT_ATTR_CONFIG2
385 ((uint64_t *) attr)[64 / sizeof(uint64_t)];
387 if (attr->type == PERF_TYPE_BREAKPOINT)
388 printf(", bp_len=%" PRIu64, val);
390 printf(", config2=%#" PRIx64, val);
392 /* End of version 1 of the structure */
399 * Print branch sample type only in case PERF_SAMPLE_BRANCH_STACK
400 * is set in the sample_type field.
402 if (attr->sample_type & (1 << 11))
403 printf(", branch_sample_type=%s", branch_sample_type);
405 /* End of version 2 of the structure */
412 # ifdef HAVE_STRUCT_PERF_EVENT_ATTR_SAMPLE_REGS_USER
413 attr->sample_regs_user;
415 ((uint64_t *) attr)[80 / sizeof(uint64_t)];
417 printf(", sample_regs_user=%#" PRIx64, val);
425 # ifdef HAVE_STRUCT_PERF_EVENT_ATTR_SAMPLE_STACK_USER
426 attr->sample_stack_user;
428 ((uint32_t *) attr)[88 / sizeof(uint32_t)];
431 * Print branch sample type only in case PERF_SAMPLE_STACK_USER
432 * is set in the sample_type field.
434 if (attr->sample_type & (1 << 13))
435 printf(", sample_stack_user=%#" PRIx32, (uint32_t) val);
443 printf(", clockid=%s", clockid);
445 /* End of version 3 of the structure */
452 # ifdef HAVE_STRUCT_PERF_EVENT_ATTR_SAMPLE_REGS_INTR
453 attr->sample_regs_intr;
455 ((uint64_t *) attr)[96 / sizeof(uint64_t)];
457 printf(", sample_regs_intr=%#" PRIx64, val);
459 /* End of version 4 of the structure */
466 # ifdef HAVE_STRUCT_PERF_EVENT_ATTR_AUX_WATERMARK
469 ((uint32_t *) attr)[104 / sizeof(uint32_t)];
471 printf(", aux_watermark=%" PRIu32, (uint32_t) val);
479 # ifdef HAVE_STRUCT_PERF_EVENT_ATTR_SAMPLE_MAX_STACK
480 attr->sample_max_stack;
482 ((uint16_t *) attr)[108 / sizeof(uint16_t)];
484 printf(", sample_max_stack=%" PRIu16, (uint16_t) val);
491 cutoff = STRACE_PEA_SIZE;
498 # endif /* !VERBOSE */
503 /* These require aligned access, so no byte-grain checks possible */
504 # if defined SPARC || defined SPARC64 || defined POWERPC || defined POWERPC64
505 # define ATTR_REC(sz) { tail_alloc((sz + 7) & ~7), sz }
507 # define ATTR_REC(sz) { tail_alloc(sz), sz }
510 # define BRANCH_TYPE_ALL \
511 "PERF_SAMPLE_BRANCH_USER|" \
512 "PERF_SAMPLE_BRANCH_KERNEL|" \
513 "PERF_SAMPLE_BRANCH_HV|" \
514 "PERF_SAMPLE_BRANCH_ANY|" \
515 "PERF_SAMPLE_BRANCH_ANY_CALL|" \
516 "PERF_SAMPLE_BRANCH_ANY_RETURN|" \
517 "PERF_SAMPLE_BRANCH_IND_CALL|" \
518 "PERF_SAMPLE_BRANCH_ABORT_TX|" \
519 "PERF_SAMPLE_BRANCH_IN_TX|" \
520 "PERF_SAMPLE_BRANCH_NO_TX|" \
521 "PERF_SAMPLE_BRANCH_COND|" \
522 "PERF_SAMPLE_BRANCH_CALL_STACK|" \
523 "PERF_SAMPLE_BRANCH_IND_JUMP|" \
524 "PERF_SAMPLE_BRANCH_CALL|" \
525 "PERF_SAMPLE_BRANCH_NO_FLAGS|" \
526 "PERF_SAMPLE_BRANCH_NO_CYCLES"
531 static const size_t attr_small_size = PERF_ATTR_SIZE_VER0 - 8;
532 static const size_t attr_v0_size = PERF_ATTR_SIZE_VER0;
533 static const size_t attr_v1_size = PERF_ATTR_SIZE_VER1;
534 static const size_t attr_v2_size = PERF_ATTR_SIZE_VER2;
535 static const size_t attr_v2_5_size = PERF_ATTR_SIZE_VER2 + 8;
536 static const size_t attr_v2_75_size = PERF_ATTR_SIZE_VER2 + 12;
537 static const size_t attr_v3_size = PERF_ATTR_SIZE_VER3;
538 static const size_t attr_v4_size = PERF_ATTR_SIZE_VER4;
539 static const size_t attr_v4_5_size = PERF_ATTR_SIZE_VER4 + 4;
540 static const size_t attr_v4_625_size = PERF_ATTR_SIZE_VER4 + 5;
541 static const size_t attr_v4_875_size = PERF_ATTR_SIZE_VER4 + 7;
542 static const size_t attr_v5_size = PERF_ATTR_SIZE_VER5;
543 static const size_t attr_big_size = PERF_ATTR_SIZE_VER5 + 32;
545 static const struct u64_val_str attr_types[] = {
546 { ARG_STR(PERF_TYPE_HARDWARE) },
547 { ARG_STR(PERF_TYPE_SOFTWARE) },
548 { ARG_STR(PERF_TYPE_TRACEPOINT) },
549 { ARG_STR(PERF_TYPE_HW_CACHE) },
550 { ARG_STR(PERF_TYPE_RAW) },
551 { ARG_STR(PERF_TYPE_BREAKPOINT) },
552 { ARG_STR(0x6) " /* PERF_TYPE_??? */" },
553 { ARG_STR(0xdeadc0de) " /* PERF_TYPE_??? */" },
555 static const struct u64_val_str
556 attr_configs[ARRAY_SIZE(attr_types)][3] = {
557 /* PERF_TYPE_HARDWARE */ {
558 { 9, "PERF_COUNT_HW_REF_CPU_CYCLES" },
559 { 10, "0xa /* PERF_COUNT_HW_??? */" },
560 { ARG_ULL_STR(0xfaceca75deadb0d4)
561 " /* PERF_COUNT_HW_??? */" },
563 /* PERF_TYPE_SOFTWARE */ {
564 { 10, "PERF_COUNT_SW_BPF_OUTPUT" },
565 { 11, "0xb /* PERF_COUNT_SW_??? */" },
566 { ARG_ULL_STR(0xdec0ded1dec0ded2)
567 " /* PERF_COUNT_SW_??? */" },
569 /* PERF_TYPE_TRACEPOINT */ {
571 { 4207856245U, "4207856245" },
572 { ARG_ULL_STR(16051074073505095380) },
574 /* PERF_TYPE_HW_CACHE */ {
575 { 0, "PERF_COUNT_HW_CACHE_L1D|"
576 "PERF_COUNT_HW_CACHE_OP_READ<<8|"
577 "PERF_COUNT_HW_CACHE_RESULT_ACCESS<<16" },
578 { 0x020207, "0x7 /* PERF_COUNT_HW_CACHE_??? */|"
579 "PERF_COUNT_HW_CACHE_OP_PREFETCH<<8|"
580 "0x2 /* PERF_COUNT_HW_CACHE_RESULT_??? */<<16" },
581 { 0xdeadf157ed010306ULL, "PERF_COUNT_HW_CACHE_NODE|"
582 "0x3 /* PERF_COUNT_HW_CACHE_OP_??? */<<8|"
583 "PERF_COUNT_HW_CACHE_RESULT_MISS<<16|"
585 "/* PERF_COUNT_HW_CACHE_??? */" },
587 /* PERF_TYPE_RAW */ {
589 { ARG_STR(0xda7a1057) },
590 { ARG_ULL_STR(0xdec0ded7dec0ded8) },
592 /* PERF_TYPE_BREAKPOINT */ {
594 { ARG_STR(0xbadc0ded) },
595 { ARG_ULL_STR(0xdec0ded9dec0deda) },
599 { ARG_STR(0xbeeff00d) },
600 { ARG_ULL_STR(0xdec0dedbdec0dedc) },
604 { ARG_STR(0xca75dead) },
605 { ARG_ULL_STR(0xdec0dedddec0dede) },
608 static const struct u64_val_str sample_types[] = {
610 { 0x800, "PERF_SAMPLE_BRANCH_STACK" },
611 { ARG_ULL_STR(0xdeadc0deda780000) " /* PERF_SAMPLE_??? */" },
612 { 0xffffffffffffffffULL,
613 "PERF_SAMPLE_IP|PERF_SAMPLE_TID|PERF_SAMPLE_TIME|"
614 "PERF_SAMPLE_ADDR|PERF_SAMPLE_READ|"
615 "PERF_SAMPLE_CALLCHAIN|PERF_SAMPLE_ID|PERF_SAMPLE_CPU|"
616 "PERF_SAMPLE_PERIOD|PERF_SAMPLE_STREAM_ID|"
617 "PERF_SAMPLE_RAW|PERF_SAMPLE_BRANCH_STACK|"
618 "PERF_SAMPLE_REGS_USER|PERF_SAMPLE_STACK_USER|"
619 "PERF_SAMPLE_WEIGHT|PERF_SAMPLE_DATA_SRC|"
620 "PERF_SAMPLE_IDENTIFIER|PERF_SAMPLE_TRANSACTION|"
621 "PERF_SAMPLE_REGS_INTR|0xfffffffffff80000" },
623 static const struct u64_val_str read_formats[] = {
625 { ARG_STR(PERF_FORMAT_TOTAL_TIME_ENABLED) },
626 { 0xf, "PERF_FORMAT_TOTAL_TIME_ENABLED|"
627 "PERF_FORMAT_TOTAL_TIME_RUNNING|"
628 "PERF_FORMAT_ID|PERF_FORMAT_GROUP" },
629 { ARG_ULL_STR(0xdeadf157dec0ded0) " /* PERF_FORMAT_??? */" },
630 { 0xffffffffffffffffULL,
631 "PERF_FORMAT_TOTAL_TIME_ENABLED|"
632 "PERF_FORMAT_TOTAL_TIME_RUNNING|"
633 "PERF_FORMAT_ID|PERF_FORMAT_GROUP|"
634 "0xfffffffffffffff0" },
636 static const char *precise_ip_descs[] = {
639 "requested to have 0 skid",
642 static const struct u32_val_str bp_types[] = {
643 { 0, "HW_BREAKPOINT_EMPTY" },
644 { 1, "HW_BREAKPOINT_R" },
645 { 3, "HW_BREAKPOINT_RW" },
646 { 5, "0x5 /* HW_BREAKPOINT_INVALID */" },
647 { 8, "0x8 /* HW_BREAKPOINT_??? */" },
648 { ARG_STR(0xface1e55) " /* HW_BREAKPOINT_??? */" },
650 static const struct u64_val_str branch_sample_types[] = {
652 { 0x80, "PERF_SAMPLE_BRANCH_ABORT_TX" },
653 { 0xffff, BRANCH_TYPE_ALL },
654 { ARG_ULL_STR(0xdeadcaffeeed0000)
655 " /* PERF_SAMPLE_BRANCH_??? */" },
656 { 0xffffffffffffffffULL,
657 BRANCH_TYPE_ALL "|0xffffffffffff0000" }
659 static const struct s32_val_str clockids[] = {
661 { ARG_STR(0xc) " /* CLOCK_??? */" },
662 { ARG_STR(0xbeeffeed) " /* CLOCK_??? */" },
667 struct perf_event_attr *ptr;
670 ATTR_REC(sizeof(struct perf_event_attr)),
671 ATTR_REC(attr_v0_size),
672 ATTR_REC(attr_v1_size),
673 ATTR_REC(attr_v2_size),
674 ATTR_REC(attr_v2_5_size),
675 ATTR_REC(attr_v2_75_size),
676 ATTR_REC(attr_v3_size),
677 ATTR_REC(attr_v4_size),
678 ATTR_REC(attr_v4_5_size),
679 ATTR_REC(attr_v4_625_size),
680 ATTR_REC(attr_v4_875_size),
681 ATTR_REC(attr_v5_size),
682 ATTR_REC(attr_big_size),
685 TAIL_ALLOC_OBJECT_CONST_PTR(struct perf_event_attr, small_attr);
688 struct perf_event_attr *attr;
693 const char *flags_str;
695 { NULL, 0xfacef00d, 0xbadabba7, -1,
696 (unsigned long) 0xFFFFFFFFFFFFFFFFLLU,
697 "PERF_FLAG_FD_NO_GROUP|PERF_FLAG_FD_OUTPUT|"
698 "PERF_FLAG_PID_CGROUP|PERF_FLAG_FD_CLOEXEC|"
699 "0x" LONG_STR_PREFIX "fffffff0"
701 { small_attr + 1, 0, 0, 0,
703 { small_attr, -1, -1, 1,
704 PERF_FLAG_FD_NO_GROUP | PERF_FLAG_FD_OUTPUT |
705 PERF_FLAG_PID_CGROUP | PERF_FLAG_FD_CLOEXEC,
706 "PERF_FLAG_FD_NO_GROUP|PERF_FLAG_FD_OUTPUT|"
707 "PERF_FLAG_PID_CGROUP|PERF_FLAG_FD_CLOEXEC" },
708 { (struct perf_event_attr *) (uintptr_t) 0xfffffacefffffeedULL,
709 -100, 100, 0xface1e55,
710 PERF_FLAG_FD_CLOEXEC, "PERF_FLAG_FD_CLOEXEC" },
716 fill_memory(small_attr, sizeof(*small_attr));
717 small_attr->size = attr_small_size;
719 for (i = 0; i < ARRAY_SIZE(args); i++) {
720 rc = syscall(__NR_perf_event_open, args[i].attr, args[i].pid,
721 args[i].cpu, args[i].group_fd, args[i].flags);
722 printf("perf_event_open(%s, %d, %d, %d, %s) = %s\n",
723 printaddr(args[i].attr), args[i].pid, args[i].cpu,
724 args[i].group_fd, args[i].flags_str, sprintrc(rc));
727 for (i = 0; i < ARRAY_SIZE(attrs) * ARRAY_SIZE(attr_types) *
728 ARRAY_SIZE(attr_configs[0]) + 1; i++) {
729 struct perf_event_attr *attr = attrs[i % ARRAY_SIZE(attrs)].ptr;
730 uint32_t size = attrs[i % ARRAY_SIZE(attrs)].size;
731 unsigned char fill_start = 0x80 + i;
732 size_t type_idx = i % ARRAY_SIZE(attr_types);
733 size_t config_idx = i % ARRAY_SIZE(attr_configs[0]);
734 size_t sample_type_idx = i % ARRAY_SIZE(sample_types);
735 size_t read_format_idx = i % ARRAY_SIZE(read_formats);
736 size_t bp_type_idx = (i / ARRAY_SIZE(attr_configs[0])) %
737 ARRAY_SIZE(bp_types);
738 size_t branch_sample_type_idx = (i / ARRAY_SIZE(sample_types)) %
739 ARRAY_SIZE(branch_sample_types);
740 size_t clockid_idx = i % ARRAY_SIZE(clockids);
741 size_t args_idx = i % ARRAY_SIZE(args);
742 const char *ip_desc_str;
744 fill_memory_ex(attr, size, fill_start, 0xff);
746 attr->type = attr_types[type_idx].val;
748 attr->config = attr_configs[type_idx][config_idx].val;
749 attr->sample_type = sample_types[sample_type_idx].val;
750 attr->read_format = read_formats[read_format_idx].val;
753 attr->__reserved_1 = 0;
755 # ifdef HAVE_STRUCT_PERF_EVENT_ATTR_BP_TYPE
758 ((uint32_t *) attr)[52 / sizeof(uint32_t)] =
760 bp_types[bp_type_idx].val;
763 # ifdef HAVE_STRUCT_PERF_EVENT_ATTR_BRANCH_SAMPLE_TYPE
764 attr->branch_sample_type =
766 ((uint64_t *) attr)[72 / sizeof(uint64_t)] =
768 branch_sample_types[branch_sample_type_idx].val;
771 # ifdef HAVE_STRUCT_PERF_EVENT_ATTR_CLOCKID
774 ((uint32_t *) attr)[92 / sizeof(uint32_t)] =
776 clockids[clockid_idx].val;
778 # ifdef HAVE_STRUCT_PERF_EVENT_ATTR_PRECISE_IP
779 ip_desc_str = precise_ip_descs[attr->precise_ip];
782 struct pea_flags flags;
784 } flags_data = { .raw = ((uint64_t *) attr)[5] };
786 ip_desc_str = precise_ip_descs[flags_data.flags.precise_ip];
790 attr->size = size + 8;
795 rc = syscall(__NR_perf_event_open, attr, args[args_idx].pid,
796 args[args_idx].cpu, args[args_idx].group_fd,
797 args[args_idx].flags);
799 printf("perf_event_open(");
800 print_event_attr(attr, i ? ((i == 1) ? 0 : size) : size + 8,
801 attr_types[type_idx].str,
802 attr_configs[type_idx][config_idx].str,
803 sample_types[sample_type_idx].str,
804 read_formats[read_format_idx].str,
806 bp_types[bp_type_idx].str,
807 branch_sample_types[branch_sample_type_idx].str,
808 clockids[clockid_idx].str, size);
809 printf(", %d, %d, %d, %s) = %s\n", args[args_idx].pid,
810 args[args_idx].cpu, args[args_idx].group_fd,
811 args[args_idx].flags_str, sprintrc(rc));
814 puts("+++ exited with 0 +++");
820 SKIP_MAIN_UNDEFINED("__NR_perf_event_open && HAVE_LINUX_PERF_EVENT_H");