Skip to content

Commit 8772c8b

Browse files
yonghong-songborkmann
authored andcommitted
tools: bpftool: support pretty print with kind_flag set
The following example shows map pretty print with structures which include bitfield members. enum A { A1, A2, A3, A4, A5 }; typedef enum A ___A; struct tmp_t { char a1:4; int a2:4; int :4; __u32 a3:4; int b; ___A b1:4; enum A b2:4; }; struct bpf_map_def SEC("maps") tmpmap = { .type = BPF_MAP_TYPE_ARRAY, .key_size = sizeof(__u32), .value_size = sizeof(struct tmp_t), .max_entries = 1, }; BPF_ANNOTATE_KV_PAIR(tmpmap, int, struct tmp_t); and the following map update in the bpf program: key = 0; struct tmp_t t = {}; t.a1 = 2; t.a2 = 4; t.a3 = 6; t.b = 7; t.b1 = 8; t.b2 = 10; bpf_map_update_elem(&tmpmap, &key, &t, 0); With this patch, I am able to print out the map values correctly with this patch: bpftool map dump id 187 [{ "key": 0, "value": { "a1": 0x2, "a2": 0x4, "a3": 0x6, "b": 7, "b1": 0x8, "b2": 0xa } } ] Previously, if a function prototype argument has a typedef type, the prototype is not printed since function __btf_dumper_type_only() bailed out with error if the type is a typedef. This commit corrected this behavior by printing out typedef properly. The following example shows forward type and typedef type can be properly printed in function prototype with modified test_btf_haskv.c. struct t; union u; __attribute__((noinline)) static int test_long_fname_1(struct dummy_tracepoint_args *arg, struct t *p1, union u *p2, __u32 unused) ... int _dummy_tracepoint(struct dummy_tracepoint_args *arg) { return test_long_fname_1(arg, 0, 0, 0); } $ bpftool p d xlated id 24 ... int test_long_fname_1(struct dummy_tracepoint_args * arg, struct t * p1, union u * p2, __u32 unused) ... Acked-by: Martin KaFai Lau <kafai@fb.com> Signed-off-by: Yonghong Song <yhs@fb.com> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
1 parent 9f95e37 commit 8772c8b

File tree

1 file changed

+27
-9
lines changed

1 file changed

+27
-9
lines changed

tools/bpf/bpftool/btf_dumper.c

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -193,25 +193,40 @@ static int btf_dumper_struct(const struct btf_dumper *d, __u32 type_id,
193193
const struct btf_type *t;
194194
struct btf_member *m;
195195
const void *data_off;
196+
int kind_flag;
196197
int ret = 0;
197198
int i, vlen;
198199

199200
t = btf__type_by_id(d->btf, type_id);
200201
if (!t)
201202
return -EINVAL;
202203

204+
kind_flag = BTF_INFO_KFLAG(t->info);
203205
vlen = BTF_INFO_VLEN(t->info);
204206
jsonw_start_object(d->jw);
205207
m = (struct btf_member *)(t + 1);
206208

207209
for (i = 0; i < vlen; i++) {
208-
data_off = data + BITS_ROUNDDOWN_BYTES(m[i].offset);
210+
__u32 bit_offset = m[i].offset;
211+
__u32 bitfield_size = 0;
212+
213+
if (kind_flag) {
214+
bitfield_size = BTF_MEMBER_BITFIELD_SIZE(bit_offset);
215+
bit_offset = BTF_MEMBER_BIT_OFFSET(bit_offset);
216+
}
217+
209218
jsonw_name(d->jw, btf__name_by_offset(d->btf, m[i].name_off));
210-
ret = btf_dumper_do_type(d, m[i].type,
211-
BITS_PER_BYTE_MASKED(m[i].offset),
212-
data_off);
213-
if (ret)
214-
break;
219+
if (bitfield_size) {
220+
btf_dumper_bitfield(bitfield_size, bit_offset,
221+
data, d->jw, d->is_plain_text);
222+
} else {
223+
data_off = data + BITS_ROUNDDOWN_BYTES(bit_offset);
224+
ret = btf_dumper_do_type(d, m[i].type,
225+
BITS_PER_BYTE_MASKED(bit_offset),
226+
data_off);
227+
if (ret)
228+
break;
229+
}
215230
}
216231

217232
jsonw_end_object(d->jw);
@@ -298,6 +313,7 @@ static int __btf_dumper_type_only(const struct btf *btf, __u32 type_id,
298313

299314
switch (BTF_INFO_KIND(t->info)) {
300315
case BTF_KIND_INT:
316+
case BTF_KIND_TYPEDEF:
301317
BTF_PRINT_ARG("%s ", btf__name_by_offset(btf, t->name_off));
302318
break;
303319
case BTF_KIND_STRUCT:
@@ -321,10 +337,11 @@ static int __btf_dumper_type_only(const struct btf *btf, __u32 type_id,
321337
BTF_PRINT_TYPE(t->type);
322338
BTF_PRINT_ARG("* ");
323339
break;
324-
case BTF_KIND_UNKN:
325340
case BTF_KIND_FWD:
326-
case BTF_KIND_TYPEDEF:
327-
return -1;
341+
BTF_PRINT_ARG("%s %s ",
342+
BTF_INFO_KFLAG(t->info) ? "union" : "struct",
343+
btf__name_by_offset(btf, t->name_off));
344+
break;
328345
case BTF_KIND_VOLATILE:
329346
BTF_PRINT_ARG("volatile ");
330347
BTF_PRINT_TYPE(t->type);
@@ -348,6 +365,7 @@ static int __btf_dumper_type_only(const struct btf *btf, __u32 type_id,
348365
if (pos == -1)
349366
return -1;
350367
break;
368+
case BTF_KIND_UNKN:
351369
default:
352370
return -1;
353371
}

0 commit comments

Comments
 (0)