Commit 2b730145 authored by Yonghong Song's avatar Yonghong Song Committed by Alexei Starovoitov
Browse files

selftests/bpf: Test new enum kflag and enum64 API functions



Add tests to use the new enum kflag and enum64 API functions
in selftest btf_write.

Acked-by: default avatarAndrii Nakryiko <andrii@kernel.org>
Signed-off-by: default avatarYonghong Song <yhs@fb.com>
Link: https://lore.kernel.org/r/20220607062703.3724287-1-yhs@fb.com


Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
parent d932815a
Loading
Loading
Loading
Loading
+22 −3
Original line number Diff line number Diff line
@@ -26,11 +26,12 @@ static const char * const btf_kind_str_mapping[] = {
	[BTF_KIND_FLOAT]	= "FLOAT",
	[BTF_KIND_DECL_TAG]	= "DECL_TAG",
	[BTF_KIND_TYPE_TAG]	= "TYPE_TAG",
	[BTF_KIND_ENUM64]	= "ENUM64",
};

static const char *btf_kind_str(__u16 kind)
{
	if (kind > BTF_KIND_TYPE_TAG)
	if (kind > BTF_KIND_ENUM64)
		return "UNKNOWN";
	return btf_kind_str_mapping[kind];
}
@@ -139,14 +140,32 @@ int fprintf_btf_type_raw(FILE *out, const struct btf *btf, __u32 id)
	}
	case BTF_KIND_ENUM: {
		const struct btf_enum *v = btf_enum(t);
		const char *fmt_str;

		fprintf(out, " size=%u vlen=%u", t->size, vlen);
		fmt_str = btf_kflag(t) ? "\n\t'%s' val=%d" : "\n\t'%s' val=%u";
		fprintf(out, " encoding=%s size=%u vlen=%u",
			btf_kflag(t) ? "SIGNED" : "UNSIGNED", t->size, vlen);
		for (i = 0; i < vlen; i++, v++) {
			fprintf(out, "\n\t'%s' val=%u",
			fprintf(out, fmt_str,
				btf_str(btf, v->name_off), v->val);
		}
		break;
	}
	case BTF_KIND_ENUM64: {
		const struct btf_enum64 *v = btf_enum64(t);
		const char *fmt_str;

		fmt_str = btf_kflag(t) ? "\n\t'%s' val=%lld" : "\n\t'%s' val=%llu";

		fprintf(out, " encoding=%s size=%u vlen=%u",
			btf_kflag(t) ? "SIGNED" : "UNSIGNED", t->size, vlen);
		for (i = 0; i < vlen; i++, v++) {
			fprintf(out, fmt_str,
				btf_str(btf, v->name_off),
				((__u64)v->val_hi32 << 32) | v->val_lo32);
		}
		break;
	}
	case BTF_KIND_FWD:
		fprintf(out, " fwd_kind=%s", btf_kflag(t) ? "union" : "struct");
		break;
+92 −34
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@ static void gen_btf(struct btf *btf)
	const struct btf_var_secinfo *vi;
	const struct btf_type *t;
	const struct btf_member *m;
	const struct btf_enum64 *v64;
	const struct btf_enum *v;
	const struct btf_param *p;
	int id, err, str_off;
@@ -171,7 +172,7 @@ static void gen_btf(struct btf *btf)
	ASSERT_STREQ(btf__str_by_offset(btf, v->name_off), "v2", "v2_name");
	ASSERT_EQ(v->val, 2, "v2_val");
	ASSERT_STREQ(btf_type_raw_dump(btf, 9),
		     "[9] ENUM 'e1' size=4 vlen=2\n"
		     "[9] ENUM 'e1' encoding=UNSIGNED size=4 vlen=2\n"
		     "\t'v1' val=1\n"
		     "\t'v2' val=2", "raw_dump");

@@ -202,7 +203,7 @@ static void gen_btf(struct btf *btf)
	ASSERT_EQ(btf_vlen(t), 0, "enum_fwd_kind");
	ASSERT_EQ(t->size, 4, "enum_fwd_sz");
	ASSERT_STREQ(btf_type_raw_dump(btf, 12),
		     "[12] ENUM 'enum_fwd' size=4 vlen=0", "raw_dump");
		     "[12] ENUM 'enum_fwd' encoding=UNSIGNED size=4 vlen=0", "raw_dump");

	/* TYPEDEF */
	id = btf__add_typedef(btf, "typedef1", 1);
