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

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

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/bpf/prog_tests/btf_distill.c
Extension
.c
Size
24775 bytes
Lines
693
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) 2024, Oracle and/or its affiliates. */

#include <test_progs.h>
#include <bpf/btf.h>
#include "btf_helpers.h"

/* Fabricate base, split BTF with references to base types needed; then create
 * split BTF with distilled base BTF and ensure expectations are met:
 *  - only referenced base types from split BTF are present
 *  - struct/union/enum are represented as empty unless anonymous, when they
 *    are represented in full in split BTF
 */
static void test_distilled_base(void)
{
	struct btf *btf1 = NULL, *btf2 = NULL, *btf3 = NULL, *btf4 = NULL;

	btf1 = btf__new_empty();
	if (!ASSERT_OK_PTR(btf1, "empty_main_btf"))
		return;

	btf__add_int(btf1, "int", 4, BTF_INT_SIGNED);	/* [1] int */
	btf__add_ptr(btf1, 1);				/* [2] ptr to int */
	btf__add_struct(btf1, "s1", 8);			/* [3] struct s1 { */
	btf__add_field(btf1, "f1", 2, 0, 0);		/*      int *f1; */
							/* } */
	btf__add_struct(btf1, "", 12);			/* [4] struct { */
	btf__add_field(btf1, "f1", 1, 0, 0);		/*	int f1; */
	btf__add_field(btf1, "f2", 3, 32, 0);		/*	struct s1 f2; */
							/* } */
	btf__add_int(btf1, "unsigned int", 4, 0);	/* [5] unsigned int */
	btf__add_union(btf1, "u1", 12);			/* [6] union u1 { */
	btf__add_field(btf1, "f1", 1, 0, 0);		/*	int f1; */
	btf__add_field(btf1, "f2", 2, 0, 0);		/*	int *f2; */
							/* } */
	btf__add_union(btf1, "", 4);			/* [7] union { */
	btf__add_field(btf1, "f1", 1, 0, 0);		/*	int f1; */
							/* } */
	btf__add_enum(btf1, "e1", 4);			/* [8] enum e1 { */
	btf__add_enum_value(btf1, "v1", 1);		/*	v1 = 1; */
							/* } */
	btf__add_enum(btf1, "", 4);			/* [9] enum { */
	btf__add_enum_value(btf1, "av1", 2);		/*	av1 = 2; */
							/* } */
	btf__add_enum64(btf1, "e641", 8, true);		/* [10] enum64 { */
	btf__add_enum64_value(btf1, "v1", 1024);	/*	v1 = 1024; */
							/* } */
	btf__add_enum64(btf1, "", 8, true);		/* [11] enum64 { */
	btf__add_enum64_value(btf1, "v1", 1025);	/*	v1 = 1025; */
							/* } */
	btf__add_struct(btf1, "unneeded", 4);		/* [12] struct unneeded { */
	btf__add_field(btf1, "f1", 1, 0, 0);		/*	int f1; */
							/* } */
	btf__add_struct(btf1, "embedded", 4);		/* [13] struct embedded { */
	btf__add_field(btf1, "f1", 1, 0, 0);		/*	int f1; */
							/* } */
	btf__add_func_proto(btf1, 1);			/* [14] int (*)(int *p1); */
	btf__add_func_param(btf1, "p1", 1);

	btf__add_array(btf1, 1, 1, 3);			/* [15] int [3]; */

	btf__add_struct(btf1, "from_proto", 4);		/* [16] struct from_proto { */
	btf__add_field(btf1, "f1", 1, 0, 0);		/*	int f1; */
							/* } */
	btf__add_union(btf1, "u1", 4);			/* [17] union u1 { */
	btf__add_field(btf1, "f1", 1, 0, 0);		/*	 int f1; */
							/* } */
	VALIDATE_RAW_BTF(
		btf1,
		"[1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED",
		"[2] PTR '(anon)' type_id=1",
		"[3] STRUCT 's1' size=8 vlen=1\n"
		"\t'f1' type_id=2 bits_offset=0",
		"[4] STRUCT '(anon)' size=12 vlen=2\n"
		"\t'f1' type_id=1 bits_offset=0\n"
		"\t'f2' type_id=3 bits_offset=32",
		"[5] INT 'unsigned int' size=4 bits_offset=0 nr_bits=32 encoding=(none)",
		"[6] UNION 'u1' size=12 vlen=2\n"
		"\t'f1' type_id=1 bits_offset=0\n"
		"\t'f2' type_id=2 bits_offset=0",
		"[7] UNION '(anon)' size=4 vlen=1\n"
		"\t'f1' type_id=1 bits_offset=0",
		"[8] ENUM 'e1' encoding=UNSIGNED size=4 vlen=1\n"
		"\t'v1' val=1",
		"[9] ENUM '(anon)' encoding=UNSIGNED size=4 vlen=1\n"
		"\t'av1' val=2",
		"[10] ENUM64 'e641' encoding=SIGNED size=8 vlen=1\n"
		"\t'v1' val=1024",
		"[11] ENUM64 '(anon)' encoding=SIGNED size=8 vlen=1\n"
		"\t'v1' val=1025",

Annotation

Implementation Notes