tools/testing/selftests/bpf/prog_tests/btf_write.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/bpf/prog_tests/btf_write.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/bpf/prog_tests/btf_write.c
Extension
.c
Size
22361 bytes
Lines
618
Domain
Support Tooling And Documentation
Bucket
tools
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

// SPDX-License-Identifier: GPL-2.0
/* Copyright (c) 2020 Facebook */
#include <test_progs.h>
#include <bpf/btf.h>
#include "btf_helpers.h"

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;

	str_off = btf__find_str(btf, "int");
	ASSERT_EQ(str_off, -ENOENT, "int_str_missing_off");

	str_off = btf__add_str(btf, "int");
	ASSERT_EQ(str_off, 1, "int_str_off");

	str_off = btf__find_str(btf, "int");
	ASSERT_EQ(str_off, 1, "int_str_found_off");

	/* BTF_KIND_INT */
	id = btf__add_int(btf, "int", 4,  BTF_INT_SIGNED);
	ASSERT_EQ(id, 1, "int_id");

	t = btf__type_by_id(btf, 1);
	/* should re-use previously added "int" string */
	ASSERT_EQ(t->name_off, str_off, "int_name_off");
	ASSERT_STREQ(btf__str_by_offset(btf, t->name_off), "int", "int_name");
	ASSERT_EQ(btf_kind(t), BTF_KIND_INT, "int_kind");
	ASSERT_EQ(t->size, 4, "int_sz");
	ASSERT_EQ(btf_int_encoding(t), BTF_INT_SIGNED, "int_enc");
	ASSERT_EQ(btf_int_bits(t), 32, "int_bits");
	ASSERT_STREQ(btf_type_raw_dump(btf, 1),
		     "[1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED", "raw_dump");

	/* invalid int size */
	id = btf__add_int(btf, "bad sz int", 7, 0);
	ASSERT_ERR(id, "int_bad_sz");
	/* invalid encoding */
	id = btf__add_int(btf, "bad enc int", 4, 123);
	ASSERT_ERR(id, "int_bad_enc");
	/* NULL name */
	id = btf__add_int(btf, NULL, 4, 0);
	ASSERT_ERR(id, "int_bad_null_name");
	/* empty name */
	id = btf__add_int(btf, "", 4, 0);
	ASSERT_ERR(id, "int_bad_empty_name");

	/* PTR/CONST/VOLATILE/RESTRICT */
	id = btf__add_ptr(btf, 1);
	ASSERT_EQ(id, 2, "ptr_id");
	t = btf__type_by_id(btf, 2);
	ASSERT_EQ(btf_kind(t), BTF_KIND_PTR, "ptr_kind");
	ASSERT_EQ(t->type, 1, "ptr_type");
	ASSERT_STREQ(btf_type_raw_dump(btf, 2),
		     "[2] PTR '(anon)' type_id=1", "raw_dump");

	id = btf__add_const(btf, 5); /* points forward to restrict */
	ASSERT_EQ(id, 3, "const_id");
	t = btf__type_by_id(btf, 3);
	ASSERT_EQ(btf_kind(t), BTF_KIND_CONST, "const_kind");
	ASSERT_EQ(t->type, 5, "const_type");
	ASSERT_STREQ(btf_type_raw_dump(btf, 3),
		     "[3] CONST '(anon)' type_id=5", "raw_dump");

	id = btf__add_volatile(btf, 3);
	ASSERT_EQ(id, 4, "volatile_id");
	t = btf__type_by_id(btf, 4);
	ASSERT_EQ(btf_kind(t), BTF_KIND_VOLATILE, "volatile_kind");
	ASSERT_EQ(t->type, 3, "volatile_type");
	ASSERT_STREQ(btf_type_raw_dump(btf, 4),
		     "[4] VOLATILE '(anon)' type_id=3", "raw_dump");

	id = btf__add_restrict(btf, 4);
	ASSERT_EQ(id, 5, "restrict_id");
	t = btf__type_by_id(btf, 5);
	ASSERT_EQ(btf_kind(t), BTF_KIND_RESTRICT, "restrict_kind");
	ASSERT_EQ(t->type, 4, "restrict_type");
	ASSERT_STREQ(btf_type_raw_dump(btf, 5),
		     "[5] RESTRICT '(anon)' type_id=4", "raw_dump");

	/* ARRAY */
	id = btf__add_array(btf, 1, 2, 10); /* int *[10] */
	ASSERT_EQ(id, 6, "array_id");
	t = btf__type_by_id(btf, 6);

Annotation

Implementation Notes