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 81e8611bbSAndrii Nakryiko void test_attach_probe(void) 91e8611bbSAndrii Nakryiko { 104bd11e08SAndrii Nakryiko DECLARE_LIBBPF_OPTS(bpf_uprobe_opts, uprobe_opts); 11f3c926a4SAndrii Nakryiko int duration = 0; 12f3c926a4SAndrii Nakryiko struct bpf_link *kprobe_link, *kretprobe_link; 13f3c926a4SAndrii Nakryiko struct bpf_link *uprobe_link, *uretprobe_link; 14f3c926a4SAndrii Nakryiko struct test_attach_probe* skel; 151e8611bbSAndrii Nakryiko size_t uprobe_offset; 164bd11e08SAndrii Nakryiko ssize_t base_addr, ref_ctr_offset; 17*d3b0e3b0SAndrii Nakryiko bool legacy; 18*d3b0e3b0SAndrii Nakryiko 19*d3b0e3b0SAndrii Nakryiko /* Check if new-style kprobe/uprobe API is supported. 20*d3b0e3b0SAndrii Nakryiko * Kernels that support new FD-based kprobe and uprobe BPF attachment 21*d3b0e3b0SAndrii Nakryiko * through perf_event_open() syscall expose 22*d3b0e3b0SAndrii Nakryiko * /sys/bus/event_source/devices/kprobe/type and 23*d3b0e3b0SAndrii Nakryiko * /sys/bus/event_source/devices/uprobe/type files, respectively. They 24*d3b0e3b0SAndrii Nakryiko * contain magic numbers that are passed as "type" field of 25*d3b0e3b0SAndrii Nakryiko * perf_event_attr. Lack of such file in the system indicates legacy 26*d3b0e3b0SAndrii Nakryiko * kernel with old-style kprobe/uprobe attach interface through 27*d3b0e3b0SAndrii Nakryiko * creating per-probe event through tracefs. For such cases 28*d3b0e3b0SAndrii Nakryiko * ref_ctr_offset feature is not supported, so we don't test it. 29*d3b0e3b0SAndrii Nakryiko */ 30*d3b0e3b0SAndrii Nakryiko legacy = access("/sys/bus/event_source/devices/kprobe/type", F_OK) != 0; 311e8611bbSAndrii Nakryiko 321e8611bbSAndrii Nakryiko base_addr = get_base_addr(); 331e8611bbSAndrii Nakryiko if (CHECK(base_addr < 0, "get_base_addr", 341e8611bbSAndrii Nakryiko "failed to find base addr: %zd", base_addr)) 351e8611bbSAndrii Nakryiko return; 36a549aaa6SAndrii Nakryiko uprobe_offset = get_uprobe_offset(&get_base_addr, base_addr); 371e8611bbSAndrii Nakryiko 384bd11e08SAndrii Nakryiko ref_ctr_offset = get_rel_offset((uintptr_t)&uprobe_ref_ctr); 394bd11e08SAndrii Nakryiko if (!ASSERT_GE(ref_ctr_offset, 0, "ref_ctr_offset")) 404bd11e08SAndrii Nakryiko return; 414bd11e08SAndrii Nakryiko 425dc7a8b2SAndrii Nakryiko skel = test_attach_probe__open_and_load(); 43f3c926a4SAndrii Nakryiko if (CHECK(!skel, "skel_open", "failed to open skeleton\n")) 441e8611bbSAndrii Nakryiko return; 45f3c926a4SAndrii Nakryiko if (CHECK(!skel->bss, "check_bss", ".bss wasn't mmap()-ed\n")) 46928ca75eSAndrii Nakryiko goto cleanup; 47928ca75eSAndrii Nakryiko 48f3c926a4SAndrii Nakryiko kprobe_link = bpf_program__attach_kprobe(skel->progs.handle_kprobe, 491e8611bbSAndrii Nakryiko false /* retprobe */, 501cb59a60SIlya Leoshkevich SYS_NANOSLEEP_KPROBE_NAME); 51bad2e478SAndrii Nakryiko if (!ASSERT_OK_PTR(kprobe_link, "attach_kprobe")) 521e8611bbSAndrii Nakryiko goto cleanup; 53f3c926a4SAndrii Nakryiko skel->links.handle_kprobe = kprobe_link; 54f3c926a4SAndrii Nakryiko 55f3c926a4SAndrii Nakryiko kretprobe_link = bpf_program__attach_kprobe(skel->progs.handle_kretprobe, 561e8611bbSAndrii Nakryiko true /* retprobe */, 571cb59a60SIlya Leoshkevich SYS_NANOSLEEP_KPROBE_NAME); 58bad2e478SAndrii Nakryiko if (!ASSERT_OK_PTR(kretprobe_link, "attach_kretprobe")) 591e8611bbSAndrii Nakryiko goto cleanup; 60f3c926a4SAndrii Nakryiko skel->links.handle_kretprobe = kretprobe_link; 61f3c926a4SAndrii Nakryiko 62*d3b0e3b0SAndrii Nakryiko if (!legacy) 634bd11e08SAndrii Nakryiko ASSERT_EQ(uprobe_ref_ctr, 0, "uprobe_ref_ctr_before"); 644bd11e08SAndrii Nakryiko 654bd11e08SAndrii Nakryiko uprobe_opts.retprobe = false; 66*d3b0e3b0SAndrii Nakryiko uprobe_opts.ref_ctr_offset = legacy ? 0 : ref_ctr_offset; 674bd11e08SAndrii Nakryiko uprobe_link = bpf_program__attach_uprobe_opts(skel->progs.handle_uprobe, 681e8611bbSAndrii Nakryiko 0 /* self pid */, 691e8611bbSAndrii Nakryiko "/proc/self/exe", 704bd11e08SAndrii Nakryiko uprobe_offset, 714bd11e08SAndrii Nakryiko &uprobe_opts); 72bad2e478SAndrii Nakryiko if (!ASSERT_OK_PTR(uprobe_link, "attach_uprobe")) 731e8611bbSAndrii Nakryiko goto cleanup; 74f3c926a4SAndrii Nakryiko skel->links.handle_uprobe = uprobe_link; 75f3c926a4SAndrii Nakryiko 76*d3b0e3b0SAndrii Nakryiko if (!legacy) 774bd11e08SAndrii Nakryiko ASSERT_GT(uprobe_ref_ctr, 0, "uprobe_ref_ctr_after"); 784bd11e08SAndrii Nakryiko 794bd11e08SAndrii Nakryiko /* if uprobe uses ref_ctr, uretprobe has to use ref_ctr as well */ 804bd11e08SAndrii Nakryiko uprobe_opts.retprobe = true; 81*d3b0e3b0SAndrii Nakryiko uprobe_opts.ref_ctr_offset = legacy ? 0 : ref_ctr_offset; 824bd11e08SAndrii Nakryiko uretprobe_link = bpf_program__attach_uprobe_opts(skel->progs.handle_uretprobe, 831e8611bbSAndrii Nakryiko -1 /* any pid */, 841e8611bbSAndrii Nakryiko "/proc/self/exe", 854bd11e08SAndrii Nakryiko uprobe_offset, &uprobe_opts); 86bad2e478SAndrii Nakryiko if (!ASSERT_OK_PTR(uretprobe_link, "attach_uretprobe")) 871e8611bbSAndrii Nakryiko goto cleanup; 88f3c926a4SAndrii Nakryiko skel->links.handle_uretprobe = uretprobe_link; 891e8611bbSAndrii Nakryiko 901e8611bbSAndrii Nakryiko /* trigger & validate kprobe && kretprobe */ 911e8611bbSAndrii Nakryiko usleep(1); 921e8611bbSAndrii Nakryiko 93f3c926a4SAndrii Nakryiko if (CHECK(skel->bss->kprobe_res != 1, "check_kprobe_res", 94f3c926a4SAndrii Nakryiko "wrong kprobe res: %d\n", skel->bss->kprobe_res)) 951e8611bbSAndrii Nakryiko goto cleanup; 96f3c926a4SAndrii Nakryiko if (CHECK(skel->bss->kretprobe_res != 2, "check_kretprobe_res", 97f3c926a4SAndrii Nakryiko "wrong kretprobe res: %d\n", skel->bss->kretprobe_res)) 981e8611bbSAndrii Nakryiko goto cleanup; 991e8611bbSAndrii Nakryiko 1001e8611bbSAndrii Nakryiko /* trigger & validate uprobe & uretprobe */ 1011e8611bbSAndrii Nakryiko get_base_addr(); 1021e8611bbSAndrii Nakryiko 103f3c926a4SAndrii Nakryiko if (CHECK(skel->bss->uprobe_res != 3, "check_uprobe_res", 104f3c926a4SAndrii Nakryiko "wrong uprobe res: %d\n", skel->bss->uprobe_res)) 1051e8611bbSAndrii Nakryiko goto cleanup; 106f3c926a4SAndrii Nakryiko if (CHECK(skel->bss->uretprobe_res != 4, "check_uretprobe_res", 107f3c926a4SAndrii Nakryiko "wrong uretprobe res: %d\n", skel->bss->uretprobe_res)) 1081e8611bbSAndrii Nakryiko goto cleanup; 1091e8611bbSAndrii Nakryiko 1101e8611bbSAndrii Nakryiko cleanup: 111f3c926a4SAndrii Nakryiko test_attach_probe__destroy(skel); 1124bd11e08SAndrii Nakryiko ASSERT_EQ(uprobe_ref_ctr, 0, "uprobe_ref_ctr_cleanup"); 1131e8611bbSAndrii Nakryiko } 114