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

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

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/bpf/prog_tests/core_reloc.c
Extension
.c
Size
34663 bytes
Lines
1159
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

struct core_reloc_test_case {
	const char *case_name;
	const char *bpf_obj_file;
	const char *btf_src_file;
	const char *input;
	int input_len;
	const char *output;
	int output_len;
	bool fails;
	bool run_btfgen_fails;
	bool needs_testmod;
	bool relaxed_core_relocs;
	const char *prog_name;
	const char *raw_tp_name;
	setup_test_fn setup;
	trigger_test_fn trigger;
};

static int find_btf_type(const struct btf *btf, const char *name, __u32 kind)
{
	int id;

	id = btf__find_by_name_kind(btf, name, kind);
	if (CHECK(id <= 0, "find_type_id", "failed to find '%s', kind %d: %d\n", name, kind, id))
		return -1;

	return id;
}

static int setup_type_id_case_local(struct core_reloc_test_case *test)
{
	struct core_reloc_type_id_output *exp = (void *)test->output;
	struct btf *local_btf = btf__parse(test->bpf_obj_file, NULL);
	struct btf *targ_btf = btf__parse(test->btf_src_file, NULL);
	const struct btf_type *t;
	const char *name;
	int i;

	if (!ASSERT_OK_PTR(local_btf, "local_btf") || !ASSERT_OK_PTR(targ_btf, "targ_btf")) {
		btf__free(local_btf);
		btf__free(targ_btf);
		return -EINVAL;
	}

	exp->local_anon_struct = -1;
	exp->local_anon_union = -1;
	exp->local_anon_enum = -1;
	exp->local_anon_func_proto_ptr = -1;
	exp->local_anon_void_ptr = -1;
	exp->local_anon_arr = -1;

	for (i = 1; i < btf__type_cnt(local_btf); i++)
	{
		t = btf__type_by_id(local_btf, i);
		/* we are interested only in anonymous types */
		if (t->name_off)
			continue;

		if (btf_is_struct(t) && btf_vlen(t) &&
		    (name = btf__name_by_offset(local_btf, btf_members(t)[0].name_off)) &&
		    strcmp(name, "marker_field") == 0) {
			exp->local_anon_struct = i;
		} else if (btf_is_union(t) && btf_vlen(t) &&
			 (name = btf__name_by_offset(local_btf, btf_members(t)[0].name_off)) &&
			 strcmp(name, "marker_field") == 0) {
			exp->local_anon_union = i;
		} else if (btf_is_enum(t) && btf_vlen(t) &&
			 (name = btf__name_by_offset(local_btf, btf_enum(t)[0].name_off)) &&
			 strcmp(name, "MARKER_ENUM_VAL") == 0) {
			exp->local_anon_enum = i;
		} else if (btf_is_ptr(t) && (t = btf__type_by_id(local_btf, t->type))) {
			if (btf_is_func_proto(t) && (t = btf__type_by_id(local_btf, t->type)) &&
			    btf_is_int(t) && (name = btf__name_by_offset(local_btf, t->name_off)) &&
			    strcmp(name, "_Bool") == 0) {
				/* ptr -> func_proto -> _Bool */
				exp->local_anon_func_proto_ptr = i;
			} else if (btf_is_void(t)) {
				/* ptr -> void */
				exp->local_anon_void_ptr = i;
			}
		} else if (btf_is_array(t) && (t = btf__type_by_id(local_btf, btf_array(t)->type)) &&
			   btf_is_int(t) && (name = btf__name_by_offset(local_btf, t->name_off)) &&
			   strcmp(name, "_Bool") == 0) {
			/* _Bool[] */
			exp->local_anon_arr = i;
		}
	}

	exp->local_struct = find_btf_type(local_btf, "a_struct", BTF_KIND_STRUCT);
	exp->local_union = find_btf_type(local_btf, "a_union", BTF_KIND_UNION);

Annotation

Implementation Notes