diff mbox series

[v2,bpf-next,02/17] bpftool: dump more info about DATASEC members

Message ID 20210416202404.3443623-3-andrii@kernel.org (mailing list archive)
State Superseded
Delegated to: BPF
Headers show
Series BPF static linker: support externs | expand

Checks

Context Check Description
netdev/cover_letter success Link
netdev/fixes_present success Link
netdev/patch_count fail Series longer than 15 patches
netdev/tree_selection success Clearly marked for bpf-next
netdev/subject_prefix success Link
netdev/cc_maintainers warning 11 maintainers not CCed: yhs@fb.com kpsingh@kernel.org kafai@fb.com iii@linux.ibm.com ast@kernel.org tklauser@distanz.ch john.fastabend@gmail.com tianjia.zhang@linux.alibaba.com songliubraving@fb.com thunder.leizhen@huawei.com quentin@isovalent.com
netdev/source_inline success Was 0 now: 0
netdev/verify_signedoff success Link
netdev/module_param success Was 0 now: 0
netdev/build_32bit success Errors and warnings before: 0 this patch: 0
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/verify_fixes success Link
netdev/checkpatch warning WARNING: line length of 81 exceeds 80 columns WARNING: line length of 89 exceeds 80 columns
netdev/build_allmodconfig_warn success Errors and warnings before: 0 this patch: 0
netdev/header_inline success Link

Commit Message

Andrii Nakryiko April 16, 2021, 8:23 p.m. UTC
Dump succinct information for each member of DATASEC: its kinds and name. This
is extremely helpful to see at a quick glance what is inside each DATASEC of
a given BTF. Without this, one has to jump around BTF data to just find out
the name of a VAR or FUNC. DATASEC's var_secinfo member is special in that
regard because it doesn't itself contain the name of the member, delegating
that to the referenced VAR and FUNC kinds. Other kinds, like
STRUCT/UNION/FUNC/ENUM, encode member names directly and thus are clearly
identifiable in BTF dump.

The new output looks like this:

[35] DATASEC '.bss' size=0 vlen=6
        type_id=8 offset=0 size=4 (VAR 'input_bss1')
        type_id=13 offset=0 size=4 (VAR 'input_bss_weak')
        type_id=16 offset=0 size=4 (VAR 'output_bss1')
        type_id=17 offset=0 size=4 (VAR 'output_data1')
        type_id=18 offset=0 size=4 (VAR 'output_rodata1')
        type_id=20 offset=0 size=8 (VAR 'output_sink1')
[36] DATASEC '.data' size=0 vlen=2
        type_id=9 offset=0 size=4 (VAR 'input_data1')
        type_id=14 offset=0 size=4 (VAR 'input_data_weak')
[37] DATASEC '.kconfig' size=0 vlen=2
        type_id=25 offset=0 size=4 (VAR 'LINUX_KERNEL_VERSION')
        type_id=28 offset=0 size=1 (VAR 'CONFIG_BPF_SYSCALL')
[38] DATASEC '.ksyms' size=0 vlen=1
        type_id=30 offset=0 size=1 (VAR 'bpf_link_fops')
[39] DATASEC '.rodata' size=0 vlen=2
        type_id=12 offset=0 size=4 (VAR 'input_rodata1')
        type_id=15 offset=0 size=4 (VAR 'input_rodata_weak')
[40] DATASEC 'license' size=0 vlen=1
        type_id=24 offset=0 size=4 (VAR 'LICENSE')

Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
---
 tools/bpf/bpftool/btf.c | 26 ++++++++++++++++++--------
 1 file changed, 18 insertions(+), 8 deletions(-)

Comments

Yonghong Song April 22, 2021, 3:09 a.m. UTC | #1
On 4/16/21 1:23 PM, Andrii Nakryiko wrote:
> Dump succinct information for each member of DATASEC: its kinds and name. This
> is extremely helpful to see at a quick glance what is inside each DATASEC of

This is indeed very useful and user friendly!

