On Fri, Mar 22, 2024 at 3:25 AM Alan Maguire <alan.maguire@xxxxxxxxxx> wrote: > > Options cover existing parsing scenarios (ELF, raw, retrieving > .BTF.ext) and also allow specification of the ELF section name > containing BTF. This will allow consumers to retrieve BTF from > .BTF.base_ref sections (BTF_BASE_REF_ELF_SEC) also. > > Signed-off-by: Alan Maguire <alan.maguire@xxxxxxxxxx> > --- > tools/lib/bpf/btf.c | 24 ++++++++++++++++++------ > tools/lib/bpf/btf.h | 32 ++++++++++++++++++++++++++++++++ > tools/lib/bpf/libbpf.map | 1 + > 3 files changed, 51 insertions(+), 6 deletions(-) > [...] > +struct btf *btf__parse_opts(const char *path, struct btf_parse_opts *opts) > +{ > + if (!OPTS_VALID(opts, btf_parse_opts)) > + return libbpf_err_ptr(-EINVAL); > + if (opts && !opts->btf_sec) please use OPTS_GET() macro to access members of opts structs > + return btf__parse_raw_split(path, opts ? opts->base_btf : NULL); this should still work for ELF parsing, so use btf_parse() which can deal both with raw BTF and parse ELF (defaulting to .BTF section) > + return libbpf_ptr(btf_parse_elf(path, > + opts ? opts->btf_sec : BTF_ELF_SEC, > + opts ? opts->base_btf : NULL, > + opts ? &opts->btf_ext : NULL)); ditto > +} > + > static struct btf *btf_parse(const char *path, struct btf *base_btf, struct btf_ext **btf_ext) > { > struct btf *btf; > @@ -1307,7 +1319,7 @@ static struct btf *btf_parse(const char *path, struct btf *base_btf, struct btf_ > return btf; > if (err != -EPROTO) > return ERR_PTR(err); > - return btf_parse_elf(path, base_btf, btf_ext); > + return btf_parse_elf(path, BTF_ELF_SEC, base_btf, btf_ext); > } > > struct btf *btf__parse(const char *path, struct btf_ext **btf_ext) > diff --git a/tools/lib/bpf/btf.h b/tools/lib/bpf/btf.h > index f2a853d6fa55..c63043520149 100644 > --- a/tools/lib/bpf/btf.h > +++ b/tools/lib/bpf/btf.h > @@ -18,6 +18,7 @@ extern "C" { > > #define BTF_ELF_SEC ".BTF" > #define BTF_EXT_ELF_SEC ".BTF.ext" > +#define BTF_BASE_REF_ELF_SEC ".BTF.base_ref" > #define MAPS_ELF_SEC ".maps" > > struct btf; > @@ -129,6 +130,37 @@ LIBBPF_API struct btf *btf__parse_elf_split(const char *path, struct btf *base_b > LIBBPF_API struct btf *btf__parse_raw(const char *path); > LIBBPF_API struct btf *btf__parse_raw_split(const char *path, struct btf *base_btf); > > +struct btf_parse_opts { > + size_t sz; > + /* use base BTF to parse split BTF */ > + struct btf *base_btf; > + /* retrieve optional .BTF.ext info */ > + struct btf_ext *btf_ext; shouldn't this be a pointer to a pointer, it's an output parameter, right? This will give control to users to define if they are interested in .BTF.ext content or not (NULL means "don't bother parsing") > + /* BTF section name */ > + const char *btf_sec; > + size_t:0; > +}; > + > +#define btf_parse_opts__last_field btf_sec > + > +/* @brief **btf__parse_opts()** parses BTF information from either a > + * raw BTF file (*btf_sec* is NULL) or from the specified BTF section, > + * also retrieving .BTF.ext info if *btf_ext* is non-NULL. If > + * *base_btf* is specified, use it to parse split BTF from the > + * specified location. > + * > + * @return new BTF object instance which has to be eventually freed with > + * **btf__free()** > + * > + * On error, error-code-encoded-as-pointer is returned, not a NULL. To extract > + * error code from such a pointer `libbpf_get_error()` should be used. If > + * `libbpf_set_strict_mode(LIBBPF_STRICT_CLEAN_PTRS)` is enabled, NULL is > + * returned on error instead. In both cases thread-local `errno` variable is > + * always set to error code as well. > + */ > + > +LIBBPF_API struct btf *btf__parse_opts(const char *path, struct btf_parse_opts *opts); > + > LIBBPF_API struct btf *btf__load_vmlinux_btf(void); > LIBBPF_API struct btf *btf__load_module_btf(const char *module_name, struct btf *vmlinux_btf); > > diff --git a/tools/lib/bpf/libbpf.map b/tools/lib/bpf/libbpf.map > index 3d53b1781af1..e9a7cb9c3c5b 100644 > --- a/tools/lib/bpf/libbpf.map > +++ b/tools/lib/bpf/libbpf.map > @@ -415,5 +415,6 @@ LIBBPF_1.4.0 { > bpf_token_create; > btf__new_split; > btf__new_split_base_ref; > + btf__parse_opts; for the next revision, please put it into 1.5.0 section, we'll have 1.4 release soon, so let's avoid accidentally adding this back to 1.4 > btf_ext__raw_data; > } LIBBPF_1.3.0; > -- > 2.39.3 >