Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'libbpf-introduce-line_info-and-func_info-getters'

Mykyta Yatsenko says:

====================
libbpf: introduce line_info and func_info getters

From: Mykyta Yatsenko <yatsenko@meta.com>

This patchset introduces new libbpf API getters that enable the retrieval
of .BTF.ext line and func info.
This change enables users to load bpf_program directly using bpf_prog_load,
bypassing the higher-level bpf_object__load API. Providing line and
function info is essential for BPF program verification in some cases.

v3 -> v5
* Fix tests on s390x, nits.

v2 -> v3
* Return ENOTSUPP if func or line info struct size differs from the one in
uapi linux headers.
* Add selftests.

v1 -> v2
Move bpf_line_info_min and bpf_func_info_min from libbpf_internal.h to
btf.h. Did not remove _min suffix, because there already are bpf_line_info
and bpf_func_info structs in uapi/../bpf.h.
====================

Link: https://patch.msgid.link/20250408234417.452565-1-mykyta.yatsenko5@gmail.com
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>

+120
+24
tools/lib/bpf/libbpf.c
··· 9446 9446 return 0; 9447 9447 } 9448 9448 9449 + struct bpf_func_info *bpf_program__func_info(const struct bpf_program *prog) 9450 + { 9451 + if (prog->func_info_rec_size != sizeof(struct bpf_func_info)) 9452 + return libbpf_err_ptr(-EOPNOTSUPP); 9453 + return prog->func_info; 9454 + } 9455 + 9456 + __u32 bpf_program__func_info_cnt(const struct bpf_program *prog) 9457 + { 9458 + return prog->func_info_cnt; 9459 + } 9460 + 9461 + struct bpf_line_info *bpf_program__line_info(const struct bpf_program *prog) 9462 + { 9463 + if (prog->line_info_rec_size != sizeof(struct bpf_line_info)) 9464 + return libbpf_err_ptr(-EOPNOTSUPP); 9465 + return prog->line_info; 9466 + } 9467 + 9468 + __u32 bpf_program__line_info_cnt(const struct bpf_program *prog) 9469 + { 9470 + return prog->line_info_cnt; 9471 + } 9472 + 9449 9473 #define SEC_DEF(sec_pfx, ptype, atype, flags, ...) { \ 9450 9474 .sec = (char *)sec_pfx, \ 9451 9475 .prog_type = BPF_PROG_TYPE_##ptype, \
+6
tools/lib/bpf/libbpf.h
··· 940 940 LIBBPF_API const char *bpf_program__log_buf(const struct bpf_program *prog, size_t *log_size); 941 941 LIBBPF_API int bpf_program__set_log_buf(struct bpf_program *prog, char *log_buf, size_t log_size); 942 942 943 + LIBBPF_API struct bpf_func_info *bpf_program__func_info(const struct bpf_program *prog); 944 + LIBBPF_API __u32 bpf_program__func_info_cnt(const struct bpf_program *prog); 945 + 946 + LIBBPF_API struct bpf_line_info *bpf_program__line_info(const struct bpf_program *prog); 947 + LIBBPF_API __u32 bpf_program__line_info_cnt(const struct bpf_program *prog); 948 + 943 949 /** 944 950 * @brief **bpf_program__set_attach_target()** sets BTF-based attach target 945 951 * for supported BPF program types:
+4
tools/lib/bpf/libbpf.map
··· 437 437 bpf_linker__add_fd; 438 438 bpf_linker__new_fd; 439 439 bpf_object__prepare; 440 + bpf_program__func_info; 441 + bpf_program__func_info_cnt; 442 + bpf_program__line_info; 443 + bpf_program__line_info_cnt; 440 444 btf__add_decl_attr; 441 445 btf__add_type_attr; 442 446 } LIBBPF_1.5.0;
+64
tools/testing/selftests/bpf/prog_tests/test_btf_ext.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* Copyright (c) 2025 Meta Platforms Inc. */ 3 + #include <test_progs.h> 4 + #include "test_btf_ext.skel.h" 5 + #include "btf_helpers.h" 6 + 7 + static void subtest_line_func_info(void) 8 + { 9 + struct test_btf_ext *skel; 10 + struct bpf_prog_info info; 11 + struct bpf_line_info line_info[128], *libbpf_line_info; 12 + struct bpf_func_info func_info[128], *libbpf_func_info; 13 + __u32 info_len = sizeof(info), libbbpf_line_info_cnt, libbbpf_func_info_cnt; 14 + int err, fd; 15 + 16 + skel = test_btf_ext__open_and_load(); 17 + if (!ASSERT_OK_PTR(skel, "skel_open_and_load")) 18 + return; 19 + 20 + fd = bpf_program__fd(skel->progs.global_func); 21 + 22 + memset(&info, 0, sizeof(info)); 23 + info.line_info = ptr_to_u64(&line_info); 24 + info.nr_line_info = sizeof(line_info); 25 + info.line_info_rec_size = sizeof(*line_info); 26 + err = bpf_prog_get_info_by_fd(fd, &info, &info_len); 27 + if (!ASSERT_OK(err, "prog_line_info")) 28 + goto out; 29 + 30 + libbpf_line_info = bpf_program__line_info(skel->progs.global_func); 31 + libbbpf_line_info_cnt = bpf_program__line_info_cnt(skel->progs.global_func); 32 + 33 + memset(&info, 0, sizeof(info)); 34 + info.func_info = ptr_to_u64(&func_info); 35 + info.nr_func_info = sizeof(func_info); 36 + info.func_info_rec_size = sizeof(*func_info); 37 + err = bpf_prog_get_info_by_fd(fd, &info, &info_len); 38 + if (!ASSERT_OK(err, "prog_func_info")) 39 + goto out; 40 + 41 + libbpf_func_info = bpf_program__func_info(skel->progs.global_func); 42 + libbbpf_func_info_cnt = bpf_program__func_info_cnt(skel->progs.global_func); 43 + 44 + if (!ASSERT_OK_PTR(libbpf_line_info, "bpf_program__line_info")) 45 + goto out; 46 + if (!ASSERT_EQ(libbbpf_line_info_cnt, info.nr_line_info, "line_info_cnt")) 47 + goto out; 48 + if (!ASSERT_OK_PTR(libbpf_func_info, "bpf_program__func_info")) 49 + goto out; 50 + if (!ASSERT_EQ(libbbpf_func_info_cnt, info.nr_func_info, "func_info_cnt")) 51 + goto out; 52 + ASSERT_MEMEQ(libbpf_line_info, line_info, libbbpf_line_info_cnt * sizeof(*line_info), 53 + "line_info"); 54 + ASSERT_MEMEQ(libbpf_func_info, func_info, libbbpf_func_info_cnt * sizeof(*func_info), 55 + "func_info"); 56 + out: 57 + test_btf_ext__destroy(skel); 58 + } 59 + 60 + void test_btf_ext(void) 61 + { 62 + if (test__start_subtest("line_func_info")) 63 + subtest_line_func_info(); 64 + }
+22
tools/testing/selftests/bpf/progs/test_btf_ext.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* Copyright (c) 2025 Meta Platforms Inc. */ 3 + 4 + #include <linux/bpf.h> 5 + #include <bpf/bpf_helpers.h> 6 + #include "bpf_misc.h" 7 + 8 + char _license[] SEC("license") = "GPL"; 9 + 10 + __noinline static void f0(void) 11 + { 12 + __u64 a = 1; 13 + 14 + __sink(a); 15 + } 16 + 17 + SEC("xdp") 18 + __u64 global_func(struct xdp_md *xdp) 19 + { 20 + f0(); 21 + return XDP_DROP; 22 + }