tools: bpftool: fix a bitfield pretty print issue
Subsystems (4)
PATCH 1/1 tools: bpftool: fix a bitfield pretty print issue
Commit b12d6ec09730 ("bpf: btf: add btf print functionality") added btf pretty print functionality to bpftool. There is a problem though in printing a bitfield whose type has modifiers.
For example, for a type like
typedef int ___int;
struct tmp_t {
int a:3;
___int b:3; };
Suppose we have a map
struct bpf_map_def SEC("maps") tmpmap = {
.type = BPF_MAP_TYPE_HASH, .key_size = sizeof(__u32), .value_size = sizeof(struct tmp_t), .max_entries = 1,
};
and the hash table is populated with one element with key 0 and value (.a = 1 and .b = 2).
In BTF, the struct member "b" will have a type "typedef" which points to an int type. The current implementation does not pass the bit offset during transition from typedef to int type, hence incorrectly print the value as
$ bpftool m d id 79
[{
"key": 0,
"value": {
"a": 0x1,
"b": 0x1
}
}
]This patch fixed the issue by carrying bit_offset along the type chain during bit_field print. The correct result can be printed as
$ bpftool m d id 76
[{
"key": 0,
"value": {
"a": 0x1,
"b": 0x2
}
}
]The kernel pretty print is implemented correctly and does not have this issue.
--- tools/bpf/bpftool/btf_dumper.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
tools/bpf/bpftool/btf_dumper.c +3 -3
@@ -32,7 +32,7 @@ static void btf_dumper_ptr(const void *data, json_writer_t *jw, }static int btf_dumper_modifier (const struct btf_dumper *d,__u32 type_id, -const void *data) +__u8 bit_offset,const void *data) {int actual_type_id;
@@ -40,7 +40,7 @@ static int btf_dumper_modifier(const struct btf_dumper *d, __u32 type_id,if (actual_type_id <0 )return actual_type_id; -return btf_dumper_do_type (d, actual_type_id,0 , data); +return btf_dumper_do_type (d, actual_type_id, bit_offset, data); }static void btf_dumper_enum (const void *data,json_writer_t *jw)
@@ -237,7 +237,7 @@ static int btf_dumper_do_type(const struct btf_dumper *d, __u32 type_id,case BTF_KIND_VOLATILE :case BTF_KIND_CONST :case BTF_KIND_RESTRICT : -return btf_dumper_modifier (d, type_id, data); +return btf_dumper_modifier (d, type_id, bit_offset, data);default :jsonw_printf (d->jw,"(unsupported-kind" );return -EINVAL ;
Signature · 1 line
2.17.1
Quoted 48 lines · Yonghong Song
Commit
b12d6ec09730("bpf: btf: add btf print functionality") added btf pretty print functionality to bpftool. There is a problem though in printing a bitfield whose type has modifiers.For example, for a type like
typedef int___int;struct tmp_t { int a:3; ___int b:3;};
Suppose we have a map
structbpf_map_defSEC("maps")tmpmap = {
.type =BPF_MAP_TYPE_HASH, .key_size =sizeof(__u32), .value_size =sizeof(struct tmp_t), .max_entries = 1,
};
and the hash table is populated with one element with key 0 and value (.a = 1 and .b = 2).In BTF, the struct member "b" will have a type "typedef" which points to an int type. The current implementation does not pass the bit offset during transition from typedef to int type, hence incorrectly print the value as
$ bpftool m d id 79 [{ "key": 0, "value": { "a": 0x1, "b": 0x1 } } ]This patch fixed the issue by carrying
bit_offsetalong the type chain duringbit_fieldprint. The correct result can be printed as$ bpftool m d id 76 [{ "key": 0, "value": { "a": 0x1, "b": 0x2 } } ]
Quoted 5 lines
The kernel pretty print is implemented correctly and does not have this issue.
Fixes b12d6ec09730 ("bpf: btf: add btf print functionality")Signed-off-by Yonghong Song <[email protected]>
Quoted 38 lines
--- tools/bpf/bpftool/btf_dumper.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)tools/bpf/bpftool/btf_dumper.c +3
-4@@ -32,7 +32,7 @@ static void btf_dumper_ptr(const void *data, json_writer_t *jw, }static int btf_dumper_modifier (const struct btf_dumper *d,__u32 type_id, -const void *data) +__u8 bit_offset,const void *data) {int actual_type_id;@@ -40,7 +40,7 @@ static int btf_dumper_modifier(const struct btf_dumper *d, __u32 type_id,if (actual_type_id <0 )return actual_type_id; -return btf_dumper_do_type (d, actual_type_id,0 , data); +return btf_dumper_do_type (d, actual_type_id, bit_offset, data); }static void btf_dumper_enum (const void *data,json_writer_t *jw)@@ -237,7 +237,7 @@ static int btf_dumper_do_type(const struct btf_dumper *d, __u32 type_id,case BTF_KIND_VOLATILE :case BTF_KIND_CONST :case BTF_KIND_RESTRICT : -return btf_dumper_modifier (d, type_id, data); +return btf_dumper_modifier (d, type_id, bit_offset, data);default :jsonw_printf (d->jw,"(unsupported-kind" );return -EINVAL ; --2.17.1
Alexei Starovoitov
AppliedQuoted 47 lines · Yonghong Song
Commit
b12d6ec09730("bpf: btf: add btf print functionality") added btf pretty print functionality to bpftool. There is a problem though in printing a bitfield whose type has modifiers.For example, for a type like
typedef int___int;struct tmp_t { int a:3; ___int b:3;};
Suppose we have a map
structbpf_map_defSEC("maps")tmpmap = {
.type =BPF_MAP_TYPE_HASH, .key_size =sizeof(__u32), .value_size =sizeof(struct tmp_t), .max_entries = 1,
};
and the hash table is populated with one element with key 0 and value (.a = 1 and .b = 2).In BTF, the struct member "b" will have a type "typedef" which points to an int type. The current implementation does not pass the bit offset during transition from typedef to int type, hence incorrectly print the value as
$ bpftool m d id 79 [{ "key": 0, "value": { "a": 0x1, "b": 0x1 } } ]This patch fixed the issue by carrying
bit_offsetalong the type chain duringbit_fieldprint. The correct result can be printed as$ bpftool m d id 76 [{ "key": 0, "value": { "a": 0x1, "b": 0x2 } } ]
Quoted 5 lines
The kernel pretty print is implemented correctly and does not have this issue.
Fixes b12d6ec09730 ("bpf: btf: add btf print functionality")Signed-off-by Yonghong Song <[email protected]>
Applied to bpf tree. Thanks