brintos

brintos / linux-shallow public Read only

0
0
Text · 3.4 KiB · 5154437 Raw
168 lines · c
1// SPDX-License-Identifier: GPL-2.02 3#include <linux/err.h>4#include <string.h>5#include <bpf/btf.h>6#include <bpf/libbpf.h>7#include <linux/btf.h>8#include <linux/kernel.h>9#define CONFIG_DEBUG_INFO_BTF10#include <linux/btf_ids.h>11#include "test_progs.h"12 13static int duration;14 15struct symbol {16	const char	*name;17	int		 type;18	int		 id;19};20 21struct symbol test_symbols[] = {22	{ "unused",  BTF_KIND_UNKN,     0 },23	{ "S",       BTF_KIND_TYPEDEF, -1 },24	{ "T",       BTF_KIND_TYPEDEF, -1 },25	{ "U",       BTF_KIND_TYPEDEF, -1 },26	{ "S",       BTF_KIND_STRUCT,  -1 },27	{ "U",       BTF_KIND_UNION,   -1 },28	{ "func",    BTF_KIND_FUNC,    -1 },29};30 31/* Align the .BTF_ids section to 4 bytes */32asm (33".pushsection " BTF_IDS_SECTION " ,\"a\"; \n"34".balign 4, 0;                            \n"35".popsection;                             \n");36 37BTF_ID_LIST(test_list_local)38BTF_ID_UNUSED39BTF_ID(typedef, S)40BTF_ID(typedef, T)41BTF_ID(typedef, U)42BTF_ID(struct,  S)43BTF_ID(union,   U)44BTF_ID(func,    func)45 46extern __u32 test_list_global[];47BTF_ID_LIST_GLOBAL(test_list_global, 1)48BTF_ID_UNUSED49BTF_ID(typedef, S)50BTF_ID(typedef, T)51BTF_ID(typedef, U)52BTF_ID(struct,  S)53BTF_ID(union,   U)54BTF_ID(func,    func)55 56BTF_SET_START(test_set)57BTF_ID(typedef, S)58BTF_ID(typedef, T)59BTF_ID(typedef, U)60BTF_ID(struct,  S)61BTF_ID(union,   U)62BTF_ID(func,    func)63BTF_SET_END(test_set)64 65static int66__resolve_symbol(struct btf *btf, int type_id)67{68	const struct btf_type *type;69	const char *str;70	unsigned int i;71 72	type = btf__type_by_id(btf, type_id);73	if (!type) {74		PRINT_FAIL("Failed to get type for ID %d\n", type_id);75		return -1;76	}77 78	for (i = 0; i < ARRAY_SIZE(test_symbols); i++) {79		if (test_symbols[i].id >= 0)80			continue;81 82		if (BTF_INFO_KIND(type->info) != test_symbols[i].type)83			continue;84 85		str = btf__name_by_offset(btf, type->name_off);86		if (!str) {87			PRINT_FAIL("Failed to get name for BTF ID %d\n", type_id);88			return -1;89		}90 91		if (!strcmp(str, test_symbols[i].name))92			test_symbols[i].id = type_id;93	}94 95	return 0;96}97 98static int resolve_symbols(void)99{100	struct btf *btf;101	int type_id;102	__u32 nr;103 104	btf = btf__parse_elf("btf_data.bpf.o", NULL);105	if (CHECK(libbpf_get_error(btf), "resolve",106		  "Failed to load BTF from btf_data.bpf.o\n"))107		return -1;108 109	nr = btf__type_cnt(btf);110 111	for (type_id = 1; type_id < nr; type_id++) {112		if (__resolve_symbol(btf, type_id))113			break;114	}115 116	btf__free(btf);117	return 0;118}119 120void test_resolve_btfids(void)121{122	__u32 *test_list, *test_lists[] = { test_list_local, test_list_global };123	unsigned int i, j;124	int ret = 0;125 126	if (resolve_symbols())127		return;128 129	/* Check BTF_ID_LIST(test_list_local) and130	 * BTF_ID_LIST_GLOBAL(test_list_global) IDs131	 */132	for (j = 0; j < ARRAY_SIZE(test_lists); j++) {133		test_list = test_lists[j];134		for (i = 0; i < ARRAY_SIZE(test_symbols); i++) {135			ret = CHECK(test_list[i] != test_symbols[i].id,136				    "id_check",137				    "wrong ID for %s (%d != %d)\n",138				    test_symbols[i].name,139				    test_list[i], test_symbols[i].id);140			if (ret)141				return;142		}143	}144 145	/* Check BTF_SET_START(test_set) IDs */146	for (i = 0; i < test_set.cnt; i++) {147		bool found = false;148 149		for (j = 0; j < ARRAY_SIZE(test_symbols); j++) {150			if (test_symbols[j].id != test_set.ids[i])151				continue;152			found = true;153			break;154		}155 156		ret = CHECK(!found, "id_check",157			    "ID %d not found in test_symbols\n",158			    test_set.ids[i]);159		if (ret)160			break;161 162		if (i > 0) {163			if (!ASSERT_LE(test_set.ids[i - 1], test_set.ids[i], "sort_check"))164				return;165		}166	}167}168