1cc15a20dSJiri Olsa // SPDX-License-Identifier: GPL-2.0 2cc15a20dSJiri Olsa 3cc15a20dSJiri Olsa #include <linux/err.h> 4cc15a20dSJiri Olsa #include <string.h> 5cc15a20dSJiri Olsa #include <bpf/btf.h> 6cc15a20dSJiri Olsa #include <bpf/libbpf.h> 7cc15a20dSJiri Olsa #include <linux/btf.h> 8cc15a20dSJiri Olsa #include <linux/kernel.h> 9cc15a20dSJiri Olsa #include <linux/btf_ids.h> 10cc15a20dSJiri Olsa #include "test_progs.h" 11cc15a20dSJiri Olsa 12cc15a20dSJiri Olsa static int duration; 13cc15a20dSJiri Olsa 14cc15a20dSJiri Olsa struct symbol { 15cc15a20dSJiri Olsa const char *name; 16cc15a20dSJiri Olsa int type; 17cc15a20dSJiri Olsa int id; 18cc15a20dSJiri Olsa }; 19cc15a20dSJiri Olsa 20cc15a20dSJiri Olsa struct symbol test_symbols[] = { 21cc15a20dSJiri Olsa { "unused", BTF_KIND_UNKN, 0 }, 22cc15a20dSJiri Olsa { "S", BTF_KIND_TYPEDEF, -1 }, 23cc15a20dSJiri Olsa { "T", BTF_KIND_TYPEDEF, -1 }, 24cc15a20dSJiri Olsa { "U", BTF_KIND_TYPEDEF, -1 }, 25cc15a20dSJiri Olsa { "S", BTF_KIND_STRUCT, -1 }, 26cc15a20dSJiri Olsa { "U", BTF_KIND_UNION, -1 }, 27cc15a20dSJiri Olsa { "func", BTF_KIND_FUNC, -1 }, 28cc15a20dSJiri Olsa }; 29cc15a20dSJiri Olsa 30cc15a20dSJiri Olsa BTF_ID_LIST(test_list) 31cc15a20dSJiri Olsa BTF_ID_UNUSED 32cc15a20dSJiri Olsa BTF_ID(typedef, S) 33cc15a20dSJiri Olsa BTF_ID(typedef, T) 34cc15a20dSJiri Olsa BTF_ID(typedef, U) 35cc15a20dSJiri Olsa BTF_ID(struct, S) 36cc15a20dSJiri Olsa BTF_ID(union, U) 37cc15a20dSJiri Olsa BTF_ID(func, func) 38cc15a20dSJiri Olsa 39cc15a20dSJiri Olsa static int 40cc15a20dSJiri Olsa __resolve_symbol(struct btf *btf, int type_id) 41cc15a20dSJiri Olsa { 42cc15a20dSJiri Olsa const struct btf_type *type; 43cc15a20dSJiri Olsa const char *str; 44cc15a20dSJiri Olsa unsigned int i; 45cc15a20dSJiri Olsa 46cc15a20dSJiri Olsa type = btf__type_by_id(btf, type_id); 47cc15a20dSJiri Olsa if (!type) { 48cc15a20dSJiri Olsa PRINT_FAIL("Failed to get type for ID %d\n", type_id); 49cc15a20dSJiri Olsa return -1; 50cc15a20dSJiri Olsa } 51cc15a20dSJiri Olsa 52cc15a20dSJiri Olsa for (i = 0; i < ARRAY_SIZE(test_symbols); i++) { 53cc15a20dSJiri Olsa if (test_symbols[i].id != -1) 54cc15a20dSJiri Olsa continue; 55cc15a20dSJiri Olsa 56cc15a20dSJiri Olsa if (BTF_INFO_KIND(type->info) != test_symbols[i].type) 57cc15a20dSJiri Olsa continue; 58cc15a20dSJiri Olsa 59cc15a20dSJiri Olsa str = btf__name_by_offset(btf, type->name_off); 60cc15a20dSJiri Olsa if (!str) { 61cc15a20dSJiri Olsa PRINT_FAIL("Failed to get name for BTF ID %d\n", type_id); 62cc15a20dSJiri Olsa return -1; 63cc15a20dSJiri Olsa } 64cc15a20dSJiri Olsa 65cc15a20dSJiri Olsa if (!strcmp(str, test_symbols[i].name)) 66cc15a20dSJiri Olsa test_symbols[i].id = type_id; 67cc15a20dSJiri Olsa } 68cc15a20dSJiri Olsa 69cc15a20dSJiri Olsa return 0; 70cc15a20dSJiri Olsa } 71cc15a20dSJiri Olsa 72cc15a20dSJiri Olsa static int resolve_symbols(void) 73cc15a20dSJiri Olsa { 74cc15a20dSJiri Olsa struct btf *btf; 75cc15a20dSJiri Olsa int type_id; 76cc15a20dSJiri Olsa __u32 nr; 77cc15a20dSJiri Olsa 78cc15a20dSJiri Olsa btf = btf__parse_elf("btf_data.o", NULL); 79cc15a20dSJiri Olsa if (CHECK(libbpf_get_error(btf), "resolve", 80cc15a20dSJiri Olsa "Failed to load BTF from btf_data.o\n")) 81cc15a20dSJiri Olsa return -1; 82cc15a20dSJiri Olsa 83cc15a20dSJiri Olsa nr = btf__get_nr_types(btf); 84cc15a20dSJiri Olsa 85cc15a20dSJiri Olsa for (type_id = 1; type_id <= nr; type_id++) { 86cc15a20dSJiri Olsa if (__resolve_symbol(btf, type_id)) 87cc15a20dSJiri Olsa break; 88cc15a20dSJiri Olsa } 89cc15a20dSJiri Olsa 90cc15a20dSJiri Olsa btf__free(btf); 91cc15a20dSJiri Olsa return 0; 92cc15a20dSJiri Olsa } 93cc15a20dSJiri Olsa 94cc15a20dSJiri Olsa int test_resolve_btfids(void) 95cc15a20dSJiri Olsa { 96cc15a20dSJiri Olsa unsigned int i; 97cc15a20dSJiri Olsa int ret = 0; 98cc15a20dSJiri Olsa 99cc15a20dSJiri Olsa if (resolve_symbols()) 100cc15a20dSJiri Olsa return -1; 101cc15a20dSJiri Olsa 102cc15a20dSJiri Olsa /* Check BTF_ID_LIST(test_list) IDs */ 103cc15a20dSJiri Olsa for (i = 0; i < ARRAY_SIZE(test_symbols) && !ret; i++) { 104cc15a20dSJiri Olsa ret = CHECK(test_list[i] != test_symbols[i].id, 105cc15a20dSJiri Olsa "id_check", 106cc15a20dSJiri Olsa "wrong ID for %s (%d != %d)\n", test_symbols[i].name, 107cc15a20dSJiri Olsa test_list[i], test_symbols[i].id); 108cc15a20dSJiri Olsa } 109cc15a20dSJiri Olsa 110cc15a20dSJiri Olsa return ret; 111cc15a20dSJiri Olsa } 112