int main()

in bpf/task_fd_query_user.c [311:424]


int main(int argc, char **argv)
{
	extern char __executable_start;
	char filename[256], buf[256];
	__u64 uprobe_file_offset;
	struct bpf_program *prog;
	struct bpf_object *obj;
	int i = 0, err = -1;

	if (load_kallsyms()) {
		printf("failed to process /proc/kallsyms\n");
		return err;
	}

	snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
	obj = bpf_object__open_file(filename, NULL);
	if (libbpf_get_error(obj)) {
		fprintf(stderr, "ERROR: opening BPF object file failed\n");
		return err;
	}

	/* load BPF program */
	if (bpf_object__load(obj)) {
		fprintf(stderr, "ERROR: loading BPF object file failed\n");
		goto cleanup;
	}

	bpf_object__for_each_program(prog, obj) {
		progs[i] = prog;
		links[i] = bpf_program__attach(progs[i]);
		if (libbpf_get_error(links[i])) {
			fprintf(stderr, "ERROR: bpf_program__attach failed\n");
			links[i] = NULL;
			goto cleanup;
		}
		i++;
	}

	/* test two functions in the corresponding *_kern.c file */
	CHECK_AND_RET(test_debug_fs_kprobe(0, "blk_mq_start_request",
					   BPF_FD_TYPE_KPROBE));
	CHECK_AND_RET(test_debug_fs_kprobe(1, "blk_account_io_done",
					   BPF_FD_TYPE_KRETPROBE));

	/* test nondebug fs kprobe */
	CHECK_AND_RET(test_nondebug_fs_probe("kprobe", "bpf_check", 0x0, 0x0,
					     false, BPF_FD_TYPE_KPROBE,
					     BPF_FD_TYPE_KRETPROBE,
					     buf, sizeof(buf)));
#ifdef __x86_64__
	/* set a kprobe on "bpf_check + 0x5", which is x64 specific */
	CHECK_AND_RET(test_nondebug_fs_probe("kprobe", "bpf_check", 0x5, 0x0,
					     false, BPF_FD_TYPE_KPROBE,
					     BPF_FD_TYPE_KRETPROBE,
					     buf, sizeof(buf)));
#endif
	CHECK_AND_RET(test_nondebug_fs_probe("kprobe", "bpf_check", 0x0, 0x0,
					     true, BPF_FD_TYPE_KPROBE,
					     BPF_FD_TYPE_KRETPROBE,
					     buf, sizeof(buf)));
	CHECK_AND_RET(test_nondebug_fs_probe("kprobe", NULL, 0x0,
					     ksym_get_addr("bpf_check"), false,
					     BPF_FD_TYPE_KPROBE,
					     BPF_FD_TYPE_KRETPROBE,
					     buf, sizeof(buf)));
	CHECK_AND_RET(test_nondebug_fs_probe("kprobe", NULL, 0x0,
					     ksym_get_addr("bpf_check"), false,
					     BPF_FD_TYPE_KPROBE,
					     BPF_FD_TYPE_KRETPROBE,
					     NULL, 0));
	CHECK_AND_RET(test_nondebug_fs_probe("kprobe", NULL, 0x0,
					     ksym_get_addr("bpf_check"), true,
					     BPF_FD_TYPE_KPROBE,
					     BPF_FD_TYPE_KRETPROBE,
					     buf, sizeof(buf)));
	CHECK_AND_RET(test_nondebug_fs_probe("kprobe", NULL, 0x0,
					     ksym_get_addr("bpf_check"), true,
					     BPF_FD_TYPE_KPROBE,
					     BPF_FD_TYPE_KRETPROBE,
					     0, 0));

	/* test nondebug fs uprobe */
	/* the calculation of uprobe file offset is based on gcc 7.3.1 on x64
	 * and the default linker script, which defines __executable_start as
	 * the start of the .text section. The calculation could be different
	 * on different systems with different compilers. The right way is
	 * to parse the ELF file. We took a shortcut here.
	 */
	uprobe_file_offset = (unsigned long)main - (unsigned long)&__executable_start;
	CHECK_AND_RET(test_nondebug_fs_probe("uprobe", (char *)argv[0],
					     uprobe_file_offset, 0x0, false,
					     BPF_FD_TYPE_UPROBE,
					     BPF_FD_TYPE_URETPROBE,
					     buf, sizeof(buf)));
	CHECK_AND_RET(test_nondebug_fs_probe("uprobe", (char *)argv[0],
					     uprobe_file_offset, 0x0, true,
					     BPF_FD_TYPE_UPROBE,
					     BPF_FD_TYPE_URETPROBE,
					     buf, sizeof(buf)));

	/* test debug fs uprobe */
	CHECK_AND_RET(test_debug_fs_uprobe((char *)argv[0], uprobe_file_offset,
					   false));
	CHECK_AND_RET(test_debug_fs_uprobe((char *)argv[0], uprobe_file_offset,
					   true));
	err = 0;

cleanup:
	for (i--; i >= 0; i--)
		bpf_link__destroy(links[i]);

	bpf_object__close(obj);
	return err;
}