> a given BTF. Without this, one has to jump around BTF data to just find out
> the name of a VAR or FUNC. DATASEC's var_secinfo member is special in that
> regard because it doesn't itself contain the name of the member, delegating
> that to the referenced VAR and FUNC kinds. Other kinds, like
> STRUCT/UNION/FUNC/ENUM, encode member names directly and thus are clearly
> identifiable in BTF dump.
> 
> The new output looks like this:
> 
> [35] DATASEC '.bss' size=0 vlen=6
>          type_id=8 offset=0 size=4 (VAR 'input_bss1')
>          type_id=13 offset=0 size=4 (VAR 'input_bss_weak')
>          type_id=16 offset=0 size=4 (VAR 'output_bss1')
>          type_id=17 offset=0 size=4 (VAR 'output_data1')
>          type_id=18 offset=0 size=4 (VAR 'output_rodata1')
>          type_id=20 offset=0 size=8 (VAR 'output_sink1')
> [36] DATASEC '.data' size=0 vlen=2
>          type_id=9 offset=0 size=4 (VAR 'input_data1')
>          type_id=14 offset=0 size=4 (VAR 'input_data_weak')
> [37] DATASEC '.kconfig' size=0 vlen=2
>          type_id=25 offset=0 size=4 (VAR 'LINUX_KERNEL_VERSION')
>          type_id=28 offset=0 size=1 (VAR 'CONFIG_BPF_SYSCALL')
> [38] DATASEC '.ksyms' size=0 vlen=1
>          type_id=30 offset=0 size=1 (VAR 'bpf_link_fops')
> [39] DATASEC '.rodata' size=0 vlen=2
>          type_id=12 offset=0 size=4 (VAR 'input_rodata1')
>          type_id=15 offset=0 size=4 (VAR 'input_rodata_weak')
> [40] DATASEC 'license' size=0 vlen=1
>          type_id=24 offset=0 size=4 (VAR 'LICENSE')
> 
> Signed-off-by: Andrii Nakryiko <andrii@kernel.org>

Acked-by: Yonghong Song <yhs@fb.com>
diff mbox series

Patch

diff --git a/tools/bpf/bpftool/btf.c b/tools/bpf/bpftool/btf.c
index 001749a34899..385d5c955cf3 100644
--- a/tools/bpf/bpftool/btf.c
+++ b/tools/bpf/bpftool/btf.c
@@ -100,26 +100,28 @@  static const char *btf_str(const struct btf *btf, __u32 off)
 	return btf__name_by_offset(btf, off) ? : "(invalid)";
 }
 
+static int btf_kind_safe(int kind)
+{
+	return kind <= BTF_KIND_MAX ? kind : BTF_KIND_UNKN;
+}
+
 static int dump_btf_type(const struct btf *btf, __u32 id,
 			 const struct btf_type *t)
 {
 	json_writer_t *w = json_wtr;
-	int kind, safe_kind;
-
-	kind = BTF_INFO_KIND(t->info);
-	safe_kind = kind <= BTF_KIND_MAX ? kind : BTF_KIND_UNKN;
+	int kind = btf_kind(t);
 
 	if (json_output) {
 		jsonw_start_object(w);
 		jsonw_uint_field(w, "id", id);
-		jsonw_string_field(w, "kind", btf_kind_str[safe_kind]);
+		jsonw_string_field(w, "kind", btf_kind_str[btf_kind_safe(kind)]);
 		jsonw_string_field(w, "name", btf_str(btf, t->name_off));
 	} else {
-		printf("[%u] %s '%s'", id, btf_kind_str[safe_kind],
+		printf("[%u] %s '%s'", id, btf_kind_str[btf_kind_safe(kind)],
 		       btf_str(btf, t->name_off));
 	}
 
-	switch (BTF_INFO_KIND(t->info)) {
+	switch (kind) {
 	case BTF_KIND_INT: {
 		__u32 v = *(__u32 *)(t + 1);
 		const char *enc;
@@ -302,7 +304,8 @@  static int dump_btf_type(const struct btf *btf, __u32 id,
 		break;
 	}
 	case BTF_KIND_DATASEC: {
-		const struct btf_var_secinfo *v = (const void *)(t+1);
+		const struct btf_var_secinfo *v = (const void *)(t + 1);
+		const struct btf_type *vt;
 		__u16 vlen = BTF_INFO_VLEN(t->info);
 		int i;
 
@@ -324,6 +327,13 @@  static int dump_btf_type(const struct btf *btf, __u32 id,
 			} else {
 				printf("\n\ttype_id=%u offset=%u size=%u",
 				       v->type, v->offset, v->size);
+
+				if (v->type <= btf__get_nr_types(btf)) {
+					vt = btf__type_by_id(btf, v->type);
+					printf(" (%s '%s')",
+					       btf_kind_str[btf_kind_safe(btf_kind(vt))],
+					       btf_str(btf, vt->name_off));
+				}
 			}
 		}
 		if (json_output)