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> 9d8dfe5bfSYonghong Song #define CONFIG_DEBUG_INFO_BTF 10cc15a20dSJiri Olsa #include <linux/btf_ids.h> 11cc15a20dSJiri Olsa #include "test_progs.h" 12cc15a20dSJiri Olsa 13cc15a20dSJiri Olsa static int duration; 14cc15a20dSJiri Olsa 15cc15a20dSJiri Olsa struct symbol { 16cc15a20dSJiri Olsa const char *name; 17cc15a20dSJiri Olsa int type; 18cc15a20dSJiri Olsa int id; 19cc15a20dSJiri Olsa }; 20cc15a20dSJiri Olsa 21cc15a20dSJiri Olsa struct symbol test_symbols[] = { 22cc15a20dSJiri Olsa { "unused", BTF_KIND_UNKN, 0 }, 23cc15a20dSJiri Olsa { "S", BTF_KIND_TYPEDEF, -1 }, 24cc15a20dSJiri Olsa { "T", BTF_KIND_TYPEDEF, -1 }, 25cc15a20dSJiri Olsa { "U", BTF_KIND_TYPEDEF, -1 }, 26cc15a20dSJiri Olsa { "S", BTF_KIND_STRUCT, -1 }, 27cc15a20dSJiri Olsa { "U", BTF_KIND_UNION, -1 }, 28cc15a20dSJiri Olsa { "func", BTF_KIND_FUNC, -1 }, 29cc15a20dSJiri Olsa }; 30cc15a20dSJiri Olsa 313effc06aSJean-Philippe Brucker /* Align the .BTF_ids section to 4 bytes */ 323effc06aSJean-Philippe Brucker asm ( 333effc06aSJean-Philippe Brucker ".pushsection " BTF_IDS_SECTION " ,\"a\"; \n" 343effc06aSJean-Philippe Brucker ".balign 4, 0; \n" 353effc06aSJean-Philippe Brucker ".popsection; \n"); 363effc06aSJean-Philippe Brucker 370f12e584SYonghong Song BTF_ID_LIST(test_list_local) 380f12e584SYonghong Song BTF_ID_UNUSED 390f12e584SYonghong Song BTF_ID(typedef, S) 400f12e584SYonghong Song BTF_ID(typedef, T) 410f12e584SYonghong Song BTF_ID(typedef, U) 420f12e584SYonghong Song BTF_ID(struct, S) 430f12e584SYonghong Song BTF_ID(union, U) 440f12e584SYonghong Song BTF_ID(func, func) 450f12e584SYonghong Song 460f12e584SYonghong Song extern __u32 test_list_global[]; 470f12e584SYonghong Song BTF_ID_LIST_GLOBAL(test_list_global) 48cc15a20dSJiri Olsa BTF_ID_UNUSED 49cc15a20dSJiri Olsa BTF_ID(typedef, S) 50cc15a20dSJiri Olsa BTF_ID(typedef, T) 51cc15a20dSJiri Olsa BTF_ID(typedef, U) 52cc15a20dSJiri Olsa BTF_ID(struct, S) 53cc15a20dSJiri Olsa BTF_ID(union, U) 54cc15a20dSJiri Olsa BTF_ID(func, func) 55cc15a20dSJiri Olsa 56cd04b04dSJiri Olsa BTF_SET_START(test_set) 57cd04b04dSJiri Olsa BTF_ID(typedef, S) 58cd04b04dSJiri Olsa BTF_ID(typedef, T) 59cd04b04dSJiri Olsa BTF_ID(typedef, U) 60cd04b04dSJiri Olsa BTF_ID(struct, S) 61cd04b04dSJiri Olsa BTF_ID(union, U) 62cd04b04dSJiri Olsa BTF_ID(func, func) 63cd04b04dSJiri Olsa BTF_SET_END(test_set) 64cd04b04dSJiri Olsa 65cc15a20dSJiri Olsa static int 66cc15a20dSJiri Olsa __resolve_symbol(struct btf *btf, int type_id) 67cc15a20dSJiri Olsa { 68cc15a20dSJiri Olsa const struct btf_type *type; 69cc15a20dSJiri Olsa const char *str; 70cc15a20dSJiri Olsa unsigned int i; 71cc15a20dSJiri Olsa 72cc15a20dSJiri Olsa type = btf__type_by_id(btf, type_id); 73cc15a20dSJiri Olsa if (!type) { 74cc15a20dSJiri Olsa PRINT_FAIL("Failed to get type for ID %d\n", type_id); 75cc15a20dSJiri Olsa return -1; 76cc15a20dSJiri Olsa } 77cc15a20dSJiri Olsa 78cc15a20dSJiri Olsa for (i = 0; i < ARRAY_SIZE(test_symbols); i++) { 79bad2e478SAndrii Nakryiko if (test_symbols[i].id >= 0) 80cc15a20dSJiri Olsa continue; 81cc15a20dSJiri Olsa 82cc15a20dSJiri Olsa if (BTF_INFO_KIND(type->info) != test_symbols[i].type) 83cc15a20dSJiri Olsa continue; 84cc15a20dSJiri Olsa 85cc15a20dSJiri Olsa str = btf__name_by_offset(btf, type->name_off); 86cc15a20dSJiri Olsa if (!str) { 87cc15a20dSJiri Olsa PRINT_FAIL("Failed to get name for BTF ID %d\n", type_id); 88cc15a20dSJiri Olsa return -1; 89cc15a20dSJiri Olsa } 90cc15a20dSJiri Olsa 91cc15a20dSJiri Olsa if (!strcmp(str, test_symbols[i].name)) 92cc15a20dSJiri Olsa test_symbols[i].id = type_id; 93cc15a20dSJiri Olsa } 94cc15a20dSJiri Olsa 95cc15a20dSJiri Olsa return 0; 96cc15a20dSJiri Olsa } 97cc15a20dSJiri Olsa 98cc15a20dSJiri Olsa static int resolve_symbols(void) 99cc15a20dSJiri Olsa { 100cc15a20dSJiri Olsa struct btf *btf; 101cc15a20dSJiri Olsa int type_id; 102cc15a20dSJiri Olsa __u32 nr; 103cc15a20dSJiri Olsa 104cc15a20dSJiri Olsa btf = btf__parse_elf("btf_data.o", NULL); 105cc15a20dSJiri Olsa if (CHECK(libbpf_get_error(btf), "resolve", 106cc15a20dSJiri Olsa "Failed to load BTF from btf_data.o\n")) 107cc15a20dSJiri Olsa return -1; 108cc15a20dSJiri Olsa 109487ef148SHengqi Chen nr = btf__type_cnt(btf); 110cc15a20dSJiri Olsa 111487ef148SHengqi Chen for (type_id = 1; type_id < nr; type_id++) { 112cc15a20dSJiri Olsa if (__resolve_symbol(btf, type_id)) 113cc15a20dSJiri Olsa break; 114cc15a20dSJiri Olsa } 115cc15a20dSJiri Olsa 116cc15a20dSJiri Olsa btf__free(btf); 117cc15a20dSJiri Olsa return 0; 118cc15a20dSJiri Olsa } 119cc15a20dSJiri Olsa 120*6972dc3bSAndrii Nakryiko void test_resolve_btfids(void) 121cc15a20dSJiri Olsa { 1220f12e584SYonghong Song __u32 *test_list, *test_lists[] = { test_list_local, test_list_global }; 1230f12e584SYonghong Song unsigned int i, j; 124cc15a20dSJiri Olsa int ret = 0; 125cc15a20dSJiri Olsa 126cc15a20dSJiri Olsa if (resolve_symbols()) 127*6972dc3bSAndrii Nakryiko return; 128cc15a20dSJiri Olsa 1290f12e584SYonghong Song /* Check BTF_ID_LIST(test_list_local) and 1300f12e584SYonghong Song * BTF_ID_LIST_GLOBAL(test_list_global) IDs 1310f12e584SYonghong Song */ 1320f12e584SYonghong Song for (j = 0; j < ARRAY_SIZE(test_lists); j++) { 1330f12e584SYonghong Song test_list = test_lists[j]; 134cd04b04dSJiri Olsa for (i = 0; i < ARRAY_SIZE(test_symbols); i++) { 135cc15a20dSJiri Olsa ret = CHECK(test_list[i] != test_symbols[i].id, 136cc15a20dSJiri Olsa "id_check", 1370f12e584SYonghong Song "wrong ID for %s (%d != %d)\n", 1380f12e584SYonghong Song test_symbols[i].name, 139cc15a20dSJiri Olsa test_list[i], test_symbols[i].id); 140cd04b04dSJiri Olsa if (ret) 141*6972dc3bSAndrii Nakryiko return; 142cd04b04dSJiri Olsa } 143cd04b04dSJiri Olsa } 144cd04b04dSJiri Olsa 145cd04b04dSJiri Olsa /* Check BTF_SET_START(test_set) IDs */ 146cd04b04dSJiri Olsa for (i = 0; i < test_set.cnt; i++) { 147cd04b04dSJiri Olsa bool found = false; 148cd04b04dSJiri Olsa 149cd04b04dSJiri Olsa for (j = 0; j < ARRAY_SIZE(test_symbols); j++) { 150cd04b04dSJiri Olsa if (test_symbols[j].id != test_set.ids[i]) 151cd04b04dSJiri Olsa continue; 152cd04b04dSJiri Olsa found = true; 153cd04b04dSJiri Olsa break; 154cd04b04dSJiri Olsa } 155cd04b04dSJiri Olsa 156cd04b04dSJiri Olsa ret = CHECK(!found, "id_check", 157cd04b04dSJiri Olsa "ID %d not found in test_symbols\n", 158cd04b04dSJiri Olsa test_set.ids[i]); 159cd04b04dSJiri Olsa if (ret) 160cd04b04dSJiri Olsa break; 161cd04b04dSJiri Olsa 162cd04b04dSJiri Olsa if (i > 0) { 1637a2fa70aSAndrii Nakryiko if (!ASSERT_LE(test_set.ids[i - 1], test_set.ids[i], "sort_check")) 164*6972dc3bSAndrii Nakryiko return; 165cc15a20dSJiri Olsa } 1660f12e584SYonghong Song } 167cc15a20dSJiri Olsa } 168