On Wed, Mar 26, 2025 at 11:07 AM Mykyta Yatsenko <mykyta.yatsenko5@xxxxxxxxx> wrote: > > From: Mykyta Yatsenko <yatsenko@xxxxxxxx> > > Introducing new libbpf API getters for BTF.ext func and line info, > namely: > bpf_program__func_info > bpf_program__func_info_cnt > bpf_program__func_info_rec_size > bpf_program__line_info > bpf_program__line_info_cnt > bpf_program__line_info_rec_size > > This change enables scenarios, when user needs to load bpf_program > directly using `bpf_prog_load`, instead of higher-level > `bpf_object__load`. Line and func info are required for checking BTF > info in verifier; verification may fail without these fields if, for > example, program calls `bpf_obj_new`. > Really, bpf_obj_new() needs func_info/line_info? Can you point where in the verifier we check this, curious why we do that. > Signed-off-by: Mykyta Yatsenko <yatsenko@xxxxxxxx> > --- > tools/lib/bpf/libbpf.c | 30 ++++++++++++++++++++++++++++++ > tools/lib/bpf/libbpf.h | 8 ++++++++ > tools/lib/bpf/libbpf.map | 6 ++++++ > 3 files changed, 44 insertions(+) > > diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c > index 6b85060f07b3..bc15526ed84c 100644 > --- a/tools/lib/bpf/libbpf.c > +++ b/tools/lib/bpf/libbpf.c > @@ -9455,6 +9455,36 @@ int bpf_program__set_log_buf(struct bpf_program *prog, char *log_buf, size_t log > return 0; > } > > +void *bpf_program__func_info(struct bpf_program *prog) const struct bpf_program, here and everywhere else > +{ > + return prog->func_info; > +} > + > +__u32 bpf_program__func_info_cnt(struct bpf_program *prog) > +{ > + return prog->func_info_cnt; > +} > + > +__u32 bpf_program__func_info_rec_size(struct bpf_program *prog) > +{ > + return prog->func_info_rec_size; > +} > + > +void *bpf_program__line_info(struct bpf_program *prog) should be `const void *`, if we went with `void *`, but see below about types > +{ > + return prog->line_info; > +} > + > +__u32 bpf_program__line_info_cnt(struct bpf_program *prog) > +{ > + return prog->line_info_cnt; > +} > + > +__u32 bpf_program__line_info_rec_size(struct bpf_program *prog) > +{ > + return prog->line_info_rec_size; > +} > + As Eduard mentioned, I don't think `void *` is a good interface. We have bpf_line_info_min and bpf_func_info_min structs in libbpf_internal.h. We have never changed those types, so at this point I feel comfortable enough to expose them as API types. Let's drop the _min suffix, and move definitions to btf.h? The only question is whether to document that each record could be bigger in size than sizeof(struct bpf_func_info) (and similarly for bpf_line_info), and thus user should always care about func_info_rec_size? Or, to keep it ergonomic and simple, and basically always return sizeof(struct bpf_func_info) data (and if it so happens that we'll in the future have different record sizes, then we'll create a local trimmed representation for user; it's a pain, but we won't be really stuck from API compatibility standpoint). I'd go with simple and ergonomic, given we haven't ever extended these records, and it's unlikely we will. Those types work well and provide enough information as is. So let's not even add _rec_size() APIs (at least for now; we can always revisit this later) pw-bot: cr > #define SEC_DEF(sec_pfx, ptype, atype, flags, ...) { \ > .sec = (char *)sec_pfx, \ > .prog_type = BPF_PROG_TYPE_##ptype, \ > diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h > index e0605403f977..29a5fd7f51f0 100644 > --- a/tools/lib/bpf/libbpf.h > +++ b/tools/lib/bpf/libbpf.h > @@ -940,6 +940,14 @@ LIBBPF_API int bpf_program__set_log_level(struct bpf_program *prog, __u32 log_le > LIBBPF_API const char *bpf_program__log_buf(const struct bpf_program *prog, size_t *log_size); > LIBBPF_API int bpf_program__set_log_buf(struct bpf_program *prog, char *log_buf, size_t log_size); > > +LIBBPF_API void *bpf_program__func_info(struct bpf_program *prog); > +LIBBPF_API __u32 bpf_program__func_info_cnt(struct bpf_program *prog); > +LIBBPF_API __u32 bpf_program__func_info_rec_size(struct bpf_program *prog); > + > +LIBBPF_API void *bpf_program__line_info(struct bpf_program *prog); > +LIBBPF_API __u32 bpf_program__line_info_cnt(struct bpf_program *prog); > +LIBBPF_API __u32 bpf_program__line_info_rec_size(struct bpf_program *prog); > + > /** > * @brief **bpf_program__set_attach_target()** sets BTF-based attach target > * for supported BPF program types: > diff --git a/tools/lib/bpf/libbpf.map b/tools/lib/bpf/libbpf.map > index d8b71f22f197..a5d83189c084 100644 > --- a/tools/lib/bpf/libbpf.map > +++ b/tools/lib/bpf/libbpf.map > @@ -437,6 +437,12 @@ LIBBPF_1.6.0 { > bpf_linker__add_fd; > bpf_linker__new_fd; > bpf_object__prepare; > + bpf_program__func_info; > + bpf_program__func_info_cnt; > + bpf_program__func_info_rec_size; > + bpf_program__line_info; > + bpf_program__line_info_cnt; > + bpf_program__line_info_rec_size; > btf__add_decl_attr; > btf__add_type_attr; > } LIBBPF_1.5.0; > -- > 2.48.1 >