forked from mirrors/linux
		
	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>
			
			
This commit is contained in:
		
							parent
							
								
									9f95e37e31
								
							
						
					
					
						commit
						8772c8bc09
					
				
					 1 changed files with 27 additions and 9 deletions
				
			
		| 
						 | 
					@ -193,6 +193,7 @@ static int btf_dumper_struct(const struct btf_dumper *d, __u32 type_id,
 | 
				
			||||||
	const struct btf_type *t;
 | 
						const struct btf_type *t;
 | 
				
			||||||
	struct btf_member *m;
 | 
						struct btf_member *m;
 | 
				
			||||||
	const void *data_off;
 | 
						const void *data_off;
 | 
				
			||||||
 | 
						int kind_flag;
 | 
				
			||||||
	int ret = 0;
 | 
						int ret = 0;
 | 
				
			||||||
	int i, vlen;
 | 
						int i, vlen;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -200,18 +201,32 @@ static int btf_dumper_struct(const struct btf_dumper *d, __u32 type_id,
 | 
				
			||||||
	if (!t)
 | 
						if (!t)
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						kind_flag = BTF_INFO_KFLAG(t->info);
 | 
				
			||||||
	vlen = BTF_INFO_VLEN(t->info);
 | 
						vlen = BTF_INFO_VLEN(t->info);
 | 
				
			||||||
	jsonw_start_object(d->jw);
 | 
						jsonw_start_object(d->jw);
 | 
				
			||||||
	m = (struct btf_member *)(t + 1);
 | 
						m = (struct btf_member *)(t + 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (i = 0; i < vlen; i++) {
 | 
						for (i = 0; i < vlen; i++) {
 | 
				
			||||||
		data_off = data + BITS_ROUNDDOWN_BYTES(m[i].offset);
 | 
							__u32 bit_offset = m[i].offset;
 | 
				
			||||||
 | 
							__u32 bitfield_size = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (kind_flag) {
 | 
				
			||||||
 | 
								bitfield_size = BTF_MEMBER_BITFIELD_SIZE(bit_offset);
 | 
				
			||||||
 | 
								bit_offset = BTF_MEMBER_BIT_OFFSET(bit_offset);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		jsonw_name(d->jw, btf__name_by_offset(d->btf, m[i].name_off));
 | 
							jsonw_name(d->jw, btf__name_by_offset(d->btf, m[i].name_off));
 | 
				
			||||||
		ret = btf_dumper_do_type(d, m[i].type,
 | 
							if (bitfield_size) {
 | 
				
			||||||
					 BITS_PER_BYTE_MASKED(m[i].offset),
 | 
								btf_dumper_bitfield(bitfield_size, bit_offset,
 | 
				
			||||||
					 data_off);
 | 
										    data, d->jw, d->is_plain_text);
 | 
				
			||||||
		if (ret)
 | 
							} else {
 | 
				
			||||||
			break;
 | 
								data_off = data + BITS_ROUNDDOWN_BYTES(bit_offset);
 | 
				
			||||||
 | 
								ret = btf_dumper_do_type(d, m[i].type,
 | 
				
			||||||
 | 
											 BITS_PER_BYTE_MASKED(bit_offset),
 | 
				
			||||||
 | 
											 data_off);
 | 
				
			||||||
 | 
								if (ret)
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	jsonw_end_object(d->jw);
 | 
						jsonw_end_object(d->jw);
 | 
				
			||||||
| 
						 | 
					@ -298,6 +313,7 @@ static int __btf_dumper_type_only(const struct btf *btf, __u32 type_id,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch (BTF_INFO_KIND(t->info)) {
 | 
						switch (BTF_INFO_KIND(t->info)) {
 | 
				
			||||||
	case BTF_KIND_INT:
 | 
						case BTF_KIND_INT:
 | 
				
			||||||
 | 
						case BTF_KIND_TYPEDEF:
 | 
				
			||||||
		BTF_PRINT_ARG("%s ", btf__name_by_offset(btf, t->name_off));
 | 
							BTF_PRINT_ARG("%s ", btf__name_by_offset(btf, t->name_off));
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case BTF_KIND_STRUCT:
 | 
						case BTF_KIND_STRUCT:
 | 
				
			||||||
| 
						 | 
					@ -321,10 +337,11 @@ static int __btf_dumper_type_only(const struct btf *btf, __u32 type_id,
 | 
				
			||||||
		BTF_PRINT_TYPE(t->type);
 | 
							BTF_PRINT_TYPE(t->type);
 | 
				
			||||||
		BTF_PRINT_ARG("* ");
 | 
							BTF_PRINT_ARG("* ");
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case BTF_KIND_UNKN:
 | 
					 | 
				
			||||||
	case BTF_KIND_FWD:
 | 
						case BTF_KIND_FWD:
 | 
				
			||||||
	case BTF_KIND_TYPEDEF:
 | 
							BTF_PRINT_ARG("%s %s ",
 | 
				
			||||||
		return -1;
 | 
								      BTF_INFO_KFLAG(t->info) ? "union" : "struct",
 | 
				
			||||||
 | 
								      btf__name_by_offset(btf, t->name_off));
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
	case BTF_KIND_VOLATILE:
 | 
						case BTF_KIND_VOLATILE:
 | 
				
			||||||
		BTF_PRINT_ARG("volatile ");
 | 
							BTF_PRINT_ARG("volatile ");
 | 
				
			||||||
		BTF_PRINT_TYPE(t->type);
 | 
							BTF_PRINT_TYPE(t->type);
 | 
				
			||||||
| 
						 | 
					@ -348,6 +365,7 @@ static int __btf_dumper_type_only(const struct btf *btf, __u32 type_id,
 | 
				
			||||||
		if (pos == -1)
 | 
							if (pos == -1)
 | 
				
			||||||
			return -1;
 | 
								return -1;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
 | 
						case BTF_KIND_UNKN:
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		return -1;
 | 
							return -1;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue