diff options
author | Yonghong Song <yhs@fb.com> | 2019-01-10 14:14:02 -0500 |
---|---|---|
committer | Daniel Borkmann <daniel@iogearbox.net> | 2019-01-11 04:40:54 -0500 |
commit | 298e59d322954e89ed2a556c601a04a4c007d1b3 (patch) | |
tree | 8702529ada7e857caa223af4c4523d5c2e58cb59 | |
parent | e43207fa2e6130e39e3aca4c55e2ee21cfb46828 (diff) |
tools/bpf: fix bpftool map dump with bitfields
Commit 8772c8bc093b ("tools: bpftool: support pretty print
with kind_flag set") added bpftool map dump with kind_flag
support. When bitfield_size can be retrieved directly from
btf_member, function btf_dumper_bitfield() is called to
dump the bitfield. The implementation passed the
wrong parameter "bit_offset" to the function. The excepted
value is the bit_offset within a byte while the passed-in
value is the struct member offset.
This commit fixed the bug with passing correct "bit_offset"
with adjusted data pointer.
Fixes: 8772c8bc093b ("tools: bpftool: support pretty print with kind_flag set")
Acked-by: Martin KaFai Lau <kafai@fb.com>
Signed-off-by: Yonghong Song <yhs@fb.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
-rw-r--r-- | tools/bpf/bpftool/btf_dumper.c | 13 |
1 files changed, 7 insertions, 6 deletions
diff --git a/tools/bpf/bpftool/btf_dumper.c b/tools/bpf/bpftool/btf_dumper.c index 3f0629edbca5..6ba5f567a9d8 100644 --- a/tools/bpf/bpftool/btf_dumper.c +++ b/tools/bpf/bpftool/btf_dumper.c | |||
@@ -82,8 +82,6 @@ static void btf_dumper_bitfield(__u32 nr_bits, __u8 bit_offset, | |||
82 | int bits_to_copy; | 82 | int bits_to_copy; |
83 | __u64 print_num; | 83 | __u64 print_num; |
84 | 84 | ||
85 | data += BITS_ROUNDDOWN_BYTES(bit_offset); | ||
86 | bit_offset = BITS_PER_BYTE_MASKED(bit_offset); | ||
87 | bits_to_copy = bit_offset + nr_bits; | 85 | bits_to_copy = bit_offset + nr_bits; |
88 | bytes_to_copy = BITS_ROUNDUP_BYTES(bits_to_copy); | 86 | bytes_to_copy = BITS_ROUNDUP_BYTES(bits_to_copy); |
89 | 87 | ||
@@ -118,7 +116,9 @@ static void btf_dumper_int_bits(__u32 int_type, __u8 bit_offset, | |||
118 | * BTF_INT_OFFSET() cannot exceed 64 bits. | 116 | * BTF_INT_OFFSET() cannot exceed 64 bits. |
119 | */ | 117 | */ |
120 | total_bits_offset = bit_offset + BTF_INT_OFFSET(int_type); | 118 | total_bits_offset = bit_offset + BTF_INT_OFFSET(int_type); |
121 | btf_dumper_bitfield(nr_bits, total_bits_offset, data, jw, | 119 | data += BITS_ROUNDDOWN_BYTES(total_bits_offset); |
120 | bit_offset = BITS_PER_BYTE_MASKED(total_bits_offset); | ||
121 | btf_dumper_bitfield(nr_bits, bit_offset, data, jw, | ||
122 | is_plain_text); | 122 | is_plain_text); |
123 | } | 123 | } |
124 | 124 | ||
@@ -216,11 +216,12 @@ static int btf_dumper_struct(const struct btf_dumper *d, __u32 type_id, | |||
216 | } | 216 | } |
217 | 217 | ||
218 | jsonw_name(d->jw, btf__name_by_offset(d->btf, m[i].name_off)); | 218 | jsonw_name(d->jw, btf__name_by_offset(d->btf, m[i].name_off)); |
219 | data_off = data + BITS_ROUNDDOWN_BYTES(bit_offset); | ||
219 | if (bitfield_size) { | 220 | if (bitfield_size) { |
220 | btf_dumper_bitfield(bitfield_size, bit_offset, | 221 | btf_dumper_bitfield(bitfield_size, |
221 | data, d->jw, d->is_plain_text); | 222 | BITS_PER_BYTE_MASKED(bit_offset), |
223 | data_off, d->jw, d->is_plain_text); | ||
222 | } else { | 224 | } else { |
223 | data_off = data + BITS_ROUNDDOWN_BYTES(bit_offset); | ||
224 | ret = btf_dumper_do_type(d, m[i].type, | 225 | ret = btf_dumper_do_type(d, m[i].type, |
225 | BITS_PER_BYTE_MASKED(bit_offset), | 226 | BITS_PER_BYTE_MASKED(bit_offset), |
226 | data_off); | 227 | data_off); |