@@ -307,6 +308,48 @@ static void gen_btf(struct btf *btf)
	ASSERT_EQ(t->type, 1, "tag_type");
	ASSERT_STREQ(btf_type_raw_dump(btf, 20),
		     "[20] TYPE_TAG 'tag1' type_id=1", "raw_dump");

	/* ENUM64 */
	id = btf__add_enum64(btf, "e1", 8, true);
	ASSERT_EQ(id, 21, "enum64_id");
	err = btf__add_enum64_value(btf, "v1", -1);
	ASSERT_OK(err, "v1_res");
	err = btf__add_enum64_value(btf, "v2", 0x123456789); /* 4886718345 */
	ASSERT_OK(err, "v2_res");
	t = btf__type_by_id(btf, 21);
	ASSERT_STREQ(btf__str_by_offset(btf, t->name_off), "e1", "enum64_name");
	ASSERT_EQ(btf_kind(t), BTF_KIND_ENUM64, "enum64_kind");
	ASSERT_EQ(btf_vlen(t), 2, "enum64_vlen");
	ASSERT_EQ(t->size, 8, "enum64_sz");
	v64 = btf_enum64(t) + 0;
	ASSERT_STREQ(btf__str_by_offset(btf, v64->name_off), "v1", "v1_name");
	ASSERT_EQ(v64->val_hi32, 0xffffffff, "v1_val");
	ASSERT_EQ(v64->val_lo32, 0xffffffff, "v1_val");
	v64 = btf_enum64(t) + 1;
	ASSERT_STREQ(btf__str_by_offset(btf, v64->name_off), "v2", "v2_name");
	ASSERT_EQ(v64->val_hi32, 0x1, "v2_val");
	ASSERT_EQ(v64->val_lo32, 0x23456789, "v2_val");
	ASSERT_STREQ(btf_type_raw_dump(btf, 21),
		     "[21] ENUM64 'e1' encoding=SIGNED size=8 vlen=2\n"
		     "\t'v1' val=-1\n"
		     "\t'v2' val=4886718345", "raw_dump");

	id = btf__add_enum64(btf, "e1", 8, false);
	ASSERT_EQ(id, 22, "enum64_id");
	err = btf__add_enum64_value(btf, "v1", 0xffffffffFFFFFFFF); /* 18446744073709551615 */
	ASSERT_OK(err, "v1_res");
	t = btf__type_by_id(btf, 22);
	ASSERT_STREQ(btf__str_by_offset(btf, t->name_off), "e1", "enum64_name");
	ASSERT_EQ(btf_kind(t), BTF_KIND_ENUM64, "enum64_kind");
	ASSERT_EQ(btf_vlen(t), 1, "enum64_vlen");
	ASSERT_EQ(t->size, 8, "enum64_sz");
	v64 = btf_enum64(t) + 0;
	ASSERT_STREQ(btf__str_by_offset(btf, v64->name_off), "v1", "v1_name");
	ASSERT_EQ(v64->val_hi32, 0xffffffff, "v1_val");
	ASSERT_EQ(v64->val_lo32, 0xffffffff, "v1_val");
	ASSERT_STREQ(btf_type_raw_dump(btf, 22),
		     "[22] ENUM64 'e1' encoding=UNSIGNED size=8 vlen=1\n"
		     "\t'v1' val=18446744073709551615", "raw_dump");
}

