Re: [RFC bpf-next 04/13] libbpf: add btf__parse_opts() API for flexible BTF parsing

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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
>





[Index of Archives]     [Linux Samsung SoC]     [Linux Rockchip SoC]     [Linux Actions SoC]     [Linux for Synopsys ARC Processors]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]


  Powered by Linux