Merge branch 'bpf: add support for BTF_KIND_DECL_TAG typedef'
Yonghong Song says: ==================== Latest upstream llvm-project added support for btf_decl_tag attributes for typedef declarations ([1], [2]). Similar to other btf_decl_tag cases, func/func_param/global_var/struct/union/field, btf_decl_tag with typedef declaration can carry information from kernel source to clang compiler and then to dwarf/BTF, for bpf verification or other use cases. This patch set added kernel support for BTF_KIND_DECL_TAG to typedef declaration (Patch 1). Additional selftests are added to cover unit testing, dedup, or bpf program usage of btf_decl_tag with typedef. (Patches 2, 3 and 4). The btf documentation is updated to include BTF_KIND_DECL_TAG typedef (Patch 5). [1] https://reviews.llvm.org/D110127 [2] https://reviews.llvm.org/D112259 ==================== Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
commit
1c50884370
@ -474,7 +474,7 @@ No additional type data follow ``btf_type``.
|
||||
* ``info.kind_flag``: 0
|
||||
* ``info.kind``: BTF_KIND_DECL_TAG
|
||||
* ``info.vlen``: 0
|
||||
* ``type``: ``struct``, ``union``, ``func`` or ``var``
|
||||
* ``type``: ``struct``, ``union``, ``func``, ``var`` or ``typedef``
|
||||
|
||||
``btf_type`` is followed by ``struct btf_decl_tag``.::
|
||||
|
||||
@ -483,8 +483,8 @@ No additional type data follow ``btf_type``.
|
||||
};
|
||||
|
||||
The ``name_off`` encodes btf_decl_tag attribute string.
|
||||
The ``type`` should be ``struct``, ``union``, ``func`` or ``var``.
|
||||
For ``var`` type, ``btf_decl_tag.component_idx`` must be ``-1``.
|
||||
The ``type`` should be ``struct``, ``union``, ``func``, ``var`` or ``typedef``.
|
||||
For ``var`` or ``typedef`` type, ``btf_decl_tag.component_idx`` must be ``-1``.
|
||||
For the other three types, if the btf_decl_tag attribute is
|
||||
applied to the ``struct``, ``union`` or ``func`` itself,
|
||||
``btf_decl_tag.component_idx`` must be ``-1``. Otherwise,
|
||||
|
@ -468,7 +468,7 @@ static bool btf_type_is_decl_tag(const struct btf_type *t)
|
||||
static bool btf_type_is_decl_tag_target(const struct btf_type *t)
|
||||
{
|
||||
return btf_type_is_func(t) || btf_type_is_struct(t) ||
|
||||
btf_type_is_var(t);
|
||||
btf_type_is_var(t) || btf_type_is_typedef(t);
|
||||
}
|
||||
|
||||
u32 btf_nr_types(const struct btf *btf)
|
||||
@ -3885,7 +3885,7 @@ static int btf_decl_tag_resolve(struct btf_verifier_env *env,
|
||||
|
||||
component_idx = btf_type_decl_tag(t)->component_idx;
|
||||
if (component_idx != -1) {
|
||||
if (btf_type_is_var(next_type)) {
|
||||
if (btf_type_is_var(next_type) || btf_type_is_typedef(next_type)) {
|
||||
btf_verifier_log_type(env, v->t, "Invalid component_idx");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -3903,6 +3903,42 @@ static struct btf_raw_test raw_tests[] = {
|
||||
.btf_load_err = true,
|
||||
.err_str = "Invalid component_idx",
|
||||
},
|
||||
{
|
||||
.descr = "decl_tag test #13, typedef, well-formed",
|
||||
.raw_types = {
|
||||
BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
|
||||
BTF_TYPEDEF_ENC(NAME_TBD, 1), /* [2] */
|
||||
BTF_DECL_TAG_ENC(NAME_TBD, 2, -1),
|
||||
BTF_END_RAW,
|
||||
},
|
||||
BTF_STR_SEC("\0t\0tag"),
|
||||
.map_type = BPF_MAP_TYPE_ARRAY,
|
||||
.map_name = "tag_type_check_btf",
|
||||
.key_size = sizeof(int),
|
||||
.value_size = 4,
|
||||
.key_type_id = 1,
|
||||
.value_type_id = 1,
|
||||
.max_entries = 1,
|
||||
},
|
||||
{
|
||||
.descr = "decl_tag test #14, typedef, invalid component_idx",
|
||||
.raw_types = {
|
||||
BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
|
||||
BTF_TYPEDEF_ENC(NAME_TBD, 1), /* [2] */
|
||||
BTF_DECL_TAG_ENC(NAME_TBD, 2, 0),
|
||||
BTF_END_RAW,
|
||||
},
|
||||
BTF_STR_SEC("\0local\0tag"),
|
||||
.map_type = BPF_MAP_TYPE_ARRAY,
|
||||
.map_name = "tag_type_check_btf",
|
||||
.key_size = sizeof(int),
|
||||
.value_size = 4,
|
||||
.key_type_id = 1,
|
||||
.value_type_id = 1,
|
||||
.max_entries = 1,
|
||||
.btf_load_err = true,
|
||||
.err_str = "Invalid component_idx",
|
||||
},
|
||||
|
||||
}; /* struct btf_raw_test raw_tests[] */
|
||||
|
||||
@ -6841,11 +6877,12 @@ const struct btf_dedup_test dedup_tests[] = {
|
||||
BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 8),
|
||||
BTF_FUNC_ENC(NAME_TBD, 12), /* [13] func */
|
||||
BTF_TYPE_FLOAT_ENC(NAME_TBD, 2), /* [14] float */
|
||||
BTF_DECL_TAG_ENC(NAME_TBD, 13, -1), /* [15] tag */
|
||||
BTF_DECL_TAG_ENC(NAME_TBD, 13, 1), /* [16] tag */
|
||||
BTF_DECL_TAG_ENC(NAME_TBD, 13, -1), /* [15] decl_tag */
|
||||
BTF_DECL_TAG_ENC(NAME_TBD, 13, 1), /* [16] decl_tag */
|
||||
BTF_DECL_TAG_ENC(NAME_TBD, 7, -1), /* [17] decl_tag */
|
||||
BTF_END_RAW,
|
||||
},
|
||||
BTF_STR_SEC("\0A\0B\0C\0D\0E\0F\0G\0H\0I\0J\0K\0L\0M\0N\0O\0P"),
|
||||
BTF_STR_SEC("\0A\0B\0C\0D\0E\0F\0G\0H\0I\0J\0K\0L\0M\0N\0O\0P\0Q"),
|
||||
},
|
||||
.expect = {
|
||||
.raw_types = {
|
||||
@ -6869,11 +6906,12 @@ const struct btf_dedup_test dedup_tests[] = {
|
||||
BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 8),
|
||||
BTF_FUNC_ENC(NAME_TBD, 12), /* [13] func */
|
||||
BTF_TYPE_FLOAT_ENC(NAME_TBD, 2), /* [14] float */
|
||||
BTF_DECL_TAG_ENC(NAME_TBD, 13, -1), /* [15] tag */
|
||||
BTF_DECL_TAG_ENC(NAME_TBD, 13, 1), /* [16] tag */
|
||||
BTF_DECL_TAG_ENC(NAME_TBD, 13, -1), /* [15] decl_tag */
|
||||
BTF_DECL_TAG_ENC(NAME_TBD, 13, 1), /* [16] decl_tag */
|
||||
BTF_DECL_TAG_ENC(NAME_TBD, 7, -1), /* [17] decl_tag */
|
||||
BTF_END_RAW,
|
||||
},
|
||||
BTF_STR_SEC("\0A\0B\0C\0D\0E\0F\0G\0H\0I\0J\0K\0L\0M\0N\0O\0P"),
|
||||
BTF_STR_SEC("\0A\0B\0C\0D\0E\0F\0G\0H\0I\0J\0K\0L\0M\0N\0O\0P\0Q"),
|
||||
},
|
||||
.opts = {
|
||||
.dont_resolve_fwds = false,
|
||||
@ -7168,6 +7206,39 @@ const struct btf_dedup_test dedup_tests[] = {
|
||||
.dont_resolve_fwds = false,
|
||||
},
|
||||
},
|
||||
{
|
||||
.descr = "dedup: typedef tags",
|
||||
.input = {
|
||||
.raw_types = {
|
||||
/* int */
|
||||
BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
|
||||
BTF_TYPEDEF_ENC(NAME_NTH(1), 1), /* [2] */
|
||||
BTF_TYPEDEF_ENC(NAME_NTH(1), 1), /* [3] */
|
||||
/* tag -> t: tag1, tag2 */
|
||||
BTF_DECL_TAG_ENC(NAME_NTH(2), 2, -1), /* [4] */
|
||||
BTF_DECL_TAG_ENC(NAME_NTH(3), 2, -1), /* [5] */
|
||||
/* tag -> t: tag1, tag3 */
|
||||
BTF_DECL_TAG_ENC(NAME_NTH(2), 3, -1), /* [6] */
|
||||
BTF_DECL_TAG_ENC(NAME_NTH(4), 3, -1), /* [7] */
|
||||
BTF_END_RAW,
|
||||
},
|
||||
BTF_STR_SEC("\0t\0tag1\0tag2\0tag3"),
|
||||
},
|
||||
.expect = {
|
||||
.raw_types = {
|
||||
BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
|
||||
BTF_TYPEDEF_ENC(NAME_NTH(1), 1), /* [2] */
|
||||
BTF_DECL_TAG_ENC(NAME_NTH(2), 2, -1), /* [3] */
|
||||
BTF_DECL_TAG_ENC(NAME_NTH(3), 2, -1), /* [4] */
|
||||
BTF_DECL_TAG_ENC(NAME_NTH(4), 2, -1), /* [5] */
|
||||
BTF_END_RAW,
|
||||
},
|
||||
BTF_STR_SEC("\0t\0tag1\0tag2\0tag3"),
|
||||
},
|
||||
.opts = {
|
||||
.dont_resolve_fwds = false,
|
||||
},
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
|
@ -24,18 +24,23 @@ struct key_t {
|
||||
int c;
|
||||
} __tag1 __tag2;
|
||||
|
||||
typedef struct {
|
||||
int a;
|
||||
int b;
|
||||
} value_t __tag1 __tag2;
|
||||
|
||||
struct {
|
||||
__uint(type, BPF_MAP_TYPE_HASH);
|
||||
__uint(max_entries, 3);
|
||||
__type(key, struct key_t);
|
||||
__type(value, __u64);
|
||||
__type(value, value_t);
|
||||
} hashmap1 SEC(".maps");
|
||||
|
||||
|
||||
static __noinline int foo(int x __tag1 __tag2) __tag1 __tag2
|
||||
{
|
||||
struct key_t key;
|
||||
__u64 val = 1;
|
||||
value_t val = {};
|
||||
|
||||
key.a = key.b = key.c = x;
|
||||
bpf_map_update_elem(&hashmap1, &key, &val, 0);
|
||||
|
Loading…
x
Reference in New Issue
Block a user