diff options
| author | Daniel Borkmann <[email protected]> | 2018-12-18 01:12:00 +0100 |
|---|---|---|
| committer | Daniel Borkmann <[email protected]> | 2018-12-18 01:12:01 +0100 |
| commit | 37c7b1caeaf60c8d3bc3cedc9ff4b9cc2f015d7e (patch) | |
| tree | 0e68981876d990fcdb98e6b1d2e6a6645e52a6ae /include | |
| parent | 6c4fc209fcf9d27efbaa48368773e4d2bfbd59aa (diff) | |
| parent | 8772c8bc093b2d5823125475e1206b80664f8acb (diff) | |
Merge branch 'bpf-btf-type-fixes'
Yonghong Song says:
====================
Commit 69b693f0aefa ("bpf: btf: Introduce BPF Type Format (BTF)")
introduced BTF, a debug info format for BTF.
The original design has a couple of issues though.
First, the bitfield size is only encoded in int type.
If the struct member bitfield type is enum, pahole ([1])
or llvm is forced to replace enum with int type. As a result, the original
type information gets lost.
Second, the original BTF design does not envision the possibility of
BTF=>header_file conversion ([2]), hence does not encode "struct" or
"union" info for a forward type. Such information is necessary to
convert BTF to a header file.
This patch set fixed the issue by introducing kind_flag, using one bit
in type->info. When kind_flag, the struct/union btf_member->offset
will encode both bitfield_size and bit_offset, covering both
int and enum base types. The kind_flag is also used to indicate whether
the forward type is a union (when set) or a struct.
Patch #1 refactors function btf_int_bits_seq_show() so Patch #2
can reuse part of the function.
Patch #2 implemented kind_flag support for struct/union/fwd types.
Patch #3 added kind_flag support for cgroup local storage map pretty print.
Patch #4 syncs kernel uapi btf.h to tools directory.
Patch #5 added unit tests for kind_flag.
Patch #6 added tests for kernel bpffs based pretty print with kind_flag.
Patch #7 refactors function btf_dumper_int_bits() so Patch #8
can reuse part of the function.
Patch #8 added bpftool support of pretty print with kind_flag set.
[1] https://git.kernel.org/pub/scm/devel/pahole/pahole.git/commit/?id=b18354f64cc215368c3bc0df4a7e5341c55c378c
[2] https://lwn.net/SubscriberLink/773198/fe3074838f5c3f26/
Change logs:
v2 -> v3:
. Relocated comments about bitfield_size/bit_offset interpretation
of the "offset" field right before the "offset" struct member.
. Added missing byte alignment checking for non-bitfield enum
member of a struct with kind_flag set.
. Added two test cases in unit tests for struct type, kind_flag set,
non-bitfield int/enum member, not-byte aligned bit offsets.
. Added comments to help understand there is no overflow for
total_bits_offset in bpftool function btf_dumper_int_bits().
. Added explanation of typedef type dumping fix in Patch #8 commit
message.
v1 -> v2:
. If kind_flag is set for a structure, ensure an int member,
whether it is a bitfield or not, is a regular int type.
. Added support so cgroup local storage map pretty print
works with kind_flag.
====================
Signed-off-by: Daniel Borkmann <[email protected]>
Diffstat (limited to 'include')
| -rw-r--r-- | include/linux/btf.h | 5 | ||||
| -rw-r--r-- | include/uapi/linux/btf.h | 20 |
2 files changed, 22 insertions, 3 deletions
diff --git a/include/linux/btf.h b/include/linux/btf.h index 58000d7e06e3..12502e25e767 100644 --- a/include/linux/btf.h +++ b/include/linux/btf.h @@ -7,6 +7,7 @@ #include <linux/types.h> struct btf; +struct btf_member; struct btf_type; union bpf_attr; @@ -46,7 +47,9 @@ void btf_type_seq_show(const struct btf *btf, u32 type_id, void *obj, struct seq_file *m); int btf_get_fd_by_id(u32 id); u32 btf_id(const struct btf *btf); -bool btf_type_is_reg_int(const struct btf_type *t, u32 expected_size); +bool btf_member_is_reg_int(const struct btf *btf, const struct btf_type *s, + const struct btf_member *m, + u32 expected_offset, u32 expected_size); #ifdef CONFIG_BPF_SYSCALL const struct btf_type *btf_type_by_id(const struct btf *btf, u32 type_id); diff --git a/include/uapi/linux/btf.h b/include/uapi/linux/btf.h index 14f66948fc95..7b7475ef2f17 100644 --- a/include/uapi/linux/btf.h +++ b/include/uapi/linux/btf.h @@ -34,7 +34,9 @@ struct btf_type { * bits 0-15: vlen (e.g. # of struct's members) * bits 16-23: unused * bits 24-27: kind (e.g. int, ptr, array...etc) - * bits 28-31: unused + * bits 28-30: unused + * bit 31: kind_flag, currently used by + * struct, union and fwd */ __u32 info; /* "size" is used by INT, ENUM, STRUCT and UNION. @@ -52,6 +54,7 @@ struct btf_type { #define BTF_INFO_KIND(info) (((info) >> 24) & 0x0f) #define BTF_INFO_VLEN(info) ((info) & 0xffff) +#define BTF_INFO_KFLAG(info) ((info) >> 31) #define BTF_KIND_UNKN 0 /* Unknown */ #define BTF_KIND_INT 1 /* Integer */ @@ -110,9 +113,22 @@ struct btf_array { struct btf_member { __u32 name_off; __u32 type; - __u32 offset; /* offset in bits */ + /* If the type info kind_flag is set, the btf_member offset + * contains both member bitfield size and bit offset. The + * bitfield size is set for bitfield members. If the type + * info kind_flag is not set, the offset contains only bit + * offset. + */ + __u32 offset; }; +/* If the struct/union type info kind_flag is set, the + * following two macros are used to access bitfield_size + * and bit_offset from btf_member.offset. + */ +#define BTF_MEMBER_BITFIELD_SIZE(val) ((val) >> 24) +#define BTF_MEMBER_BIT_OFFSET(val) ((val) & 0xffffff) + /* BTF_KIND_FUNC_PROTO is followed by multiple "struct btf_param". * The exact number of btf_param is stored in the vlen (of the * info in "struct btf_type"). |