11e8611bbSAndrii Nakryiko // SPDX-License-Identifier: GPL-2.0 21e8611bbSAndrii Nakryiko #include <test_progs.h> 3f3c926a4SAndrii Nakryiko #include "test_attach_probe.skel.h" 41e8611bbSAndrii Nakryiko 54bd11e08SAndrii Nakryiko /* this is how USDT semaphore is actually defined, except volatile modifier */ 64bd11e08SAndrii Nakryiko volatile unsigned short uprobe_ref_ctr __attribute__((unused)) __attribute((section(".probes"))); 74bd11e08SAndrii Nakryiko 8*ff943683SAndrii Nakryiko /* uprobe attach point */ 9*ff943683SAndrii Nakryiko static void trigger_func(void) 10*ff943683SAndrii Nakryiko { 11*ff943683SAndrii Nakryiko asm volatile (""); 129e7240fbSYucong Sun } 139e7240fbSYucong Sun 141e8611bbSAndrii Nakryiko void test_attach_probe(void) 151e8611bbSAndrii Nakryiko { 164bd11e08SAndrii Nakryiko DECLARE_LIBBPF_OPTS(bpf_uprobe_opts, uprobe_opts); 17f3c926a4SAndrii Nakryiko int duration = 0; 18f3c926a4SAndrii Nakryiko struct bpf_link *kprobe_link, *kretprobe_link; 19f3c926a4SAndrii Nakryiko struct bpf_link *uprobe_link, *uretprobe_link; 20f3c926a4SAndrii Nakryiko struct test_attach_probe* skel; 21*ff943683SAndrii Nakryiko ssize_t uprobe_offset, ref_ctr_offset; 22d3b0e3b0SAndrii Nakryiko bool legacy; 23d3b0e3b0SAndrii Nakryiko 24d3b0e3b0SAndrii Nakryiko /* Check if new-style kprobe/uprobe API is supported. 25d3b0e3b0SAndrii Nakryiko * Kernels that support new FD-based kprobe and uprobe BPF attachment 26d3b0e3b0SAndrii Nakryiko * through perf_event_open() syscall expose 27d3b0e3b0SAndrii Nakryiko * /sys/bus/event_source/devices/kprobe/type and 28d3b0e3b0SAndrii Nakryiko * /sys/bus/event_source/devices/uprobe/type files, respectively. They 29d3b0e3b0SAndrii Nakryiko * contain magic numbers that are passed as "type" field of 30d3b0e3b0SAndrii Nakryiko * perf_event_attr. Lack of such file in the system indicates legacy 31d3b0e3b0SAndrii Nakryiko * kernel with old-style kprobe/uprobe attach interface through 32d3b0e3b0SAndrii Nakryiko * creating per-probe event through tracefs. For such cases 33d3b0e3b0SAndrii Nakryiko * ref_ctr_offset feature is not supported, so we don't test it. 34d3b0e3b0SAndrii Nakryiko */ 35d3b0e3b0SAndrii Nakryiko legacy = access("/sys/bus/event_source/devices/kprobe/type", F_OK) != 0; 361e8611bbSAndrii Nakryiko 37*ff943683SAndrii Nakryiko uprobe_offset = get_uprobe_offset(&trigger_func); 38*ff943683SAndrii Nakryiko if (!ASSERT_GE(uprobe_offset, 0, "uprobe_offset")) 391e8611bbSAndrii Nakryiko return; 401e8611bbSAndrii Nakryiko 414bd11e08SAndrii Nakryiko ref_ctr_offset = get_rel_offset((uintptr_t)&uprobe_ref_ctr); 424bd11e08SAndrii Nakryiko if (!ASSERT_GE(ref_ctr_offset, 0, "ref_ctr_offset")) 434bd11e08SAndrii Nakryiko return; 444bd11e08SAndrii Nakryiko 455dc7a8b2SAndrii Nakryiko skel = test_attach_probe__open_and_load(); 46f3c926a4SAndrii Nakryiko if (CHECK(!skel, "skel_open", "failed to open skeleton\n")) 471e8611bbSAndrii Nakryiko return; 48f3c926a4SAndrii Nakryiko if (CHECK(!skel->bss, "check_bss", ".bss wasn't mmap()-ed\n")) 49928ca75eSAndrii Nakryiko goto cleanup; 50928ca75eSAndrii Nakryiko 51f3c926a4SAndrii Nakryiko kprobe_link = bpf_program__attach_kprobe(skel->progs.handle_kprobe, 521e8611bbSAndrii Nakryiko false /* retprobe */, 531cb59a60SIlya Leoshkevich SYS_NANOSLEEP_KPROBE_NAME); 54bad2e478SAndrii Nakryiko if (!ASSERT_OK_PTR(kprobe_link, "attach_kprobe")) 551e8611bbSAndrii Nakryiko goto cleanup; 56f3c926a4SAndrii Nakryiko skel->links.handle_kprobe = kprobe_link; 57f3c926a4SAndrii Nakryiko 58f3c926a4SAndrii Nakryiko kretprobe_link = bpf_program__attach_kprobe(skel->progs.handle_kretprobe, 591e8611bbSAndrii Nakryiko true /* retprobe */, 601cb59a60SIlya Leoshkevich SYS_NANOSLEEP_KPROBE_NAME); 61bad2e478SAndrii Nakryiko if (!ASSERT_OK_PTR(kretprobe_link, "attach_kretprobe")) 621e8611bbSAndrii Nakryiko goto cleanup; 63f3c926a4SAndrii Nakryiko skel->links.handle_kretprobe = kretprobe_link; 64f3c926a4SAndrii Nakryiko 65d3b0e3b0SAndrii Nakryiko if (!legacy) 664bd11e08SAndrii Nakryiko ASSERT_EQ(uprobe_ref_ctr, 0, "uprobe_ref_ctr_before"); 674bd11e08SAndrii Nakryiko 684bd11e08SAndrii Nakryiko uprobe_opts.retprobe = false; 69d3b0e3b0SAndrii Nakryiko uprobe_opts.ref_ctr_offset = legacy ? 0 : ref_ctr_offset; 704bd11e08SAndrii Nakryiko uprobe_link = bpf_program__attach_uprobe_opts(skel->progs.handle_uprobe, 711e8611bbSAndrii Nakryiko 0 /* self pid */, 721e8611bbSAndrii Nakryiko "/proc/self/exe", 734bd11e08SAndrii Nakryiko uprobe_offset, 744bd11e08SAndrii Nakryiko &uprobe_opts); 75bad2e478SAndrii Nakryiko if (!ASSERT_OK_PTR(uprobe_link, "attach_uprobe")) 761e8611bbSAndrii Nakryiko goto cleanup; 77f3c926a4SAndrii Nakryiko skel->links.handle_uprobe = uprobe_link; 78f3c926a4SAndrii Nakryiko 79d3b0e3b0SAndrii Nakryiko if (!legacy) 804bd11e08SAndrii Nakryiko ASSERT_GT(uprobe_ref_ctr, 0, "uprobe_ref_ctr_after"); 814bd11e08SAndrii Nakryiko 824bd11e08SAndrii Nakryiko /* if uprobe uses ref_ctr, uretprobe has to use ref_ctr as well */ 834bd11e08SAndrii Nakryiko uprobe_opts.retprobe = true; 84d3b0e3b0SAndrii Nakryiko uprobe_opts.ref_ctr_offset = legacy ? 0 : ref_ctr_offset; 854bd11e08SAndrii Nakryiko uretprobe_link = bpf_program__attach_uprobe_opts(skel->progs.handle_uretprobe, 861e8611bbSAndrii Nakryiko -1 /* any pid */, 871e8611bbSAndrii Nakryiko "/proc/self/exe", 884bd11e08SAndrii Nakryiko uprobe_offset, &uprobe_opts); 89bad2e478SAndrii Nakryiko if (!ASSERT_OK_PTR(uretprobe_link, "attach_uretprobe")) 901e8611bbSAndrii Nakryiko goto cleanup; 91f3c926a4SAndrii Nakryiko skel->links.handle_uretprobe = uretprobe_link; 921e8611bbSAndrii Nakryiko 931e8611bbSAndrii Nakryiko /* trigger & validate kprobe && kretprobe */ 941e8611bbSAndrii Nakryiko usleep(1); 951e8611bbSAndrii Nakryiko 96f3c926a4SAndrii Nakryiko if (CHECK(skel->bss->kprobe_res != 1, "check_kprobe_res", 97f3c926a4SAndrii Nakryiko "wrong kprobe res: %d\n", skel->bss->kprobe_res)) 981e8611bbSAndrii Nakryiko goto cleanup; 99f3c926a4SAndrii Nakryiko if (CHECK(skel->bss->kretprobe_res != 2, "check_kretprobe_res", 100f3c926a4SAndrii Nakryiko "wrong kretprobe res: %d\n", skel->bss->kretprobe_res)) 1011e8611bbSAndrii Nakryiko goto cleanup; 1021e8611bbSAndrii Nakryiko 1031e8611bbSAndrii Nakryiko /* trigger & validate uprobe & uretprobe */ 104*ff943683SAndrii Nakryiko trigger_func(); 1051e8611bbSAndrii Nakryiko 106f3c926a4SAndrii Nakryiko if (CHECK(skel->bss->uprobe_res != 3, "check_uprobe_res", 107f3c926a4SAndrii Nakryiko "wrong uprobe res: %d\n", skel->bss->uprobe_res)) 1081e8611bbSAndrii Nakryiko goto cleanup; 109f3c926a4SAndrii Nakryiko if (CHECK(skel->bss->uretprobe_res != 4, "check_uretprobe_res", 110f3c926a4SAndrii Nakryiko "wrong uretprobe res: %d\n", skel->bss->uretprobe_res)) 1111e8611bbSAndrii Nakryiko goto cleanup; 1121e8611bbSAndrii Nakryiko 1131e8611bbSAndrii Nakryiko cleanup: 114f3c926a4SAndrii Nakryiko test_attach_probe__destroy(skel); 1154bd11e08SAndrii Nakryiko ASSERT_EQ(uprobe_ref_ctr, 0, "uprobe_ref_ctr_cleanup"); 1161e8611bbSAndrii Nakryiko } 117