public inbox for dwarves@vger.kernel.org
 help / color / mirror / Atom feed
From: Quentin Monnet <qmo@kernel.org>
To: Alan Maguire <alan.maguire@oracle.com>,
	andrii@kernel.org, ast@kernel.org
Cc: daniel@iogearbox.net, martin.lau@linux.dev, eddyz87@gmail.com,
	song@kernel.org, yonghong.song@linux.dev,
	john.fastabend@gmail.com, kpsingh@kernel.org, sdf@fomichev.me,
	haoluo@google.com, jolsa@kernel.org, masahiroy@kernel.org,
	ihor.solodrai@linux.dev, dwarves@vger.kernel.org,
	bpf@vger.kernel.org, ttreyer@meta.com
Subject: Re: [PATCH v5 bpf-next 8/9] bpftool: add BTF dump "format meta" to dump header/metadata
Date: Tue, 3 Jun 2025 11:22:25 +0100	[thread overview]
Message-ID: <736d2e41-5ee8-43d9-888e-954382fcca21@kernel.org> (raw)
In-Reply-To: <20250528095743.791722-9-alan.maguire@oracle.com>

2025-05-28 10:57 UTC+0100 ~ Alan Maguire <alan.maguire@oracle.com>
> Provide a way to dump BTF metadata info via bpftool; this
> consists of BTF size, header fields and kind layout info
> (if available); for example
> 
> $ bpftool btf dump file vmlinux format meta
> size 5169836
> magic 0xeb9f
> version 1
> flags 0x1
> hdr_len 40
> type_len 3041436
> type_off 0
> str_len 2128279
> str_off 3041436
> kind_layout_len 80
> kind_layout_off 5169716
> kind 0    UNKNOWN    flags 0x0    info_sz 0    elem_sz 0
> kind 1    INT        flags 0x0    info_sz 4    elem_sz 0
> kind 2    PTR        flags 0x0    info_sz 0    elem_sz 0
> kind 3    ARRAY      flags 0x0    info_sz 12   elem_sz 0
> kind 4    STRUCT     flags 0x0    info_sz 0    elem_sz 12
> ...
> 
> JSON output is also supported:
> 
> $ bpftool -j btf dump file vmlinux format meta | jq


Just so that you know, we have "bpftool -p" (which is the short version
for "bpftool --json --pretty") that will prettify the output without
requiring you to pipe to jq.


> {
>   "size": 5169836,
>   "header": {
>     "magic": 60319,
>     "version": 1,
>     "flags": 1,
>     "hdr_len": 40,
>     "type_len": 3041436,
>     "type_off": 0,
>     "str_len": 2128279,
>     "str_off": 3041436,
>     "kind_layout_len": 80,
>     "kind_layout_offset": 5169716,
>   },
>   "kind_layouts": [
>     {
>       "kind": 0,
>       "name": "UNKNOWN",
>       "flags": 0,
>       "info_sz": 0,
>       "elem_sz": 0
>     },
>     {
>       "kind": 1,
>       "name": "INT",
>       "flags": 0,
>       "info_sz": 4,
>       "elem_sz": 0
>     },
> ...
> 
> Signed-off-by: Alan Maguire <alan.maguire@oracle.com>
> ---
>  tools/bpf/bpftool/bash-completion/bpftool |  2 +-
>  tools/bpf/bpftool/btf.c                   | 90 ++++++++++++++++++++++-
>  2 files changed, 88 insertions(+), 4 deletions(-)
> 
> diff --git a/tools/bpf/bpftool/bash-completion/bpftool b/tools/bpf/bpftool/bash-completion/bpftool
> index 1ce409a6cbd9..8accc9e153a7 100644
> --- a/tools/bpf/bpftool/bash-completion/bpftool
> +++ b/tools/bpf/bpftool/bash-completion/bpftool
> @@ -928,7 +928,7 @@ _bpftool()
>                              return 0
>                              ;;
>                          format)
> -                            COMPREPLY=( $( compgen -W "c raw" -- "$cur" ) )
> +                            COMPREPLY=( $( compgen -W "c raw meta" -- "$cur" ) )
>                              ;;
>                          root_id)
>                              return 0;


