未验证 提交 d3762912 编写于 作者: O openeuler-ci-bot 提交者: Gitee

!108 tools/bpftool: Add BTF_KIND_FLOAT support

Merge Pull Request from: @zhengzengkai 
 
Some BPF programs compiled on s390 fail to load, because s390
arch-specific linux headers contain float and double types.

Introduce support for such types by representing them using the new
BTF_KIND_FLOAT. This series deals with libbpf, bpftool, in-kernel BTF
parser as well as selftests and documentation. 
 
Link:https://gitee.com/openeuler/kernel/pulls/108 
Reviewed-by: Xu Kuohai <xukuohai@huawei.com> 
Signed-off-by: Xie XiuQi <xiexiuqi@huawei.com> 
...@@ -84,6 +84,7 @@ sequentially and type id is assigned to each recognized type starting from id ...@@ -84,6 +84,7 @@ sequentially and type id is assigned to each recognized type starting from id
#define BTF_KIND_FUNC_PROTO 13 /* Function Proto */ #define BTF_KIND_FUNC_PROTO 13 /* Function Proto */
#define BTF_KIND_VAR 14 /* Variable */ #define BTF_KIND_VAR 14 /* Variable */
#define BTF_KIND_DATASEC 15 /* Section */ #define BTF_KIND_DATASEC 15 /* Section */
#define BTF_KIND_FLOAT 16 /* Floating point */
#define BTF_KIND_DECL_TAG 17 /* Decl Tag */ #define BTF_KIND_DECL_TAG 17 /* Decl Tag */
#define BTF_KIND_TYPE_TAG 18 /* Type Tag */ #define BTF_KIND_TYPE_TAG 18 /* Type Tag */
...@@ -97,8 +98,8 @@ Each type contains the following common data:: ...@@ -97,8 +98,8 @@ Each type contains the following common data::
/* "info" bits arrangement /* "info" bits arrangement
* bits 0-15: vlen (e.g. # of struct's members) * bits 0-15: vlen (e.g. # of struct's members)
* bits 16-23: unused * bits 16-23: unused
* bits 24-27: kind (e.g. int, ptr, array...etc) * bits 24-28: kind (e.g. int, ptr, array...etc)
* bits 28-30: unused * bits 29-30: unused
* bit 31: kind_flag, currently used by * bit 31: kind_flag, currently used by
* struct, union and fwd * struct, union and fwd
*/ */
...@@ -454,6 +455,18 @@ map definition. ...@@ -454,6 +455,18 @@ map definition.
* ``offset``: the in-section offset of the variable * ``offset``: the in-section offset of the variable
* ``size``: the size of the variable in bytes * ``size``: the size of the variable in bytes
2.2.16 BTF_KIND_FLOAT
~~~~~~~~~~~~~~~~~~~~~
``struct btf_type`` encoding requirement:
* ``name_off``: any valid offset
* ``info.kind_flag``: 0
* ``info.kind``: BTF_KIND_FLOAT
* ``info.vlen``: 0
* ``size``: the size of the float type in bytes: 2, 4, 8, 12 or 16.
No additional type data follow ``btf_type``.
2.2.17 BTF_KIND_DECL_TAG 2.2.17 BTF_KIND_DECL_TAG
~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~
......
...@@ -174,7 +174,7 @@ ...@@ -174,7 +174,7 @@
#define BITS_ROUNDUP_BYTES(bits) \ #define BITS_ROUNDUP_BYTES(bits) \
(BITS_ROUNDDOWN_BYTES(bits) + !!BITS_PER_BYTE_MASKED(bits)) (BITS_ROUNDDOWN_BYTES(bits) + !!BITS_PER_BYTE_MASKED(bits))
#define BTF_INFO_MASK 0x8f00ffff #define BTF_INFO_MASK 0x9f00ffff
#define BTF_INT_MASK 0x0fffffff #define BTF_INT_MASK 0x0fffffff
#define BTF_TYPE_ID_VALID(type_id) ((type_id) <= BTF_MAX_TYPE) #define BTF_TYPE_ID_VALID(type_id) ((type_id) <= BTF_MAX_TYPE)
#define BTF_STR_OFFSET_VALID(name_off) ((name_off) <= BTF_MAX_NAME_OFFSET) #define BTF_STR_OFFSET_VALID(name_off) ((name_off) <= BTF_MAX_NAME_OFFSET)
...@@ -281,6 +281,7 @@ static const char * const btf_kind_str[NR_BTF_KINDS] = { ...@@ -281,6 +281,7 @@ static const char * const btf_kind_str[NR_BTF_KINDS] = {
[BTF_KIND_FUNC_PROTO] = "FUNC_PROTO", [BTF_KIND_FUNC_PROTO] = "FUNC_PROTO",
[BTF_KIND_VAR] = "VAR", [BTF_KIND_VAR] = "VAR",
[BTF_KIND_DATASEC] = "DATASEC", [BTF_KIND_DATASEC] = "DATASEC",
[BTF_KIND_FLOAT] = "FLOAT",
[BTF_KIND_DECL_TAG] = "DECL_TAG", [BTF_KIND_DECL_TAG] = "DECL_TAG",
[BTF_KIND_TYPE_TAG] = "TYPE_TAG", [BTF_KIND_TYPE_TAG] = "TYPE_TAG",
}; };
...@@ -591,6 +592,7 @@ static bool btf_type_has_size(const struct btf_type *t) ...@@ -591,6 +592,7 @@ static bool btf_type_has_size(const struct btf_type *t)
case BTF_KIND_UNION: case BTF_KIND_UNION:
case BTF_KIND_ENUM: case BTF_KIND_ENUM:
case BTF_KIND_DATASEC: case BTF_KIND_DATASEC:
case BTF_KIND_FLOAT:
return true; return true;
} }
...@@ -1726,6 +1728,7 @@ __btf_resolve_size(const struct btf *btf, const struct btf_type *type, ...@@ -1726,6 +1728,7 @@ __btf_resolve_size(const struct btf *btf, const struct btf_type *type,
case BTF_KIND_STRUCT: case BTF_KIND_STRUCT:
case BTF_KIND_UNION: case BTF_KIND_UNION:
case BTF_KIND_ENUM: case BTF_KIND_ENUM:
case BTF_KIND_FLOAT:
size = type->size; size = type->size;
goto resolved; goto resolved;
...@@ -1872,7 +1875,7 @@ static int btf_df_check_kflag_member(struct btf_verifier_env *env, ...@@ -1872,7 +1875,7 @@ static int btf_df_check_kflag_member(struct btf_verifier_env *env,
return -EINVAL; return -EINVAL;
} }
/* Used for ptr, array and struct/union type members. /* Used for ptr, array struct/union and float type members.
* int, enum and modifier types have their specific callback functions. * int, enum and modifier types have their specific callback functions.
*/ */
static int btf_generic_check_kflag_member(struct btf_verifier_env *env, static int btf_generic_check_kflag_member(struct btf_verifier_env *env,
...@@ -3706,6 +3709,81 @@ static const struct btf_kind_operations datasec_ops = { ...@@ -3706,6 +3709,81 @@ static const struct btf_kind_operations datasec_ops = {
.show = btf_datasec_show, .show = btf_datasec_show,
}; };
static s32 btf_float_check_meta(struct btf_verifier_env *env,
const struct btf_type *t,
u32 meta_left)
{
if (btf_type_vlen(t)) {
btf_verifier_log_type(env, t, "vlen != 0");
return -EINVAL;
}
if (btf_type_kflag(t)) {
btf_verifier_log_type(env, t, "Invalid btf_info kind_flag");
return -EINVAL;
}
if (t->size != 2 && t->size != 4 && t->size != 8 && t->size != 12 &&
t->size != 16) {
btf_verifier_log_type(env, t, "Invalid type_size");
return -EINVAL;
}
btf_verifier_log_type(env, t, NULL);
return 0;
}
static int btf_float_check_member(struct btf_verifier_env *env,
const struct btf_type *struct_type,
const struct btf_member *member,
const struct btf_type *member_type)
{
u64 start_offset_bytes;
u64 end_offset_bytes;
u64 misalign_bits;
u64 align_bytes;
u64 align_bits;
/* Different architectures have different alignment requirements, so
* here we check only for the reasonable minimum. This way we ensure
* that types after CO-RE can pass the kernel BTF verifier.
*/
align_bytes = min_t(u64, sizeof(void *), member_type->size);
align_bits = align_bytes * BITS_PER_BYTE;
div64_u64_rem(member->offset, align_bits, &misalign_bits);
if (misalign_bits) {
btf_verifier_log_member(env, struct_type, member,
"Member is not properly aligned");
return -EINVAL;
}
start_offset_bytes = member->offset / BITS_PER_BYTE;
end_offset_bytes = start_offset_bytes + member_type->size;
if (end_offset_bytes > struct_type->size) {
btf_verifier_log_member(env, struct_type, member,
"Member exceeds struct_size");
return -EINVAL;
}
return 0;
}
static void btf_float_log(struct btf_verifier_env *env,
const struct btf_type *t)
{
btf_verifier_log(env, "size=%u", t->size);
}
static const struct btf_kind_operations float_ops = {
.check_meta = btf_float_check_meta,
.resolve = btf_df_resolve,
.check_member = btf_float_check_member,
.check_kflag_member = btf_generic_check_kflag_member,
.log_details = btf_float_log,
.show = btf_df_show,
};
static s32 btf_decl_tag_check_meta(struct btf_verifier_env *env, static s32 btf_decl_tag_check_meta(struct btf_verifier_env *env,
const struct btf_type *t, const struct btf_type *t,
u32 meta_left) u32 meta_left)
...@@ -3943,6 +4021,7 @@ static const struct btf_kind_operations * const kind_ops[NR_BTF_KINDS] = { ...@@ -3943,6 +4021,7 @@ static const struct btf_kind_operations * const kind_ops[NR_BTF_KINDS] = {
[BTF_KIND_FUNC_PROTO] = &func_proto_ops, [BTF_KIND_FUNC_PROTO] = &func_proto_ops,
[BTF_KIND_VAR] = &var_ops, [BTF_KIND_VAR] = &var_ops,
[BTF_KIND_DATASEC] = &datasec_ops, [BTF_KIND_DATASEC] = &datasec_ops,
[BTF_KIND_FLOAT] = &float_ops,
[BTF_KIND_DECL_TAG] = &decl_tag_ops, [BTF_KIND_DECL_TAG] = &decl_tag_ops,
[BTF_KIND_TYPE_TAG] = &modifier_ops, [BTF_KIND_TYPE_TAG] = &modifier_ops,
}; };
......
...@@ -36,6 +36,7 @@ static const char * const btf_kind_str[NR_BTF_KINDS] = { ...@@ -36,6 +36,7 @@ static const char * const btf_kind_str[NR_BTF_KINDS] = {
[BTF_KIND_FUNC_PROTO] = "FUNC_PROTO", [BTF_KIND_FUNC_PROTO] = "FUNC_PROTO",
[BTF_KIND_VAR] = "VAR", [BTF_KIND_VAR] = "VAR",
[BTF_KIND_DATASEC] = "DATASEC", [BTF_KIND_DATASEC] = "DATASEC",
[BTF_KIND_FLOAT] = "FLOAT",
[BTF_KIND_DECL_TAG] = "DECL_TAG", [BTF_KIND_DECL_TAG] = "DECL_TAG",
[BTF_KIND_TYPE_TAG] = "TYPE_TAG", [BTF_KIND_TYPE_TAG] = "TYPE_TAG",
}; };
...@@ -330,6 +331,13 @@ static int dump_btf_type(const struct btf *btf, __u32 id, ...@@ -330,6 +331,13 @@ static int dump_btf_type(const struct btf *btf, __u32 id,
jsonw_end_array(w); jsonw_end_array(w);
break; break;
} }
case BTF_KIND_FLOAT: {
if (json_output)
jsonw_uint_field(w, "size", t->size);
else
printf(" size=%u", t->size);
break;
}
case BTF_KIND_DECL_TAG: { case BTF_KIND_DECL_TAG: {
const struct btf_decl_tag *tag = (const void *)(t + 1); const struct btf_decl_tag *tag = (const void *)(t + 1);
......
...@@ -598,6 +598,7 @@ static int __btf_dumper_type_only(const struct btf *btf, __u32 type_id, ...@@ -598,6 +598,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: case BTF_KIND_TYPEDEF:
case BTF_KIND_FLOAT:
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:
......
...@@ -23,6 +23,7 @@ static const char * const btf_kind_str_mapping[] = { ...@@ -23,6 +23,7 @@ static const char * const btf_kind_str_mapping[] = {
[BTF_KIND_FUNC_PROTO] = "FUNC_PROTO", [BTF_KIND_FUNC_PROTO] = "FUNC_PROTO",
[BTF_KIND_VAR] = "VAR", [BTF_KIND_VAR] = "VAR",
[BTF_KIND_DATASEC] = "DATASEC", [BTF_KIND_DATASEC] = "DATASEC",
[BTF_KIND_FLOAT] = "FLOAT",
}; };
static const char *btf_kind_str(__u16 kind) static const char *btf_kind_str(__u16 kind)
...@@ -173,6 +174,9 @@ int fprintf_btf_type_raw(FILE *out, const struct btf *btf, __u32 id) ...@@ -173,6 +174,9 @@ int fprintf_btf_type_raw(FILE *out, const struct btf *btf, __u32 id)
} }
break; break;
} }
case BTF_KIND_FLOAT:
fprintf(out, " size=%u", t->size);
break;
default: default:
break; break;
} }
......
...@@ -1903,7 +1903,7 @@ static struct btf_raw_test raw_tests[] = { ...@@ -1903,7 +1903,7 @@ static struct btf_raw_test raw_tests[] = {
.raw_types = { .raw_types = {
/* int */ /* [1] */ /* int */ /* [1] */
BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
BTF_TYPE_ENC(0, 0x10000000, 4), BTF_TYPE_ENC(0, 0x20000000, 4),
BTF_END_RAW, BTF_END_RAW,
}, },
.str_sec = "", .str_sec = "",
...@@ -3531,6 +3531,136 @@ static struct btf_raw_test raw_tests[] = { ...@@ -3531,6 +3531,136 @@ static struct btf_raw_test raw_tests[] = {
.max_entries = 1, .max_entries = 1,
}, },
{
.descr = "float test #1, well-formed",
.raw_types = {
BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
/* [1] */
BTF_TYPE_FLOAT_ENC(NAME_TBD, 2), /* [2] */
BTF_TYPE_FLOAT_ENC(NAME_TBD, 4), /* [3] */
BTF_TYPE_FLOAT_ENC(NAME_TBD, 8), /* [4] */
BTF_TYPE_FLOAT_ENC(NAME_TBD, 12), /* [5] */
BTF_TYPE_FLOAT_ENC(NAME_TBD, 16), /* [6] */
BTF_STRUCT_ENC(NAME_TBD, 5, 48), /* [7] */
BTF_MEMBER_ENC(NAME_TBD, 2, 0),
BTF_MEMBER_ENC(NAME_TBD, 3, 32),
BTF_MEMBER_ENC(NAME_TBD, 4, 64),
BTF_MEMBER_ENC(NAME_TBD, 5, 128),
BTF_MEMBER_ENC(NAME_TBD, 6, 256),
BTF_END_RAW,
},
BTF_STR_SEC("\0int\0_Float16\0float\0double\0_Float80\0long_double"
"\0floats\0a\0b\0c\0d\0e"),
.map_type = BPF_MAP_TYPE_ARRAY,
.map_name = "float_type_check_btf",
.key_size = sizeof(int),
.value_size = 48,
.key_type_id = 1,
.value_type_id = 7,
.max_entries = 1,
},
{
.descr = "float test #2, invalid vlen",
.raw_types = {
BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
/* [1] */
BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_FLOAT, 0, 1), 4),
/* [2] */
BTF_END_RAW,
},
BTF_STR_SEC("\0int\0float"),
.map_type = BPF_MAP_TYPE_ARRAY,
.map_name = "float_type_check_btf",
.key_size = sizeof(int),
.value_size = 4,
.key_type_id = 1,
.value_type_id = 2,
.max_entries = 1,
.btf_load_err = true,
.err_str = "vlen != 0",
},
{
.descr = "float test #3, invalid kind_flag",
.raw_types = {
BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
/* [1] */
BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_FLOAT, 1, 0), 4),
/* [2] */
BTF_END_RAW,
},
BTF_STR_SEC("\0int\0float"),
.map_type = BPF_MAP_TYPE_ARRAY,
.map_name = "float_type_check_btf",
.key_size = sizeof(int),
.value_size = 4,
.key_type_id = 1,
.value_type_id = 2,
.max_entries = 1,
.btf_load_err = true,
.err_str = "Invalid btf_info kind_flag",
},
{
.descr = "float test #4, member does not fit",
.raw_types = {
BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
/* [1] */
BTF_TYPE_FLOAT_ENC(NAME_TBD, 4), /* [2] */
BTF_STRUCT_ENC(NAME_TBD, 1, 2), /* [3] */
BTF_MEMBER_ENC(NAME_TBD, 2, 0),
BTF_END_RAW,
},
BTF_STR_SEC("\0int\0float\0floats\0x"),
.map_type = BPF_MAP_TYPE_ARRAY,
.map_name = "float_type_check_btf",
.key_size = sizeof(int),
.value_size = 4,
.key_type_id = 1,
.value_type_id = 3,
.max_entries = 1,
.btf_load_err = true,
.err_str = "Member exceeds struct_size",
},
{
.descr = "float test #5, member is not properly aligned",
.raw_types = {
BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
/* [1] */
BTF_TYPE_FLOAT_ENC(NAME_TBD, 4), /* [2] */
BTF_STRUCT_ENC(NAME_TBD, 1, 8), /* [3] */
BTF_MEMBER_ENC(NAME_TBD, 2, 8),
BTF_END_RAW,
},
BTF_STR_SEC("\0int\0float\0floats\0x"),
.map_type = BPF_MAP_TYPE_ARRAY,
.map_name = "float_type_check_btf",
.key_size = sizeof(int),
.value_size = 4,
.key_type_id = 1,
.value_type_id = 3,
.max_entries = 1,
.btf_load_err = true,
.err_str = "Member is not properly aligned",
},
{
.descr = "float test #6, invalid size",
.raw_types = {
BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
/* [1] */
BTF_TYPE_FLOAT_ENC(NAME_TBD, 6), /* [2] */
BTF_END_RAW,
},
BTF_STR_SEC("\0int\0float"),
.map_type = BPF_MAP_TYPE_ARRAY,
.map_name = "float_type_check_btf",
.key_size = sizeof(int),
.value_size = 6,
.key_type_id = 1,
.value_type_id = 2,
.max_entries = 1,
.btf_load_err = true,
.err_str = "Invalid type_size",
},
}; /* struct btf_raw_test raw_tests[] */ }; /* struct btf_raw_test raw_tests[] */
static const char *get_next_str(const char *start, const char *end) static const char *get_next_str(const char *start, const char *end)
...@@ -6284,11 +6414,12 @@ const struct btf_dedup_test dedup_tests[] = { ...@@ -6284,11 +6414,12 @@ const struct btf_dedup_test dedup_tests[] = {
/* int[16] */ /* int[16] */
BTF_TYPE_ARRAY_ENC(1, 1, 16), /* [2] */ BTF_TYPE_ARRAY_ENC(1, 1, 16), /* [2] */
/* struct s { */ /* struct s { */
BTF_STRUCT_ENC(NAME_NTH(2), 4, 84), /* [3] */ BTF_STRUCT_ENC(NAME_NTH(2), 5, 88), /* [3] */
BTF_MEMBER_ENC(NAME_NTH(3), 4, 0), /* struct s *next; */ BTF_MEMBER_ENC(NAME_NTH(3), 4, 0), /* struct s *next; */
BTF_MEMBER_ENC(NAME_NTH(4), 5, 64), /* const int *a; */ BTF_MEMBER_ENC(NAME_NTH(4), 5, 64), /* const int *a; */
BTF_MEMBER_ENC(NAME_NTH(5), 2, 128), /* int b[16]; */ BTF_MEMBER_ENC(NAME_NTH(5), 2, 128), /* int b[16]; */
BTF_MEMBER_ENC(NAME_NTH(6), 1, 640), /* int c; */ BTF_MEMBER_ENC(NAME_NTH(6), 1, 640), /* int c; */
BTF_MEMBER_ENC(NAME_NTH(8), 13, 672), /* float d; */
/* ptr -> [3] struct s */ /* ptr -> [3] struct s */
BTF_PTR_ENC(3), /* [4] */ BTF_PTR_ENC(3), /* [4] */
/* ptr -> [6] const int */ /* ptr -> [6] const int */
...@@ -6299,39 +6430,43 @@ const struct btf_dedup_test dedup_tests[] = { ...@@ -6299,39 +6430,43 @@ const struct btf_dedup_test dedup_tests[] = {
/* full copy of the above */ /* full copy of the above */
BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4), /* [7] */ BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4), /* [7] */
BTF_TYPE_ARRAY_ENC(7, 7, 16), /* [8] */ BTF_TYPE_ARRAY_ENC(7, 7, 16), /* [8] */
BTF_STRUCT_ENC(NAME_NTH(2), 4, 84), /* [9] */ BTF_STRUCT_ENC(NAME_NTH(2), 5, 88), /* [9] */
BTF_MEMBER_ENC(NAME_NTH(3), 10, 0), BTF_MEMBER_ENC(NAME_NTH(3), 10, 0),
BTF_MEMBER_ENC(NAME_NTH(4), 11, 64), BTF_MEMBER_ENC(NAME_NTH(4), 11, 64),
BTF_MEMBER_ENC(NAME_NTH(5), 8, 128), BTF_MEMBER_ENC(NAME_NTH(5), 8, 128),
BTF_MEMBER_ENC(NAME_NTH(6), 7, 640), BTF_MEMBER_ENC(NAME_NTH(6), 7, 640),
BTF_MEMBER_ENC(NAME_NTH(8), 13, 672),
BTF_PTR_ENC(9), /* [10] */ BTF_PTR_ENC(9), /* [10] */
BTF_PTR_ENC(12), /* [11] */ BTF_PTR_ENC(12), /* [11] */
BTF_CONST_ENC(7), /* [12] */ BTF_CONST_ENC(7), /* [12] */
BTF_TYPE_FLOAT_ENC(NAME_NTH(7), 4), /* [13] */
BTF_END_RAW, BTF_END_RAW,
}, },
BTF_STR_SEC("\0int\0s\0next\0a\0b\0c\0"), BTF_STR_SEC("\0int\0s\0next\0a\0b\0c\0float\0d"),
}, },
.expect = { .expect = {
.raw_types = { .raw_types = {
/* int */ /* int */
BTF_TYPE_INT_ENC(NAME_NTH(4), BTF_INT_SIGNED, 0, 32, 4), /* [1] */ BTF_TYPE_INT_ENC(NAME_NTH(5), BTF_INT_SIGNED, 0, 32, 4), /* [1] */
/* int[16] */ /* int[16] */
BTF_TYPE_ARRAY_ENC(1, 1, 16), /* [2] */ BTF_TYPE_ARRAY_ENC(1, 1, 16), /* [2] */
/* struct s { */ /* struct s { */
BTF_STRUCT_ENC(NAME_NTH(6), 4, 84), /* [3] */ BTF_STRUCT_ENC(NAME_NTH(8), 5, 88), /* [3] */
BTF_MEMBER_ENC(NAME_NTH(5), 4, 0), /* struct s *next; */ BTF_MEMBER_ENC(NAME_NTH(7), 4, 0), /* struct s *next; */
BTF_MEMBER_ENC(NAME_NTH(1), 5, 64), /* const int *a; */ BTF_MEMBER_ENC(NAME_NTH(1), 5, 64), /* const int *a; */
BTF_MEMBER_ENC(NAME_NTH(2), 2, 128), /* int b[16]; */ BTF_MEMBER_ENC(NAME_NTH(2), 2, 128), /* int b[16]; */
BTF_MEMBER_ENC(NAME_NTH(3), 1, 640), /* int c; */ BTF_MEMBER_ENC(NAME_NTH(3), 1, 640), /* int c; */
BTF_MEMBER_ENC(NAME_NTH(4), 7, 672), /* float d; */
/* ptr -> [3] struct s */ /* ptr -> [3] struct s */
BTF_PTR_ENC(3), /* [4] */ BTF_PTR_ENC(3), /* [4] */
/* ptr -> [6] const int */ /* ptr -> [6] const int */
BTF_PTR_ENC(6), /* [5] */ BTF_PTR_ENC(6), /* [5] */
/* const -> [1] int */ /* const -> [1] int */
BTF_CONST_ENC(1), /* [6] */ BTF_CONST_ENC(1), /* [6] */
BTF_TYPE_FLOAT_ENC(NAME_NTH(7), 4), /* [7] */
BTF_END_RAW, BTF_END_RAW,
}, },
BTF_STR_SEC("\0a\0b\0c\0int\0next\0s"), BTF_STR_SEC("\0a\0b\0c\0d\0int\0float\0next\0s"),
}, },
.opts = { .opts = {
.dont_resolve_fwds = false, .dont_resolve_fwds = false,
...@@ -6452,9 +6587,10 @@ const struct btf_dedup_test dedup_tests[] = { ...@@ -6452,9 +6587,10 @@ const struct btf_dedup_test dedup_tests[] = {
BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1), BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 8), BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 8),
BTF_FUNC_ENC(NAME_TBD, 12), /* [13] func */ BTF_FUNC_ENC(NAME_TBD, 12), /* [13] func */
BTF_TYPE_FLOAT_ENC(NAME_TBD, 2), /* [14] float */
BTF_END_RAW, BTF_END_RAW,
}, },
BTF_STR_SEC("\0A\0B\0C\0D\0E\0F\0G\0H\0I\0J\0K\0L\0M"), BTF_STR_SEC("\0A\0B\0C\0D\0E\0F\0G\0H\0I\0J\0K\0L\0M\0N"),
}, },
.expect = { .expect = {
.raw_types = { .raw_types = {
...@@ -6477,16 +6613,17 @@ const struct btf_dedup_test dedup_tests[] = { ...@@ -6477,16 +6613,17 @@ const struct btf_dedup_test dedup_tests[] = {
BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1), BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 8), BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 8),
BTF_FUNC_ENC(NAME_TBD, 12), /* [13] func */ BTF_FUNC_ENC(NAME_TBD, 12), /* [13] func */
BTF_TYPE_FLOAT_ENC(NAME_TBD, 2), /* [14] float */
BTF_END_RAW, BTF_END_RAW,
}, },
BTF_STR_SEC("\0A\0B\0C\0D\0E\0F\0G\0H\0I\0J\0K\0L\0M"), BTF_STR_SEC("\0A\0B\0C\0D\0E\0F\0G\0H\0I\0J\0K\0L\0M\0N"),
}, },
.opts = { .opts = {
.dont_resolve_fwds = false, .dont_resolve_fwds = false,
}, },
}, },
{ {
.descr = "dedup: no int duplicates", .descr = "dedup: no int/float duplicates",
.input = { .input = {
.raw_types = { .raw_types = {
BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 8), BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 8),
...@@ -6501,9 +6638,15 @@ const struct btf_dedup_test dedup_tests[] = { ...@@ -6501,9 +6638,15 @@ const struct btf_dedup_test dedup_tests[] = {
BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 27, 8), BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 27, 8),
/* different byte size */ /* different byte size */
BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4), BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4),
/* all allowed sizes */
BTF_TYPE_FLOAT_ENC(NAME_NTH(3), 2),
BTF_TYPE_FLOAT_ENC(NAME_NTH(3), 4),
BTF_TYPE_FLOAT_ENC(NAME_NTH(3), 8),
BTF_TYPE_FLOAT_ENC(NAME_NTH(3), 12),
BTF_TYPE_FLOAT_ENC(NAME_NTH(3), 16),
BTF_END_RAW, BTF_END_RAW,
}, },
BTF_STR_SEC("\0int\0some other int"), BTF_STR_SEC("\0int\0some other int\0float"),
}, },
.expect = { .expect = {
.raw_types = { .raw_types = {
...@@ -6519,9 +6662,15 @@ const struct btf_dedup_test dedup_tests[] = { ...@@ -6519,9 +6662,15 @@ const struct btf_dedup_test dedup_tests[] = {
BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 27, 8), BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 27, 8),
/* different byte size */ /* different byte size */
BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4), BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4),
/* all allowed sizes */
BTF_TYPE_FLOAT_ENC(NAME_NTH(3), 2),
BTF_TYPE_FLOAT_ENC(NAME_NTH(3), 4),
BTF_TYPE_FLOAT_ENC(NAME_NTH(3), 8),
BTF_TYPE_FLOAT_ENC(NAME_NTH(3), 12),
BTF_TYPE_FLOAT_ENC(NAME_NTH(3), 16),
BTF_END_RAW, BTF_END_RAW,
}, },
BTF_STR_SEC("\0int\0some other int"), BTF_STR_SEC("\0int\0some other int\0float"),
}, },
.opts = { .opts = {
.dont_resolve_fwds = false, .dont_resolve_fwds = false,
...@@ -6633,6 +6782,7 @@ static int btf_type_size(const struct btf_type *t) ...@@ -6633,6 +6782,7 @@ static int btf_type_size(const struct btf_type *t)
case BTF_KIND_PTR: case BTF_KIND_PTR:
case BTF_KIND_TYPEDEF: case BTF_KIND_TYPEDEF:
case BTF_KIND_FUNC: case BTF_KIND_FUNC:
case BTF_KIND_FLOAT:
return base_size; return base_size;
case BTF_KIND_INT: case BTF_KIND_INT:
return base_size + sizeof(__u32); return base_size + sizeof(__u32);
......
...@@ -66,4 +66,7 @@ ...@@ -66,4 +66,7 @@
#define BTF_FUNC_ENC(name, func_proto) \ #define BTF_FUNC_ENC(name, func_proto) \
BTF_TYPE_ENC(name, BTF_INFO_ENC(BTF_KIND_FUNC, 0, 0), func_proto) BTF_TYPE_ENC(name, BTF_INFO_ENC(BTF_KIND_FUNC, 0, 0), func_proto)
#define BTF_TYPE_FLOAT_ENC(name, sz) \
BTF_TYPE_ENC(name, BTF_INFO_ENC(BTF_KIND_FLOAT, 0, 0), sz)
#endif /* _TEST_BTF_H */ #endif /* _TEST_BTF_H */
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册