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