static void test_btf_add()
@@ -332,12 +375,12 @@ static void test_btf_add()
		"\t'f2' type_id=1 bits_offset=32 bitfield_size=16",
		"[8] UNION 'u1' size=8 vlen=1\n"
		"\t'f1' type_id=1 bits_offset=0 bitfield_size=16",
		"[9] ENUM 'e1' size=4 vlen=2\n"
		"[9] ENUM 'e1' encoding=UNSIGNED size=4 vlen=2\n"
		"\t'v1' val=1\n"
		"\t'v2' val=2",
		"[10] FWD 'struct_fwd' fwd_kind=struct",
		"[11] FWD 'union_fwd' fwd_kind=union",
		"[12] ENUM 'enum_fwd' size=4 vlen=0",
		"[12] ENUM 'enum_fwd' encoding=UNSIGNED size=4 vlen=0",
		"[13] TYPEDEF 'typedef1' type_id=1",
		"[14] FUNC 'func1' type_id=15 linkage=global",
		"[15] FUNC_PROTO '(anon)' ret_type_id=1 vlen=2\n"
@@ -348,7 +391,12 @@ static void test_btf_add()
		"\ttype_id=1 offset=4 size=8",
		"[18] DECL_TAG 'tag1' type_id=16 component_idx=-1",
		"[19] DECL_TAG 'tag2' type_id=14 component_idx=1",
		"[20] TYPE_TAG 'tag1' type_id=1");
		"[20] TYPE_TAG 'tag1' type_id=1",
		"[21] ENUM64 'e1' encoding=SIGNED size=8 vlen=2\n"
		"\t'v1' val=-1\n"
		"\t'v2' val=4886718345",
		"[22] ENUM64 'e1' encoding=UNSIGNED size=8 vlen=1\n"
		"\t'v1' val=18446744073709551615");

	btf__free(btf);
}
@@ -370,7 +418,7 @@ static void test_btf_add_btf()
	gen_btf(btf2);

	id = btf__add_btf(btf1, btf2);
	if (!ASSERT_EQ(id, 21, "id"))
	if (!ASSERT_EQ(id, 23, "id"))
		goto cleanup;

	VALIDATE_RAW_BTF(
@@ -386,12 +434,12 @@ static void test_btf_add_btf()
		"\t'f2' type_id=1 bits_offset=32 bitfield_size=16",
		"[8] UNION 'u1' size=8 vlen=1\n"
		"\t'f1' type_id=1 bits_offset=0 bitfield_size=16",
		"[9] ENUM 'e1' size=4 vlen=2\n"
		"[9] ENUM 'e1' encoding=UNSIGNED size=4 vlen=2\n"
		"\t'v1' val=1\n"
		"\t'v2' val=2",
		"[10] FWD 'struct_fwd' fwd_kind=struct",
		"[11] FWD 'union_fwd' fwd_kind=union",
		"[12] ENUM 'enum_fwd' size=4 vlen=0",
		"[12] ENUM 'enum_fwd' encoding=UNSIGNED size=4 vlen=0",
		"[13] TYPEDEF 'typedef1' type_id=1",
		"[14] FUNC 'func1' type_id=15 linkage=global",
		"[15] FUNC_PROTO '(anon)' ret_type_id=1 vlen=2\n"
@@ -403,36 +451,46 @@ static void test_btf_add_btf()
		"[18] DECL_TAG 'tag1' type_id=16 component_idx=-1",
		"[19] DECL_TAG 'tag2' type_id=14 component_idx=1",
		"[20] TYPE_TAG 'tag1' type_id=1",
		"[21] ENUM64 'e1' encoding=SIGNED size=8 vlen=2\n"
		"\t'v1' val=-1\n"
		"\t'v2' val=4886718345",
		"[22] ENUM64 'e1' encoding=UNSIGNED size=8 vlen=1\n"
		"\t'v1' val=18446744073709551615",

		/* types appended from the second BTF */
		"[21] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED",
		"[22] PTR '(anon)' type_id=21",
		"[23] CONST '(anon)' type_id=25",
		"[24] VOLATILE '(anon)' type_id=23",
		"[25] RESTRICT '(anon)' type_id=24",
		"[26] ARRAY '(anon)' type_id=22 index_type_id=21 nr_elems=10",
		"[27] STRUCT 's1' size=8 vlen=2\n"
		"\t'f1' type_id=21 bits_offset=0\n"
		"\t'f2' type_id=21 bits_offset=32 bitfield_size=16",
		"[28] UNION 'u1' size=8 vlen=1\n"
		"\t'f1' type_id=21 bits_offset=0 bitfield_size=16",
		"[29] ENUM 'e1' size=4 vlen=2\n"
		"[23] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED",
		"[24] PTR '(anon)' type_id=23",
		"[25] CONST '(anon)' type_id=27",
		"[26] VOLATILE '(anon)' type_id=25",
		"[27] RESTRICT '(anon)' type_id=26",
		"[28] ARRAY '(anon)' type_id=24 index_type_id=23 nr_elems=10",
		"[29] STRUCT 's1' size=8 vlen=2\n"
		"\t'f1' type_id=23 bits_offset=0\n"
		"\t'f2' type_id=23 bits_offset=32 bitfield_size=16",
		"[30] UNION 'u1' size=8 vlen=1\n"
		"\t'f1' type_id=23 bits_offset=0 bitfield_size=16",
		"[31] ENUM 'e1' encoding=UNSIGNED size=4 vlen=2\n"
		"\t'v1' val=1\n"
		"\t'v2' val=2",
		"[30] FWD 'struct_fwd' fwd_kind=struct",
		"[31] FWD 'union_fwd' fwd_kind=union",
		"[32] ENUM 'enum_fwd' size=4 vlen=0",
		"[33] TYPEDEF 'typedef1' type_id=21",
		"[34] FUNC 'func1' type_id=35 linkage=global",
		"[35] FUNC_PROTO '(anon)' ret_type_id=21 vlen=2\n"
		"\t'p1' type_id=21\n"
		"\t'p2' type_id=22",
		"[36] VAR 'var1' type_id=21, linkage=global-alloc",
		"[37] DATASEC 'datasec1' size=12 vlen=1\n"
		"\ttype_id=21 offset=4 size=8",
		"[38] DECL_TAG 'tag1' type_id=36 component_idx=-1",
		"[39] DECL_TAG 'tag2' type_id=34 component_idx=1",
		"[40] TYPE_TAG 'tag1' type_id=21");
		"[32] FWD 'struct_fwd' fwd_kind=struct",
		"[33] FWD 'union_fwd' fwd_kind=union",
		"[34] ENUM 'enum_fwd' encoding=UNSIGNED size=4 vlen=0",
		"[35] TYPEDEF 'typedef1' type_id=23",
		"[36] FUNC 'func1' type_id=37 linkage=global",
		"[37] FUNC_PROTO '(anon)' ret_type_id=23 vlen=2\n"
		"\t'p1' type_id=23\n"
		"\t'p2' type_id=24",
		"[38] VAR 'var1' type_id=23, linkage=global-alloc",
		"[39] DATASEC 'datasec1' size=12 vlen=1\n"
		"\ttype_id=23 offset=4 size=8",
		"[40] DECL_TAG 'tag1' type_id=38 component_idx=-1",
		"[41] DECL_TAG 'tag2' type_id=36 component_idx=1",
		"[42] TYPE_TAG 'tag1' type_id=23",
		"[43] ENUM64 'e1' encoding=SIGNED size=8 vlen=2\n"
		"\t'v1' val=-1\n"
		"\t'v2' val=4886718345",
		"[44] ENUM64 'e1' encoding=UNSIGNED size=8 vlen=1\n"
		"\t'v1' val=18446744073709551615");

cleanup:
	btf__free(btf1);