(root)/
strace-6.5/
tests/
ioctl_perf-success.c
       1  /*
       2   * Check decoding of successful PERF_EVENT_IOC_{ID,QUERY_BPF} ioctls.
       3   *
       4   * Copyright (c) 2018-2021 The strace developers.
       5   * All rights reserved.
       6   *
       7   * SPDX-License-Identifier: GPL-2.0-or-later
       8   */
       9  
      10  #include "tests.h"
      11  #include <assert.h>
      12  #include <inttypes.h>
      13  #include <stdio.h>
      14  #include <stdlib.h>
      15  #include <string.h>
      16  #include <sys/ioctl.h>
      17  #include <linux/perf_event.h>
      18  
      19  int
      20  main(int argc, char **argv)
      21  {
      22  	static const uint64_t magic64 = 0xfacefeeddeadc0deULL;
      23  
      24  	TAIL_ALLOC_OBJECT_CONST_PTR(uint64_t, u64_ptr);
      25  	uint64_t *const u64_efault = u64_ptr + 1;
      26  	uint32_t *const u32_arr = tail_alloc(sizeof(uint32_t) * 4);
      27  	uint32_t *const u32_efault = u32_arr + 4;
      28  
      29  	unsigned long num_skip;
      30  	long inject_retval;
      31  	bool locked = false;
      32  
      33  	*u64_ptr = magic64;
      34  
      35  	if (argc == 1)
      36  		return 0;
      37  
      38  	if (argc < 3)
      39  		error_msg_and_fail("Usage: %s NUM_SKIP INJECT_RETVAL", argv[0]);
      40  
      41  	num_skip = strtoul(argv[1], NULL, 0);
      42  	inject_retval = strtol(argv[2], NULL, 0);
      43  
      44  	if (inject_retval < 0)
      45  		error_msg_and_fail("Expected non-negative INJECT_RETVAL, "
      46  				   "but got %ld", inject_retval);
      47  
      48  	for (unsigned long i = 0; i < num_skip; i++) {
      49  		long ret = ioctl(-1, PERF_EVENT_IOC_ID, NULL);
      50  
      51  		printf("ioctl(-1, PERF_EVENT_IOC_ID, NULL) = %s%s\n",
      52  		       sprintrc(ret),
      53  		       ret == inject_retval ? " (INJECTED)" : "");
      54  
      55  		if (ret != inject_retval)
      56  			continue;
      57  
      58  		locked = true;
      59  		break;
      60  	}
      61  
      62  	if (!locked)
      63  		error_msg_and_fail("Hasn't locked on ioctl(-1"
      64  				   ", PERF_EVENT_IOC_ID, NULL) returning %lu",
      65  				   inject_retval);
      66  
      67  	/* PERF_EVENT_IOC_ID */
      68  	assert(ioctl(-1, PERF_EVENT_IOC_ID, NULL) == inject_retval);
      69  	printf("ioctl(-1, PERF_EVENT_IOC_ID, NULL) = %ld (INJECTED)\n",
      70  	       inject_retval);
      71  
      72  	assert(ioctl(-1, PERF_EVENT_IOC_ID, u64_efault) == inject_retval);
      73  	printf("ioctl(-1, PERF_EVENT_IOC_ID, %p) = %ld (INJECTED)\n",
      74  	       u64_efault, inject_retval);
      75  
      76  	assert(ioctl(-1, PERF_EVENT_IOC_ID, u64_ptr) == inject_retval);
      77  	printf("ioctl(-1, PERF_EVENT_IOC_ID, [%" PRIu64 "]) = %ld (INJECTED)\n",
      78  	       magic64, inject_retval);
      79  
      80  	/* PERF_EVENT_IOC_QUERY_BPF */
      81  	assert(ioctl(-1, PERF_EVENT_IOC_QUERY_BPF, NULL) == inject_retval);
      82  	printf("ioctl(-1, PERF_EVENT_IOC_QUERY_BPF, NULL) = %ld (INJECTED)\n",
      83  	       inject_retval);
      84  
      85  	assert(ioctl(-1, PERF_EVENT_IOC_QUERY_BPF, u32_efault)
      86  	       == inject_retval);
      87  	printf("ioctl(-1, PERF_EVENT_IOC_QUERY_BPF, %p) = %ld (INJECTED)\n",
      88  	       u32_efault, inject_retval);
      89  
      90  	u32_arr[3] = 0xdeadbeef;
      91  	assert(ioctl(-1, PERF_EVENT_IOC_QUERY_BPF, u32_arr + 3)
      92  	       == inject_retval);
      93  	printf("ioctl(-1, PERF_EVENT_IOC_QUERY_BPF, {ids_len=3735928559, ...}) "
      94  	       "= %ld (INJECTED)\n",
      95  	       inject_retval);
      96  
      97  	u32_arr[2] = 0xdecaffed;
      98  	assert(ioctl(-1, PERF_EVENT_IOC_QUERY_BPF, u32_arr + 2)
      99  	       == inject_retval);
     100  	printf("ioctl(-1, PERF_EVENT_IOC_QUERY_BPF, {ids_len=3737845741"
     101  	       ", prog_cnt=3735928559, ids=%p})"
     102  	       " = %ld (INJECTED)\n",
     103  	       u32_efault, inject_retval);
     104  
     105  	u32_arr[0] = 0xbadc0ded;
     106  	u32_arr[1] = 5;
     107  	assert(ioctl(-1, PERF_EVENT_IOC_QUERY_BPF, u32_arr) == inject_retval);
     108  	printf("ioctl(-1, PERF_EVENT_IOC_QUERY_BPF, {ids_len=3134983661"
     109  	       ", prog_cnt=5, ids=[3737845741, 3735928559, ... /* %p */]})"
     110  	       " = %ld (INJECTED)\n",
     111  	       u32_efault, inject_retval);
     112  
     113  	u32_arr[1] = 2;
     114  	assert(ioctl(-1, PERF_EVENT_IOC_QUERY_BPF, u32_arr) == inject_retval);
     115  	printf("ioctl(-1, PERF_EVENT_IOC_QUERY_BPF, {ids_len=3134983661"
     116  	       ", prog_cnt=2, ids=[3737845741, 3735928559]})"
     117  	       " = %ld (INJECTED)\n",
     118  	       inject_retval);
     119  
     120  	puts("+++ exited with 0 +++");
     121  	return 0;
     122  }