Thanks for the bash completion; could you also please update bpftool's
documentation? The bpftool-btf.rst page (two locations: the "BTF
COMMANDS" summary at the top, and the command description - you could
even add the example from your commit description as an example at the
bottom of the page, if you'd like).


> diff --git a/tools/bpf/bpftool/btf.c b/tools/bpf/bpftool/btf.c
> index 6b14cbfa58aa..686608fb7b6c 100644
> --- a/tools/bpf/bpftool/btf.c
> +++ b/tools/bpf/bpftool/btf.c
> @@ -835,6 +835,86 @@ static int dump_btf_c(const struct btf *btf,
>  	return err;
>  }
>  
> +static int dump_btf_meta(const struct btf *btf)
> +{
> +	const struct btf_header *hdr;
> +	const struct btf_kind_layout *k;
> +	__u8 i, nr_kinds = 0;
> +	const void *data;
> +	__u32 data_sz;
> +
> +	data = btf__raw_data(btf, &data_sz);
> +	if (!data)
> +		return -ENOMEM;
> +	hdr = data;
> +	if (json_output) {
> +		jsonw_start_object(json_wtr);		/* metadata object */
> +		jsonw_uint_field(json_wtr, "size", data_sz);
> +		jsonw_name(json_wtr, "header");
> +		jsonw_start_object(json_wtr);		/* header object */
> +		jsonw_uint_field(json_wtr, "magic", hdr->magic);
> +		jsonw_uint_field(json_wtr, "version", hdr->version);
> +		jsonw_uint_field(json_wtr, "flags", hdr->flags);
> +		jsonw_uint_field(json_wtr, "hdr_len", hdr->hdr_len);
> +		jsonw_uint_field(json_wtr, "type_len", hdr->type_len);
> +		jsonw_uint_field(json_wtr, "type_off", hdr->type_off);
> +		jsonw_uint_field(json_wtr, "str_len", hdr->str_len);
> +		jsonw_uint_field(json_wtr, "str_off", hdr->str_off);
> +	} else {
> +		printf("size %-10u\n", data_sz);
> +		printf("magic 0x%-10x\nversion %-10d\nflags 0x%-10x\nhdr_len %-10u\n",
> +		       hdr->magic, hdr->version, hdr->flags, hdr->hdr_len);
> +		printf("type_len %-10u\ntype_off %-10u\n", hdr->type_len, hdr->type_off);
> +		printf("str_len %-10u\nstr_off %-10u\n", hdr->str_len, hdr->str_off);
> +	}
> +
> +	if (hdr->hdr_len < sizeof(struct btf_header)) {
> +		if (json_output) {
> +			jsonw_end_object(json_wtr);	/* end header object */
> +			jsonw_end_object(json_wtr);	/* end metadata object */
> +		}
> +		return 0;
> +	}
> +	if (hdr->kind_layout_len > 0 && hdr->kind_layout_off > 0) {
> +		k = (void *)hdr + hdr->hdr_len + hdr->kind_layout_off;
> +		nr_kinds = hdr->kind_layout_len / sizeof(*k);
> +	}
> +	if (json_output) {
> +		jsonw_uint_field(json_wtr, "kind_layout_len", hdr->kind_layout_len);
> +		jsonw_uint_field(json_wtr, "kind_layout_offset", hdr->kind_layout_off);
> +		jsonw_end_object(json_wtr);		/* end header object */
> +
> +		if (nr_kinds > 0) {
> +			jsonw_name(json_wtr, "kind_layouts");
> +			jsonw_start_array(json_wtr);
> +			for (i = 0; i < nr_kinds; i++) {
> +				jsonw_start_object(json_wtr);
> +				jsonw_uint_field(json_wtr, "kind", i);
> +				if (i < NR_BTF_KINDS)
> +					jsonw_string_field(json_wtr, "name", btf_kind_str[i]);
> +				else
> +					jsonw_null_field(json_wtr, "name");


Thanks!


> +				jsonw_uint_field(json_wtr, "flags", k[i].flags);
> +				jsonw_uint_field(json_wtr, "info_sz", k[i].info_sz);
> +				jsonw_uint_field(json_wtr, "elem_sz", k[i].elem_sz);
> +				jsonw_end_object(json_wtr);
> +			}
> +			jsonw_end_array(json_wtr);
> +		}
> +		jsonw_end_object(json_wtr);		/* end metadata object */


Why not have the fields unconditionally in JSON?

	...
	  "kind_layout_len": 0,
	  "kind_layout_offset": 0,
	},
	"kind_layouts": [
	]

This would allow tools to know explicitely that there's no kind layout
info, or to loop on kind_layouts without having to check for existence
first.

If the fields are not set, I find it always difficult to know if there's
no kind info or if bpftool didn't support dumping the kind info (in that
case this concern doesn't really apply because we add support for kind
info dump and the "meta" format at the same time, but users don't
necessarily know that).

Thanks,
Quentin

  reply	other threads:[~2025-06-03 10:22 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-05-28  9:57 [PATCH v5 bpf-next 0/9] Add kind layout to BTF Alan Maguire
2025-05-28  9:57 ` [PATCH v5 bpf-next 1/9] btf: add kind layout encoding to UAPI Alan Maguire
2025-05-28  9:57 ` [PATCH v5 bpf-next 2/9] libbpf: Support kind layout section handling in BTF Alan Maguire
2025-05-28  9:57 ` [PATCH v5 bpf-next 3/9] libbpf: use kind layout to compute an unknown kind size Alan Maguire
2025-05-29  5:35   ` Alexei Starovoitov
2025-05-29 12:53     ` Alan Maguire
2025-05-29 16:30       ` Alexei Starovoitov
2025-05-30 17:20         ` Alan Maguire
2025-05-28  9:57 ` [PATCH v5 bpf-next 4/9] libbpf: Add kind layout encoding support Alan Maguire
2025-05-28  9:57 ` [PATCH v5 bpf-next 5/9] libbpf: BTF validation can use kind layout for unknown kinds Alan Maguire
2025-05-28  9:57 ` [PATCH v5 bpf-next 6/9] btf: support kernel parsing of BTF with kind layout Alan Maguire
2025-05-28  9:57 ` [PATCH v5 bpf-next 7/9] selftests/bpf: test kind encoding/decoding Alan Maguire
2025-05-28  9:57 ` [PATCH v5 bpf-next 8/9] bpftool: add BTF dump "format meta" to dump header/metadata Alan Maguire
2025-06-03 10:22   ` Quentin Monnet [this message]
2025-05-28  9:57 ` [PATCH v5 bpf-next 9/9] kbuild, bpf: Specify "kind_layout" optional feature Alan Maguire

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=736d2e41-5ee8-43d9-888e-954382fcca21@kernel.org \
    --to=qmo@kernel.org \
    --cc=alan.maguire@oracle.com \
    --cc=andrii@kernel.org \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=dwarves@vger.kernel.org \
    --cc=eddyz87@gmail.com \
    --cc=haoluo@google.com \
    --cc=ihor.solodrai@linux.dev \
    --cc=john.fastabend@gmail.com \
    --cc=jolsa@kernel.org \
    --cc=kpsingh@kernel.org \
    --cc=martin.lau@linux.dev \
    --cc=masahiroy@kernel.org \
    --cc=sdf@fomichev.me \
    --cc=song@kernel.org \
    --cc=ttreyer@meta.com \
    --cc=yonghong.song@linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox