Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
at v5.6-rc2 7025 lines 192 kB view raw
1/* SPDX-License-Identifier: GPL-2.0 */ 2/* Copyright (c) 2018 Facebook */ 3 4#include <linux/bpf.h> 5#include <linux/btf.h> 6#include <linux/err.h> 7#include <linux/kernel.h> 8#include <linux/filter.h> 9#include <linux/unistd.h> 10#include <bpf/bpf.h> 11#include <sys/resource.h> 12#include <libelf.h> 13#include <gelf.h> 14#include <string.h> 15#include <stdlib.h> 16#include <stdio.h> 17#include <stdarg.h> 18#include <unistd.h> 19#include <fcntl.h> 20#include <errno.h> 21#include <assert.h> 22#include <bpf/libbpf.h> 23#include <bpf/btf.h> 24 25#include "bpf_rlimit.h" 26#include "bpf_util.h" 27#include "test_btf.h" 28 29#define MAX_INSNS 512 30#define MAX_SUBPROGS 16 31 32static uint32_t pass_cnt; 33static uint32_t error_cnt; 34static uint32_t skip_cnt; 35 36#define CHECK(condition, format...) ({ \ 37 int __ret = !!(condition); \ 38 if (__ret) { \ 39 fprintf(stderr, "%s:%d:FAIL ", __func__, __LINE__); \ 40 fprintf(stderr, format); \ 41 } \ 42 __ret; \ 43}) 44 45static int count_result(int err) 46{ 47 if (err) 48 error_cnt++; 49 else 50 pass_cnt++; 51 52 fprintf(stderr, "\n"); 53 return err; 54} 55 56static int __base_pr(enum libbpf_print_level level __attribute__((unused)), 57 const char *format, va_list args) 58{ 59 return vfprintf(stderr, format, args); 60} 61 62#define BTF_END_RAW 0xdeadbeef 63#define NAME_TBD 0xdeadb33f 64 65#define NAME_NTH(N) (0xffff0000 | N) 66#define IS_NAME_NTH(X) ((X & 0xffff0000) == 0xffff0000) 67#define GET_NAME_NTH_IDX(X) (X & 0x0000ffff) 68 69#define MAX_NR_RAW_U32 1024 70#define BTF_LOG_BUF_SIZE 65535 71 72static struct args { 73 unsigned int raw_test_num; 74 unsigned int file_test_num; 75 unsigned int get_info_test_num; 76 unsigned int info_raw_test_num; 77 unsigned int dedup_test_num; 78 bool raw_test; 79 bool file_test; 80 bool get_info_test; 81 bool pprint_test; 82 bool always_log; 83 bool info_raw_test; 84 bool dedup_test; 85} args; 86 87static char btf_log_buf[BTF_LOG_BUF_SIZE]; 88 89static struct btf_header hdr_tmpl = { 90 .magic = BTF_MAGIC, 91 .version = BTF_VERSION, 92 .hdr_len = sizeof(struct btf_header), 93}; 94 95/* several different mapv kinds(types) supported by pprint */ 96enum pprint_mapv_kind_t { 97 PPRINT_MAPV_KIND_BASIC = 0, 98 PPRINT_MAPV_KIND_INT128, 99}; 100 101struct btf_raw_test { 102 const char *descr; 103 const char *str_sec; 104 const char *map_name; 105 const char *err_str; 106 __u32 raw_types[MAX_NR_RAW_U32]; 107 __u32 str_sec_size; 108 enum bpf_map_type map_type; 109 __u32 key_size; 110 __u32 value_size; 111 __u32 key_type_id; 112 __u32 value_type_id; 113 __u32 max_entries; 114 bool btf_load_err; 115 bool map_create_err; 116 bool ordered_map; 117 bool lossless_map; 118 bool percpu_map; 119 int hdr_len_delta; 120 int type_off_delta; 121 int str_off_delta; 122 int str_len_delta; 123 enum pprint_mapv_kind_t mapv_kind; 124}; 125 126#define BTF_STR_SEC(str) \ 127 .str_sec = str, .str_sec_size = sizeof(str) 128 129static struct btf_raw_test raw_tests[] = { 130/* enum E { 131 * E0, 132 * E1, 133 * }; 134 * 135 * struct A { 136 * unsigned long long m; 137 * int n; 138 * char o; 139 * [3 bytes hole] 140 * int p[8]; 141 * int q[4][8]; 142 * enum E r; 143 * }; 144 */ 145{ 146 .descr = "struct test #1", 147 .raw_types = { 148 /* int */ 149 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 150 /* unsigned long long */ 151 BTF_TYPE_INT_ENC(0, 0, 0, 64, 8), /* [2] */ 152 /* char */ 153 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1), /* [3] */ 154 /* int[8] */ 155 BTF_TYPE_ARRAY_ENC(1, 1, 8), /* [4] */ 156 /* struct A { */ /* [5] */ 157 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 6), 180), 158 BTF_MEMBER_ENC(NAME_TBD, 2, 0), /* unsigned long long m;*/ 159 BTF_MEMBER_ENC(NAME_TBD, 1, 64),/* int n; */ 160 BTF_MEMBER_ENC(NAME_TBD, 3, 96),/* char o; */ 161 BTF_MEMBER_ENC(NAME_TBD, 4, 128),/* int p[8] */ 162 BTF_MEMBER_ENC(NAME_TBD, 6, 384),/* int q[4][8] */ 163 BTF_MEMBER_ENC(NAME_TBD, 7, 1408), /* enum E r */ 164 /* } */ 165 /* int[4][8] */ 166 BTF_TYPE_ARRAY_ENC(4, 1, 4), /* [6] */ 167 /* enum E */ /* [7] */ 168 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 2), sizeof(int)), 169 BTF_ENUM_ENC(NAME_TBD, 0), 170 BTF_ENUM_ENC(NAME_TBD, 1), 171 BTF_END_RAW, 172 }, 173 .str_sec = "\0A\0m\0n\0o\0p\0q\0r\0E\0E0\0E1", 174 .str_sec_size = sizeof("\0A\0m\0n\0o\0p\0q\0r\0E\0E0\0E1"), 175 .map_type = BPF_MAP_TYPE_ARRAY, 176 .map_name = "struct_test1_map", 177 .key_size = sizeof(int), 178 .value_size = 180, 179 .key_type_id = 1, 180 .value_type_id = 5, 181 .max_entries = 4, 182}, 183 184/* typedef struct b Struct_B; 185 * 186 * struct A { 187 * int m; 188 * struct b n[4]; 189 * const Struct_B o[4]; 190 * }; 191 * 192 * struct B { 193 * int m; 194 * int n; 195 * }; 196 */ 197{ 198 .descr = "struct test #2", 199 .raw_types = { 200 /* int */ /* [1] */ 201 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), 202 /* struct b [4] */ /* [2] */ 203 BTF_TYPE_ARRAY_ENC(4, 1, 4), 204 205 /* struct A { */ /* [3] */ 206 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 3), 68), 207 BTF_MEMBER_ENC(NAME_TBD, 1, 0), /* int m; */ 208 BTF_MEMBER_ENC(NAME_TBD, 2, 32),/* struct B n[4] */ 209 BTF_MEMBER_ENC(NAME_TBD, 8, 288),/* const Struct_B o[4];*/ 210 /* } */ 211 212 /* struct B { */ /* [4] */ 213 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), 8), 214 BTF_MEMBER_ENC(NAME_TBD, 1, 0), /* int m; */ 215 BTF_MEMBER_ENC(NAME_TBD, 1, 32),/* int n; */ 216 /* } */ 217 218 /* const int */ /* [5] */ 219 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 1), 220 /* typedef struct b Struct_B */ /* [6] */ 221 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_TYPEDEF, 0, 0), 4), 222 /* const Struct_B */ /* [7] */ 223 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 6), 224 /* const Struct_B [4] */ /* [8] */ 225 BTF_TYPE_ARRAY_ENC(7, 1, 4), 226 BTF_END_RAW, 227 }, 228 .str_sec = "\0A\0m\0n\0o\0B\0m\0n\0Struct_B", 229 .str_sec_size = sizeof("\0A\0m\0n\0o\0B\0m\0n\0Struct_B"), 230 .map_type = BPF_MAP_TYPE_ARRAY, 231 .map_name = "struct_test2_map", 232 .key_size = sizeof(int), 233 .value_size = 68, 234 .key_type_id = 1, 235 .value_type_id = 3, 236 .max_entries = 4, 237}, 238{ 239 .descr = "struct test #3 Invalid member offset", 240 .raw_types = { 241 /* int */ /* [1] */ 242 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), 243 /* int64 */ /* [2] */ 244 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 64, 8), 245 246 /* struct A { */ /* [3] */ 247 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), 16), 248 BTF_MEMBER_ENC(NAME_TBD, 1, 64), /* int m; */ 249 BTF_MEMBER_ENC(NAME_TBD, 2, 0), /* int64 n; */ 250 /* } */ 251 BTF_END_RAW, 252 }, 253 .str_sec = "\0A\0m\0n\0", 254 .str_sec_size = sizeof("\0A\0m\0n\0"), 255 .map_type = BPF_MAP_TYPE_ARRAY, 256 .map_name = "struct_test3_map", 257 .key_size = sizeof(int), 258 .value_size = 16, 259 .key_type_id = 1, 260 .value_type_id = 3, 261 .max_entries = 4, 262 .btf_load_err = true, 263 .err_str = "Invalid member bits_offset", 264}, 265/* 266 * struct A { 267 * unsigned long long m; 268 * int n; 269 * char o; 270 * [3 bytes hole] 271 * int p[8]; 272 * }; 273 */ 274{ 275 .descr = "global data test #1", 276 .raw_types = { 277 /* int */ 278 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 279 /* unsigned long long */ 280 BTF_TYPE_INT_ENC(0, 0, 0, 64, 8), /* [2] */ 281 /* char */ 282 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1), /* [3] */ 283 /* int[8] */ 284 BTF_TYPE_ARRAY_ENC(1, 1, 8), /* [4] */ 285 /* struct A { */ /* [5] */ 286 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 4), 48), 287 BTF_MEMBER_ENC(NAME_TBD, 2, 0), /* unsigned long long m;*/ 288 BTF_MEMBER_ENC(NAME_TBD, 1, 64),/* int n; */ 289 BTF_MEMBER_ENC(NAME_TBD, 3, 96),/* char o; */ 290 BTF_MEMBER_ENC(NAME_TBD, 4, 128),/* int p[8] */ 291 /* } */ 292 BTF_END_RAW, 293 }, 294 .str_sec = "\0A\0m\0n\0o\0p", 295 .str_sec_size = sizeof("\0A\0m\0n\0o\0p"), 296 .map_type = BPF_MAP_TYPE_ARRAY, 297 .map_name = "struct_test1_map", 298 .key_size = sizeof(int), 299 .value_size = 48, 300 .key_type_id = 1, 301 .value_type_id = 5, 302 .max_entries = 4, 303}, 304/* 305 * struct A { 306 * unsigned long long m; 307 * int n; 308 * char o; 309 * [3 bytes hole] 310 * int p[8]; 311 * }; 312 * static struct A t; <- in .bss 313 */ 314{ 315 .descr = "global data test #2", 316 .raw_types = { 317 /* int */ 318 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 319 /* unsigned long long */ 320 BTF_TYPE_INT_ENC(0, 0, 0, 64, 8), /* [2] */ 321 /* char */ 322 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1), /* [3] */ 323 /* int[8] */ 324 BTF_TYPE_ARRAY_ENC(1, 1, 8), /* [4] */ 325 /* struct A { */ /* [5] */ 326 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 4), 48), 327 BTF_MEMBER_ENC(NAME_TBD, 2, 0), /* unsigned long long m;*/ 328 BTF_MEMBER_ENC(NAME_TBD, 1, 64),/* int n; */ 329 BTF_MEMBER_ENC(NAME_TBD, 3, 96),/* char o; */ 330 BTF_MEMBER_ENC(NAME_TBD, 4, 128),/* int p[8] */ 331 /* } */ 332 /* static struct A t */ 333 BTF_VAR_ENC(NAME_TBD, 5, 0), /* [6] */ 334 /* .bss section */ /* [7] */ 335 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 48), 336 BTF_VAR_SECINFO_ENC(6, 0, 48), 337 BTF_END_RAW, 338 }, 339 .str_sec = "\0A\0m\0n\0o\0p\0t\0.bss", 340 .str_sec_size = sizeof("\0A\0m\0n\0o\0p\0t\0.bss"), 341 .map_type = BPF_MAP_TYPE_ARRAY, 342 .map_name = ".bss", 343 .key_size = sizeof(int), 344 .value_size = 48, 345 .key_type_id = 0, 346 .value_type_id = 7, 347 .max_entries = 1, 348}, 349{ 350 .descr = "global data test #3", 351 .raw_types = { 352 /* int */ 353 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 354 /* static int t */ 355 BTF_VAR_ENC(NAME_TBD, 1, 0), /* [2] */ 356 /* .bss section */ /* [3] */ 357 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4), 358 BTF_VAR_SECINFO_ENC(2, 0, 4), 359 BTF_END_RAW, 360 }, 361 .str_sec = "\0t\0.bss", 362 .str_sec_size = sizeof("\0t\0.bss"), 363 .map_type = BPF_MAP_TYPE_ARRAY, 364 .map_name = ".bss", 365 .key_size = sizeof(int), 366 .value_size = 4, 367 .key_type_id = 0, 368 .value_type_id = 3, 369 .max_entries = 1, 370}, 371{ 372 .descr = "global data test #4, unsupported linkage", 373 .raw_types = { 374 /* int */ 375 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 376 /* static int t */ 377 BTF_VAR_ENC(NAME_TBD, 1, 2), /* [2] */ 378 /* .bss section */ /* [3] */ 379 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4), 380 BTF_VAR_SECINFO_ENC(2, 0, 4), 381 BTF_END_RAW, 382 }, 383 .str_sec = "\0t\0.bss", 384 .str_sec_size = sizeof("\0t\0.bss"), 385 .map_type = BPF_MAP_TYPE_ARRAY, 386 .map_name = ".bss", 387 .key_size = sizeof(int), 388 .value_size = 4, 389 .key_type_id = 0, 390 .value_type_id = 3, 391 .max_entries = 1, 392 .btf_load_err = true, 393 .err_str = "Linkage not supported", 394}, 395{ 396 .descr = "global data test #5, invalid var type", 397 .raw_types = { 398 /* static void t */ 399 BTF_VAR_ENC(NAME_TBD, 0, 0), /* [1] */ 400 /* .bss section */ /* [2] */ 401 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4), 402 BTF_VAR_SECINFO_ENC(1, 0, 4), 403 BTF_END_RAW, 404 }, 405 .str_sec = "\0t\0.bss", 406 .str_sec_size = sizeof("\0t\0.bss"), 407 .map_type = BPF_MAP_TYPE_ARRAY, 408 .map_name = ".bss", 409 .key_size = sizeof(int), 410 .value_size = 4, 411 .key_type_id = 0, 412 .value_type_id = 2, 413 .max_entries = 1, 414 .btf_load_err = true, 415 .err_str = "Invalid type_id", 416}, 417{ 418 .descr = "global data test #6, invalid var type (fwd type)", 419 .raw_types = { 420 /* union A */ 421 BTF_TYPE_ENC(NAME_TBD, 422 BTF_INFO_ENC(BTF_KIND_FWD, 1, 0), 0), /* [1] */ 423 /* static union A t */ 424 BTF_VAR_ENC(NAME_TBD, 1, 0), /* [2] */ 425 /* .bss section */ /* [3] */ 426 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4), 427 BTF_VAR_SECINFO_ENC(2, 0, 4), 428 BTF_END_RAW, 429 }, 430 .str_sec = "\0A\0t\0.bss", 431 .str_sec_size = sizeof("\0A\0t\0.bss"), 432 .map_type = BPF_MAP_TYPE_ARRAY, 433 .map_name = ".bss", 434 .key_size = sizeof(int), 435 .value_size = 4, 436 .key_type_id = 0, 437 .value_type_id = 2, 438 .max_entries = 1, 439 .btf_load_err = true, 440 .err_str = "Invalid type", 441}, 442{ 443 .descr = "global data test #7, invalid var type (fwd type)", 444 .raw_types = { 445 /* union A */ 446 BTF_TYPE_ENC(NAME_TBD, 447 BTF_INFO_ENC(BTF_KIND_FWD, 1, 0), 0), /* [1] */ 448 /* static union A t */ 449 BTF_VAR_ENC(NAME_TBD, 1, 0), /* [2] */ 450 /* .bss section */ /* [3] */ 451 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4), 452 BTF_VAR_SECINFO_ENC(1, 0, 4), 453 BTF_END_RAW, 454 }, 455 .str_sec = "\0A\0t\0.bss", 456 .str_sec_size = sizeof("\0A\0t\0.bss"), 457 .map_type = BPF_MAP_TYPE_ARRAY, 458 .map_name = ".bss", 459 .key_size = sizeof(int), 460 .value_size = 4, 461 .key_type_id = 0, 462 .value_type_id = 2, 463 .max_entries = 1, 464 .btf_load_err = true, 465 .err_str = "Invalid type", 466}, 467{ 468 .descr = "global data test #8, invalid var size", 469 .raw_types = { 470 /* int */ 471 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 472 /* unsigned long long */ 473 BTF_TYPE_INT_ENC(0, 0, 0, 64, 8), /* [2] */ 474 /* char */ 475 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1), /* [3] */ 476 /* int[8] */ 477 BTF_TYPE_ARRAY_ENC(1, 1, 8), /* [4] */ 478 /* struct A { */ /* [5] */ 479 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 4), 48), 480 BTF_MEMBER_ENC(NAME_TBD, 2, 0), /* unsigned long long m;*/ 481 BTF_MEMBER_ENC(NAME_TBD, 1, 64),/* int n; */ 482 BTF_MEMBER_ENC(NAME_TBD, 3, 96),/* char o; */ 483 BTF_MEMBER_ENC(NAME_TBD, 4, 128),/* int p[8] */ 484 /* } */ 485 /* static struct A t */ 486 BTF_VAR_ENC(NAME_TBD, 5, 0), /* [6] */ 487 /* .bss section */ /* [7] */ 488 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 48), 489 BTF_VAR_SECINFO_ENC(6, 0, 47), 490 BTF_END_RAW, 491 }, 492 .str_sec = "\0A\0m\0n\0o\0p\0t\0.bss", 493 .str_sec_size = sizeof("\0A\0m\0n\0o\0p\0t\0.bss"), 494 .map_type = BPF_MAP_TYPE_ARRAY, 495 .map_name = ".bss", 496 .key_size = sizeof(int), 497 .value_size = 48, 498 .key_type_id = 0, 499 .value_type_id = 7, 500 .max_entries = 1, 501 .btf_load_err = true, 502 .err_str = "Invalid size", 503}, 504{ 505 .descr = "global data test #9, invalid var size", 506 .raw_types = { 507 /* int */ 508 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 509 /* unsigned long long */ 510 BTF_TYPE_INT_ENC(0, 0, 0, 64, 8), /* [2] */ 511 /* char */ 512 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1), /* [3] */ 513 /* int[8] */ 514 BTF_TYPE_ARRAY_ENC(1, 1, 8), /* [4] */ 515 /* struct A { */ /* [5] */ 516 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 4), 48), 517 BTF_MEMBER_ENC(NAME_TBD, 2, 0), /* unsigned long long m;*/ 518 BTF_MEMBER_ENC(NAME_TBD, 1, 64),/* int n; */ 519 BTF_MEMBER_ENC(NAME_TBD, 3, 96),/* char o; */ 520 BTF_MEMBER_ENC(NAME_TBD, 4, 128),/* int p[8] */ 521 /* } */ 522 /* static struct A t */ 523 BTF_VAR_ENC(NAME_TBD, 5, 0), /* [6] */ 524 /* .bss section */ /* [7] */ 525 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 46), 526 BTF_VAR_SECINFO_ENC(6, 0, 48), 527 BTF_END_RAW, 528 }, 529 .str_sec = "\0A\0m\0n\0o\0p\0t\0.bss", 530 .str_sec_size = sizeof("\0A\0m\0n\0o\0p\0t\0.bss"), 531 .map_type = BPF_MAP_TYPE_ARRAY, 532 .map_name = ".bss", 533 .key_size = sizeof(int), 534 .value_size = 48, 535 .key_type_id = 0, 536 .value_type_id = 7, 537 .max_entries = 1, 538 .btf_load_err = true, 539 .err_str = "Invalid size", 540}, 541{ 542 .descr = "global data test #10, invalid var size", 543 .raw_types = { 544 /* int */ 545 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 546 /* unsigned long long */ 547 BTF_TYPE_INT_ENC(0, 0, 0, 64, 8), /* [2] */ 548 /* char */ 549 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1), /* [3] */ 550 /* int[8] */ 551 BTF_TYPE_ARRAY_ENC(1, 1, 8), /* [4] */ 552 /* struct A { */ /* [5] */ 553 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 4), 48), 554 BTF_MEMBER_ENC(NAME_TBD, 2, 0), /* unsigned long long m;*/ 555 BTF_MEMBER_ENC(NAME_TBD, 1, 64),/* int n; */ 556 BTF_MEMBER_ENC(NAME_TBD, 3, 96),/* char o; */ 557 BTF_MEMBER_ENC(NAME_TBD, 4, 128),/* int p[8] */ 558 /* } */ 559 /* static struct A t */ 560 BTF_VAR_ENC(NAME_TBD, 5, 0), /* [6] */ 561 /* .bss section */ /* [7] */ 562 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 46), 563 BTF_VAR_SECINFO_ENC(6, 0, 46), 564 BTF_END_RAW, 565 }, 566 .str_sec = "\0A\0m\0n\0o\0p\0t\0.bss", 567 .str_sec_size = sizeof("\0A\0m\0n\0o\0p\0t\0.bss"), 568 .map_type = BPF_MAP_TYPE_ARRAY, 569 .map_name = ".bss", 570 .key_size = sizeof(int), 571 .value_size = 48, 572 .key_type_id = 0, 573 .value_type_id = 7, 574 .max_entries = 1, 575 .btf_load_err = true, 576 .err_str = "Invalid size", 577}, 578{ 579 .descr = "global data test #11, multiple section members", 580 .raw_types = { 581 /* int */ 582 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 583 /* unsigned long long */ 584 BTF_TYPE_INT_ENC(0, 0, 0, 64, 8), /* [2] */ 585 /* char */ 586 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1), /* [3] */ 587 /* int[8] */ 588 BTF_TYPE_ARRAY_ENC(1, 1, 8), /* [4] */ 589 /* struct A { */ /* [5] */ 590 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 4), 48), 591 BTF_MEMBER_ENC(NAME_TBD, 2, 0), /* unsigned long long m;*/ 592 BTF_MEMBER_ENC(NAME_TBD, 1, 64),/* int n; */ 593 BTF_MEMBER_ENC(NAME_TBD, 3, 96),/* char o; */ 594 BTF_MEMBER_ENC(NAME_TBD, 4, 128),/* int p[8] */ 595 /* } */ 596 /* static struct A t */ 597 BTF_VAR_ENC(NAME_TBD, 5, 0), /* [6] */ 598 /* static int u */ 599 BTF_VAR_ENC(NAME_TBD, 1, 0), /* [7] */ 600 /* .bss section */ /* [8] */ 601 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 2), 62), 602 BTF_VAR_SECINFO_ENC(6, 10, 48), 603 BTF_VAR_SECINFO_ENC(7, 58, 4), 604 BTF_END_RAW, 605 }, 606 .str_sec = "\0A\0m\0n\0o\0p\0t\0u\0.bss", 607 .str_sec_size = sizeof("\0A\0m\0n\0o\0p\0t\0u\0.bss"), 608 .map_type = BPF_MAP_TYPE_ARRAY, 609 .map_name = ".bss", 610 .key_size = sizeof(int), 611 .value_size = 62, 612 .key_type_id = 0, 613 .value_type_id = 8, 614 .max_entries = 1, 615}, 616{ 617 .descr = "global data test #12, invalid offset", 618 .raw_types = { 619 /* int */ 620 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 621 /* unsigned long long */ 622 BTF_TYPE_INT_ENC(0, 0, 0, 64, 8), /* [2] */ 623 /* char */ 624 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1), /* [3] */ 625 /* int[8] */ 626 BTF_TYPE_ARRAY_ENC(1, 1, 8), /* [4] */ 627 /* struct A { */ /* [5] */ 628 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 4), 48), 629 BTF_MEMBER_ENC(NAME_TBD, 2, 0), /* unsigned long long m;*/ 630 BTF_MEMBER_ENC(NAME_TBD, 1, 64),/* int n; */ 631 BTF_MEMBER_ENC(NAME_TBD, 3, 96),/* char o; */ 632 BTF_MEMBER_ENC(NAME_TBD, 4, 128),/* int p[8] */ 633 /* } */ 634 /* static struct A t */ 635 BTF_VAR_ENC(NAME_TBD, 5, 0), /* [6] */ 636 /* static int u */ 637 BTF_VAR_ENC(NAME_TBD, 1, 0), /* [7] */ 638 /* .bss section */ /* [8] */ 639 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 2), 62), 640 BTF_VAR_SECINFO_ENC(6, 10, 48), 641 BTF_VAR_SECINFO_ENC(7, 60, 4), 642 BTF_END_RAW, 643 }, 644 .str_sec = "\0A\0m\0n\0o\0p\0t\0u\0.bss", 645 .str_sec_size = sizeof("\0A\0m\0n\0o\0p\0t\0u\0.bss"), 646 .map_type = BPF_MAP_TYPE_ARRAY, 647 .map_name = ".bss", 648 .key_size = sizeof(int), 649 .value_size = 62, 650 .key_type_id = 0, 651 .value_type_id = 8, 652 .max_entries = 1, 653 .btf_load_err = true, 654 .err_str = "Invalid offset+size", 655}, 656{ 657 .descr = "global data test #13, invalid offset", 658 .raw_types = { 659 /* int */ 660 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 661 /* unsigned long long */ 662 BTF_TYPE_INT_ENC(0, 0, 0, 64, 8), /* [2] */ 663 /* char */ 664 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1), /* [3] */ 665 /* int[8] */ 666 BTF_TYPE_ARRAY_ENC(1, 1, 8), /* [4] */ 667 /* struct A { */ /* [5] */ 668 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 4), 48), 669 BTF_MEMBER_ENC(NAME_TBD, 2, 0), /* unsigned long long m;*/ 670 BTF_MEMBER_ENC(NAME_TBD, 1, 64),/* int n; */ 671 BTF_MEMBER_ENC(NAME_TBD, 3, 96),/* char o; */ 672 BTF_MEMBER_ENC(NAME_TBD, 4, 128),/* int p[8] */ 673 /* } */ 674 /* static struct A t */ 675 BTF_VAR_ENC(NAME_TBD, 5, 0), /* [6] */ 676 /* static int u */ 677 BTF_VAR_ENC(NAME_TBD, 1, 0), /* [7] */ 678 /* .bss section */ /* [8] */ 679 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 2), 62), 680 BTF_VAR_SECINFO_ENC(6, 10, 48), 681 BTF_VAR_SECINFO_ENC(7, 12, 4), 682 BTF_END_RAW, 683 }, 684 .str_sec = "\0A\0m\0n\0o\0p\0t\0u\0.bss", 685 .str_sec_size = sizeof("\0A\0m\0n\0o\0p\0t\0u\0.bss"), 686 .map_type = BPF_MAP_TYPE_ARRAY, 687 .map_name = ".bss", 688 .key_size = sizeof(int), 689 .value_size = 62, 690 .key_type_id = 0, 691 .value_type_id = 8, 692 .max_entries = 1, 693 .btf_load_err = true, 694 .err_str = "Invalid offset", 695}, 696{ 697 .descr = "global data test #14, invalid offset", 698 .raw_types = { 699 /* int */ 700 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 701 /* unsigned long long */ 702 BTF_TYPE_INT_ENC(0, 0, 0, 64, 8), /* [2] */ 703 /* char */ 704 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1), /* [3] */ 705 /* int[8] */ 706 BTF_TYPE_ARRAY_ENC(1, 1, 8), /* [4] */ 707 /* struct A { */ /* [5] */ 708 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 4), 48), 709 BTF_MEMBER_ENC(NAME_TBD, 2, 0), /* unsigned long long m;*/ 710 BTF_MEMBER_ENC(NAME_TBD, 1, 64),/* int n; */ 711 BTF_MEMBER_ENC(NAME_TBD, 3, 96),/* char o; */ 712 BTF_MEMBER_ENC(NAME_TBD, 4, 128),/* int p[8] */ 713 /* } */ 714 /* static struct A t */ 715 BTF_VAR_ENC(NAME_TBD, 5, 0), /* [6] */ 716 /* static int u */ 717 BTF_VAR_ENC(NAME_TBD, 1, 0), /* [7] */ 718 /* .bss section */ /* [8] */ 719 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 2), 62), 720 BTF_VAR_SECINFO_ENC(7, 58, 4), 721 BTF_VAR_SECINFO_ENC(6, 10, 48), 722 BTF_END_RAW, 723 }, 724 .str_sec = "\0A\0m\0n\0o\0p\0t\0u\0.bss", 725 .str_sec_size = sizeof("\0A\0m\0n\0o\0p\0t\0u\0.bss"), 726 .map_type = BPF_MAP_TYPE_ARRAY, 727 .map_name = ".bss", 728 .key_size = sizeof(int), 729 .value_size = 62, 730 .key_type_id = 0, 731 .value_type_id = 8, 732 .max_entries = 1, 733 .btf_load_err = true, 734 .err_str = "Invalid offset", 735}, 736{ 737 .descr = "global data test #15, not var kind", 738 .raw_types = { 739 /* int */ 740 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 741 BTF_VAR_ENC(NAME_TBD, 1, 0), /* [2] */ 742 /* .bss section */ /* [3] */ 743 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4), 744 BTF_VAR_SECINFO_ENC(1, 0, 4), 745 BTF_END_RAW, 746 }, 747 .str_sec = "\0A\0t\0.bss", 748 .str_sec_size = sizeof("\0A\0t\0.bss"), 749 .map_type = BPF_MAP_TYPE_ARRAY, 750 .map_name = ".bss", 751 .key_size = sizeof(int), 752 .value_size = 4, 753 .key_type_id = 0, 754 .value_type_id = 3, 755 .max_entries = 1, 756 .btf_load_err = true, 757 .err_str = "Not a VAR kind member", 758}, 759{ 760 .descr = "global data test #16, invalid var referencing sec", 761 .raw_types = { 762 /* int */ 763 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 764 BTF_VAR_ENC(NAME_TBD, 5, 0), /* [2] */ 765 BTF_VAR_ENC(NAME_TBD, 2, 0), /* [3] */ 766 /* a section */ /* [4] */ 767 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4), 768 BTF_VAR_SECINFO_ENC(3, 0, 4), 769 /* a section */ /* [5] */ 770 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4), 771 BTF_VAR_SECINFO_ENC(6, 0, 4), 772 BTF_VAR_ENC(NAME_TBD, 1, 0), /* [6] */ 773 BTF_END_RAW, 774 }, 775 .str_sec = "\0A\0t\0s\0a\0a", 776 .str_sec_size = sizeof("\0A\0t\0s\0a\0a"), 777 .map_type = BPF_MAP_TYPE_ARRAY, 778 .map_name = ".bss", 779 .key_size = sizeof(int), 780 .value_size = 4, 781 .key_type_id = 0, 782 .value_type_id = 4, 783 .max_entries = 1, 784 .btf_load_err = true, 785 .err_str = "Invalid type_id", 786}, 787{ 788 .descr = "global data test #17, invalid var referencing var", 789 .raw_types = { 790 /* int */ 791 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 792 BTF_VAR_ENC(NAME_TBD, 1, 0), /* [2] */ 793 BTF_VAR_ENC(NAME_TBD, 2, 0), /* [3] */ 794 /* a section */ /* [4] */ 795 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4), 796 BTF_VAR_SECINFO_ENC(3, 0, 4), 797 BTF_END_RAW, 798 }, 799 .str_sec = "\0A\0t\0s\0a\0a", 800 .str_sec_size = sizeof("\0A\0t\0s\0a\0a"), 801 .map_type = BPF_MAP_TYPE_ARRAY, 802 .map_name = ".bss", 803 .key_size = sizeof(int), 804 .value_size = 4, 805 .key_type_id = 0, 806 .value_type_id = 4, 807 .max_entries = 1, 808 .btf_load_err = true, 809 .err_str = "Invalid type_id", 810}, 811{ 812 .descr = "global data test #18, invalid var loop", 813 .raw_types = { 814 /* int */ 815 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 816 BTF_VAR_ENC(NAME_TBD, 2, 0), /* [2] */ 817 /* .bss section */ /* [3] */ 818 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4), 819 BTF_VAR_SECINFO_ENC(2, 0, 4), 820 BTF_END_RAW, 821 }, 822 .str_sec = "\0A\0t\0aaa", 823 .str_sec_size = sizeof("\0A\0t\0aaa"), 824 .map_type = BPF_MAP_TYPE_ARRAY, 825 .map_name = ".bss", 826 .key_size = sizeof(int), 827 .value_size = 4, 828 .key_type_id = 0, 829 .value_type_id = 4, 830 .max_entries = 1, 831 .btf_load_err = true, 832 .err_str = "Invalid type_id", 833}, 834{ 835 .descr = "global data test #19, invalid var referencing var", 836 .raw_types = { 837 /* int */ 838 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 839 BTF_VAR_ENC(NAME_TBD, 3, 0), /* [2] */ 840 BTF_VAR_ENC(NAME_TBD, 1, 0), /* [3] */ 841 BTF_END_RAW, 842 }, 843 .str_sec = "\0A\0t\0s\0a\0a", 844 .str_sec_size = sizeof("\0A\0t\0s\0a\0a"), 845 .map_type = BPF_MAP_TYPE_ARRAY, 846 .map_name = ".bss", 847 .key_size = sizeof(int), 848 .value_size = 4, 849 .key_type_id = 0, 850 .value_type_id = 4, 851 .max_entries = 1, 852 .btf_load_err = true, 853 .err_str = "Invalid type_id", 854}, 855{ 856 .descr = "global data test #20, invalid ptr referencing var", 857 .raw_types = { 858 /* int */ 859 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 860 /* PTR type_id=3 */ /* [2] */ 861 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 3), 862 BTF_VAR_ENC(NAME_TBD, 1, 0), /* [3] */ 863 BTF_END_RAW, 864 }, 865 .str_sec = "\0A\0t\0s\0a\0a", 866 .str_sec_size = sizeof("\0A\0t\0s\0a\0a"), 867 .map_type = BPF_MAP_TYPE_ARRAY, 868 .map_name = ".bss", 869 .key_size = sizeof(int), 870 .value_size = 4, 871 .key_type_id = 0, 872 .value_type_id = 4, 873 .max_entries = 1, 874 .btf_load_err = true, 875 .err_str = "Invalid type_id", 876}, 877{ 878 .descr = "global data test #21, var included in struct", 879 .raw_types = { 880 /* int */ 881 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 882 /* struct A { */ /* [2] */ 883 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), sizeof(int) * 2), 884 BTF_MEMBER_ENC(NAME_TBD, 1, 0), /* int m; */ 885 BTF_MEMBER_ENC(NAME_TBD, 3, 32),/* VAR type_id=3; */ 886 /* } */ 887 BTF_VAR_ENC(NAME_TBD, 1, 0), /* [3] */ 888 BTF_END_RAW, 889 }, 890 .str_sec = "\0A\0t\0s\0a\0a", 891 .str_sec_size = sizeof("\0A\0t\0s\0a\0a"), 892 .map_type = BPF_MAP_TYPE_ARRAY, 893 .map_name = ".bss", 894 .key_size = sizeof(int), 895 .value_size = 4, 896 .key_type_id = 0, 897 .value_type_id = 4, 898 .max_entries = 1, 899 .btf_load_err = true, 900 .err_str = "Invalid member", 901}, 902{ 903 .descr = "global data test #22, array of var", 904 .raw_types = { 905 /* int */ 906 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 907 BTF_TYPE_ARRAY_ENC(3, 1, 4), /* [2] */ 908 BTF_VAR_ENC(NAME_TBD, 1, 0), /* [3] */ 909 BTF_END_RAW, 910 }, 911 .str_sec = "\0A\0t\0s\0a\0a", 912 .str_sec_size = sizeof("\0A\0t\0s\0a\0a"), 913 .map_type = BPF_MAP_TYPE_ARRAY, 914 .map_name = ".bss", 915 .key_size = sizeof(int), 916 .value_size = 4, 917 .key_type_id = 0, 918 .value_type_id = 4, 919 .max_entries = 1, 920 .btf_load_err = true, 921 .err_str = "Invalid elem", 922}, 923/* Test member exceeds the size of struct. 924 * 925 * struct A { 926 * int m; 927 * int n; 928 * }; 929 */ 930{ 931 .descr = "size check test #1", 932 .raw_types = { 933 /* int */ /* [1] */ 934 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), 935 /* struct A { */ /* [2] */ 936 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), sizeof(int) * 2 - 1), 937 BTF_MEMBER_ENC(NAME_TBD, 1, 0), /* int m; */ 938 BTF_MEMBER_ENC(NAME_TBD, 1, 32),/* int n; */ 939 /* } */ 940 BTF_END_RAW, 941 }, 942 .str_sec = "\0A\0m\0n", 943 .str_sec_size = sizeof("\0A\0m\0n"), 944 .map_type = BPF_MAP_TYPE_ARRAY, 945 .map_name = "size_check1_map", 946 .key_size = sizeof(int), 947 .value_size = 1, 948 .key_type_id = 1, 949 .value_type_id = 2, 950 .max_entries = 4, 951 .btf_load_err = true, 952 .err_str = "Member exceeds struct_size", 953}, 954 955/* Test member exeeds the size of struct 956 * 957 * struct A { 958 * int m; 959 * int n[2]; 960 * }; 961 */ 962{ 963 .descr = "size check test #2", 964 .raw_types = { 965 /* int */ /* [1] */ 966 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, sizeof(int)), 967 /* int[2] */ /* [2] */ 968 BTF_TYPE_ARRAY_ENC(1, 1, 2), 969 /* struct A { */ /* [3] */ 970 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), sizeof(int) * 3 - 1), 971 BTF_MEMBER_ENC(NAME_TBD, 1, 0), /* int m; */ 972 BTF_MEMBER_ENC(NAME_TBD, 2, 32),/* int n[2]; */ 973 /* } */ 974 BTF_END_RAW, 975 }, 976 .str_sec = "\0A\0m\0n", 977 .str_sec_size = sizeof("\0A\0m\0n"), 978 .map_type = BPF_MAP_TYPE_ARRAY, 979 .map_name = "size_check2_map", 980 .key_size = sizeof(int), 981 .value_size = 1, 982 .key_type_id = 1, 983 .value_type_id = 3, 984 .max_entries = 4, 985 .btf_load_err = true, 986 .err_str = "Member exceeds struct_size", 987}, 988 989/* Test member exeeds the size of struct 990 * 991 * struct A { 992 * int m; 993 * void *n; 994 * }; 995 */ 996{ 997 .descr = "size check test #3", 998 .raw_types = { 999 /* int */ /* [1] */ 1000 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, sizeof(int)), 1001 /* void* */ /* [2] */ 1002 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 0), 1003 /* struct A { */ /* [3] */ 1004 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), sizeof(int) + sizeof(void *) - 1), 1005 BTF_MEMBER_ENC(NAME_TBD, 1, 0), /* int m; */ 1006 BTF_MEMBER_ENC(NAME_TBD, 2, 32),/* void *n; */ 1007 /* } */ 1008 BTF_END_RAW, 1009 }, 1010 .str_sec = "\0A\0m\0n", 1011 .str_sec_size = sizeof("\0A\0m\0n"), 1012 .map_type = BPF_MAP_TYPE_ARRAY, 1013 .map_name = "size_check3_map", 1014 .key_size = sizeof(int), 1015 .value_size = 1, 1016 .key_type_id = 1, 1017 .value_type_id = 3, 1018 .max_entries = 4, 1019 .btf_load_err = true, 1020 .err_str = "Member exceeds struct_size", 1021}, 1022 1023/* Test member exceeds the size of struct 1024 * 1025 * enum E { 1026 * E0, 1027 * E1, 1028 * }; 1029 * 1030 * struct A { 1031 * int m; 1032 * enum E n; 1033 * }; 1034 */ 1035{ 1036 .descr = "size check test #4", 1037 .raw_types = { 1038 /* int */ /* [1] */ 1039 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, sizeof(int)), 1040 /* enum E { */ /* [2] */ 1041 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 2), sizeof(int)), 1042 BTF_ENUM_ENC(NAME_TBD, 0), 1043 BTF_ENUM_ENC(NAME_TBD, 1), 1044 /* } */ 1045 /* struct A { */ /* [3] */ 1046 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), sizeof(int) * 2 - 1), 1047 BTF_MEMBER_ENC(NAME_TBD, 1, 0), /* int m; */ 1048 BTF_MEMBER_ENC(NAME_TBD, 2, 32),/* enum E n; */ 1049 /* } */ 1050 BTF_END_RAW, 1051 }, 1052 .str_sec = "\0E\0E0\0E1\0A\0m\0n", 1053 .str_sec_size = sizeof("\0E\0E0\0E1\0A\0m\0n"), 1054 .map_type = BPF_MAP_TYPE_ARRAY, 1055 .map_name = "size_check4_map", 1056 .key_size = sizeof(int), 1057 .value_size = 1, 1058 .key_type_id = 1, 1059 .value_type_id = 3, 1060 .max_entries = 4, 1061 .btf_load_err = true, 1062 .err_str = "Member exceeds struct_size", 1063}, 1064 1065/* typedef const void * const_void_ptr; 1066 * struct A { 1067 * const_void_ptr m; 1068 * }; 1069 */ 1070{ 1071 .descr = "void test #1", 1072 .raw_types = { 1073 /* int */ /* [1] */ 1074 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), 1075 /* const void */ /* [2] */ 1076 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 0), 1077 /* const void* */ /* [3] */ 1078 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 2), 1079 /* typedef const void * const_void_ptr */ 1080 BTF_TYPEDEF_ENC(NAME_TBD, 3), /* [4] */ 1081 /* struct A { */ /* [5] */ 1082 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), sizeof(void *)), 1083 /* const_void_ptr m; */ 1084 BTF_MEMBER_ENC(NAME_TBD, 4, 0), 1085 /* } */ 1086 BTF_END_RAW, 1087 }, 1088 .str_sec = "\0const_void_ptr\0A\0m", 1089 .str_sec_size = sizeof("\0const_void_ptr\0A\0m"), 1090 .map_type = BPF_MAP_TYPE_ARRAY, 1091 .map_name = "void_test1_map", 1092 .key_size = sizeof(int), 1093 .value_size = sizeof(void *), 1094 .key_type_id = 1, 1095 .value_type_id = 4, 1096 .max_entries = 4, 1097}, 1098 1099/* struct A { 1100 * const void m; 1101 * }; 1102 */ 1103{ 1104 .descr = "void test #2", 1105 .raw_types = { 1106 /* int */ /* [1] */ 1107 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), 1108 /* const void */ /* [2] */ 1109 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 0), 1110 /* struct A { */ /* [3] */ 1111 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), 8), 1112 /* const void m; */ 1113 BTF_MEMBER_ENC(NAME_TBD, 2, 0), 1114 /* } */ 1115 BTF_END_RAW, 1116 }, 1117 .str_sec = "\0A\0m", 1118 .str_sec_size = sizeof("\0A\0m"), 1119 .map_type = BPF_MAP_TYPE_ARRAY, 1120 .map_name = "void_test2_map", 1121 .key_size = sizeof(int), 1122 .value_size = sizeof(void *), 1123 .key_type_id = 1, 1124 .value_type_id = 3, 1125 .max_entries = 4, 1126 .btf_load_err = true, 1127 .err_str = "Invalid member", 1128}, 1129 1130/* typedef const void * const_void_ptr; 1131 * const_void_ptr[4] 1132 */ 1133{ 1134 .descr = "void test #3", 1135 .raw_types = { 1136 /* int */ /* [1] */ 1137 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), 1138 /* const void */ /* [2] */ 1139 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 0), 1140 /* const void* */ /* [3] */ 1141 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 2), 1142 /* typedef const void * const_void_ptr */ 1143 BTF_TYPEDEF_ENC(NAME_TBD, 3), /* [4] */ 1144 /* const_void_ptr[4] */ 1145 BTF_TYPE_ARRAY_ENC(4, 1, 4), /* [5] */ 1146 BTF_END_RAW, 1147 }, 1148 .str_sec = "\0const_void_ptr", 1149 .str_sec_size = sizeof("\0const_void_ptr"), 1150 .map_type = BPF_MAP_TYPE_ARRAY, 1151 .map_name = "void_test3_map", 1152 .key_size = sizeof(int), 1153 .value_size = sizeof(void *) * 4, 1154 .key_type_id = 1, 1155 .value_type_id = 5, 1156 .max_entries = 4, 1157}, 1158 1159/* const void[4] */ 1160{ 1161 .descr = "void test #4", 1162 .raw_types = { 1163 /* int */ /* [1] */ 1164 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), 1165 /* const void */ /* [2] */ 1166 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 0), 1167 /* const void[4] */ /* [3] */ 1168 BTF_TYPE_ARRAY_ENC(2, 1, 4), 1169 BTF_END_RAW, 1170 }, 1171 .str_sec = "\0A\0m", 1172 .str_sec_size = sizeof("\0A\0m"), 1173 .map_type = BPF_MAP_TYPE_ARRAY, 1174 .map_name = "void_test4_map", 1175 .key_size = sizeof(int), 1176 .value_size = sizeof(void *) * 4, 1177 .key_type_id = 1, 1178 .value_type_id = 3, 1179 .max_entries = 4, 1180 .btf_load_err = true, 1181 .err_str = "Invalid elem", 1182}, 1183 1184/* Array_A <------------------+ 1185 * elem_type == Array_B | 1186 * | | 1187 * | | 1188 * Array_B <-------- + | 1189 * elem_type == Array A --+ 1190 */ 1191{ 1192 .descr = "loop test #1", 1193 .raw_types = { 1194 /* int */ /* [1] */ 1195 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), 1196 /* Array_A */ /* [2] */ 1197 BTF_TYPE_ARRAY_ENC(3, 1, 8), 1198 /* Array_B */ /* [3] */ 1199 BTF_TYPE_ARRAY_ENC(2, 1, 8), 1200 BTF_END_RAW, 1201 }, 1202 .str_sec = "", 1203 .str_sec_size = sizeof(""), 1204 .map_type = BPF_MAP_TYPE_ARRAY, 1205 .map_name = "loop_test1_map", 1206 .key_size = sizeof(int), 1207 .value_size = sizeof(sizeof(int) * 8), 1208 .key_type_id = 1, 1209 .value_type_id = 2, 1210 .max_entries = 4, 1211 .btf_load_err = true, 1212 .err_str = "Loop detected", 1213}, 1214 1215/* typedef is _before_ the BTF type of Array_A and Array_B 1216 * 1217 * typedef Array_B int_array; 1218 * 1219 * Array_A <------------------+ 1220 * elem_type == int_array | 1221 * | | 1222 * | | 1223 * Array_B <-------- + | 1224 * elem_type == Array_A --+ 1225 */ 1226{ 1227 .descr = "loop test #2", 1228 .raw_types = { 1229 /* int */ 1230 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 1231 /* typedef Array_B int_array */ 1232 BTF_TYPEDEF_ENC(1, 4), /* [2] */ 1233 /* Array_A */ 1234 BTF_TYPE_ARRAY_ENC(2, 1, 8), /* [3] */ 1235 /* Array_B */ 1236 BTF_TYPE_ARRAY_ENC(3, 1, 8), /* [4] */ 1237 BTF_END_RAW, 1238 }, 1239 .str_sec = "\0int_array\0", 1240 .str_sec_size = sizeof("\0int_array"), 1241 .map_type = BPF_MAP_TYPE_ARRAY, 1242 .map_name = "loop_test2_map", 1243 .key_size = sizeof(int), 1244 .value_size = sizeof(sizeof(int) * 8), 1245 .key_type_id = 1, 1246 .value_type_id = 2, 1247 .max_entries = 4, 1248 .btf_load_err = true, 1249 .err_str = "Loop detected", 1250}, 1251 1252/* Array_A <------------------+ 1253 * elem_type == Array_B | 1254 * | | 1255 * | | 1256 * Array_B <-------- + | 1257 * elem_type == Array_A --+ 1258 */ 1259{ 1260 .descr = "loop test #3", 1261 .raw_types = { 1262 /* int */ /* [1] */ 1263 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), 1264 /* Array_A */ /* [2] */ 1265 BTF_TYPE_ARRAY_ENC(3, 1, 8), 1266 /* Array_B */ /* [3] */ 1267 BTF_TYPE_ARRAY_ENC(2, 1, 8), 1268 BTF_END_RAW, 1269 }, 1270 .str_sec = "", 1271 .str_sec_size = sizeof(""), 1272 .map_type = BPF_MAP_TYPE_ARRAY, 1273 .map_name = "loop_test3_map", 1274 .key_size = sizeof(int), 1275 .value_size = sizeof(sizeof(int) * 8), 1276 .key_type_id = 1, 1277 .value_type_id = 2, 1278 .max_entries = 4, 1279 .btf_load_err = true, 1280 .err_str = "Loop detected", 1281}, 1282 1283/* typedef is _between_ the BTF type of Array_A and Array_B 1284 * 1285 * typedef Array_B int_array; 1286 * 1287 * Array_A <------------------+ 1288 * elem_type == int_array | 1289 * | | 1290 * | | 1291 * Array_B <-------- + | 1292 * elem_type == Array_A --+ 1293 */ 1294{ 1295 .descr = "loop test #4", 1296 .raw_types = { 1297 /* int */ /* [1] */ 1298 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), 1299 /* Array_A */ /* [2] */ 1300 BTF_TYPE_ARRAY_ENC(3, 1, 8), 1301 /* typedef Array_B int_array */ /* [3] */ 1302 BTF_TYPEDEF_ENC(NAME_TBD, 4), 1303 /* Array_B */ /* [4] */ 1304 BTF_TYPE_ARRAY_ENC(2, 1, 8), 1305 BTF_END_RAW, 1306 }, 1307 .str_sec = "\0int_array\0", 1308 .str_sec_size = sizeof("\0int_array"), 1309 .map_type = BPF_MAP_TYPE_ARRAY, 1310 .map_name = "loop_test4_map", 1311 .key_size = sizeof(int), 1312 .value_size = sizeof(sizeof(int) * 8), 1313 .key_type_id = 1, 1314 .value_type_id = 2, 1315 .max_entries = 4, 1316 .btf_load_err = true, 1317 .err_str = "Loop detected", 1318}, 1319 1320/* typedef struct B Struct_B 1321 * 1322 * struct A { 1323 * int x; 1324 * Struct_B y; 1325 * }; 1326 * 1327 * struct B { 1328 * int x; 1329 * struct A y; 1330 * }; 1331 */ 1332{ 1333 .descr = "loop test #5", 1334 .raw_types = { 1335 /* int */ 1336 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 1337 /* struct A */ /* [2] */ 1338 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), 8), 1339 BTF_MEMBER_ENC(NAME_TBD, 1, 0), /* int x; */ 1340 BTF_MEMBER_ENC(NAME_TBD, 3, 32),/* Struct_B y; */ 1341 /* typedef struct B Struct_B */ 1342 BTF_TYPEDEF_ENC(NAME_TBD, 4), /* [3] */ 1343 /* struct B */ /* [4] */ 1344 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), 8), 1345 BTF_MEMBER_ENC(NAME_TBD, 1, 0), /* int x; */ 1346 BTF_MEMBER_ENC(NAME_TBD, 2, 32),/* struct A y; */ 1347 BTF_END_RAW, 1348 }, 1349 .str_sec = "\0A\0x\0y\0Struct_B\0B\0x\0y", 1350 .str_sec_size = sizeof("\0A\0x\0y\0Struct_B\0B\0x\0y"), 1351 .map_type = BPF_MAP_TYPE_ARRAY, 1352 .map_name = "loop_test5_map", 1353 .key_size = sizeof(int), 1354 .value_size = 8, 1355 .key_type_id = 1, 1356 .value_type_id = 2, 1357 .max_entries = 4, 1358 .btf_load_err = true, 1359 .err_str = "Loop detected", 1360}, 1361 1362/* struct A { 1363 * int x; 1364 * struct A array_a[4]; 1365 * }; 1366 */ 1367{ 1368 .descr = "loop test #6", 1369 .raw_types = { 1370 /* int */ 1371 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 1372 BTF_TYPE_ARRAY_ENC(3, 1, 4), /* [2] */ 1373 /* struct A */ /* [3] */ 1374 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), 8), 1375 BTF_MEMBER_ENC(NAME_TBD, 1, 0), /* int x; */ 1376 BTF_MEMBER_ENC(NAME_TBD, 2, 32),/* struct A array_a[4]; */ 1377 BTF_END_RAW, 1378 }, 1379 .str_sec = "\0A\0x\0y", 1380 .str_sec_size = sizeof("\0A\0x\0y"), 1381 .map_type = BPF_MAP_TYPE_ARRAY, 1382 .map_name = "loop_test6_map", 1383 .key_size = sizeof(int), 1384 .value_size = 8, 1385 .key_type_id = 1, 1386 .value_type_id = 2, 1387 .max_entries = 4, 1388 .btf_load_err = true, 1389 .err_str = "Loop detected", 1390}, 1391 1392{ 1393 .descr = "loop test #7", 1394 .raw_types = { 1395 /* int */ /* [1] */ 1396 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), 1397 /* struct A { */ /* [2] */ 1398 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), sizeof(void *)), 1399 /* const void *m; */ 1400 BTF_MEMBER_ENC(NAME_TBD, 3, 0), 1401 /* CONST type_id=3 */ /* [3] */ 1402 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 4), 1403 /* PTR type_id=2 */ /* [4] */ 1404 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 3), 1405 BTF_END_RAW, 1406 }, 1407 .str_sec = "\0A\0m", 1408 .str_sec_size = sizeof("\0A\0m"), 1409 .map_type = BPF_MAP_TYPE_ARRAY, 1410 .map_name = "loop_test7_map", 1411 .key_size = sizeof(int), 1412 .value_size = sizeof(void *), 1413 .key_type_id = 1, 1414 .value_type_id = 2, 1415 .max_entries = 4, 1416 .btf_load_err = true, 1417 .err_str = "Loop detected", 1418}, 1419 1420{ 1421 .descr = "loop test #8", 1422 .raw_types = { 1423 /* int */ /* [1] */ 1424 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), 1425 /* struct A { */ /* [2] */ 1426 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), sizeof(void *)), 1427 /* const void *m; */ 1428 BTF_MEMBER_ENC(NAME_TBD, 4, 0), 1429 /* struct B { */ /* [3] */ 1430 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), sizeof(void *)), 1431 /* const void *n; */ 1432 BTF_MEMBER_ENC(NAME_TBD, 6, 0), 1433 /* CONST type_id=5 */ /* [4] */ 1434 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 5), 1435 /* PTR type_id=6 */ /* [5] */ 1436 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 6), 1437 /* CONST type_id=7 */ /* [6] */ 1438 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 7), 1439 /* PTR type_id=4 */ /* [7] */ 1440 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 4), 1441 BTF_END_RAW, 1442 }, 1443 .str_sec = "\0A\0m\0B\0n", 1444 .str_sec_size = sizeof("\0A\0m\0B\0n"), 1445 .map_type = BPF_MAP_TYPE_ARRAY, 1446 .map_name = "loop_test8_map", 1447 .key_size = sizeof(int), 1448 .value_size = sizeof(void *), 1449 .key_type_id = 1, 1450 .value_type_id = 2, 1451 .max_entries = 4, 1452 .btf_load_err = true, 1453 .err_str = "Loop detected", 1454}, 1455 1456{ 1457 .descr = "string section does not end with null", 1458 .raw_types = { 1459 /* int */ /* [1] */ 1460 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), 1461 BTF_END_RAW, 1462 }, 1463 .str_sec = "\0int", 1464 .str_sec_size = sizeof("\0int") - 1, 1465 .map_type = BPF_MAP_TYPE_ARRAY, 1466 .map_name = "hdr_test_map", 1467 .key_size = sizeof(int), 1468 .value_size = sizeof(int), 1469 .key_type_id = 1, 1470 .value_type_id = 1, 1471 .max_entries = 4, 1472 .btf_load_err = true, 1473 .err_str = "Invalid string section", 1474}, 1475 1476{ 1477 .descr = "empty string section", 1478 .raw_types = { 1479 /* int */ /* [1] */ 1480 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), 1481 BTF_END_RAW, 1482 }, 1483 .str_sec = "", 1484 .str_sec_size = 0, 1485 .map_type = BPF_MAP_TYPE_ARRAY, 1486 .map_name = "hdr_test_map", 1487 .key_size = sizeof(int), 1488 .value_size = sizeof(int), 1489 .key_type_id = 1, 1490 .value_type_id = 1, 1491 .max_entries = 4, 1492 .btf_load_err = true, 1493 .err_str = "Invalid string section", 1494}, 1495 1496{ 1497 .descr = "empty type section", 1498 .raw_types = { 1499 BTF_END_RAW, 1500 }, 1501 .str_sec = "\0int", 1502 .str_sec_size = sizeof("\0int"), 1503 .map_type = BPF_MAP_TYPE_ARRAY, 1504 .map_name = "hdr_test_map", 1505 .key_size = sizeof(int), 1506 .value_size = sizeof(int), 1507 .key_type_id = 1, 1508 .value_type_id = 1, 1509 .max_entries = 4, 1510 .btf_load_err = true, 1511 .err_str = "No type found", 1512}, 1513 1514{ 1515 .descr = "btf_header test. Longer hdr_len", 1516 .raw_types = { 1517 /* int */ /* [1] */ 1518 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), 1519 BTF_END_RAW, 1520 }, 1521 .str_sec = "\0int", 1522 .str_sec_size = sizeof("\0int"), 1523 .map_type = BPF_MAP_TYPE_ARRAY, 1524 .map_name = "hdr_test_map", 1525 .key_size = sizeof(int), 1526 .value_size = sizeof(int), 1527 .key_type_id = 1, 1528 .value_type_id = 1, 1529 .max_entries = 4, 1530 .btf_load_err = true, 1531 .hdr_len_delta = 4, 1532 .err_str = "Unsupported btf_header", 1533}, 1534 1535{ 1536 .descr = "btf_header test. Gap between hdr and type", 1537 .raw_types = { 1538 /* int */ /* [1] */ 1539 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), 1540 BTF_END_RAW, 1541 }, 1542 .str_sec = "\0int", 1543 .str_sec_size = sizeof("\0int"), 1544 .map_type = BPF_MAP_TYPE_ARRAY, 1545 .map_name = "hdr_test_map", 1546 .key_size = sizeof(int), 1547 .value_size = sizeof(int), 1548 .key_type_id = 1, 1549 .value_type_id = 1, 1550 .max_entries = 4, 1551 .btf_load_err = true, 1552 .type_off_delta = 4, 1553 .err_str = "Unsupported section found", 1554}, 1555 1556{ 1557 .descr = "btf_header test. Gap between type and str", 1558 .raw_types = { 1559 /* int */ /* [1] */ 1560 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), 1561 BTF_END_RAW, 1562 }, 1563 .str_sec = "\0int", 1564 .str_sec_size = sizeof("\0int"), 1565 .map_type = BPF_MAP_TYPE_ARRAY, 1566 .map_name = "hdr_test_map", 1567 .key_size = sizeof(int), 1568 .value_size = sizeof(int), 1569 .key_type_id = 1, 1570 .value_type_id = 1, 1571 .max_entries = 4, 1572 .btf_load_err = true, 1573 .str_off_delta = 4, 1574 .err_str = "Unsupported section found", 1575}, 1576 1577{ 1578 .descr = "btf_header test. Overlap between type and str", 1579 .raw_types = { 1580 /* int */ /* [1] */ 1581 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), 1582 BTF_END_RAW, 1583 }, 1584 .str_sec = "\0int", 1585 .str_sec_size = sizeof("\0int"), 1586 .map_type = BPF_MAP_TYPE_ARRAY, 1587 .map_name = "hdr_test_map", 1588 .key_size = sizeof(int), 1589 .value_size = sizeof(int), 1590 .key_type_id = 1, 1591 .value_type_id = 1, 1592 .max_entries = 4, 1593 .btf_load_err = true, 1594 .str_off_delta = -4, 1595 .err_str = "Section overlap found", 1596}, 1597 1598{ 1599 .descr = "btf_header test. Larger BTF size", 1600 .raw_types = { 1601 /* int */ /* [1] */ 1602 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), 1603 BTF_END_RAW, 1604 }, 1605 .str_sec = "\0int", 1606 .str_sec_size = sizeof("\0int"), 1607 .map_type = BPF_MAP_TYPE_ARRAY, 1608 .map_name = "hdr_test_map", 1609 .key_size = sizeof(int), 1610 .value_size = sizeof(int), 1611 .key_type_id = 1, 1612 .value_type_id = 1, 1613 .max_entries = 4, 1614 .btf_load_err = true, 1615 .str_len_delta = -4, 1616 .err_str = "Unsupported section found", 1617}, 1618 1619{ 1620 .descr = "btf_header test. Smaller BTF size", 1621 .raw_types = { 1622 /* int */ /* [1] */ 1623 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), 1624 BTF_END_RAW, 1625 }, 1626 .str_sec = "\0int", 1627 .str_sec_size = sizeof("\0int"), 1628 .map_type = BPF_MAP_TYPE_ARRAY, 1629 .map_name = "hdr_test_map", 1630 .key_size = sizeof(int), 1631 .value_size = sizeof(int), 1632 .key_type_id = 1, 1633 .value_type_id = 1, 1634 .max_entries = 4, 1635 .btf_load_err = true, 1636 .str_len_delta = 4, 1637 .err_str = "Total section length too long", 1638}, 1639 1640{ 1641 .descr = "array test. index_type/elem_type \"int\"", 1642 .raw_types = { 1643 /* int */ /* [1] */ 1644 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), 1645 /* int[16] */ /* [2] */ 1646 BTF_TYPE_ARRAY_ENC(1, 1, 16), 1647 BTF_END_RAW, 1648 }, 1649 .str_sec = "", 1650 .str_sec_size = sizeof(""), 1651 .map_type = BPF_MAP_TYPE_ARRAY, 1652 .map_name = "array_test_map", 1653 .key_size = sizeof(int), 1654 .value_size = sizeof(int), 1655 .key_type_id = 1, 1656 .value_type_id = 1, 1657 .max_entries = 4, 1658}, 1659 1660{ 1661 .descr = "array test. index_type/elem_type \"const int\"", 1662 .raw_types = { 1663 /* int */ /* [1] */ 1664 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), 1665 /* int[16] */ /* [2] */ 1666 BTF_TYPE_ARRAY_ENC(3, 3, 16), 1667 /* CONST type_id=1 */ /* [3] */ 1668 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 1), 1669 BTF_END_RAW, 1670 }, 1671 .str_sec = "", 1672 .str_sec_size = sizeof(""), 1673 .map_type = BPF_MAP_TYPE_ARRAY, 1674 .map_name = "array_test_map", 1675 .key_size = sizeof(int), 1676 .value_size = sizeof(int), 1677 .key_type_id = 1, 1678 .value_type_id = 1, 1679 .max_entries = 4, 1680}, 1681 1682{ 1683 .descr = "array test. index_type \"const int:31\"", 1684 .raw_types = { 1685 /* int */ /* [1] */ 1686 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), 1687 /* int:31 */ /* [2] */ 1688 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 31, 4), 1689 /* int[16] */ /* [3] */ 1690 BTF_TYPE_ARRAY_ENC(1, 4, 16), 1691 /* CONST type_id=2 */ /* [4] */ 1692 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 2), 1693 BTF_END_RAW, 1694 }, 1695 .str_sec = "", 1696 .str_sec_size = sizeof(""), 1697 .map_type = BPF_MAP_TYPE_ARRAY, 1698 .map_name = "array_test_map", 1699 .key_size = sizeof(int), 1700 .value_size = sizeof(int), 1701 .key_type_id = 1, 1702 .value_type_id = 1, 1703 .max_entries = 4, 1704 .btf_load_err = true, 1705 .err_str = "Invalid index", 1706}, 1707 1708{ 1709 .descr = "array test. elem_type \"const int:31\"", 1710 .raw_types = { 1711 /* int */ /* [1] */ 1712 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), 1713 /* int:31 */ /* [2] */ 1714 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 31, 4), 1715 /* int[16] */ /* [3] */ 1716 BTF_TYPE_ARRAY_ENC(4, 1, 16), 1717 /* CONST type_id=2 */ /* [4] */ 1718 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 2), 1719 BTF_END_RAW, 1720 }, 1721 .str_sec = "", 1722 .str_sec_size = sizeof(""), 1723 .map_type = BPF_MAP_TYPE_ARRAY, 1724 .map_name = "array_test_map", 1725 .key_size = sizeof(int), 1726 .value_size = sizeof(int), 1727 .key_type_id = 1, 1728 .value_type_id = 1, 1729 .max_entries = 4, 1730 .btf_load_err = true, 1731 .err_str = "Invalid array of int", 1732}, 1733 1734{ 1735 .descr = "array test. index_type \"void\"", 1736 .raw_types = { 1737 /* int */ /* [1] */ 1738 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), 1739 /* int[16] */ /* [2] */ 1740 BTF_TYPE_ARRAY_ENC(1, 0, 16), 1741 BTF_END_RAW, 1742 }, 1743 .str_sec = "", 1744 .str_sec_size = sizeof(""), 1745 .map_type = BPF_MAP_TYPE_ARRAY, 1746 .map_name = "array_test_map", 1747 .key_size = sizeof(int), 1748 .value_size = sizeof(int), 1749 .key_type_id = 1, 1750 .value_type_id = 1, 1751 .max_entries = 4, 1752 .btf_load_err = true, 1753 .err_str = "Invalid index", 1754}, 1755 1756{ 1757 .descr = "array test. index_type \"const void\"", 1758 .raw_types = { 1759 /* int */ /* [1] */ 1760 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), 1761 /* int[16] */ /* [2] */ 1762 BTF_TYPE_ARRAY_ENC(1, 3, 16), 1763 /* CONST type_id=0 (void) */ /* [3] */ 1764 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 0), 1765 BTF_END_RAW, 1766 }, 1767 .str_sec = "", 1768 .str_sec_size = sizeof(""), 1769 .map_type = BPF_MAP_TYPE_ARRAY, 1770 .map_name = "array_test_map", 1771 .key_size = sizeof(int), 1772 .value_size = sizeof(int), 1773 .key_type_id = 1, 1774 .value_type_id = 1, 1775 .max_entries = 4, 1776 .btf_load_err = true, 1777 .err_str = "Invalid index", 1778}, 1779 1780{ 1781 .descr = "array test. elem_type \"const void\"", 1782 .raw_types = { 1783 /* int */ /* [1] */ 1784 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), 1785 /* int[16] */ /* [2] */ 1786 BTF_TYPE_ARRAY_ENC(3, 1, 16), 1787 /* CONST type_id=0 (void) */ /* [3] */ 1788 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 0), 1789 BTF_END_RAW, 1790 }, 1791 .str_sec = "", 1792 .str_sec_size = sizeof(""), 1793 .map_type = BPF_MAP_TYPE_ARRAY, 1794 .map_name = "array_test_map", 1795 .key_size = sizeof(int), 1796 .value_size = sizeof(int), 1797 .key_type_id = 1, 1798 .value_type_id = 1, 1799 .max_entries = 4, 1800 .btf_load_err = true, 1801 .err_str = "Invalid elem", 1802}, 1803 1804{ 1805 .descr = "array test. elem_type \"const void *\"", 1806 .raw_types = { 1807 /* int */ /* [1] */ 1808 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), 1809 /* const void *[16] */ /* [2] */ 1810 BTF_TYPE_ARRAY_ENC(3, 1, 16), 1811 /* CONST type_id=4 */ /* [3] */ 1812 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 4), 1813 /* void* */ /* [4] */ 1814 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 0), 1815 BTF_END_RAW, 1816 }, 1817 .str_sec = "", 1818 .str_sec_size = sizeof(""), 1819 .map_type = BPF_MAP_TYPE_ARRAY, 1820 .map_name = "array_test_map", 1821 .key_size = sizeof(int), 1822 .value_size = sizeof(int), 1823 .key_type_id = 1, 1824 .value_type_id = 1, 1825 .max_entries = 4, 1826}, 1827 1828{ 1829 .descr = "array test. index_type \"const void *\"", 1830 .raw_types = { 1831 /* int */ /* [1] */ 1832 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), 1833 /* const void *[16] */ /* [2] */ 1834 BTF_TYPE_ARRAY_ENC(3, 3, 16), 1835 /* CONST type_id=4 */ /* [3] */ 1836 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 4), 1837 /* void* */ /* [4] */ 1838 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 0), 1839 BTF_END_RAW, 1840 }, 1841 .str_sec = "", 1842 .str_sec_size = sizeof(""), 1843 .map_type = BPF_MAP_TYPE_ARRAY, 1844 .map_name = "array_test_map", 1845 .key_size = sizeof(int), 1846 .value_size = sizeof(int), 1847 .key_type_id = 1, 1848 .value_type_id = 1, 1849 .max_entries = 4, 1850 .btf_load_err = true, 1851 .err_str = "Invalid index", 1852}, 1853 1854{ 1855 .descr = "array test. t->size != 0\"", 1856 .raw_types = { 1857 /* int */ /* [1] */ 1858 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), 1859 /* int[16] */ /* [2] */ 1860 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ARRAY, 0, 0), 1), 1861 BTF_ARRAY_ENC(1, 1, 16), 1862 BTF_END_RAW, 1863 }, 1864 .str_sec = "", 1865 .str_sec_size = sizeof(""), 1866 .map_type = BPF_MAP_TYPE_ARRAY, 1867 .map_name = "array_test_map", 1868 .key_size = sizeof(int), 1869 .value_size = sizeof(int), 1870 .key_type_id = 1, 1871 .value_type_id = 1, 1872 .max_entries = 4, 1873 .btf_load_err = true, 1874 .err_str = "size != 0", 1875}, 1876 1877{ 1878 .descr = "int test. invalid int_data", 1879 .raw_types = { 1880 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_INT, 0, 0), 4), 1881 0x10000000, 1882 BTF_END_RAW, 1883 }, 1884 .str_sec = "", 1885 .str_sec_size = sizeof(""), 1886 .map_type = BPF_MAP_TYPE_ARRAY, 1887 .map_name = "array_test_map", 1888 .key_size = sizeof(int), 1889 .value_size = sizeof(int), 1890 .key_type_id = 1, 1891 .value_type_id = 1, 1892 .max_entries = 4, 1893 .btf_load_err = true, 1894 .err_str = "Invalid int_data", 1895}, 1896 1897{ 1898 .descr = "invalid BTF_INFO", 1899 .raw_types = { 1900 /* int */ /* [1] */ 1901 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), 1902 BTF_TYPE_ENC(0, 0x10000000, 4), 1903 BTF_END_RAW, 1904 }, 1905 .str_sec = "", 1906 .str_sec_size = sizeof(""), 1907 .map_type = BPF_MAP_TYPE_ARRAY, 1908 .map_name = "array_test_map", 1909 .key_size = sizeof(int), 1910 .value_size = sizeof(int), 1911 .key_type_id = 1, 1912 .value_type_id = 1, 1913 .max_entries = 4, 1914 .btf_load_err = true, 1915 .err_str = "Invalid btf_info", 1916}, 1917 1918{ 1919 .descr = "fwd test. t->type != 0\"", 1920 .raw_types = { 1921 /* int */ /* [1] */ 1922 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), 1923 /* fwd type */ /* [2] */ 1924 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_FWD, 0, 0), 1), 1925 BTF_END_RAW, 1926 }, 1927 .str_sec = "", 1928 .str_sec_size = sizeof(""), 1929 .map_type = BPF_MAP_TYPE_ARRAY, 1930 .map_name = "fwd_test_map", 1931 .key_size = sizeof(int), 1932 .value_size = sizeof(int), 1933 .key_type_id = 1, 1934 .value_type_id = 1, 1935 .max_entries = 4, 1936 .btf_load_err = true, 1937 .err_str = "type != 0", 1938}, 1939 1940{ 1941 .descr = "typedef (invalid name, name_off = 0)", 1942 .raw_types = { 1943 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 1944 BTF_TYPEDEF_ENC(0, 1), /* [2] */ 1945 BTF_END_RAW, 1946 }, 1947 .str_sec = "\0__int", 1948 .str_sec_size = sizeof("\0__int"), 1949 .map_type = BPF_MAP_TYPE_ARRAY, 1950 .map_name = "typedef_check_btf", 1951 .key_size = sizeof(int), 1952 .value_size = sizeof(int), 1953 .key_type_id = 1, 1954 .value_type_id = 1, 1955 .max_entries = 4, 1956 .btf_load_err = true, 1957 .err_str = "Invalid name", 1958}, 1959 1960{ 1961 .descr = "typedef (invalid name, invalid identifier)", 1962 .raw_types = { 1963 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 1964 BTF_TYPEDEF_ENC(NAME_TBD, 1), /* [2] */ 1965 BTF_END_RAW, 1966 }, 1967 .str_sec = "\0__!int", 1968 .str_sec_size = sizeof("\0__!int"), 1969 .map_type = BPF_MAP_TYPE_ARRAY, 1970 .map_name = "typedef_check_btf", 1971 .key_size = sizeof(int), 1972 .value_size = sizeof(int), 1973 .key_type_id = 1, 1974 .value_type_id = 1, 1975 .max_entries = 4, 1976 .btf_load_err = true, 1977 .err_str = "Invalid name", 1978}, 1979 1980{ 1981 .descr = "ptr type (invalid name, name_off <> 0)", 1982 .raw_types = { 1983 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 1984 BTF_TYPE_ENC(NAME_TBD, 1985 BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 1), /* [2] */ 1986 BTF_END_RAW, 1987 }, 1988 .str_sec = "\0__int", 1989 .str_sec_size = sizeof("\0__int"), 1990 .map_type = BPF_MAP_TYPE_ARRAY, 1991 .map_name = "ptr_type_check_btf", 1992 .key_size = sizeof(int), 1993 .value_size = sizeof(int), 1994 .key_type_id = 1, 1995 .value_type_id = 1, 1996 .max_entries = 4, 1997 .btf_load_err = true, 1998 .err_str = "Invalid name", 1999}, 2000 2001{ 2002 .descr = "volatile type (invalid name, name_off <> 0)", 2003 .raw_types = { 2004 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 2005 BTF_TYPE_ENC(NAME_TBD, 2006 BTF_INFO_ENC(BTF_KIND_VOLATILE, 0, 0), 1), /* [2] */ 2007 BTF_END_RAW, 2008 }, 2009 .str_sec = "\0__int", 2010 .str_sec_size = sizeof("\0__int"), 2011 .map_type = BPF_MAP_TYPE_ARRAY, 2012 .map_name = "volatile_type_check_btf", 2013 .key_size = sizeof(int), 2014 .value_size = sizeof(int), 2015 .key_type_id = 1, 2016 .value_type_id = 1, 2017 .max_entries = 4, 2018 .btf_load_err = true, 2019 .err_str = "Invalid name", 2020}, 2021 2022{ 2023 .descr = "const type (invalid name, name_off <> 0)", 2024 .raw_types = { 2025 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 2026 BTF_TYPE_ENC(NAME_TBD, 2027 BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 1), /* [2] */ 2028 BTF_END_RAW, 2029 }, 2030 .str_sec = "\0__int", 2031 .str_sec_size = sizeof("\0__int"), 2032 .map_type = BPF_MAP_TYPE_ARRAY, 2033 .map_name = "const_type_check_btf", 2034 .key_size = sizeof(int), 2035 .value_size = sizeof(int), 2036 .key_type_id = 1, 2037 .value_type_id = 1, 2038 .max_entries = 4, 2039 .btf_load_err = true, 2040 .err_str = "Invalid name", 2041}, 2042 2043{ 2044 .descr = "restrict type (invalid name, name_off <> 0)", 2045 .raw_types = { 2046 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 2047 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 1), /* [2] */ 2048 BTF_TYPE_ENC(NAME_TBD, 2049 BTF_INFO_ENC(BTF_KIND_RESTRICT, 0, 0), 2), /* [3] */ 2050 BTF_END_RAW, 2051 }, 2052 .str_sec = "\0__int", 2053 .str_sec_size = sizeof("\0__int"), 2054 .map_type = BPF_MAP_TYPE_ARRAY, 2055 .map_name = "restrict_type_check_btf", 2056 .key_size = sizeof(int), 2057 .value_size = sizeof(int), 2058 .key_type_id = 1, 2059 .value_type_id = 1, 2060 .max_entries = 4, 2061 .btf_load_err = true, 2062 .err_str = "Invalid name", 2063}, 2064 2065{ 2066 .descr = "fwd type (invalid name, name_off = 0)", 2067 .raw_types = { 2068 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 2069 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_FWD, 0, 0), 0), /* [2] */ 2070 BTF_END_RAW, 2071 }, 2072 .str_sec = "\0__skb", 2073 .str_sec_size = sizeof("\0__skb"), 2074 .map_type = BPF_MAP_TYPE_ARRAY, 2075 .map_name = "fwd_type_check_btf", 2076 .key_size = sizeof(int), 2077 .value_size = sizeof(int), 2078 .key_type_id = 1, 2079 .value_type_id = 1, 2080 .max_entries = 4, 2081 .btf_load_err = true, 2082 .err_str = "Invalid name", 2083}, 2084 2085{ 2086 .descr = "fwd type (invalid name, invalid identifier)", 2087 .raw_types = { 2088 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 2089 BTF_TYPE_ENC(NAME_TBD, 2090 BTF_INFO_ENC(BTF_KIND_FWD, 0, 0), 0), /* [2] */ 2091 BTF_END_RAW, 2092 }, 2093 .str_sec = "\0__!skb", 2094 .str_sec_size = sizeof("\0__!skb"), 2095 .map_type = BPF_MAP_TYPE_ARRAY, 2096 .map_name = "fwd_type_check_btf", 2097 .key_size = sizeof(int), 2098 .value_size = sizeof(int), 2099 .key_type_id = 1, 2100 .value_type_id = 1, 2101 .max_entries = 4, 2102 .btf_load_err = true, 2103 .err_str = "Invalid name", 2104}, 2105 2106{ 2107 .descr = "array type (invalid name, name_off <> 0)", 2108 .raw_types = { 2109 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 2110 BTF_TYPE_ENC(NAME_TBD, 2111 BTF_INFO_ENC(BTF_KIND_ARRAY, 0, 0), 0), /* [2] */ 2112 BTF_ARRAY_ENC(1, 1, 4), 2113 BTF_END_RAW, 2114 }, 2115 .str_sec = "\0__skb", 2116 .str_sec_size = sizeof("\0__skb"), 2117 .map_type = BPF_MAP_TYPE_ARRAY, 2118 .map_name = "array_type_check_btf", 2119 .key_size = sizeof(int), 2120 .value_size = sizeof(int), 2121 .key_type_id = 1, 2122 .value_type_id = 1, 2123 .max_entries = 4, 2124 .btf_load_err = true, 2125 .err_str = "Invalid name", 2126}, 2127 2128{ 2129 .descr = "struct type (name_off = 0)", 2130 .raw_types = { 2131 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 2132 BTF_TYPE_ENC(0, 2133 BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), 4), /* [2] */ 2134 BTF_MEMBER_ENC(NAME_TBD, 1, 0), 2135 BTF_END_RAW, 2136 }, 2137 .str_sec = "\0A", 2138 .str_sec_size = sizeof("\0A"), 2139 .map_type = BPF_MAP_TYPE_ARRAY, 2140 .map_name = "struct_type_check_btf", 2141 .key_size = sizeof(int), 2142 .value_size = sizeof(int), 2143 .key_type_id = 1, 2144 .value_type_id = 1, 2145 .max_entries = 4, 2146}, 2147 2148{ 2149 .descr = "struct type (invalid name, invalid identifier)", 2150 .raw_types = { 2151 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 2152 BTF_TYPE_ENC(NAME_TBD, 2153 BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), 4), /* [2] */ 2154 BTF_MEMBER_ENC(NAME_TBD, 1, 0), 2155 BTF_END_RAW, 2156 }, 2157 .str_sec = "\0A!\0B", 2158 .str_sec_size = sizeof("\0A!\0B"), 2159 .map_type = BPF_MAP_TYPE_ARRAY, 2160 .map_name = "struct_type_check_btf", 2161 .key_size = sizeof(int), 2162 .value_size = sizeof(int), 2163 .key_type_id = 1, 2164 .value_type_id = 1, 2165 .max_entries = 4, 2166 .btf_load_err = true, 2167 .err_str = "Invalid name", 2168}, 2169 2170{ 2171 .descr = "struct member (name_off = 0)", 2172 .raw_types = { 2173 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 2174 BTF_TYPE_ENC(0, 2175 BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), 4), /* [2] */ 2176 BTF_MEMBER_ENC(NAME_TBD, 1, 0), 2177 BTF_END_RAW, 2178 }, 2179 .str_sec = "\0A", 2180 .str_sec_size = sizeof("\0A"), 2181 .map_type = BPF_MAP_TYPE_ARRAY, 2182 .map_name = "struct_type_check_btf", 2183 .key_size = sizeof(int), 2184 .value_size = sizeof(int), 2185 .key_type_id = 1, 2186 .value_type_id = 1, 2187 .max_entries = 4, 2188}, 2189 2190{ 2191 .descr = "struct member (invalid name, invalid identifier)", 2192 .raw_types = { 2193 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 2194 BTF_TYPE_ENC(NAME_TBD, 2195 BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), 4), /* [2] */ 2196 BTF_MEMBER_ENC(NAME_TBD, 1, 0), 2197 BTF_END_RAW, 2198 }, 2199 .str_sec = "\0A\0B*", 2200 .str_sec_size = sizeof("\0A\0B*"), 2201 .map_type = BPF_MAP_TYPE_ARRAY, 2202 .map_name = "struct_type_check_btf", 2203 .key_size = sizeof(int), 2204 .value_size = sizeof(int), 2205 .key_type_id = 1, 2206 .value_type_id = 1, 2207 .max_entries = 4, 2208 .btf_load_err = true, 2209 .err_str = "Invalid name", 2210}, 2211 2212{ 2213 .descr = "enum type (name_off = 0)", 2214 .raw_types = { 2215 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 2216 BTF_TYPE_ENC(0, 2217 BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 2218 sizeof(int)), /* [2] */ 2219 BTF_ENUM_ENC(NAME_TBD, 0), 2220 BTF_END_RAW, 2221 }, 2222 .str_sec = "\0A\0B", 2223 .str_sec_size = sizeof("\0A\0B"), 2224 .map_type = BPF_MAP_TYPE_ARRAY, 2225 .map_name = "enum_type_check_btf", 2226 .key_size = sizeof(int), 2227 .value_size = sizeof(int), 2228 .key_type_id = 1, 2229 .value_type_id = 1, 2230 .max_entries = 4, 2231}, 2232 2233{ 2234 .descr = "enum type (invalid name, invalid identifier)", 2235 .raw_types = { 2236 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 2237 BTF_TYPE_ENC(NAME_TBD, 2238 BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 2239 sizeof(int)), /* [2] */ 2240 BTF_ENUM_ENC(NAME_TBD, 0), 2241 BTF_END_RAW, 2242 }, 2243 .str_sec = "\0A!\0B", 2244 .str_sec_size = sizeof("\0A!\0B"), 2245 .map_type = BPF_MAP_TYPE_ARRAY, 2246 .map_name = "enum_type_check_btf", 2247 .key_size = sizeof(int), 2248 .value_size = sizeof(int), 2249 .key_type_id = 1, 2250 .value_type_id = 1, 2251 .max_entries = 4, 2252 .btf_load_err = true, 2253 .err_str = "Invalid name", 2254}, 2255 2256{ 2257 .descr = "enum member (invalid name, name_off = 0)", 2258 .raw_types = { 2259 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 2260 BTF_TYPE_ENC(0, 2261 BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 2262 sizeof(int)), /* [2] */ 2263 BTF_ENUM_ENC(0, 0), 2264 BTF_END_RAW, 2265 }, 2266 .str_sec = "", 2267 .str_sec_size = sizeof(""), 2268 .map_type = BPF_MAP_TYPE_ARRAY, 2269 .map_name = "enum_type_check_btf", 2270 .key_size = sizeof(int), 2271 .value_size = sizeof(int), 2272 .key_type_id = 1, 2273 .value_type_id = 1, 2274 .max_entries = 4, 2275 .btf_load_err = true, 2276 .err_str = "Invalid name", 2277}, 2278 2279{ 2280 .descr = "enum member (invalid name, invalid identifier)", 2281 .raw_types = { 2282 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 2283 BTF_TYPE_ENC(0, 2284 BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 2285 sizeof(int)), /* [2] */ 2286 BTF_ENUM_ENC(NAME_TBD, 0), 2287 BTF_END_RAW, 2288 }, 2289 .str_sec = "\0A!", 2290 .str_sec_size = sizeof("\0A!"), 2291 .map_type = BPF_MAP_TYPE_ARRAY, 2292 .map_name = "enum_type_check_btf", 2293 .key_size = sizeof(int), 2294 .value_size = sizeof(int), 2295 .key_type_id = 1, 2296 .value_type_id = 1, 2297 .max_entries = 4, 2298 .btf_load_err = true, 2299 .err_str = "Invalid name", 2300}, 2301{ 2302 .descr = "arraymap invalid btf key (a bit field)", 2303 .raw_types = { 2304 /* int */ /* [1] */ 2305 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), 2306 /* 32 bit int with 32 bit offset */ /* [2] */ 2307 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 32, 32, 8), 2308 BTF_END_RAW, 2309 }, 2310 .str_sec = "", 2311 .str_sec_size = sizeof(""), 2312 .map_type = BPF_MAP_TYPE_ARRAY, 2313 .map_name = "array_map_check_btf", 2314 .key_size = sizeof(int), 2315 .value_size = sizeof(int), 2316 .key_type_id = 2, 2317 .value_type_id = 1, 2318 .max_entries = 4, 2319 .map_create_err = true, 2320}, 2321 2322{ 2323 .descr = "arraymap invalid btf key (!= 32 bits)", 2324 .raw_types = { 2325 /* int */ /* [1] */ 2326 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), 2327 /* 16 bit int with 0 bit offset */ /* [2] */ 2328 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 16, 2), 2329 BTF_END_RAW, 2330 }, 2331 .str_sec = "", 2332 .str_sec_size = sizeof(""), 2333 .map_type = BPF_MAP_TYPE_ARRAY, 2334 .map_name = "array_map_check_btf", 2335 .key_size = sizeof(int), 2336 .value_size = sizeof(int), 2337 .key_type_id = 2, 2338 .value_type_id = 1, 2339 .max_entries = 4, 2340 .map_create_err = true, 2341}, 2342 2343{ 2344 .descr = "arraymap invalid btf value (too small)", 2345 .raw_types = { 2346 /* int */ /* [1] */ 2347 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), 2348 BTF_END_RAW, 2349 }, 2350 .str_sec = "", 2351 .str_sec_size = sizeof(""), 2352 .map_type = BPF_MAP_TYPE_ARRAY, 2353 .map_name = "array_map_check_btf", 2354 .key_size = sizeof(int), 2355 /* btf_value_size < map->value_size */ 2356 .value_size = sizeof(__u64), 2357 .key_type_id = 1, 2358 .value_type_id = 1, 2359 .max_entries = 4, 2360 .map_create_err = true, 2361}, 2362 2363{ 2364 .descr = "arraymap invalid btf value (too big)", 2365 .raw_types = { 2366 /* int */ /* [1] */ 2367 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), 2368 BTF_END_RAW, 2369 }, 2370 .str_sec = "", 2371 .str_sec_size = sizeof(""), 2372 .map_type = BPF_MAP_TYPE_ARRAY, 2373 .map_name = "array_map_check_btf", 2374 .key_size = sizeof(int), 2375 /* btf_value_size > map->value_size */ 2376 .value_size = sizeof(__u16), 2377 .key_type_id = 1, 2378 .value_type_id = 1, 2379 .max_entries = 4, 2380 .map_create_err = true, 2381}, 2382 2383{ 2384 .descr = "func proto (int (*)(int, unsigned int))", 2385 .raw_types = { 2386 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 2387 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [2] */ 2388 /* int (*)(int, unsigned int) */ 2389 BTF_FUNC_PROTO_ENC(1, 2), /* [3] */ 2390 BTF_FUNC_PROTO_ARG_ENC(0, 1), 2391 BTF_FUNC_PROTO_ARG_ENC(0, 2), 2392 BTF_END_RAW, 2393 }, 2394 .str_sec = "", 2395 .str_sec_size = sizeof(""), 2396 .map_type = BPF_MAP_TYPE_ARRAY, 2397 .map_name = "func_proto_type_check_btf", 2398 .key_size = sizeof(int), 2399 .value_size = sizeof(int), 2400 .key_type_id = 1, 2401 .value_type_id = 1, 2402 .max_entries = 4, 2403}, 2404 2405{ 2406 .descr = "func proto (vararg)", 2407 .raw_types = { 2408 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 2409 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [2] */ 2410 /* void (*)(int, unsigned int, ...) */ 2411 BTF_FUNC_PROTO_ENC(0, 3), /* [3] */ 2412 BTF_FUNC_PROTO_ARG_ENC(0, 1), 2413 BTF_FUNC_PROTO_ARG_ENC(0, 2), 2414 BTF_FUNC_PROTO_ARG_ENC(0, 0), 2415 BTF_END_RAW, 2416 }, 2417 .str_sec = "", 2418 .str_sec_size = sizeof(""), 2419 .map_type = BPF_MAP_TYPE_ARRAY, 2420 .map_name = "func_proto_type_check_btf", 2421 .key_size = sizeof(int), 2422 .value_size = sizeof(int), 2423 .key_type_id = 1, 2424 .value_type_id = 1, 2425 .max_entries = 4, 2426}, 2427 2428{ 2429 .descr = "func proto (vararg with name)", 2430 .raw_types = { 2431 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 2432 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [2] */ 2433 /* void (*)(int a, unsigned int b, ... c) */ 2434 BTF_FUNC_PROTO_ENC(0, 3), /* [3] */ 2435 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1), 2436 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2), 2437 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 0), 2438 BTF_END_RAW, 2439 }, 2440 .str_sec = "\0a\0b\0c", 2441 .str_sec_size = sizeof("\0a\0b\0c"), 2442 .map_type = BPF_MAP_TYPE_ARRAY, 2443 .map_name = "func_proto_type_check_btf", 2444 .key_size = sizeof(int), 2445 .value_size = sizeof(int), 2446 .key_type_id = 1, 2447 .value_type_id = 1, 2448 .max_entries = 4, 2449 .btf_load_err = true, 2450 .err_str = "Invalid arg#3", 2451}, 2452 2453{ 2454 .descr = "func proto (arg after vararg)", 2455 .raw_types = { 2456 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 2457 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [2] */ 2458 /* void (*)(int a, ..., unsigned int b) */ 2459 BTF_FUNC_PROTO_ENC(0, 3), /* [3] */ 2460 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1), 2461 BTF_FUNC_PROTO_ARG_ENC(0, 0), 2462 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2), 2463 BTF_END_RAW, 2464 }, 2465 .str_sec = "\0a\0b", 2466 .str_sec_size = sizeof("\0a\0b"), 2467 .map_type = BPF_MAP_TYPE_ARRAY, 2468 .map_name = "func_proto_type_check_btf", 2469 .key_size = sizeof(int), 2470 .value_size = sizeof(int), 2471 .key_type_id = 1, 2472 .value_type_id = 1, 2473 .max_entries = 4, 2474 .btf_load_err = true, 2475 .err_str = "Invalid arg#2", 2476}, 2477 2478{ 2479 .descr = "func proto (CONST=>TYPEDEF=>PTR=>FUNC_PROTO)", 2480 .raw_types = { 2481 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 2482 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [2] */ 2483 /* typedef void (*func_ptr)(int, unsigned int) */ 2484 BTF_TYPEDEF_ENC(NAME_TBD, 5), /* [3] */ 2485 /* const func_ptr */ 2486 BTF_CONST_ENC(3), /* [4] */ 2487 BTF_PTR_ENC(6), /* [5] */ 2488 BTF_FUNC_PROTO_ENC(0, 2), /* [6] */ 2489 BTF_FUNC_PROTO_ARG_ENC(0, 1), 2490 BTF_FUNC_PROTO_ARG_ENC(0, 2), 2491 BTF_END_RAW, 2492 }, 2493 .str_sec = "\0func_ptr", 2494 .str_sec_size = sizeof("\0func_ptr"), 2495 .map_type = BPF_MAP_TYPE_ARRAY, 2496 .map_name = "func_proto_type_check_btf", 2497 .key_size = sizeof(int), 2498 .value_size = sizeof(int), 2499 .key_type_id = 1, 2500 .value_type_id = 1, 2501 .max_entries = 4, 2502}, 2503 2504{ 2505 .descr = "func proto (TYPEDEF=>FUNC_PROTO)", 2506 .raw_types = { 2507 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 2508 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [2] */ 2509 BTF_TYPEDEF_ENC(NAME_TBD, 4), /* [3] */ 2510 BTF_FUNC_PROTO_ENC(0, 2), /* [4] */ 2511 BTF_FUNC_PROTO_ARG_ENC(0, 1), 2512 BTF_FUNC_PROTO_ARG_ENC(0, 2), 2513 BTF_END_RAW, 2514 }, 2515 .str_sec = "\0func_typedef", 2516 .str_sec_size = sizeof("\0func_typedef"), 2517 .map_type = BPF_MAP_TYPE_ARRAY, 2518 .map_name = "func_proto_type_check_btf", 2519 .key_size = sizeof(int), 2520 .value_size = sizeof(int), 2521 .key_type_id = 1, 2522 .value_type_id = 1, 2523 .max_entries = 4, 2524}, 2525 2526{ 2527 .descr = "func proto (btf_resolve(arg))", 2528 .raw_types = { 2529 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 2530 /* void (*)(const void *) */ 2531 BTF_FUNC_PROTO_ENC(0, 1), /* [2] */ 2532 BTF_FUNC_PROTO_ARG_ENC(0, 3), 2533 BTF_CONST_ENC(4), /* [3] */ 2534 BTF_PTR_ENC(0), /* [4] */ 2535 BTF_END_RAW, 2536 }, 2537 .str_sec = "", 2538 .str_sec_size = sizeof(""), 2539 .map_type = BPF_MAP_TYPE_ARRAY, 2540 .map_name = "func_proto_type_check_btf", 2541 .key_size = sizeof(int), 2542 .value_size = sizeof(int), 2543 .key_type_id = 1, 2544 .value_type_id = 1, 2545 .max_entries = 4, 2546}, 2547 2548{ 2549 .descr = "func proto (Not all arg has name)", 2550 .raw_types = { 2551 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 2552 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [2] */ 2553 /* void (*)(int, unsigned int b) */ 2554 BTF_FUNC_PROTO_ENC(0, 2), /* [3] */ 2555 BTF_FUNC_PROTO_ARG_ENC(0, 1), 2556 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2), 2557 BTF_END_RAW, 2558 }, 2559 .str_sec = "\0b", 2560 .str_sec_size = sizeof("\0b"), 2561 .map_type = BPF_MAP_TYPE_ARRAY, 2562 .map_name = "func_proto_type_check_btf", 2563 .key_size = sizeof(int), 2564 .value_size = sizeof(int), 2565 .key_type_id = 1, 2566 .value_type_id = 1, 2567 .max_entries = 4, 2568}, 2569 2570{ 2571 .descr = "func proto (Bad arg name_off)", 2572 .raw_types = { 2573 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 2574 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [2] */ 2575 /* void (*)(int a, unsigned int <bad_name_off>) */ 2576 BTF_FUNC_PROTO_ENC(0, 2), /* [3] */ 2577 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1), 2578 BTF_FUNC_PROTO_ARG_ENC(0x0fffffff, 2), 2579 BTF_END_RAW, 2580 }, 2581 .str_sec = "\0a", 2582 .str_sec_size = sizeof("\0a"), 2583 .map_type = BPF_MAP_TYPE_ARRAY, 2584 .map_name = "func_proto_type_check_btf", 2585 .key_size = sizeof(int), 2586 .value_size = sizeof(int), 2587 .key_type_id = 1, 2588 .value_type_id = 1, 2589 .max_entries = 4, 2590 .btf_load_err = true, 2591 .err_str = "Invalid arg#2", 2592}, 2593 2594{ 2595 .descr = "func proto (Bad arg name)", 2596 .raw_types = { 2597 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 2598 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [2] */ 2599 /* void (*)(int a, unsigned int !!!) */ 2600 BTF_FUNC_PROTO_ENC(0, 2), /* [3] */ 2601 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1), 2602 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2), 2603 BTF_END_RAW, 2604 }, 2605 .str_sec = "\0a\0!!!", 2606 .str_sec_size = sizeof("\0a\0!!!"), 2607 .map_type = BPF_MAP_TYPE_ARRAY, 2608 .map_name = "func_proto_type_check_btf", 2609 .key_size = sizeof(int), 2610 .value_size = sizeof(int), 2611 .key_type_id = 1, 2612 .value_type_id = 1, 2613 .max_entries = 4, 2614 .btf_load_err = true, 2615 .err_str = "Invalid arg#2", 2616}, 2617 2618{ 2619 .descr = "func proto (Invalid return type)", 2620 .raw_types = { 2621 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 2622 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [2] */ 2623 /* <bad_ret_type> (*)(int, unsigned int) */ 2624 BTF_FUNC_PROTO_ENC(100, 2), /* [3] */ 2625 BTF_FUNC_PROTO_ARG_ENC(0, 1), 2626 BTF_FUNC_PROTO_ARG_ENC(0, 2), 2627 BTF_END_RAW, 2628 }, 2629 .str_sec = "", 2630 .str_sec_size = sizeof(""), 2631 .map_type = BPF_MAP_TYPE_ARRAY, 2632 .map_name = "func_proto_type_check_btf", 2633 .key_size = sizeof(int), 2634 .value_size = sizeof(int), 2635 .key_type_id = 1, 2636 .value_type_id = 1, 2637 .max_entries = 4, 2638 .btf_load_err = true, 2639 .err_str = "Invalid return type", 2640}, 2641 2642{ 2643 .descr = "func proto (with func name)", 2644 .raw_types = { 2645 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 2646 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [2] */ 2647 /* void func_proto(int, unsigned int) */ 2648 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_FUNC_PROTO, 0, 2), 0), /* [3] */ 2649 BTF_FUNC_PROTO_ARG_ENC(0, 1), 2650 BTF_FUNC_PROTO_ARG_ENC(0, 2), 2651 BTF_END_RAW, 2652 }, 2653 .str_sec = "\0func_proto", 2654 .str_sec_size = sizeof("\0func_proto"), 2655 .map_type = BPF_MAP_TYPE_ARRAY, 2656 .map_name = "func_proto_type_check_btf", 2657 .key_size = sizeof(int), 2658 .value_size = sizeof(int), 2659 .key_type_id = 1, 2660 .value_type_id = 1, 2661 .max_entries = 4, 2662 .btf_load_err = true, 2663 .err_str = "Invalid name", 2664}, 2665 2666{ 2667 .descr = "func proto (const void arg)", 2668 .raw_types = { 2669 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 2670 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [2] */ 2671 /* void (*)(const void) */ 2672 BTF_FUNC_PROTO_ENC(0, 1), /* [3] */ 2673 BTF_FUNC_PROTO_ARG_ENC(0, 4), 2674 BTF_CONST_ENC(0), /* [4] */ 2675 BTF_END_RAW, 2676 }, 2677 .str_sec = "", 2678 .str_sec_size = sizeof(""), 2679 .map_type = BPF_MAP_TYPE_ARRAY, 2680 .map_name = "func_proto_type_check_btf", 2681 .key_size = sizeof(int), 2682 .value_size = sizeof(int), 2683 .key_type_id = 1, 2684 .value_type_id = 1, 2685 .max_entries = 4, 2686 .btf_load_err = true, 2687 .err_str = "Invalid arg#1", 2688}, 2689 2690{ 2691 .descr = "func (void func(int a, unsigned int b))", 2692 .raw_types = { 2693 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 2694 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [2] */ 2695 /* void (*)(int a, unsigned int b) */ 2696 BTF_FUNC_PROTO_ENC(0, 2), /* [3] */ 2697 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1), 2698 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2), 2699 /* void func(int a, unsigned int b) */ 2700 BTF_FUNC_ENC(NAME_TBD, 3), /* [4] */ 2701 BTF_END_RAW, 2702 }, 2703 .str_sec = "\0a\0b\0func", 2704 .str_sec_size = sizeof("\0a\0b\0func"), 2705 .map_type = BPF_MAP_TYPE_ARRAY, 2706 .map_name = "func_type_check_btf", 2707 .key_size = sizeof(int), 2708 .value_size = sizeof(int), 2709 .key_type_id = 1, 2710 .value_type_id = 1, 2711 .max_entries = 4, 2712}, 2713 2714{ 2715 .descr = "func (No func name)", 2716 .raw_types = { 2717 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 2718 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [2] */ 2719 /* void (*)(int a, unsigned int b) */ 2720 BTF_FUNC_PROTO_ENC(0, 2), /* [3] */ 2721 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1), 2722 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2), 2723 /* void <no_name>(int a, unsigned int b) */ 2724 BTF_FUNC_ENC(0, 3), /* [4] */ 2725 BTF_END_RAW, 2726 }, 2727 .str_sec = "\0a\0b", 2728 .str_sec_size = sizeof("\0a\0b"), 2729 .map_type = BPF_MAP_TYPE_ARRAY, 2730 .map_name = "func_type_check_btf", 2731 .key_size = sizeof(int), 2732 .value_size = sizeof(int), 2733 .key_type_id = 1, 2734 .value_type_id = 1, 2735 .max_entries = 4, 2736 .btf_load_err = true, 2737 .err_str = "Invalid name", 2738}, 2739 2740{ 2741 .descr = "func (Invalid func name)", 2742 .raw_types = { 2743 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 2744 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [2] */ 2745 /* void (*)(int a, unsigned int b) */ 2746 BTF_FUNC_PROTO_ENC(0, 2), /* [3] */ 2747 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1), 2748 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2), 2749 /* void !!!(int a, unsigned int b) */ 2750 BTF_FUNC_ENC(NAME_TBD, 3), /* [4] */ 2751 BTF_END_RAW, 2752 }, 2753 .str_sec = "\0a\0b\0!!!", 2754 .str_sec_size = sizeof("\0a\0b\0!!!"), 2755 .map_type = BPF_MAP_TYPE_ARRAY, 2756 .map_name = "func_type_check_btf", 2757 .key_size = sizeof(int), 2758 .value_size = sizeof(int), 2759 .key_type_id = 1, 2760 .value_type_id = 1, 2761 .max_entries = 4, 2762 .btf_load_err = true, 2763 .err_str = "Invalid name", 2764}, 2765 2766{ 2767 .descr = "func (Some arg has no name)", 2768 .raw_types = { 2769 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 2770 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [2] */ 2771 /* void (*)(int a, unsigned int) */ 2772 BTF_FUNC_PROTO_ENC(0, 2), /* [3] */ 2773 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1), 2774 BTF_FUNC_PROTO_ARG_ENC(0, 2), 2775 /* void func(int a, unsigned int) */ 2776 BTF_FUNC_ENC(NAME_TBD, 3), /* [4] */ 2777 BTF_END_RAW, 2778 }, 2779 .str_sec = "\0a\0func", 2780 .str_sec_size = sizeof("\0a\0func"), 2781 .map_type = BPF_MAP_TYPE_ARRAY, 2782 .map_name = "func_type_check_btf", 2783 .key_size = sizeof(int), 2784 .value_size = sizeof(int), 2785 .key_type_id = 1, 2786 .value_type_id = 1, 2787 .max_entries = 4, 2788 .btf_load_err = true, 2789 .err_str = "Invalid arg#2", 2790}, 2791 2792{ 2793 .descr = "func (Non zero vlen)", 2794 .raw_types = { 2795 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 2796 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [2] */ 2797 /* void (*)(int a, unsigned int b) */ 2798 BTF_FUNC_PROTO_ENC(0, 2), /* [3] */ 2799 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1), 2800 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2), 2801 /* void func(int a, unsigned int b) */ 2802 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_FUNC, 0, 2), 3), /* [4] */ 2803 BTF_END_RAW, 2804 }, 2805 .str_sec = "\0a\0b\0func", 2806 .str_sec_size = sizeof("\0a\0b\0func"), 2807 .map_type = BPF_MAP_TYPE_ARRAY, 2808 .map_name = "func_type_check_btf", 2809 .key_size = sizeof(int), 2810 .value_size = sizeof(int), 2811 .key_type_id = 1, 2812 .value_type_id = 1, 2813 .max_entries = 4, 2814 .btf_load_err = true, 2815 .err_str = "vlen != 0", 2816}, 2817 2818{ 2819 .descr = "func (Not referring to FUNC_PROTO)", 2820 .raw_types = { 2821 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 2822 BTF_FUNC_ENC(NAME_TBD, 1), /* [2] */ 2823 BTF_END_RAW, 2824 }, 2825 .str_sec = "\0func", 2826 .str_sec_size = sizeof("\0func"), 2827 .map_type = BPF_MAP_TYPE_ARRAY, 2828 .map_name = "func_type_check_btf", 2829 .key_size = sizeof(int), 2830 .value_size = sizeof(int), 2831 .key_type_id = 1, 2832 .value_type_id = 1, 2833 .max_entries = 4, 2834 .btf_load_err = true, 2835 .err_str = "Invalid type_id", 2836}, 2837 2838{ 2839 .descr = "invalid int kind_flag", 2840 .raw_types = { 2841 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 2842 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_INT, 1, 0), 4), /* [2] */ 2843 BTF_INT_ENC(0, 0, 32), 2844 BTF_END_RAW, 2845 }, 2846 BTF_STR_SEC(""), 2847 .map_type = BPF_MAP_TYPE_ARRAY, 2848 .map_name = "int_type_check_btf", 2849 .key_size = sizeof(int), 2850 .value_size = sizeof(int), 2851 .key_type_id = 1, 2852 .value_type_id = 1, 2853 .max_entries = 4, 2854 .btf_load_err = true, 2855 .err_str = "Invalid btf_info kind_flag", 2856}, 2857 2858{ 2859 .descr = "invalid ptr kind_flag", 2860 .raw_types = { 2861 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 2862 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 1, 0), 1), /* [2] */ 2863 BTF_END_RAW, 2864 }, 2865 BTF_STR_SEC(""), 2866 .map_type = BPF_MAP_TYPE_ARRAY, 2867 .map_name = "ptr_type_check_btf", 2868 .key_size = sizeof(int), 2869 .value_size = sizeof(int), 2870 .key_type_id = 1, 2871 .value_type_id = 1, 2872 .max_entries = 4, 2873 .btf_load_err = true, 2874 .err_str = "Invalid btf_info kind_flag", 2875}, 2876 2877{ 2878 .descr = "invalid array kind_flag", 2879 .raw_types = { 2880 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 2881 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ARRAY, 1, 0), 0), /* [2] */ 2882 BTF_ARRAY_ENC(1, 1, 1), 2883 BTF_END_RAW, 2884 }, 2885 BTF_STR_SEC(""), 2886 .map_type = BPF_MAP_TYPE_ARRAY, 2887 .map_name = "array_type_check_btf", 2888 .key_size = sizeof(int), 2889 .value_size = sizeof(int), 2890 .key_type_id = 1, 2891 .value_type_id = 1, 2892 .max_entries = 4, 2893 .btf_load_err = true, 2894 .err_str = "Invalid btf_info kind_flag", 2895}, 2896 2897{ 2898 .descr = "invalid enum kind_flag", 2899 .raw_types = { 2900 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 2901 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 1, 1), 4), /* [2] */ 2902 BTF_ENUM_ENC(NAME_TBD, 0), 2903 BTF_END_RAW, 2904 }, 2905 BTF_STR_SEC("\0A"), 2906 .map_type = BPF_MAP_TYPE_ARRAY, 2907 .map_name = "enum_type_check_btf", 2908 .key_size = sizeof(int), 2909 .value_size = sizeof(int), 2910 .key_type_id = 1, 2911 .value_type_id = 1, 2912 .max_entries = 4, 2913 .btf_load_err = true, 2914 .err_str = "Invalid btf_info kind_flag", 2915}, 2916 2917{ 2918 .descr = "valid fwd kind_flag", 2919 .raw_types = { 2920 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 2921 BTF_TYPE_ENC(NAME_TBD, 2922 BTF_INFO_ENC(BTF_KIND_FWD, 1, 0), 0), /* [2] */ 2923 BTF_END_RAW, 2924 }, 2925 BTF_STR_SEC("\0A"), 2926 .map_type = BPF_MAP_TYPE_ARRAY, 2927 .map_name = "fwd_type_check_btf", 2928 .key_size = sizeof(int), 2929 .value_size = sizeof(int), 2930 .key_type_id = 1, 2931 .value_type_id = 1, 2932 .max_entries = 4, 2933}, 2934 2935{ 2936 .descr = "invalid typedef kind_flag", 2937 .raw_types = { 2938 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 2939 BTF_TYPE_ENC(NAME_TBD, 2940 BTF_INFO_ENC(BTF_KIND_TYPEDEF, 1, 0), 1), /* [2] */ 2941 BTF_END_RAW, 2942 }, 2943 BTF_STR_SEC("\0A"), 2944 .map_type = BPF_MAP_TYPE_ARRAY, 2945 .map_name = "typedef_type_check_btf", 2946 .key_size = sizeof(int), 2947 .value_size = sizeof(int), 2948 .key_type_id = 1, 2949 .value_type_id = 1, 2950 .max_entries = 4, 2951 .btf_load_err = true, 2952 .err_str = "Invalid btf_info kind_flag", 2953}, 2954 2955{ 2956 .descr = "invalid volatile kind_flag", 2957 .raw_types = { 2958 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 2959 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_VOLATILE, 1, 0), 1), /* [2] */ 2960 BTF_END_RAW, 2961 }, 2962 BTF_STR_SEC(""), 2963 .map_type = BPF_MAP_TYPE_ARRAY, 2964 .map_name = "volatile_type_check_btf", 2965 .key_size = sizeof(int), 2966 .value_size = sizeof(int), 2967 .key_type_id = 1, 2968 .value_type_id = 1, 2969 .max_entries = 4, 2970 .btf_load_err = true, 2971 .err_str = "Invalid btf_info kind_flag", 2972}, 2973 2974{ 2975 .descr = "invalid const kind_flag", 2976 .raw_types = { 2977 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 2978 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 1, 0), 1), /* [2] */ 2979 BTF_END_RAW, 2980 }, 2981 BTF_STR_SEC(""), 2982 .map_type = BPF_MAP_TYPE_ARRAY, 2983 .map_name = "const_type_check_btf", 2984 .key_size = sizeof(int), 2985 .value_size = sizeof(int), 2986 .key_type_id = 1, 2987 .value_type_id = 1, 2988 .max_entries = 4, 2989 .btf_load_err = true, 2990 .err_str = "Invalid btf_info kind_flag", 2991}, 2992 2993{ 2994 .descr = "invalid restrict kind_flag", 2995 .raw_types = { 2996 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 2997 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_RESTRICT, 1, 0), 1), /* [2] */ 2998 BTF_END_RAW, 2999 }, 3000 BTF_STR_SEC(""), 3001 .map_type = BPF_MAP_TYPE_ARRAY, 3002 .map_name = "restrict_type_check_btf", 3003 .key_size = sizeof(int), 3004 .value_size = sizeof(int), 3005 .key_type_id = 1, 3006 .value_type_id = 1, 3007 .max_entries = 4, 3008 .btf_load_err = true, 3009 .err_str = "Invalid btf_info kind_flag", 3010}, 3011 3012{ 3013 .descr = "invalid func kind_flag", 3014 .raw_types = { 3015 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 3016 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_FUNC_PROTO, 0, 0), 0), /* [2] */ 3017 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_FUNC, 1, 0), 2), /* [3] */ 3018 BTF_END_RAW, 3019 }, 3020 BTF_STR_SEC("\0A"), 3021 .map_type = BPF_MAP_TYPE_ARRAY, 3022 .map_name = "func_type_check_btf", 3023 .key_size = sizeof(int), 3024 .value_size = sizeof(int), 3025 .key_type_id = 1, 3026 .value_type_id = 1, 3027 .max_entries = 4, 3028 .btf_load_err = true, 3029 .err_str = "Invalid btf_info kind_flag", 3030}, 3031 3032{ 3033 .descr = "invalid func_proto kind_flag", 3034 .raw_types = { 3035 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 3036 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_FUNC_PROTO, 1, 0), 0), /* [2] */ 3037 BTF_END_RAW, 3038 }, 3039 BTF_STR_SEC(""), 3040 .map_type = BPF_MAP_TYPE_ARRAY, 3041 .map_name = "func_proto_type_check_btf", 3042 .key_size = sizeof(int), 3043 .value_size = sizeof(int), 3044 .key_type_id = 1, 3045 .value_type_id = 1, 3046 .max_entries = 4, 3047 .btf_load_err = true, 3048 .err_str = "Invalid btf_info kind_flag", 3049}, 3050 3051{ 3052 .descr = "valid struct, kind_flag, bitfield_size = 0", 3053 .raw_types = { 3054 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 3055 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 8), /* [2] */ 3056 BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(0, 0)), 3057 BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(0, 32)), 3058 BTF_END_RAW, 3059 }, 3060 BTF_STR_SEC("\0A\0B"), 3061 .map_type = BPF_MAP_TYPE_ARRAY, 3062 .map_name = "struct_type_check_btf", 3063 .key_size = sizeof(int), 3064 .value_size = sizeof(int), 3065 .key_type_id = 1, 3066 .value_type_id = 1, 3067 .max_entries = 4, 3068}, 3069 3070{ 3071 .descr = "valid struct, kind_flag, int member, bitfield_size != 0", 3072 .raw_types = { 3073 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 3074 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 4), /* [2] */ 3075 BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(4, 0)), 3076 BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(4, 4)), 3077 BTF_END_RAW, 3078 }, 3079 BTF_STR_SEC("\0A\0B"), 3080 .map_type = BPF_MAP_TYPE_ARRAY, 3081 .map_name = "struct_type_check_btf", 3082 .key_size = sizeof(int), 3083 .value_size = sizeof(int), 3084 .key_type_id = 1, 3085 .value_type_id = 1, 3086 .max_entries = 4, 3087}, 3088 3089{ 3090 .descr = "valid union, kind_flag, int member, bitfield_size != 0", 3091 .raw_types = { 3092 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 3093 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 1, 2), 4), /* [2] */ 3094 BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(4, 0)), 3095 BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(4, 0)), 3096 BTF_END_RAW, 3097 }, 3098 BTF_STR_SEC("\0A\0B"), 3099 .map_type = BPF_MAP_TYPE_ARRAY, 3100 .map_name = "union_type_check_btf", 3101 .key_size = sizeof(int), 3102 .value_size = sizeof(int), 3103 .key_type_id = 1, 3104 .value_type_id = 1, 3105 .max_entries = 4, 3106}, 3107 3108{ 3109 .descr = "valid struct, kind_flag, enum member, bitfield_size != 0", 3110 .raw_types = { 3111 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 3112 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4), /* [2] */ 3113 BTF_ENUM_ENC(NAME_TBD, 0), 3114 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 4),/* [3] */ 3115 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(4, 0)), 3116 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(4, 4)), 3117 BTF_END_RAW, 3118 }, 3119 BTF_STR_SEC("\0A\0B\0C"), 3120 .map_type = BPF_MAP_TYPE_ARRAY, 3121 .map_name = "struct_type_check_btf", 3122 .key_size = sizeof(int), 3123 .value_size = sizeof(int), 3124 .key_type_id = 1, 3125 .value_type_id = 1, 3126 .max_entries = 4, 3127}, 3128 3129{ 3130 .descr = "valid union, kind_flag, enum member, bitfield_size != 0", 3131 .raw_types = { 3132 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 3133 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4), /* [2] */ 3134 BTF_ENUM_ENC(NAME_TBD, 0), 3135 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 1, 2), 4), /* [3] */ 3136 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(4, 0)), 3137 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(4, 0)), 3138 BTF_END_RAW, 3139 }, 3140 BTF_STR_SEC("\0A\0B\0C"), 3141 .map_type = BPF_MAP_TYPE_ARRAY, 3142 .map_name = "union_type_check_btf", 3143 .key_size = sizeof(int), 3144 .value_size = sizeof(int), 3145 .key_type_id = 1, 3146 .value_type_id = 1, 3147 .max_entries = 4, 3148}, 3149 3150{ 3151 .descr = "valid struct, kind_flag, typedef member, bitfield_size != 0", 3152 .raw_types = { 3153 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 3154 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4), /* [2] */ 3155 BTF_ENUM_ENC(NAME_TBD, 0), 3156 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 4),/* [3] */ 3157 BTF_MEMBER_ENC(NAME_TBD, 4, BTF_MEMBER_OFFSET(4, 0)), 3158 BTF_MEMBER_ENC(NAME_TBD, 5, BTF_MEMBER_OFFSET(4, 4)), 3159 BTF_TYPEDEF_ENC(NAME_TBD, 1), /* [4] */ 3160 BTF_TYPEDEF_ENC(NAME_TBD, 2), /* [5] */ 3161 BTF_END_RAW, 3162 }, 3163 BTF_STR_SEC("\0A\0B\0C\0D\0E"), 3164 .map_type = BPF_MAP_TYPE_ARRAY, 3165 .map_name = "struct_type_check_btf", 3166 .key_size = sizeof(int), 3167 .value_size = sizeof(int), 3168 .key_type_id = 1, 3169 .value_type_id = 1, 3170 .max_entries = 4, 3171}, 3172 3173{ 3174 .descr = "valid union, kind_flag, typedef member, bitfield_size != 0", 3175 .raw_types = { 3176 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 3177 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4), /* [2] */ 3178 BTF_ENUM_ENC(NAME_TBD, 0), 3179 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 1, 2), 4), /* [3] */ 3180 BTF_MEMBER_ENC(NAME_TBD, 4, BTF_MEMBER_OFFSET(4, 0)), 3181 BTF_MEMBER_ENC(NAME_TBD, 5, BTF_MEMBER_OFFSET(4, 0)), 3182 BTF_TYPEDEF_ENC(NAME_TBD, 1), /* [4] */ 3183 BTF_TYPEDEF_ENC(NAME_TBD, 2), /* [5] */ 3184 BTF_END_RAW, 3185 }, 3186 BTF_STR_SEC("\0A\0B\0C\0D\0E"), 3187 .map_type = BPF_MAP_TYPE_ARRAY, 3188 .map_name = "union_type_check_btf", 3189 .key_size = sizeof(int), 3190 .value_size = sizeof(int), 3191 .key_type_id = 1, 3192 .value_type_id = 1, 3193 .max_entries = 4, 3194}, 3195 3196{ 3197 .descr = "invalid struct, kind_flag, bitfield_size greater than struct size", 3198 .raw_types = { 3199 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 3200 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 4), /* [2] */ 3201 BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(20, 0)), 3202 BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(20, 20)), 3203 BTF_END_RAW, 3204 }, 3205 BTF_STR_SEC("\0A\0B"), 3206 .map_type = BPF_MAP_TYPE_ARRAY, 3207 .map_name = "struct_type_check_btf", 3208 .key_size = sizeof(int), 3209 .value_size = sizeof(int), 3210 .key_type_id = 1, 3211 .value_type_id = 1, 3212 .max_entries = 4, 3213 .btf_load_err = true, 3214 .err_str = "Member exceeds struct_size", 3215}, 3216 3217{ 3218 .descr = "invalid struct, kind_flag, bitfield base_type int not regular", 3219 .raw_types = { 3220 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 3221 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 20, 4), /* [2] */ 3222 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 4), /* [3] */ 3223 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(20, 0)), 3224 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(20, 20)), 3225 BTF_END_RAW, 3226 }, 3227 BTF_STR_SEC("\0A\0B"), 3228 .map_type = BPF_MAP_TYPE_ARRAY, 3229 .map_name = "struct_type_check_btf", 3230 .key_size = sizeof(int), 3231 .value_size = sizeof(int), 3232 .key_type_id = 1, 3233 .value_type_id = 1, 3234 .max_entries = 4, 3235 .btf_load_err = true, 3236 .err_str = "Invalid member base type", 3237}, 3238 3239{ 3240 .descr = "invalid struct, kind_flag, base_type int not regular", 3241 .raw_types = { 3242 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 3243 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 12, 4), /* [2] */ 3244 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 4), /* [3] */ 3245 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(8, 0)), 3246 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(8, 8)), 3247 BTF_END_RAW, 3248 }, 3249 BTF_STR_SEC("\0A\0B"), 3250 .map_type = BPF_MAP_TYPE_ARRAY, 3251 .map_name = "struct_type_check_btf", 3252 .key_size = sizeof(int), 3253 .value_size = sizeof(int), 3254 .key_type_id = 1, 3255 .value_type_id = 1, 3256 .max_entries = 4, 3257 .btf_load_err = true, 3258 .err_str = "Invalid member base type", 3259}, 3260 3261{ 3262 .descr = "invalid union, kind_flag, bitfield_size greater than struct size", 3263 .raw_types = { 3264 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 3265 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 1, 2), 2), /* [2] */ 3266 BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(8, 0)), 3267 BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(20, 0)), 3268 BTF_END_RAW, 3269 }, 3270 BTF_STR_SEC("\0A\0B"), 3271 .map_type = BPF_MAP_TYPE_ARRAY, 3272 .map_name = "union_type_check_btf", 3273 .key_size = sizeof(int), 3274 .value_size = sizeof(int), 3275 .key_type_id = 1, 3276 .value_type_id = 1, 3277 .max_entries = 4, 3278 .btf_load_err = true, 3279 .err_str = "Member exceeds struct_size", 3280}, 3281 3282{ 3283 .descr = "invalid struct, kind_flag, int member, bitfield_size = 0, wrong byte alignment", 3284 .raw_types = { 3285 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 3286 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [2] */ 3287 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 12), /* [3] */ 3288 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(0, 0)), 3289 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(0, 36)), 3290 BTF_END_RAW, 3291 }, 3292 BTF_STR_SEC("\0A\0B"), 3293 .map_type = BPF_MAP_TYPE_ARRAY, 3294 .map_name = "struct_type_check_btf", 3295 .key_size = sizeof(int), 3296 .value_size = sizeof(int), 3297 .key_type_id = 1, 3298 .value_type_id = 1, 3299 .max_entries = 4, 3300 .btf_load_err = true, 3301 .err_str = "Invalid member offset", 3302}, 3303 3304{ 3305 .descr = "invalid struct, kind_flag, enum member, bitfield_size = 0, wrong byte alignment", 3306 .raw_types = { 3307 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 3308 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [2] */ 3309 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4), /* [2] */ 3310 BTF_ENUM_ENC(NAME_TBD, 0), 3311 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 12), /* [3] */ 3312 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(0, 0)), 3313 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(0, 36)), 3314 BTF_END_RAW, 3315 }, 3316 BTF_STR_SEC("\0A\0B\0C"), 3317 .map_type = BPF_MAP_TYPE_ARRAY, 3318 .map_name = "struct_type_check_btf", 3319 .key_size = sizeof(int), 3320 .value_size = sizeof(int), 3321 .key_type_id = 1, 3322 .value_type_id = 1, 3323 .max_entries = 4, 3324 .btf_load_err = true, 3325 .err_str = "Invalid member offset", 3326}, 3327 3328{ 3329 .descr = "128-bit int", 3330 .raw_types = { 3331 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 3332 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 128, 16), /* [2] */ 3333 BTF_END_RAW, 3334 }, 3335 BTF_STR_SEC("\0A"), 3336 .map_type = BPF_MAP_TYPE_ARRAY, 3337 .map_name = "int_type_check_btf", 3338 .key_size = sizeof(int), 3339 .value_size = sizeof(int), 3340 .key_type_id = 1, 3341 .value_type_id = 1, 3342 .max_entries = 4, 3343}, 3344 3345{ 3346 .descr = "struct, 128-bit int member", 3347 .raw_types = { 3348 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 3349 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 128, 16), /* [2] */ 3350 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), 16), /* [3] */ 3351 BTF_MEMBER_ENC(NAME_TBD, 2, 0), 3352 BTF_END_RAW, 3353 }, 3354 BTF_STR_SEC("\0A"), 3355 .map_type = BPF_MAP_TYPE_ARRAY, 3356 .map_name = "struct_type_check_btf", 3357 .key_size = sizeof(int), 3358 .value_size = sizeof(int), 3359 .key_type_id = 1, 3360 .value_type_id = 1, 3361 .max_entries = 4, 3362}, 3363 3364{ 3365 .descr = "struct, 120-bit int member bitfield", 3366 .raw_types = { 3367 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 3368 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 120, 16), /* [2] */ 3369 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), 16), /* [3] */ 3370 BTF_MEMBER_ENC(NAME_TBD, 2, 0), 3371 BTF_END_RAW, 3372 }, 3373 BTF_STR_SEC("\0A"), 3374 .map_type = BPF_MAP_TYPE_ARRAY, 3375 .map_name = "struct_type_check_btf", 3376 .key_size = sizeof(int), 3377 .value_size = sizeof(int), 3378 .key_type_id = 1, 3379 .value_type_id = 1, 3380 .max_entries = 4, 3381}, 3382 3383{ 3384 .descr = "struct, kind_flag, 128-bit int member", 3385 .raw_types = { 3386 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 3387 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 128, 16), /* [2] */ 3388 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 1), 16), /* [3] */ 3389 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(0, 0)), 3390 BTF_END_RAW, 3391 }, 3392 BTF_STR_SEC("\0A"), 3393 .map_type = BPF_MAP_TYPE_ARRAY, 3394 .map_name = "struct_type_check_btf", 3395 .key_size = sizeof(int), 3396 .value_size = sizeof(int), 3397 .key_type_id = 1, 3398 .value_type_id = 1, 3399 .max_entries = 4, 3400}, 3401 3402{ 3403 .descr = "struct, kind_flag, 120-bit int member bitfield", 3404 .raw_types = { 3405 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 3406 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 128, 16), /* [2] */ 3407 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 1), 16), /* [3] */ 3408 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(120, 0)), 3409 BTF_END_RAW, 3410 }, 3411 BTF_STR_SEC("\0A"), 3412 .map_type = BPF_MAP_TYPE_ARRAY, 3413 .map_name = "struct_type_check_btf", 3414 .key_size = sizeof(int), 3415 .value_size = sizeof(int), 3416 .key_type_id = 1, 3417 .value_type_id = 1, 3418 .max_entries = 4, 3419}, 3420/* 3421 * typedef int arr_t[16]; 3422 * struct s { 3423 * arr_t *a; 3424 * }; 3425 */ 3426{ 3427 .descr = "struct->ptr->typedef->array->int size resolution", 3428 .raw_types = { 3429 BTF_STRUCT_ENC(NAME_TBD, 1, 8), /* [1] */ 3430 BTF_MEMBER_ENC(NAME_TBD, 2, 0), 3431 BTF_PTR_ENC(3), /* [2] */ 3432 BTF_TYPEDEF_ENC(NAME_TBD, 4), /* [3] */ 3433 BTF_TYPE_ARRAY_ENC(5, 5, 16), /* [4] */ 3434 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [5] */ 3435 BTF_END_RAW, 3436 }, 3437 BTF_STR_SEC("\0s\0a\0arr_t"), 3438 .map_type = BPF_MAP_TYPE_ARRAY, 3439 .map_name = "ptr_mod_chain_size_resolve_map", 3440 .key_size = sizeof(int), 3441 .value_size = sizeof(int) * 16, 3442 .key_type_id = 5 /* int */, 3443 .value_type_id = 3 /* arr_t */, 3444 .max_entries = 4, 3445}, 3446/* 3447 * typedef int arr_t[16][8][4]; 3448 * struct s { 3449 * arr_t *a; 3450 * }; 3451 */ 3452{ 3453 .descr = "struct->ptr->typedef->multi-array->int size resolution", 3454 .raw_types = { 3455 BTF_STRUCT_ENC(NAME_TBD, 1, 8), /* [1] */ 3456 BTF_MEMBER_ENC(NAME_TBD, 2, 0), 3457 BTF_PTR_ENC(3), /* [2] */ 3458 BTF_TYPEDEF_ENC(NAME_TBD, 4), /* [3] */ 3459 BTF_TYPE_ARRAY_ENC(5, 7, 16), /* [4] */ 3460 BTF_TYPE_ARRAY_ENC(6, 7, 8), /* [5] */ 3461 BTF_TYPE_ARRAY_ENC(7, 7, 4), /* [6] */ 3462 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [7] */ 3463 BTF_END_RAW, 3464 }, 3465 BTF_STR_SEC("\0s\0a\0arr_t"), 3466 .map_type = BPF_MAP_TYPE_ARRAY, 3467 .map_name = "multi_arr_size_resolve_map", 3468 .key_size = sizeof(int), 3469 .value_size = sizeof(int) * 16 * 8 * 4, 3470 .key_type_id = 7 /* int */, 3471 .value_type_id = 3 /* arr_t */, 3472 .max_entries = 4, 3473}, 3474/* 3475 * typedef int int_t; 3476 * typedef int_t arr3_t[4]; 3477 * typedef arr3_t arr2_t[8]; 3478 * typedef arr2_t arr1_t[16]; 3479 * struct s { 3480 * arr1_t *a; 3481 * }; 3482 */ 3483{ 3484 .descr = "typedef/multi-arr mix size resolution", 3485 .raw_types = { 3486 BTF_STRUCT_ENC(NAME_TBD, 1, 8), /* [1] */ 3487 BTF_MEMBER_ENC(NAME_TBD, 2, 0), 3488 BTF_PTR_ENC(3), /* [2] */ 3489 BTF_TYPEDEF_ENC(NAME_TBD, 4), /* [3] */ 3490 BTF_TYPE_ARRAY_ENC(5, 10, 16), /* [4] */ 3491 BTF_TYPEDEF_ENC(NAME_TBD, 6), /* [5] */ 3492 BTF_TYPE_ARRAY_ENC(7, 10, 8), /* [6] */ 3493 BTF_TYPEDEF_ENC(NAME_TBD, 8), /* [7] */ 3494 BTF_TYPE_ARRAY_ENC(9, 10, 4), /* [8] */ 3495 BTF_TYPEDEF_ENC(NAME_TBD, 10), /* [9] */ 3496 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [10] */ 3497 BTF_END_RAW, 3498 }, 3499 BTF_STR_SEC("\0s\0a\0arr1_t\0arr2_t\0arr3_t\0int_t"), 3500 .map_type = BPF_MAP_TYPE_ARRAY, 3501 .map_name = "typedef_arra_mix_size_resolve_map", 3502 .key_size = sizeof(int), 3503 .value_size = sizeof(int) * 16 * 8 * 4, 3504 .key_type_id = 10 /* int */, 3505 .value_type_id = 3 /* arr_t */, 3506 .max_entries = 4, 3507}, 3508 3509}; /* struct btf_raw_test raw_tests[] */ 3510 3511static const char *get_next_str(const char *start, const char *end) 3512{ 3513 return start < end - 1 ? start + 1 : NULL; 3514} 3515 3516static int get_raw_sec_size(const __u32 *raw_types) 3517{ 3518 int i; 3519 3520 for (i = MAX_NR_RAW_U32 - 1; 3521 i >= 0 && raw_types[i] != BTF_END_RAW; 3522 i--) 3523 ; 3524 3525 return i < 0 ? i : i * sizeof(raw_types[0]); 3526} 3527 3528static void *btf_raw_create(const struct btf_header *hdr, 3529 const __u32 *raw_types, 3530 const char *str, 3531 unsigned int str_sec_size, 3532 unsigned int *btf_size, 3533 const char **ret_next_str) 3534{ 3535 const char *next_str = str, *end_str = str + str_sec_size; 3536 const char **strs_idx = NULL, **tmp_strs_idx; 3537 int strs_cap = 0, strs_cnt = 0, next_str_idx = 0; 3538 unsigned int size_needed, offset; 3539 struct btf_header *ret_hdr; 3540 int i, type_sec_size, err = 0; 3541 uint32_t *ret_types; 3542 void *raw_btf = NULL; 3543 3544 type_sec_size = get_raw_sec_size(raw_types); 3545 if (CHECK(type_sec_size < 0, "Cannot get nr_raw_types")) 3546 return NULL; 3547 3548 size_needed = sizeof(*hdr) + type_sec_size + str_sec_size; 3549 raw_btf = malloc(size_needed); 3550 if (CHECK(!raw_btf, "Cannot allocate memory for raw_btf")) 3551 return NULL; 3552 3553 /* Copy header */ 3554 memcpy(raw_btf, hdr, sizeof(*hdr)); 3555 offset = sizeof(*hdr); 3556 3557 /* Index strings */ 3558 while ((next_str = get_next_str(next_str, end_str))) { 3559 if (strs_cnt == strs_cap) { 3560 strs_cap += max(16, strs_cap / 2); 3561 tmp_strs_idx = realloc(strs_idx, 3562 sizeof(*strs_idx) * strs_cap); 3563 if (CHECK(!tmp_strs_idx, 3564 "Cannot allocate memory for strs_idx")) { 3565 err = -1; 3566 goto done; 3567 } 3568 strs_idx = tmp_strs_idx; 3569 } 3570 strs_idx[strs_cnt++] = next_str; 3571 next_str += strlen(next_str); 3572 } 3573 3574 /* Copy type section */ 3575 ret_types = raw_btf + offset; 3576 for (i = 0; i < type_sec_size / sizeof(raw_types[0]); i++) { 3577 if (raw_types[i] == NAME_TBD) { 3578 if (CHECK(next_str_idx == strs_cnt, 3579 "Error in getting next_str #%d", 3580 next_str_idx)) { 3581 err = -1; 3582 goto done; 3583 } 3584 ret_types[i] = strs_idx[next_str_idx++] - str; 3585 } else if (IS_NAME_NTH(raw_types[i])) { 3586 int idx = GET_NAME_NTH_IDX(raw_types[i]); 3587 3588 if (CHECK(idx <= 0 || idx > strs_cnt, 3589 "Error getting string #%d, strs_cnt:%d", 3590 idx, strs_cnt)) { 3591 err = -1; 3592 goto done; 3593 } 3594 ret_types[i] = strs_idx[idx-1] - str; 3595 } else { 3596 ret_types[i] = raw_types[i]; 3597 } 3598 } 3599 offset += type_sec_size; 3600 3601 /* Copy string section */ 3602 memcpy(raw_btf + offset, str, str_sec_size); 3603 3604 ret_hdr = (struct btf_header *)raw_btf; 3605 ret_hdr->type_len = type_sec_size; 3606 ret_hdr->str_off = type_sec_size; 3607 ret_hdr->str_len = str_sec_size; 3608 3609 *btf_size = size_needed; 3610 if (ret_next_str) 3611 *ret_next_str = 3612 next_str_idx < strs_cnt ? strs_idx[next_str_idx] : NULL; 3613 3614done: 3615 if (err) { 3616 if (raw_btf) 3617 free(raw_btf); 3618 if (strs_idx) 3619 free(strs_idx); 3620 return NULL; 3621 } 3622 return raw_btf; 3623} 3624 3625static int do_test_raw(unsigned int test_num) 3626{ 3627 struct btf_raw_test *test = &raw_tests[test_num - 1]; 3628 struct bpf_create_map_attr create_attr = {}; 3629 int map_fd = -1, btf_fd = -1; 3630 unsigned int raw_btf_size; 3631 struct btf_header *hdr; 3632 void *raw_btf; 3633 int err; 3634 3635 fprintf(stderr, "BTF raw test[%u] (%s): ", test_num, test->descr); 3636 raw_btf = btf_raw_create(&hdr_tmpl, 3637 test->raw_types, 3638 test->str_sec, 3639 test->str_sec_size, 3640 &raw_btf_size, NULL); 3641 3642 if (!raw_btf) 3643 return -1; 3644 3645 hdr = raw_btf; 3646 3647 hdr->hdr_len = (int)hdr->hdr_len + test->hdr_len_delta; 3648 hdr->type_off = (int)hdr->type_off + test->type_off_delta; 3649 hdr->str_off = (int)hdr->str_off + test->str_off_delta; 3650 hdr->str_len = (int)hdr->str_len + test->str_len_delta; 3651 3652 *btf_log_buf = '\0'; 3653 btf_fd = bpf_load_btf(raw_btf, raw_btf_size, 3654 btf_log_buf, BTF_LOG_BUF_SIZE, 3655 args.always_log); 3656 free(raw_btf); 3657 3658 err = ((btf_fd == -1) != test->btf_load_err); 3659 if (CHECK(err, "btf_fd:%d test->btf_load_err:%u", 3660 btf_fd, test->btf_load_err) || 3661 CHECK(test->err_str && !strstr(btf_log_buf, test->err_str), 3662 "expected err_str:%s", test->err_str)) { 3663 err = -1; 3664 goto done; 3665 } 3666 3667 if (err || btf_fd == -1) 3668 goto done; 3669 3670 create_attr.name = test->map_name; 3671 create_attr.map_type = test->map_type; 3672 create_attr.key_size = test->key_size; 3673 create_attr.value_size = test->value_size; 3674 create_attr.max_entries = test->max_entries; 3675 create_attr.btf_fd = btf_fd; 3676 create_attr.btf_key_type_id = test->key_type_id; 3677 create_attr.btf_value_type_id = test->value_type_id; 3678 3679 map_fd = bpf_create_map_xattr(&create_attr); 3680 3681 err = ((map_fd == -1) != test->map_create_err); 3682 CHECK(err, "map_fd:%d test->map_create_err:%u", 3683 map_fd, test->map_create_err); 3684 3685done: 3686 if (!err) 3687 fprintf(stderr, "OK"); 3688 3689 if (*btf_log_buf && (err || args.always_log)) 3690 fprintf(stderr, "\n%s", btf_log_buf); 3691 3692 if (btf_fd != -1) 3693 close(btf_fd); 3694 if (map_fd != -1) 3695 close(map_fd); 3696 3697 return err; 3698} 3699 3700static int test_raw(void) 3701{ 3702 unsigned int i; 3703 int err = 0; 3704 3705 if (args.raw_test_num) 3706 return count_result(do_test_raw(args.raw_test_num)); 3707 3708 for (i = 1; i <= ARRAY_SIZE(raw_tests); i++) 3709 err |= count_result(do_test_raw(i)); 3710 3711 return err; 3712} 3713 3714struct btf_get_info_test { 3715 const char *descr; 3716 const char *str_sec; 3717 __u32 raw_types[MAX_NR_RAW_U32]; 3718 __u32 str_sec_size; 3719 int btf_size_delta; 3720 int (*special_test)(unsigned int test_num); 3721}; 3722 3723static int test_big_btf_info(unsigned int test_num); 3724static int test_btf_id(unsigned int test_num); 3725 3726const struct btf_get_info_test get_info_tests[] = { 3727{ 3728 .descr = "== raw_btf_size+1", 3729 .raw_types = { 3730 /* int */ /* [1] */ 3731 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), 3732 BTF_END_RAW, 3733 }, 3734 .str_sec = "", 3735 .str_sec_size = sizeof(""), 3736 .btf_size_delta = 1, 3737}, 3738{ 3739 .descr = "== raw_btf_size-3", 3740 .raw_types = { 3741 /* int */ /* [1] */ 3742 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), 3743 BTF_END_RAW, 3744 }, 3745 .str_sec = "", 3746 .str_sec_size = sizeof(""), 3747 .btf_size_delta = -3, 3748}, 3749{ 3750 .descr = "Large bpf_btf_info", 3751 .raw_types = { 3752 /* int */ /* [1] */ 3753 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), 3754 BTF_END_RAW, 3755 }, 3756 .str_sec = "", 3757 .str_sec_size = sizeof(""), 3758 .special_test = test_big_btf_info, 3759}, 3760{ 3761 .descr = "BTF ID", 3762 .raw_types = { 3763 /* int */ /* [1] */ 3764 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), 3765 /* unsigned int */ /* [2] */ 3766 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), 3767 BTF_END_RAW, 3768 }, 3769 .str_sec = "", 3770 .str_sec_size = sizeof(""), 3771 .special_test = test_btf_id, 3772}, 3773}; 3774 3775static inline __u64 ptr_to_u64(const void *ptr) 3776{ 3777 return (__u64)(unsigned long)ptr; 3778} 3779 3780static int test_big_btf_info(unsigned int test_num) 3781{ 3782 const struct btf_get_info_test *test = &get_info_tests[test_num - 1]; 3783 uint8_t *raw_btf = NULL, *user_btf = NULL; 3784 unsigned int raw_btf_size; 3785 struct { 3786 struct bpf_btf_info info; 3787 uint64_t garbage; 3788 } info_garbage; 3789 struct bpf_btf_info *info; 3790 int btf_fd = -1, err; 3791 uint32_t info_len; 3792 3793 raw_btf = btf_raw_create(&hdr_tmpl, 3794 test->raw_types, 3795 test->str_sec, 3796 test->str_sec_size, 3797 &raw_btf_size, NULL); 3798 3799 if (!raw_btf) 3800 return -1; 3801 3802 *btf_log_buf = '\0'; 3803 3804 user_btf = malloc(raw_btf_size); 3805 if (CHECK(!user_btf, "!user_btf")) { 3806 err = -1; 3807 goto done; 3808 } 3809 3810 btf_fd = bpf_load_btf(raw_btf, raw_btf_size, 3811 btf_log_buf, BTF_LOG_BUF_SIZE, 3812 args.always_log); 3813 if (CHECK(btf_fd == -1, "errno:%d", errno)) { 3814 err = -1; 3815 goto done; 3816 } 3817 3818 /* 3819 * GET_INFO should error out if the userspace info 3820 * has non zero tailing bytes. 3821 */ 3822 info = &info_garbage.info; 3823 memset(info, 0, sizeof(*info)); 3824 info_garbage.garbage = 0xdeadbeef; 3825 info_len = sizeof(info_garbage); 3826 info->btf = ptr_to_u64(user_btf); 3827 info->btf_size = raw_btf_size; 3828 3829 err = bpf_obj_get_info_by_fd(btf_fd, info, &info_len); 3830 if (CHECK(!err, "!err")) { 3831 err = -1; 3832 goto done; 3833 } 3834 3835 /* 3836 * GET_INFO should succeed even info_len is larger than 3837 * the kernel supported as long as tailing bytes are zero. 3838 * The kernel supported info len should also be returned 3839 * to userspace. 3840 */ 3841 info_garbage.garbage = 0; 3842 err = bpf_obj_get_info_by_fd(btf_fd, info, &info_len); 3843 if (CHECK(err || info_len != sizeof(*info), 3844 "err:%d errno:%d info_len:%u sizeof(*info):%lu", 3845 err, errno, info_len, sizeof(*info))) { 3846 err = -1; 3847 goto done; 3848 } 3849 3850 fprintf(stderr, "OK"); 3851 3852done: 3853 if (*btf_log_buf && (err || args.always_log)) 3854 fprintf(stderr, "\n%s", btf_log_buf); 3855 3856 free(raw_btf); 3857 free(user_btf); 3858 3859 if (btf_fd != -1) 3860 close(btf_fd); 3861 3862 return err; 3863} 3864 3865static int test_btf_id(unsigned int test_num) 3866{ 3867 const struct btf_get_info_test *test = &get_info_tests[test_num - 1]; 3868 struct bpf_create_map_attr create_attr = {}; 3869 uint8_t *raw_btf = NULL, *user_btf[2] = {}; 3870 int btf_fd[2] = {-1, -1}, map_fd = -1; 3871 struct bpf_map_info map_info = {}; 3872 struct bpf_btf_info info[2] = {}; 3873 unsigned int raw_btf_size; 3874 uint32_t info_len; 3875 int err, i, ret; 3876 3877 raw_btf = btf_raw_create(&hdr_tmpl, 3878 test->raw_types, 3879 test->str_sec, 3880 test->str_sec_size, 3881 &raw_btf_size, NULL); 3882 3883 if (!raw_btf) 3884 return -1; 3885 3886 *btf_log_buf = '\0'; 3887 3888 for (i = 0; i < 2; i++) { 3889 user_btf[i] = malloc(raw_btf_size); 3890 if (CHECK(!user_btf[i], "!user_btf[%d]", i)) { 3891 err = -1; 3892 goto done; 3893 } 3894 info[i].btf = ptr_to_u64(user_btf[i]); 3895 info[i].btf_size = raw_btf_size; 3896 } 3897 3898 btf_fd[0] = bpf_load_btf(raw_btf, raw_btf_size, 3899 btf_log_buf, BTF_LOG_BUF_SIZE, 3900 args.always_log); 3901 if (CHECK(btf_fd[0] == -1, "errno:%d", errno)) { 3902 err = -1; 3903 goto done; 3904 } 3905 3906 /* Test BPF_OBJ_GET_INFO_BY_ID on btf_id */ 3907 info_len = sizeof(info[0]); 3908 err = bpf_obj_get_info_by_fd(btf_fd[0], &info[0], &info_len); 3909 if (CHECK(err, "errno:%d", errno)) { 3910 err = -1; 3911 goto done; 3912 } 3913 3914 btf_fd[1] = bpf_btf_get_fd_by_id(info[0].id); 3915 if (CHECK(btf_fd[1] == -1, "errno:%d", errno)) { 3916 err = -1; 3917 goto done; 3918 } 3919 3920 ret = 0; 3921 err = bpf_obj_get_info_by_fd(btf_fd[1], &info[1], &info_len); 3922 if (CHECK(err || info[0].id != info[1].id || 3923 info[0].btf_size != info[1].btf_size || 3924 (ret = memcmp(user_btf[0], user_btf[1], info[0].btf_size)), 3925 "err:%d errno:%d id0:%u id1:%u btf_size0:%u btf_size1:%u memcmp:%d", 3926 err, errno, info[0].id, info[1].id, 3927 info[0].btf_size, info[1].btf_size, ret)) { 3928 err = -1; 3929 goto done; 3930 } 3931 3932 /* Test btf members in struct bpf_map_info */ 3933 create_attr.name = "test_btf_id"; 3934 create_attr.map_type = BPF_MAP_TYPE_ARRAY; 3935 create_attr.key_size = sizeof(int); 3936 create_attr.value_size = sizeof(unsigned int); 3937 create_attr.max_entries = 4; 3938 create_attr.btf_fd = btf_fd[0]; 3939 create_attr.btf_key_type_id = 1; 3940 create_attr.btf_value_type_id = 2; 3941 3942 map_fd = bpf_create_map_xattr(&create_attr); 3943 if (CHECK(map_fd == -1, "errno:%d", errno)) { 3944 err = -1; 3945 goto done; 3946 } 3947 3948 info_len = sizeof(map_info); 3949 err = bpf_obj_get_info_by_fd(map_fd, &map_info, &info_len); 3950 if (CHECK(err || map_info.btf_id != info[0].id || 3951 map_info.btf_key_type_id != 1 || map_info.btf_value_type_id != 2, 3952 "err:%d errno:%d info.id:%u btf_id:%u btf_key_type_id:%u btf_value_type_id:%u", 3953 err, errno, info[0].id, map_info.btf_id, map_info.btf_key_type_id, 3954 map_info.btf_value_type_id)) { 3955 err = -1; 3956 goto done; 3957 } 3958 3959 for (i = 0; i < 2; i++) { 3960 close(btf_fd[i]); 3961 btf_fd[i] = -1; 3962 } 3963 3964 /* Test BTF ID is removed from the kernel */ 3965 btf_fd[0] = bpf_btf_get_fd_by_id(map_info.btf_id); 3966 if (CHECK(btf_fd[0] == -1, "errno:%d", errno)) { 3967 err = -1; 3968 goto done; 3969 } 3970 close(btf_fd[0]); 3971 btf_fd[0] = -1; 3972 3973 /* The map holds the last ref to BTF and its btf_id */ 3974 close(map_fd); 3975 map_fd = -1; 3976 btf_fd[0] = bpf_btf_get_fd_by_id(map_info.btf_id); 3977 if (CHECK(btf_fd[0] != -1, "BTF lingers")) { 3978 err = -1; 3979 goto done; 3980 } 3981 3982 fprintf(stderr, "OK"); 3983 3984done: 3985 if (*btf_log_buf && (err || args.always_log)) 3986 fprintf(stderr, "\n%s", btf_log_buf); 3987 3988 free(raw_btf); 3989 if (map_fd != -1) 3990 close(map_fd); 3991 for (i = 0; i < 2; i++) { 3992 free(user_btf[i]); 3993 if (btf_fd[i] != -1) 3994 close(btf_fd[i]); 3995 } 3996 3997 return err; 3998} 3999 4000static int do_test_get_info(unsigned int test_num) 4001{ 4002 const struct btf_get_info_test *test = &get_info_tests[test_num - 1]; 4003 unsigned int raw_btf_size, user_btf_size, expected_nbytes; 4004 uint8_t *raw_btf = NULL, *user_btf = NULL; 4005 struct bpf_btf_info info = {}; 4006 int btf_fd = -1, err, ret; 4007 uint32_t info_len; 4008 4009 fprintf(stderr, "BTF GET_INFO test[%u] (%s): ", 4010 test_num, test->descr); 4011 4012 if (test->special_test) 4013 return test->special_test(test_num); 4014 4015 raw_btf = btf_raw_create(&hdr_tmpl, 4016 test->raw_types, 4017 test->str_sec, 4018 test->str_sec_size, 4019 &raw_btf_size, NULL); 4020 4021 if (!raw_btf) 4022 return -1; 4023 4024 *btf_log_buf = '\0'; 4025 4026 user_btf = malloc(raw_btf_size); 4027 if (CHECK(!user_btf, "!user_btf")) { 4028 err = -1; 4029 goto done; 4030 } 4031 4032 btf_fd = bpf_load_btf(raw_btf, raw_btf_size, 4033 btf_log_buf, BTF_LOG_BUF_SIZE, 4034 args.always_log); 4035 if (CHECK(btf_fd == -1, "errno:%d", errno)) { 4036 err = -1; 4037 goto done; 4038 } 4039 4040 user_btf_size = (int)raw_btf_size + test->btf_size_delta; 4041 expected_nbytes = min(raw_btf_size, user_btf_size); 4042 if (raw_btf_size > expected_nbytes) 4043 memset(user_btf + expected_nbytes, 0xff, 4044 raw_btf_size - expected_nbytes); 4045 4046 info_len = sizeof(info); 4047 info.btf = ptr_to_u64(user_btf); 4048 info.btf_size = user_btf_size; 4049 4050 ret = 0; 4051 err = bpf_obj_get_info_by_fd(btf_fd, &info, &info_len); 4052 if (CHECK(err || !info.id || info_len != sizeof(info) || 4053 info.btf_size != raw_btf_size || 4054 (ret = memcmp(raw_btf, user_btf, expected_nbytes)), 4055 "err:%d errno:%d info.id:%u info_len:%u sizeof(info):%lu raw_btf_size:%u info.btf_size:%u expected_nbytes:%u memcmp:%d", 4056 err, errno, info.id, info_len, sizeof(info), 4057 raw_btf_size, info.btf_size, expected_nbytes, ret)) { 4058 err = -1; 4059 goto done; 4060 } 4061 4062 while (expected_nbytes < raw_btf_size) { 4063 fprintf(stderr, "%u...", expected_nbytes); 4064 if (CHECK(user_btf[expected_nbytes++] != 0xff, 4065 "user_btf[%u]:%x != 0xff", expected_nbytes - 1, 4066 user_btf[expected_nbytes - 1])) { 4067 err = -1; 4068 goto done; 4069 } 4070 } 4071 4072 fprintf(stderr, "OK"); 4073 4074done: 4075 if (*btf_log_buf && (err || args.always_log)) 4076 fprintf(stderr, "\n%s", btf_log_buf); 4077 4078 free(raw_btf); 4079 free(user_btf); 4080 4081 if (btf_fd != -1) 4082 close(btf_fd); 4083 4084 return err; 4085} 4086 4087static int test_get_info(void) 4088{ 4089 unsigned int i; 4090 int err = 0; 4091 4092 if (args.get_info_test_num) 4093 return count_result(do_test_get_info(args.get_info_test_num)); 4094 4095 for (i = 1; i <= ARRAY_SIZE(get_info_tests); i++) 4096 err |= count_result(do_test_get_info(i)); 4097 4098 return err; 4099} 4100 4101struct btf_file_test { 4102 const char *file; 4103 bool btf_kv_notfound; 4104}; 4105 4106static struct btf_file_test file_tests[] = { 4107 { .file = "test_btf_haskv.o", }, 4108 { .file = "test_btf_newkv.o", }, 4109 { .file = "test_btf_nokv.o", .btf_kv_notfound = true, }, 4110}; 4111 4112static int do_test_file(unsigned int test_num) 4113{ 4114 const struct btf_file_test *test = &file_tests[test_num - 1]; 4115 const char *expected_fnames[] = {"_dummy_tracepoint", 4116 "test_long_fname_1", 4117 "test_long_fname_2"}; 4118 struct btf_ext *btf_ext = NULL; 4119 struct bpf_prog_info info = {}; 4120 struct bpf_object *obj = NULL; 4121 struct bpf_func_info *finfo; 4122 struct bpf_program *prog; 4123 __u32 info_len, rec_size; 4124 bool has_btf_ext = false; 4125 struct btf *btf = NULL; 4126 void *func_info = NULL; 4127 struct bpf_map *map; 4128 int i, err, prog_fd; 4129 4130 fprintf(stderr, "BTF libbpf test[%u] (%s): ", test_num, 4131 test->file); 4132 4133 btf = btf__parse_elf(test->file, &btf_ext); 4134 if (IS_ERR(btf)) { 4135 if (PTR_ERR(btf) == -ENOENT) { 4136 fprintf(stderr, "SKIP. No ELF %s found", BTF_ELF_SEC); 4137 skip_cnt++; 4138 return 0; 4139 } 4140 return PTR_ERR(btf); 4141 } 4142 btf__free(btf); 4143 4144 has_btf_ext = btf_ext != NULL; 4145 btf_ext__free(btf_ext); 4146 4147 obj = bpf_object__open(test->file); 4148 if (CHECK(IS_ERR(obj), "obj: %ld", PTR_ERR(obj))) 4149 return PTR_ERR(obj); 4150 4151 prog = bpf_program__next(NULL, obj); 4152 if (CHECK(!prog, "Cannot find bpf_prog")) { 4153 err = -1; 4154 goto done; 4155 } 4156 4157 bpf_program__set_type(prog, BPF_PROG_TYPE_TRACEPOINT); 4158 err = bpf_object__load(obj); 4159 if (CHECK(err < 0, "bpf_object__load: %d", err)) 4160 goto done; 4161 prog_fd = bpf_program__fd(prog); 4162 4163 map = bpf_object__find_map_by_name(obj, "btf_map"); 4164 if (CHECK(!map, "btf_map not found")) { 4165 err = -1; 4166 goto done; 4167 } 4168 4169 err = (bpf_map__btf_key_type_id(map) == 0 || bpf_map__btf_value_type_id(map) == 0) 4170 != test->btf_kv_notfound; 4171 if (CHECK(err, "btf_key_type_id:%u btf_value_type_id:%u test->btf_kv_notfound:%u", 4172 bpf_map__btf_key_type_id(map), bpf_map__btf_value_type_id(map), 4173 test->btf_kv_notfound)) 4174 goto done; 4175 4176 if (!has_btf_ext) 4177 goto skip; 4178 4179 /* get necessary program info */ 4180 info_len = sizeof(struct bpf_prog_info); 4181 err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len); 4182 4183 if (CHECK(err == -1, "invalid get info (1st) errno:%d", errno)) { 4184 fprintf(stderr, "%s\n", btf_log_buf); 4185 err = -1; 4186 goto done; 4187 } 4188 if (CHECK(info.nr_func_info != 3, 4189 "incorrect info.nr_func_info (1st) %d", 4190 info.nr_func_info)) { 4191 err = -1; 4192 goto done; 4193 } 4194 rec_size = info.func_info_rec_size; 4195 if (CHECK(rec_size != sizeof(struct bpf_func_info), 4196 "incorrect info.func_info_rec_size (1st) %d\n", rec_size)) { 4197 err = -1; 4198 goto done; 4199 } 4200 4201 func_info = malloc(info.nr_func_info * rec_size); 4202 if (CHECK(!func_info, "out of memory")) { 4203 err = -1; 4204 goto done; 4205 } 4206 4207 /* reset info to only retrieve func_info related data */ 4208 memset(&info, 0, sizeof(info)); 4209 info.nr_func_info = 3; 4210 info.func_info_rec_size = rec_size; 4211 info.func_info = ptr_to_u64(func_info); 4212 4213 err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len); 4214 4215 if (CHECK(err == -1, "invalid get info (2nd) errno:%d", errno)) { 4216 fprintf(stderr, "%s\n", btf_log_buf); 4217 err = -1; 4218 goto done; 4219 } 4220 if (CHECK(info.nr_func_info != 3, 4221 "incorrect info.nr_func_info (2nd) %d", 4222 info.nr_func_info)) { 4223 err = -1; 4224 goto done; 4225 } 4226 if (CHECK(info.func_info_rec_size != rec_size, 4227 "incorrect info.func_info_rec_size (2nd) %d", 4228 info.func_info_rec_size)) { 4229 err = -1; 4230 goto done; 4231 } 4232 4233 err = btf__get_from_id(info.btf_id, &btf); 4234 if (CHECK(err, "cannot get btf from kernel, err: %d", err)) 4235 goto done; 4236 4237 /* check three functions */ 4238 finfo = func_info; 4239 for (i = 0; i < 3; i++) { 4240 const struct btf_type *t; 4241 const char *fname; 4242 4243 t = btf__type_by_id(btf, finfo->type_id); 4244 if (CHECK(!t, "btf__type_by_id failure: id %u", 4245 finfo->type_id)) { 4246 err = -1; 4247 goto done; 4248 } 4249 4250 fname = btf__name_by_offset(btf, t->name_off); 4251 err = strcmp(fname, expected_fnames[i]); 4252 /* for the second and third functions in .text section, 4253 * the compiler may order them either way. 4254 */ 4255 if (i && err) 4256 err = strcmp(fname, expected_fnames[3 - i]); 4257 if (CHECK(err, "incorrect fname %s", fname ? : "")) { 4258 err = -1; 4259 goto done; 4260 } 4261 4262 finfo = (void *)finfo + rec_size; 4263 } 4264 4265skip: 4266 fprintf(stderr, "OK"); 4267 4268done: 4269 free(func_info); 4270 bpf_object__close(obj); 4271 return err; 4272} 4273 4274static int test_file(void) 4275{ 4276 unsigned int i; 4277 int err = 0; 4278 4279 if (args.file_test_num) 4280 return count_result(do_test_file(args.file_test_num)); 4281 4282 for (i = 1; i <= ARRAY_SIZE(file_tests); i++) 4283 err |= count_result(do_test_file(i)); 4284 4285 return err; 4286} 4287 4288const char *pprint_enum_str[] = { 4289 "ENUM_ZERO", 4290 "ENUM_ONE", 4291 "ENUM_TWO", 4292 "ENUM_THREE", 4293}; 4294 4295struct pprint_mapv { 4296 uint32_t ui32; 4297 uint16_t ui16; 4298 /* 2 bytes hole */ 4299 int32_t si32; 4300 uint32_t unused_bits2a:2, 4301 bits28:28, 4302 unused_bits2b:2; 4303 union { 4304 uint64_t ui64; 4305 uint8_t ui8a[8]; 4306 }; 4307 enum { 4308 ENUM_ZERO, 4309 ENUM_ONE, 4310 ENUM_TWO, 4311 ENUM_THREE, 4312 } aenum; 4313 uint32_t ui32b; 4314 uint32_t bits2c:2; 4315 uint8_t si8_4[2][2]; 4316}; 4317 4318#ifdef __SIZEOF_INT128__ 4319struct pprint_mapv_int128 { 4320 __int128 si128a; 4321 __int128 si128b; 4322 unsigned __int128 bits3:3; 4323 unsigned __int128 bits80:80; 4324 unsigned __int128 ui128; 4325}; 4326#endif 4327 4328static struct btf_raw_test pprint_test_template[] = { 4329{ 4330 .raw_types = { 4331 /* unsighed char */ /* [1] */ 4332 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 8, 1), 4333 /* unsigned short */ /* [2] */ 4334 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 16, 2), 4335 /* unsigned int */ /* [3] */ 4336 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4), 4337 /* int */ /* [4] */ 4338 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), 4339 /* unsigned long long */ /* [5] */ 4340 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 64, 8), 4341 /* 2 bits */ /* [6] */ 4342 BTF_TYPE_INT_ENC(0, 0, 0, 2, 2), 4343 /* 28 bits */ /* [7] */ 4344 BTF_TYPE_INT_ENC(0, 0, 0, 28, 4), 4345 /* uint8_t[8] */ /* [8] */ 4346 BTF_TYPE_ARRAY_ENC(9, 1, 8), 4347 /* typedef unsigned char uint8_t */ /* [9] */ 4348 BTF_TYPEDEF_ENC(NAME_TBD, 1), 4349 /* typedef unsigned short uint16_t */ /* [10] */ 4350 BTF_TYPEDEF_ENC(NAME_TBD, 2), 4351 /* typedef unsigned int uint32_t */ /* [11] */ 4352 BTF_TYPEDEF_ENC(NAME_TBD, 3), 4353 /* typedef int int32_t */ /* [12] */ 4354 BTF_TYPEDEF_ENC(NAME_TBD, 4), 4355 /* typedef unsigned long long uint64_t *//* [13] */ 4356 BTF_TYPEDEF_ENC(NAME_TBD, 5), 4357 /* union (anon) */ /* [14] */ 4358 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 0, 2), 8), 4359 BTF_MEMBER_ENC(NAME_TBD, 13, 0),/* uint64_t ui64; */ 4360 BTF_MEMBER_ENC(NAME_TBD, 8, 0), /* uint8_t ui8a[8]; */ 4361 /* enum (anon) */ /* [15] */ 4362 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 4), 4), 4363 BTF_ENUM_ENC(NAME_TBD, 0), 4364 BTF_ENUM_ENC(NAME_TBD, 1), 4365 BTF_ENUM_ENC(NAME_TBD, 2), 4366 BTF_ENUM_ENC(NAME_TBD, 3), 4367 /* struct pprint_mapv */ /* [16] */ 4368 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 11), 40), 4369 BTF_MEMBER_ENC(NAME_TBD, 11, 0), /* uint32_t ui32 */ 4370 BTF_MEMBER_ENC(NAME_TBD, 10, 32), /* uint16_t ui16 */ 4371 BTF_MEMBER_ENC(NAME_TBD, 12, 64), /* int32_t si32 */ 4372 BTF_MEMBER_ENC(NAME_TBD, 6, 96), /* unused_bits2a */ 4373 BTF_MEMBER_ENC(NAME_TBD, 7, 98), /* bits28 */ 4374 BTF_MEMBER_ENC(NAME_TBD, 6, 126), /* unused_bits2b */ 4375 BTF_MEMBER_ENC(0, 14, 128), /* union (anon) */ 4376 BTF_MEMBER_ENC(NAME_TBD, 15, 192), /* aenum */ 4377 BTF_MEMBER_ENC(NAME_TBD, 11, 224), /* uint32_t ui32b */ 4378 BTF_MEMBER_ENC(NAME_TBD, 6, 256), /* bits2c */ 4379 BTF_MEMBER_ENC(NAME_TBD, 17, 264), /* si8_4 */ 4380 BTF_TYPE_ARRAY_ENC(18, 1, 2), /* [17] */ 4381 BTF_TYPE_ARRAY_ENC(1, 1, 2), /* [18] */ 4382 BTF_END_RAW, 4383 }, 4384 BTF_STR_SEC("\0unsigned char\0unsigned short\0unsigned int\0int\0unsigned long long\0uint8_t\0uint16_t\0uint32_t\0int32_t\0uint64_t\0ui64\0ui8a\0ENUM_ZERO\0ENUM_ONE\0ENUM_TWO\0ENUM_THREE\0pprint_mapv\0ui32\0ui16\0si32\0unused_bits2a\0bits28\0unused_bits2b\0aenum\0ui32b\0bits2c\0si8_4"), 4385 .key_size = sizeof(unsigned int), 4386 .value_size = sizeof(struct pprint_mapv), 4387 .key_type_id = 3, /* unsigned int */ 4388 .value_type_id = 16, /* struct pprint_mapv */ 4389 .max_entries = 128 * 1024, 4390}, 4391 4392{ 4393 /* this type will have the same type as the 4394 * first .raw_types definition, but struct type will 4395 * be encoded with kind_flag set. 4396 */ 4397 .raw_types = { 4398 /* unsighed char */ /* [1] */ 4399 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 8, 1), 4400 /* unsigned short */ /* [2] */ 4401 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 16, 2), 4402 /* unsigned int */ /* [3] */ 4403 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4), 4404 /* int */ /* [4] */ 4405 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), 4406 /* unsigned long long */ /* [5] */ 4407 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 64, 8), 4408 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [6] */ 4409 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [7] */ 4410 /* uint8_t[8] */ /* [8] */ 4411 BTF_TYPE_ARRAY_ENC(9, 1, 8), 4412 /* typedef unsigned char uint8_t */ /* [9] */ 4413 BTF_TYPEDEF_ENC(NAME_TBD, 1), 4414 /* typedef unsigned short uint16_t */ /* [10] */ 4415 BTF_TYPEDEF_ENC(NAME_TBD, 2), 4416 /* typedef unsigned int uint32_t */ /* [11] */ 4417 BTF_TYPEDEF_ENC(NAME_TBD, 3), 4418 /* typedef int int32_t */ /* [12] */ 4419 BTF_TYPEDEF_ENC(NAME_TBD, 4), 4420 /* typedef unsigned long long uint64_t *//* [13] */ 4421 BTF_TYPEDEF_ENC(NAME_TBD, 5), 4422 /* union (anon) */ /* [14] */ 4423 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 0, 2), 8), 4424 BTF_MEMBER_ENC(NAME_TBD, 13, 0),/* uint64_t ui64; */ 4425 BTF_MEMBER_ENC(NAME_TBD, 8, 0), /* uint8_t ui8a[8]; */ 4426 /* enum (anon) */ /* [15] */ 4427 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 4), 4), 4428 BTF_ENUM_ENC(NAME_TBD, 0), 4429 BTF_ENUM_ENC(NAME_TBD, 1), 4430 BTF_ENUM_ENC(NAME_TBD, 2), 4431 BTF_ENUM_ENC(NAME_TBD, 3), 4432 /* struct pprint_mapv */ /* [16] */ 4433 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 11), 40), 4434 BTF_MEMBER_ENC(NAME_TBD, 11, BTF_MEMBER_OFFSET(0, 0)), /* uint32_t ui32 */ 4435 BTF_MEMBER_ENC(NAME_TBD, 10, BTF_MEMBER_OFFSET(0, 32)), /* uint16_t ui16 */ 4436 BTF_MEMBER_ENC(NAME_TBD, 12, BTF_MEMBER_OFFSET(0, 64)), /* int32_t si32 */ 4437 BTF_MEMBER_ENC(NAME_TBD, 6, BTF_MEMBER_OFFSET(2, 96)), /* unused_bits2a */ 4438 BTF_MEMBER_ENC(NAME_TBD, 7, BTF_MEMBER_OFFSET(28, 98)), /* bits28 */ 4439 BTF_MEMBER_ENC(NAME_TBD, 6, BTF_MEMBER_OFFSET(2, 126)), /* unused_bits2b */ 4440 BTF_MEMBER_ENC(0, 14, BTF_MEMBER_OFFSET(0, 128)), /* union (anon) */ 4441 BTF_MEMBER_ENC(NAME_TBD, 15, BTF_MEMBER_OFFSET(0, 192)), /* aenum */ 4442 BTF_MEMBER_ENC(NAME_TBD, 11, BTF_MEMBER_OFFSET(0, 224)), /* uint32_t ui32b */ 4443 BTF_MEMBER_ENC(NAME_TBD, 6, BTF_MEMBER_OFFSET(2, 256)), /* bits2c */ 4444 BTF_MEMBER_ENC(NAME_TBD, 17, 264), /* si8_4 */ 4445 BTF_TYPE_ARRAY_ENC(18, 1, 2), /* [17] */ 4446 BTF_TYPE_ARRAY_ENC(1, 1, 2), /* [18] */ 4447 BTF_END_RAW, 4448 }, 4449 BTF_STR_SEC("\0unsigned char\0unsigned short\0unsigned int\0int\0unsigned long long\0uint8_t\0uint16_t\0uint32_t\0int32_t\0uint64_t\0ui64\0ui8a\0ENUM_ZERO\0ENUM_ONE\0ENUM_TWO\0ENUM_THREE\0pprint_mapv\0ui32\0ui16\0si32\0unused_bits2a\0bits28\0unused_bits2b\0aenum\0ui32b\0bits2c\0si8_4"), 4450 .key_size = sizeof(unsigned int), 4451 .value_size = sizeof(struct pprint_mapv), 4452 .key_type_id = 3, /* unsigned int */ 4453 .value_type_id = 16, /* struct pprint_mapv */ 4454 .max_entries = 128 * 1024, 4455}, 4456 4457{ 4458 /* this type will have the same layout as the 4459 * first .raw_types definition. The struct type will 4460 * be encoded with kind_flag set, bitfield members 4461 * are added typedef/const/volatile, and bitfield members 4462 * will have both int and enum types. 4463 */ 4464 .raw_types = { 4465 /* unsighed char */ /* [1] */ 4466 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 8, 1), 4467 /* unsigned short */ /* [2] */ 4468 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 16, 2), 4469 /* unsigned int */ /* [3] */ 4470 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4), 4471 /* int */ /* [4] */ 4472 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), 4473 /* unsigned long long */ /* [5] */ 4474 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 64, 8), 4475 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [6] */ 4476 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [7] */ 4477 /* uint8_t[8] */ /* [8] */ 4478 BTF_TYPE_ARRAY_ENC(9, 1, 8), 4479 /* typedef unsigned char uint8_t */ /* [9] */ 4480 BTF_TYPEDEF_ENC(NAME_TBD, 1), 4481 /* typedef unsigned short uint16_t */ /* [10] */ 4482 BTF_TYPEDEF_ENC(NAME_TBD, 2), 4483 /* typedef unsigned int uint32_t */ /* [11] */ 4484 BTF_TYPEDEF_ENC(NAME_TBD, 3), 4485 /* typedef int int32_t */ /* [12] */ 4486 BTF_TYPEDEF_ENC(NAME_TBD, 4), 4487 /* typedef unsigned long long uint64_t *//* [13] */ 4488 BTF_TYPEDEF_ENC(NAME_TBD, 5), 4489 /* union (anon) */ /* [14] */ 4490 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 0, 2), 8), 4491 BTF_MEMBER_ENC(NAME_TBD, 13, 0),/* uint64_t ui64; */ 4492 BTF_MEMBER_ENC(NAME_TBD, 8, 0), /* uint8_t ui8a[8]; */ 4493 /* enum (anon) */ /* [15] */ 4494 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 4), 4), 4495 BTF_ENUM_ENC(NAME_TBD, 0), 4496 BTF_ENUM_ENC(NAME_TBD, 1), 4497 BTF_ENUM_ENC(NAME_TBD, 2), 4498 BTF_ENUM_ENC(NAME_TBD, 3), 4499 /* struct pprint_mapv */ /* [16] */ 4500 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 11), 40), 4501 BTF_MEMBER_ENC(NAME_TBD, 11, BTF_MEMBER_OFFSET(0, 0)), /* uint32_t ui32 */ 4502 BTF_MEMBER_ENC(NAME_TBD, 10, BTF_MEMBER_OFFSET(0, 32)), /* uint16_t ui16 */ 4503 BTF_MEMBER_ENC(NAME_TBD, 12, BTF_MEMBER_OFFSET(0, 64)), /* int32_t si32 */ 4504 BTF_MEMBER_ENC(NAME_TBD, 17, BTF_MEMBER_OFFSET(2, 96)), /* unused_bits2a */ 4505 BTF_MEMBER_ENC(NAME_TBD, 7, BTF_MEMBER_OFFSET(28, 98)), /* bits28 */ 4506 BTF_MEMBER_ENC(NAME_TBD, 19, BTF_MEMBER_OFFSET(2, 126)),/* unused_bits2b */ 4507 BTF_MEMBER_ENC(0, 14, BTF_MEMBER_OFFSET(0, 128)), /* union (anon) */ 4508 BTF_MEMBER_ENC(NAME_TBD, 15, BTF_MEMBER_OFFSET(0, 192)), /* aenum */ 4509 BTF_MEMBER_ENC(NAME_TBD, 11, BTF_MEMBER_OFFSET(0, 224)), /* uint32_t ui32b */ 4510 BTF_MEMBER_ENC(NAME_TBD, 17, BTF_MEMBER_OFFSET(2, 256)), /* bits2c */ 4511 BTF_MEMBER_ENC(NAME_TBD, 20, BTF_MEMBER_OFFSET(0, 264)), /* si8_4 */ 4512 /* typedef unsigned int ___int */ /* [17] */ 4513 BTF_TYPEDEF_ENC(NAME_TBD, 18), 4514 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_VOLATILE, 0, 0), 6), /* [18] */ 4515 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 15), /* [19] */ 4516 BTF_TYPE_ARRAY_ENC(21, 1, 2), /* [20] */ 4517 BTF_TYPE_ARRAY_ENC(1, 1, 2), /* [21] */ 4518 BTF_END_RAW, 4519 }, 4520 BTF_STR_SEC("\0unsigned char\0unsigned short\0unsigned int\0int\0unsigned long long\0uint8_t\0uint16_t\0uint32_t\0int32_t\0uint64_t\0ui64\0ui8a\0ENUM_ZERO\0ENUM_ONE\0ENUM_TWO\0ENUM_THREE\0pprint_mapv\0ui32\0ui16\0si32\0unused_bits2a\0bits28\0unused_bits2b\0aenum\0ui32b\0bits2c\0___int\0si8_4"), 4521 .key_size = sizeof(unsigned int), 4522 .value_size = sizeof(struct pprint_mapv), 4523 .key_type_id = 3, /* unsigned int */ 4524 .value_type_id = 16, /* struct pprint_mapv */ 4525 .max_entries = 128 * 1024, 4526}, 4527 4528#ifdef __SIZEOF_INT128__ 4529{ 4530 /* test int128 */ 4531 .raw_types = { 4532 /* unsigned int */ /* [1] */ 4533 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4), 4534 /* __int128 */ /* [2] */ 4535 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 128, 16), 4536 /* unsigned __int128 */ /* [3] */ 4537 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 128, 16), 4538 /* struct pprint_mapv_int128 */ /* [4] */ 4539 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 5), 64), 4540 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(0, 0)), /* si128a */ 4541 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(0, 128)), /* si128b */ 4542 BTF_MEMBER_ENC(NAME_TBD, 3, BTF_MEMBER_OFFSET(3, 256)), /* bits3 */ 4543 BTF_MEMBER_ENC(NAME_TBD, 3, BTF_MEMBER_OFFSET(80, 259)), /* bits80 */ 4544 BTF_MEMBER_ENC(NAME_TBD, 3, BTF_MEMBER_OFFSET(0, 384)), /* ui128 */ 4545 BTF_END_RAW, 4546 }, 4547 BTF_STR_SEC("\0unsigned int\0__int128\0unsigned __int128\0pprint_mapv_int128\0si128a\0si128b\0bits3\0bits80\0ui128"), 4548 .key_size = sizeof(unsigned int), 4549 .value_size = sizeof(struct pprint_mapv_int128), 4550 .key_type_id = 1, 4551 .value_type_id = 4, 4552 .max_entries = 128 * 1024, 4553 .mapv_kind = PPRINT_MAPV_KIND_INT128, 4554}, 4555#endif 4556 4557}; 4558 4559static struct btf_pprint_test_meta { 4560 const char *descr; 4561 enum bpf_map_type map_type; 4562 const char *map_name; 4563 bool ordered_map; 4564 bool lossless_map; 4565 bool percpu_map; 4566} pprint_tests_meta[] = { 4567{ 4568 .descr = "BTF pretty print array", 4569 .map_type = BPF_MAP_TYPE_ARRAY, 4570 .map_name = "pprint_test_array", 4571 .ordered_map = true, 4572 .lossless_map = true, 4573 .percpu_map = false, 4574}, 4575 4576{ 4577 .descr = "BTF pretty print hash", 4578 .map_type = BPF_MAP_TYPE_HASH, 4579 .map_name = "pprint_test_hash", 4580 .ordered_map = false, 4581 .lossless_map = true, 4582 .percpu_map = false, 4583}, 4584 4585{ 4586 .descr = "BTF pretty print lru hash", 4587 .map_type = BPF_MAP_TYPE_LRU_HASH, 4588 .map_name = "pprint_test_lru_hash", 4589 .ordered_map = false, 4590 .lossless_map = false, 4591 .percpu_map = false, 4592}, 4593 4594{ 4595 .descr = "BTF pretty print percpu array", 4596 .map_type = BPF_MAP_TYPE_PERCPU_ARRAY, 4597 .map_name = "pprint_test_percpu_array", 4598 .ordered_map = true, 4599 .lossless_map = true, 4600 .percpu_map = true, 4601}, 4602 4603{ 4604 .descr = "BTF pretty print percpu hash", 4605 .map_type = BPF_MAP_TYPE_PERCPU_HASH, 4606 .map_name = "pprint_test_percpu_hash", 4607 .ordered_map = false, 4608 .lossless_map = true, 4609 .percpu_map = true, 4610}, 4611 4612{ 4613 .descr = "BTF pretty print lru percpu hash", 4614 .map_type = BPF_MAP_TYPE_LRU_PERCPU_HASH, 4615 .map_name = "pprint_test_lru_percpu_hash", 4616 .ordered_map = false, 4617 .lossless_map = false, 4618 .percpu_map = true, 4619}, 4620 4621}; 4622 4623static size_t get_pprint_mapv_size(enum pprint_mapv_kind_t mapv_kind) 4624{ 4625 if (mapv_kind == PPRINT_MAPV_KIND_BASIC) 4626 return sizeof(struct pprint_mapv); 4627 4628#ifdef __SIZEOF_INT128__ 4629 if (mapv_kind == PPRINT_MAPV_KIND_INT128) 4630 return sizeof(struct pprint_mapv_int128); 4631#endif 4632 4633 assert(0); 4634} 4635 4636static void set_pprint_mapv(enum pprint_mapv_kind_t mapv_kind, 4637 void *mapv, uint32_t i, 4638 int num_cpus, int rounded_value_size) 4639{ 4640 int cpu; 4641 4642 if (mapv_kind == PPRINT_MAPV_KIND_BASIC) { 4643 struct pprint_mapv *v = mapv; 4644 4645 for (cpu = 0; cpu < num_cpus; cpu++) { 4646 v->ui32 = i + cpu; 4647 v->si32 = -i; 4648 v->unused_bits2a = 3; 4649 v->bits28 = i; 4650 v->unused_bits2b = 3; 4651 v->ui64 = i; 4652 v->aenum = i & 0x03; 4653 v->ui32b = 4; 4654 v->bits2c = 1; 4655 v->si8_4[0][0] = (cpu + i) & 0xff; 4656 v->si8_4[0][1] = (cpu + i + 1) & 0xff; 4657 v->si8_4[1][0] = (cpu + i + 2) & 0xff; 4658 v->si8_4[1][1] = (cpu + i + 3) & 0xff; 4659 v = (void *)v + rounded_value_size; 4660 } 4661 } 4662 4663#ifdef __SIZEOF_INT128__ 4664 if (mapv_kind == PPRINT_MAPV_KIND_INT128) { 4665 struct pprint_mapv_int128 *v = mapv; 4666 4667 for (cpu = 0; cpu < num_cpus; cpu++) { 4668 v->si128a = i; 4669 v->si128b = -i; 4670 v->bits3 = i & 0x07; 4671 v->bits80 = (((unsigned __int128)1) << 64) + i; 4672 v->ui128 = (((unsigned __int128)2) << 64) + i; 4673 v = (void *)v + rounded_value_size; 4674 } 4675 } 4676#endif 4677} 4678 4679ssize_t get_pprint_expected_line(enum pprint_mapv_kind_t mapv_kind, 4680 char *expected_line, ssize_t line_size, 4681 bool percpu_map, unsigned int next_key, 4682 int cpu, void *mapv) 4683{ 4684 ssize_t nexpected_line = -1; 4685 4686 if (mapv_kind == PPRINT_MAPV_KIND_BASIC) { 4687 struct pprint_mapv *v = mapv; 4688 4689 nexpected_line = snprintf(expected_line, line_size, 4690 "%s%u: {%u,0,%d,0x%x,0x%x,0x%x," 4691 "{%lu|[%u,%u,%u,%u,%u,%u,%u,%u]},%s," 4692 "%u,0x%x,[[%d,%d],[%d,%d]]}\n", 4693 percpu_map ? "\tcpu" : "", 4694 percpu_map ? cpu : next_key, 4695 v->ui32, v->si32, 4696 v->unused_bits2a, 4697 v->bits28, 4698 v->unused_bits2b, 4699 v->ui64, 4700 v->ui8a[0], v->ui8a[1], 4701 v->ui8a[2], v->ui8a[3], 4702 v->ui8a[4], v->ui8a[5], 4703 v->ui8a[6], v->ui8a[7], 4704 pprint_enum_str[v->aenum], 4705 v->ui32b, 4706 v->bits2c, 4707 v->si8_4[0][0], v->si8_4[0][1], 4708 v->si8_4[1][0], v->si8_4[1][1]); 4709 } 4710 4711#ifdef __SIZEOF_INT128__ 4712 if (mapv_kind == PPRINT_MAPV_KIND_INT128) { 4713 struct pprint_mapv_int128 *v = mapv; 4714 4715 nexpected_line = snprintf(expected_line, line_size, 4716 "%s%u: {0x%lx,0x%lx,0x%lx," 4717 "0x%lx%016lx,0x%lx%016lx}\n", 4718 percpu_map ? "\tcpu" : "", 4719 percpu_map ? cpu : next_key, 4720 (uint64_t)v->si128a, 4721 (uint64_t)v->si128b, 4722 (uint64_t)v->bits3, 4723 (uint64_t)(v->bits80 >> 64), 4724 (uint64_t)v->bits80, 4725 (uint64_t)(v->ui128 >> 64), 4726 (uint64_t)v->ui128); 4727 } 4728#endif 4729 4730 return nexpected_line; 4731} 4732 4733static int check_line(const char *expected_line, int nexpected_line, 4734 int expected_line_len, const char *line) 4735{ 4736 if (CHECK(nexpected_line == expected_line_len, 4737 "expected_line is too long")) 4738 return -1; 4739 4740 if (strcmp(expected_line, line)) { 4741 fprintf(stderr, "unexpected pprint output\n"); 4742 fprintf(stderr, "expected: %s", expected_line); 4743 fprintf(stderr, " read: %s", line); 4744 return -1; 4745 } 4746 4747 return 0; 4748} 4749 4750 4751static int do_test_pprint(int test_num) 4752{ 4753 const struct btf_raw_test *test = &pprint_test_template[test_num]; 4754 enum pprint_mapv_kind_t mapv_kind = test->mapv_kind; 4755 struct bpf_create_map_attr create_attr = {}; 4756 bool ordered_map, lossless_map, percpu_map; 4757 int err, ret, num_cpus, rounded_value_size; 4758 unsigned int key, nr_read_elems; 4759 int map_fd = -1, btf_fd = -1; 4760 unsigned int raw_btf_size; 4761 char expected_line[255]; 4762 FILE *pin_file = NULL; 4763 char pin_path[255]; 4764 size_t line_len = 0; 4765 char *line = NULL; 4766 void *mapv = NULL; 4767 uint8_t *raw_btf; 4768 ssize_t nread; 4769 4770 fprintf(stderr, "%s(#%d)......", test->descr, test_num); 4771 raw_btf = btf_raw_create(&hdr_tmpl, test->raw_types, 4772 test->str_sec, test->str_sec_size, 4773 &raw_btf_size, NULL); 4774 4775 if (!raw_btf) 4776 return -1; 4777 4778 *btf_log_buf = '\0'; 4779 btf_fd = bpf_load_btf(raw_btf, raw_btf_size, 4780 btf_log_buf, BTF_LOG_BUF_SIZE, 4781 args.always_log); 4782 free(raw_btf); 4783 4784 if (CHECK(btf_fd == -1, "errno:%d", errno)) { 4785 err = -1; 4786 goto done; 4787 } 4788 4789 create_attr.name = test->map_name; 4790 create_attr.map_type = test->map_type; 4791 create_attr.key_size = test->key_size; 4792 create_attr.value_size = test->value_size; 4793 create_attr.max_entries = test->max_entries; 4794 create_attr.btf_fd = btf_fd; 4795 create_attr.btf_key_type_id = test->key_type_id; 4796 create_attr.btf_value_type_id = test->value_type_id; 4797 4798 map_fd = bpf_create_map_xattr(&create_attr); 4799 if (CHECK(map_fd == -1, "errno:%d", errno)) { 4800 err = -1; 4801 goto done; 4802 } 4803 4804 ret = snprintf(pin_path, sizeof(pin_path), "%s/%s", 4805 "/sys/fs/bpf", test->map_name); 4806 4807 if (CHECK(ret == sizeof(pin_path), "pin_path %s/%s is too long", 4808 "/sys/fs/bpf", test->map_name)) { 4809 err = -1; 4810 goto done; 4811 } 4812 4813 err = bpf_obj_pin(map_fd, pin_path); 4814 if (CHECK(err, "bpf_obj_pin(%s): errno:%d.", pin_path, errno)) 4815 goto done; 4816 4817 percpu_map = test->percpu_map; 4818 num_cpus = percpu_map ? bpf_num_possible_cpus() : 1; 4819 rounded_value_size = round_up(get_pprint_mapv_size(mapv_kind), 8); 4820 mapv = calloc(num_cpus, rounded_value_size); 4821 if (CHECK(!mapv, "mapv allocation failure")) { 4822 err = -1; 4823 goto done; 4824 } 4825 4826 for (key = 0; key < test->max_entries; key++) { 4827 set_pprint_mapv(mapv_kind, mapv, key, num_cpus, rounded_value_size); 4828 bpf_map_update_elem(map_fd, &key, mapv, 0); 4829 } 4830 4831 pin_file = fopen(pin_path, "r"); 4832 if (CHECK(!pin_file, "fopen(%s): errno:%d", pin_path, errno)) { 4833 err = -1; 4834 goto done; 4835 } 4836 4837 /* Skip lines start with '#' */ 4838 while ((nread = getline(&line, &line_len, pin_file)) > 0 && 4839 *line == '#') 4840 ; 4841 4842 if (CHECK(nread <= 0, "Unexpected EOF")) { 4843 err = -1; 4844 goto done; 4845 } 4846 4847 nr_read_elems = 0; 4848 ordered_map = test->ordered_map; 4849 lossless_map = test->lossless_map; 4850 do { 4851 ssize_t nexpected_line; 4852 unsigned int next_key; 4853 void *cmapv; 4854 int cpu; 4855 4856 next_key = ordered_map ? nr_read_elems : atoi(line); 4857 set_pprint_mapv(mapv_kind, mapv, next_key, num_cpus, rounded_value_size); 4858 cmapv = mapv; 4859 4860 for (cpu = 0; cpu < num_cpus; cpu++) { 4861 if (percpu_map) { 4862 /* for percpu map, the format looks like: 4863 * <key>: { 4864 * cpu0: <value_on_cpu0> 4865 * cpu1: <value_on_cpu1> 4866 * ... 4867 * cpun: <value_on_cpun> 4868 * } 4869 * 4870 * let us verify the line containing the key here. 4871 */ 4872 if (cpu == 0) { 4873 nexpected_line = snprintf(expected_line, 4874 sizeof(expected_line), 4875 "%u: {\n", 4876 next_key); 4877 4878 err = check_line(expected_line, nexpected_line, 4879 sizeof(expected_line), line); 4880 if (err == -1) 4881 goto done; 4882 } 4883 4884 /* read value@cpu */ 4885 nread = getline(&line, &line_len, pin_file); 4886 if (nread < 0) 4887 break; 4888 } 4889 4890 nexpected_line = get_pprint_expected_line(mapv_kind, expected_line, 4891 sizeof(expected_line), 4892 percpu_map, next_key, 4893 cpu, cmapv); 4894 err = check_line(expected_line, nexpected_line, 4895 sizeof(expected_line), line); 4896 if (err == -1) 4897 goto done; 4898 4899 cmapv = cmapv + rounded_value_size; 4900 } 4901 4902 if (percpu_map) { 4903 /* skip the last bracket for the percpu map */ 4904 nread = getline(&line, &line_len, pin_file); 4905 if (nread < 0) 4906 break; 4907 } 4908 4909 nread = getline(&line, &line_len, pin_file); 4910 } while (++nr_read_elems < test->max_entries && nread > 0); 4911 4912 if (lossless_map && 4913 CHECK(nr_read_elems < test->max_entries, 4914 "Unexpected EOF. nr_read_elems:%u test->max_entries:%u", 4915 nr_read_elems, test->max_entries)) { 4916 err = -1; 4917 goto done; 4918 } 4919 4920 if (CHECK(nread > 0, "Unexpected extra pprint output: %s", line)) { 4921 err = -1; 4922 goto done; 4923 } 4924 4925 err = 0; 4926 4927done: 4928 if (mapv) 4929 free(mapv); 4930 if (!err) 4931 fprintf(stderr, "OK"); 4932 if (*btf_log_buf && (err || args.always_log)) 4933 fprintf(stderr, "\n%s", btf_log_buf); 4934 if (btf_fd != -1) 4935 close(btf_fd); 4936 if (map_fd != -1) 4937 close(map_fd); 4938 if (pin_file) 4939 fclose(pin_file); 4940 unlink(pin_path); 4941 free(line); 4942 4943 return err; 4944} 4945 4946static int test_pprint(void) 4947{ 4948 unsigned int i; 4949 int err = 0; 4950 4951 /* test various maps with the first test template */ 4952 for (i = 0; i < ARRAY_SIZE(pprint_tests_meta); i++) { 4953 pprint_test_template[0].descr = pprint_tests_meta[i].descr; 4954 pprint_test_template[0].map_type = pprint_tests_meta[i].map_type; 4955 pprint_test_template[0].map_name = pprint_tests_meta[i].map_name; 4956 pprint_test_template[0].ordered_map = pprint_tests_meta[i].ordered_map; 4957 pprint_test_template[0].lossless_map = pprint_tests_meta[i].lossless_map; 4958 pprint_test_template[0].percpu_map = pprint_tests_meta[i].percpu_map; 4959 4960 err |= count_result(do_test_pprint(0)); 4961 } 4962 4963 /* test rest test templates with the first map */ 4964 for (i = 1; i < ARRAY_SIZE(pprint_test_template); i++) { 4965 pprint_test_template[i].descr = pprint_tests_meta[0].descr; 4966 pprint_test_template[i].map_type = pprint_tests_meta[0].map_type; 4967 pprint_test_template[i].map_name = pprint_tests_meta[0].map_name; 4968 pprint_test_template[i].ordered_map = pprint_tests_meta[0].ordered_map; 4969 pprint_test_template[i].lossless_map = pprint_tests_meta[0].lossless_map; 4970 pprint_test_template[i].percpu_map = pprint_tests_meta[0].percpu_map; 4971 err |= count_result(do_test_pprint(i)); 4972 } 4973 4974 return err; 4975} 4976 4977#define BPF_LINE_INFO_ENC(insn_off, file_off, line_off, line_num, line_col) \ 4978 (insn_off), (file_off), (line_off), ((line_num) << 10 | ((line_col) & 0x3ff)) 4979 4980static struct prog_info_raw_test { 4981 const char *descr; 4982 const char *str_sec; 4983 const char *err_str; 4984 __u32 raw_types[MAX_NR_RAW_U32]; 4985 __u32 str_sec_size; 4986 struct bpf_insn insns[MAX_INSNS]; 4987 __u32 prog_type; 4988 __u32 func_info[MAX_SUBPROGS][2]; 4989 __u32 func_info_rec_size; 4990 __u32 func_info_cnt; 4991 __u32 line_info[MAX_NR_RAW_U32]; 4992 __u32 line_info_rec_size; 4993 __u32 nr_jited_ksyms; 4994 bool expected_prog_load_failure; 4995 __u32 dead_code_cnt; 4996 __u32 dead_code_mask; 4997 __u32 dead_func_cnt; 4998 __u32 dead_func_mask; 4999} info_raw_tests[] = { 5000{ 5001 .descr = "func_type (main func + one sub)", 5002 .raw_types = { 5003 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 5004 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4), /* [2] */ 5005 BTF_FUNC_PROTO_ENC(1, 2), /* [3] */ 5006 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1), 5007 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2), 5008 BTF_FUNC_PROTO_ENC(1, 2), /* [4] */ 5009 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2), 5010 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1), 5011 BTF_FUNC_ENC(NAME_TBD, 3), /* [5] */ 5012 BTF_FUNC_ENC(NAME_TBD, 4), /* [6] */ 5013 BTF_END_RAW, 5014 }, 5015 .str_sec = "\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB", 5016 .str_sec_size = sizeof("\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB"), 5017 .insns = { 5018 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2), 5019 BPF_MOV64_IMM(BPF_REG_0, 1), 5020 BPF_EXIT_INSN(), 5021 BPF_MOV64_IMM(BPF_REG_0, 2), 5022 BPF_EXIT_INSN(), 5023 }, 5024 .prog_type = BPF_PROG_TYPE_TRACEPOINT, 5025 .func_info = { {0, 5}, {3, 6} }, 5026 .func_info_rec_size = 8, 5027 .func_info_cnt = 2, 5028 .line_info = { BTF_END_RAW }, 5029}, 5030 5031{ 5032 .descr = "func_type (Incorrect func_info_rec_size)", 5033 .raw_types = { 5034 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 5035 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4), /* [2] */ 5036 BTF_FUNC_PROTO_ENC(1, 2), /* [3] */ 5037 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1), 5038 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2), 5039 BTF_FUNC_PROTO_ENC(1, 2), /* [4] */ 5040 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2), 5041 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1), 5042 BTF_FUNC_ENC(NAME_TBD, 3), /* [5] */ 5043 BTF_FUNC_ENC(NAME_TBD, 4), /* [6] */ 5044 BTF_END_RAW, 5045 }, 5046 .str_sec = "\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB", 5047 .str_sec_size = sizeof("\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB"), 5048 .insns = { 5049 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2), 5050 BPF_MOV64_IMM(BPF_REG_0, 1), 5051 BPF_EXIT_INSN(), 5052 BPF_MOV64_IMM(BPF_REG_0, 2), 5053 BPF_EXIT_INSN(), 5054 }, 5055 .prog_type = BPF_PROG_TYPE_TRACEPOINT, 5056 .func_info = { {0, 5}, {3, 6} }, 5057 .func_info_rec_size = 4, 5058 .func_info_cnt = 2, 5059 .line_info = { BTF_END_RAW }, 5060 .expected_prog_load_failure = true, 5061}, 5062 5063{ 5064 .descr = "func_type (Incorrect func_info_cnt)", 5065 .raw_types = { 5066 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 5067 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4), /* [2] */ 5068 BTF_FUNC_PROTO_ENC(1, 2), /* [3] */ 5069 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1), 5070 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2), 5071 BTF_FUNC_PROTO_ENC(1, 2), /* [4] */ 5072 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2), 5073 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1), 5074 BTF_FUNC_ENC(NAME_TBD, 3), /* [5] */ 5075 BTF_FUNC_ENC(NAME_TBD, 4), /* [6] */ 5076 BTF_END_RAW, 5077 }, 5078 .str_sec = "\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB", 5079 .str_sec_size = sizeof("\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB"), 5080 .insns = { 5081 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2), 5082 BPF_MOV64_IMM(BPF_REG_0, 1), 5083 BPF_EXIT_INSN(), 5084 BPF_MOV64_IMM(BPF_REG_0, 2), 5085 BPF_EXIT_INSN(), 5086 }, 5087 .prog_type = BPF_PROG_TYPE_TRACEPOINT, 5088 .func_info = { {0, 5}, {3, 6} }, 5089 .func_info_rec_size = 8, 5090 .func_info_cnt = 1, 5091 .line_info = { BTF_END_RAW }, 5092 .expected_prog_load_failure = true, 5093}, 5094 5095{ 5096 .descr = "func_type (Incorrect bpf_func_info.insn_off)", 5097 .raw_types = { 5098 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 5099 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4), /* [2] */ 5100 BTF_FUNC_PROTO_ENC(1, 2), /* [3] */ 5101 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1), 5102 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2), 5103 BTF_FUNC_PROTO_ENC(1, 2), /* [4] */ 5104 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2), 5105 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1), 5106 BTF_FUNC_ENC(NAME_TBD, 3), /* [5] */ 5107 BTF_FUNC_ENC(NAME_TBD, 4), /* [6] */ 5108 BTF_END_RAW, 5109 }, 5110 .str_sec = "\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB", 5111 .str_sec_size = sizeof("\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB"), 5112 .insns = { 5113 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2), 5114 BPF_MOV64_IMM(BPF_REG_0, 1), 5115 BPF_EXIT_INSN(), 5116 BPF_MOV64_IMM(BPF_REG_0, 2), 5117 BPF_EXIT_INSN(), 5118 }, 5119 .prog_type = BPF_PROG_TYPE_TRACEPOINT, 5120 .func_info = { {0, 5}, {2, 6} }, 5121 .func_info_rec_size = 8, 5122 .func_info_cnt = 2, 5123 .line_info = { BTF_END_RAW }, 5124 .expected_prog_load_failure = true, 5125}, 5126 5127{ 5128 .descr = "line_info (No subprog)", 5129 .raw_types = { 5130 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 5131 BTF_END_RAW, 5132 }, 5133 BTF_STR_SEC("\0int\0int a=1;\0int b=2;\0return a + b;\0return a + b;"), 5134 .insns = { 5135 BPF_MOV64_IMM(BPF_REG_0, 1), 5136 BPF_MOV64_IMM(BPF_REG_1, 2), 5137 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1), 5138 BPF_EXIT_INSN(), 5139 }, 5140 .prog_type = BPF_PROG_TYPE_TRACEPOINT, 5141 .func_info_cnt = 0, 5142 .line_info = { 5143 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10), 5144 BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 2, 9), 5145 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8), 5146 BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 4, 7), 5147 BTF_END_RAW, 5148 }, 5149 .line_info_rec_size = sizeof(struct bpf_line_info), 5150 .nr_jited_ksyms = 1, 5151}, 5152 5153{ 5154 .descr = "line_info (No subprog. insn_off >= prog->len)", 5155 .raw_types = { 5156 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 5157 BTF_END_RAW, 5158 }, 5159 BTF_STR_SEC("\0int\0int a=1;\0int b=2;\0return a + b;\0return a + b;"), 5160 .insns = { 5161 BPF_MOV64_IMM(BPF_REG_0, 1), 5162 BPF_MOV64_IMM(BPF_REG_1, 2), 5163 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1), 5164 BPF_EXIT_INSN(), 5165 }, 5166 .prog_type = BPF_PROG_TYPE_TRACEPOINT, 5167 .func_info_cnt = 0, 5168 .line_info = { 5169 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10), 5170 BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 2, 9), 5171 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8), 5172 BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 4, 7), 5173 BPF_LINE_INFO_ENC(4, 0, 0, 5, 6), 5174 BTF_END_RAW, 5175 }, 5176 .line_info_rec_size = sizeof(struct bpf_line_info), 5177 .nr_jited_ksyms = 1, 5178 .err_str = "line_info[4].insn_off", 5179 .expected_prog_load_failure = true, 5180}, 5181 5182{ 5183 .descr = "line_info (Zero bpf insn code)", 5184 .raw_types = { 5185 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 5186 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 64, 8), /* [2] */ 5187 BTF_TYPEDEF_ENC(NAME_TBD, 2), /* [3] */ 5188 BTF_END_RAW, 5189 }, 5190 BTF_STR_SEC("\0int\0unsigned long\0u64\0u64 a=1;\0return a;"), 5191 .insns = { 5192 BPF_LD_IMM64(BPF_REG_0, 1), 5193 BPF_EXIT_INSN(), 5194 }, 5195 .prog_type = BPF_PROG_TYPE_TRACEPOINT, 5196 .func_info_cnt = 0, 5197 .line_info = { 5198 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10), 5199 BPF_LINE_INFO_ENC(1, 0, 0, 2, 9), 5200 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8), 5201 BTF_END_RAW, 5202 }, 5203 .line_info_rec_size = sizeof(struct bpf_line_info), 5204 .nr_jited_ksyms = 1, 5205 .err_str = "Invalid insn code at line_info[1]", 5206 .expected_prog_load_failure = true, 5207}, 5208 5209{ 5210 .descr = "line_info (No subprog. zero tailing line_info", 5211 .raw_types = { 5212 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 5213 BTF_END_RAW, 5214 }, 5215 BTF_STR_SEC("\0int\0int a=1;\0int b=2;\0return a + b;\0return a + b;"), 5216 .insns = { 5217 BPF_MOV64_IMM(BPF_REG_0, 1), 5218 BPF_MOV64_IMM(BPF_REG_1, 2), 5219 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1), 5220 BPF_EXIT_INSN(), 5221 }, 5222 .prog_type = BPF_PROG_TYPE_TRACEPOINT, 5223 .func_info_cnt = 0, 5224 .line_info = { 5225 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10), 0, 5226 BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 2, 9), 0, 5227 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8), 0, 5228 BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 4, 7), 0, 5229 BTF_END_RAW, 5230 }, 5231 .line_info_rec_size = sizeof(struct bpf_line_info) + sizeof(__u32), 5232 .nr_jited_ksyms = 1, 5233}, 5234 5235{ 5236 .descr = "line_info (No subprog. nonzero tailing line_info)", 5237 .raw_types = { 5238 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 5239 BTF_END_RAW, 5240 }, 5241 BTF_STR_SEC("\0int\0int a=1;\0int b=2;\0return a + b;\0return a + b;"), 5242 .insns = { 5243 BPF_MOV64_IMM(BPF_REG_0, 1), 5244 BPF_MOV64_IMM(BPF_REG_1, 2), 5245 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1), 5246 BPF_EXIT_INSN(), 5247 }, 5248 .prog_type = BPF_PROG_TYPE_TRACEPOINT, 5249 .func_info_cnt = 0, 5250 .line_info = { 5251 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10), 0, 5252 BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 2, 9), 0, 5253 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8), 0, 5254 BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 4, 7), 1, 5255 BTF_END_RAW, 5256 }, 5257 .line_info_rec_size = sizeof(struct bpf_line_info) + sizeof(__u32), 5258 .nr_jited_ksyms = 1, 5259 .err_str = "nonzero tailing record in line_info", 5260 .expected_prog_load_failure = true, 5261}, 5262 5263{ 5264 .descr = "line_info (subprog)", 5265 .raw_types = { 5266 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 5267 BTF_END_RAW, 5268 }, 5269 BTF_STR_SEC("\0int\0int a=1+1;\0return func(a);\0b+=1;\0return b;"), 5270 .insns = { 5271 BPF_MOV64_IMM(BPF_REG_2, 1), 5272 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1), 5273 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), 5274 BPF_CALL_REL(1), 5275 BPF_EXIT_INSN(), 5276 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1), 5277 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1), 5278 BPF_EXIT_INSN(), 5279 }, 5280 .prog_type = BPF_PROG_TYPE_TRACEPOINT, 5281 .func_info_cnt = 0, 5282 .line_info = { 5283 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10), 5284 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 2, 9), 5285 BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 3, 8), 5286 BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 4, 7), 5287 BTF_END_RAW, 5288 }, 5289 .line_info_rec_size = sizeof(struct bpf_line_info), 5290 .nr_jited_ksyms = 2, 5291}, 5292 5293{ 5294 .descr = "line_info (subprog + func_info)", 5295 .raw_types = { 5296 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 5297 BTF_FUNC_PROTO_ENC(1, 1), /* [2] */ 5298 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1), 5299 BTF_FUNC_ENC(NAME_TBD, 2), /* [3] */ 5300 BTF_FUNC_ENC(NAME_TBD, 2), /* [4] */ 5301 BTF_END_RAW, 5302 }, 5303 BTF_STR_SEC("\0int\0x\0sub\0main\0int a=1+1;\0return func(a);\0b+=1;\0return b;"), 5304 .insns = { 5305 BPF_MOV64_IMM(BPF_REG_2, 1), 5306 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1), 5307 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), 5308 BPF_CALL_REL(1), 5309 BPF_EXIT_INSN(), 5310 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1), 5311 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1), 5312 BPF_EXIT_INSN(), 5313 }, 5314 .prog_type = BPF_PROG_TYPE_TRACEPOINT, 5315 .func_info_cnt = 2, 5316 .func_info_rec_size = 8, 5317 .func_info = { {0, 4}, {5, 3} }, 5318 .line_info = { 5319 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10), 5320 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 2, 9), 5321 BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 3, 8), 5322 BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 4, 7), 5323 BTF_END_RAW, 5324 }, 5325 .line_info_rec_size = sizeof(struct bpf_line_info), 5326 .nr_jited_ksyms = 2, 5327}, 5328 5329{ 5330 .descr = "line_info (subprog. missing 1st func line info)", 5331 .raw_types = { 5332 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 5333 BTF_END_RAW, 5334 }, 5335 BTF_STR_SEC("\0int\0int a=1+1;\0return func(a);\0b+=1;\0return b;"), 5336 .insns = { 5337 BPF_MOV64_IMM(BPF_REG_2, 1), 5338 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1), 5339 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), 5340 BPF_CALL_REL(1), 5341 BPF_EXIT_INSN(), 5342 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1), 5343 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1), 5344 BPF_EXIT_INSN(), 5345 }, 5346 .prog_type = BPF_PROG_TYPE_TRACEPOINT, 5347 .func_info_cnt = 0, 5348 .line_info = { 5349 BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 1, 10), 5350 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 2, 9), 5351 BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 3, 8), 5352 BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 4, 7), 5353 BTF_END_RAW, 5354 }, 5355 .line_info_rec_size = sizeof(struct bpf_line_info), 5356 .nr_jited_ksyms = 2, 5357 .err_str = "missing bpf_line_info for func#0", 5358 .expected_prog_load_failure = true, 5359}, 5360 5361{ 5362 .descr = "line_info (subprog. missing 2nd func line info)", 5363 .raw_types = { 5364 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 5365 BTF_END_RAW, 5366 }, 5367 BTF_STR_SEC("\0int\0int a=1+1;\0return func(a);\0b+=1;\0return b;"), 5368 .insns = { 5369 BPF_MOV64_IMM(BPF_REG_2, 1), 5370 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1), 5371 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), 5372 BPF_CALL_REL(1), 5373 BPF_EXIT_INSN(), 5374 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1), 5375 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1), 5376 BPF_EXIT_INSN(), 5377 }, 5378 .prog_type = BPF_PROG_TYPE_TRACEPOINT, 5379 .func_info_cnt = 0, 5380 .line_info = { 5381 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10), 5382 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 2, 9), 5383 BPF_LINE_INFO_ENC(6, 0, NAME_TBD, 3, 8), 5384 BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 4, 7), 5385 BTF_END_RAW, 5386 }, 5387 .line_info_rec_size = sizeof(struct bpf_line_info), 5388 .nr_jited_ksyms = 2, 5389 .err_str = "missing bpf_line_info for func#1", 5390 .expected_prog_load_failure = true, 5391}, 5392 5393{ 5394 .descr = "line_info (subprog. unordered insn offset)", 5395 .raw_types = { 5396 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 5397 BTF_END_RAW, 5398 }, 5399 BTF_STR_SEC("\0int\0int a=1+1;\0return func(a);\0b+=1;\0return b;"), 5400 .insns = { 5401 BPF_MOV64_IMM(BPF_REG_2, 1), 5402 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1), 5403 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), 5404 BPF_CALL_REL(1), 5405 BPF_EXIT_INSN(), 5406 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1), 5407 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1), 5408 BPF_EXIT_INSN(), 5409 }, 5410 .prog_type = BPF_PROG_TYPE_TRACEPOINT, 5411 .func_info_cnt = 0, 5412 .line_info = { 5413 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10), 5414 BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 2, 9), 5415 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8), 5416 BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 4, 7), 5417 BTF_END_RAW, 5418 }, 5419 .line_info_rec_size = sizeof(struct bpf_line_info), 5420 .nr_jited_ksyms = 2, 5421 .err_str = "Invalid line_info[2].insn_off", 5422 .expected_prog_load_failure = true, 5423}, 5424 5425{ 5426 .descr = "line_info (dead start)", 5427 .raw_types = { 5428 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 5429 BTF_END_RAW, 5430 }, 5431 BTF_STR_SEC("\0int\0/* dead jmp */\0int a=1;\0int b=2;\0return a + b;\0return a + b;"), 5432 .insns = { 5433 BPF_JMP_IMM(BPF_JA, 0, 0, 0), 5434 BPF_MOV64_IMM(BPF_REG_0, 1), 5435 BPF_MOV64_IMM(BPF_REG_1, 2), 5436 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1), 5437 BPF_EXIT_INSN(), 5438 }, 5439 .prog_type = BPF_PROG_TYPE_TRACEPOINT, 5440 .func_info_cnt = 0, 5441 .line_info = { 5442 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10), 5443 BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 2, 9), 5444 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8), 5445 BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 4, 7), 5446 BPF_LINE_INFO_ENC(4, 0, NAME_TBD, 5, 6), 5447 BTF_END_RAW, 5448 }, 5449 .line_info_rec_size = sizeof(struct bpf_line_info), 5450 .nr_jited_ksyms = 1, 5451 .dead_code_cnt = 1, 5452 .dead_code_mask = 0x01, 5453}, 5454 5455{ 5456 .descr = "line_info (dead end)", 5457 .raw_types = { 5458 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 5459 BTF_END_RAW, 5460 }, 5461 BTF_STR_SEC("\0int\0int a=1;\0int b=2;\0return a + b;\0/* dead jmp */\0return a + b;\0/* dead exit */"), 5462 .insns = { 5463 BPF_MOV64_IMM(BPF_REG_0, 1), 5464 BPF_MOV64_IMM(BPF_REG_1, 2), 5465 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1), 5466 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 10, 1), 5467 BPF_EXIT_INSN(), 5468 BPF_EXIT_INSN(), 5469 }, 5470 .prog_type = BPF_PROG_TYPE_TRACEPOINT, 5471 .func_info_cnt = 0, 5472 .line_info = { 5473 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 12), 5474 BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 2, 11), 5475 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 10), 5476 BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 4, 9), 5477 BPF_LINE_INFO_ENC(4, 0, NAME_TBD, 5, 8), 5478 BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 6, 7), 5479 BTF_END_RAW, 5480 }, 5481 .line_info_rec_size = sizeof(struct bpf_line_info), 5482 .nr_jited_ksyms = 1, 5483 .dead_code_cnt = 2, 5484 .dead_code_mask = 0x28, 5485}, 5486 5487{ 5488 .descr = "line_info (dead code + subprog + func_info)", 5489 .raw_types = { 5490 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 5491 BTF_FUNC_PROTO_ENC(1, 1), /* [2] */ 5492 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1), 5493 BTF_FUNC_ENC(NAME_TBD, 2), /* [3] */ 5494 BTF_FUNC_ENC(NAME_TBD, 2), /* [4] */ 5495 BTF_END_RAW, 5496 }, 5497 BTF_STR_SEC("\0int\0x\0sub\0main\0int a=1+1;\0/* dead jmp */" 5498 "\0/* dead */\0/* dead */\0/* dead */\0/* dead */" 5499 "\0/* dead */\0/* dead */\0/* dead */\0/* dead */" 5500 "\0return func(a);\0b+=1;\0return b;"), 5501 .insns = { 5502 BPF_MOV64_IMM(BPF_REG_2, 1), 5503 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1), 5504 BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), 5505 BPF_JMP_IMM(BPF_JGE, BPF_REG_2, 0, 8), 5506 BPF_MOV64_IMM(BPF_REG_2, 1), 5507 BPF_MOV64_IMM(BPF_REG_2, 1), 5508 BPF_MOV64_IMM(BPF_REG_2, 1), 5509 BPF_MOV64_IMM(BPF_REG_2, 1), 5510 BPF_MOV64_IMM(BPF_REG_2, 1), 5511 BPF_MOV64_IMM(BPF_REG_2, 1), 5512 BPF_MOV64_IMM(BPF_REG_2, 1), 5513 BPF_MOV64_IMM(BPF_REG_2, 1), 5514 BPF_CALL_REL(1), 5515 BPF_EXIT_INSN(), 5516 BPF_MOV64_REG(BPF_REG_0, BPF_REG_1), 5517 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1), 5518 BPF_EXIT_INSN(), 5519 }, 5520 .prog_type = BPF_PROG_TYPE_TRACEPOINT, 5521 .func_info_cnt = 2, 5522 .func_info_rec_size = 8, 5523 .func_info = { {0, 4}, {14, 3} }, 5524 .line_info = { 5525 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10), 5526 BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 1, 10), 5527 BPF_LINE_INFO_ENC(4, 0, NAME_TBD, 1, 10), 5528 BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 1, 10), 5529 BPF_LINE_INFO_ENC(6, 0, NAME_TBD, 1, 10), 5530 BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 1, 10), 5531 BPF_LINE_INFO_ENC(8, 0, NAME_TBD, 1, 10), 5532 BPF_LINE_INFO_ENC(9, 0, NAME_TBD, 1, 10), 5533 BPF_LINE_INFO_ENC(10, 0, NAME_TBD, 1, 10), 5534 BPF_LINE_INFO_ENC(11, 0, NAME_TBD, 2, 9), 5535 BPF_LINE_INFO_ENC(12, 0, NAME_TBD, 2, 9), 5536 BPF_LINE_INFO_ENC(14, 0, NAME_TBD, 3, 8), 5537 BPF_LINE_INFO_ENC(16, 0, NAME_TBD, 4, 7), 5538 BTF_END_RAW, 5539 }, 5540 .line_info_rec_size = sizeof(struct bpf_line_info), 5541 .nr_jited_ksyms = 2, 5542 .dead_code_cnt = 9, 5543 .dead_code_mask = 0x3fe, 5544}, 5545 5546{ 5547 .descr = "line_info (dead subprog)", 5548 .raw_types = { 5549 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 5550 BTF_FUNC_PROTO_ENC(1, 1), /* [2] */ 5551 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1), 5552 BTF_FUNC_ENC(NAME_TBD, 2), /* [3] */ 5553 BTF_FUNC_ENC(NAME_TBD, 2), /* [4] */ 5554 BTF_FUNC_ENC(NAME_TBD, 2), /* [5] */ 5555 BTF_END_RAW, 5556 }, 5557 BTF_STR_SEC("\0int\0x\0dead\0main\0func\0int a=1+1;\0/* live call */" 5558 "\0return 0;\0return 0;\0/* dead */\0/* dead */" 5559 "\0/* dead */\0return bla + 1;\0return bla + 1;" 5560 "\0return bla + 1;\0return func(a);\0b+=1;\0return b;"), 5561 .insns = { 5562 BPF_MOV64_IMM(BPF_REG_2, 1), 5563 BPF_JMP_IMM(BPF_JGE, BPF_REG_2, 0, 1), 5564 BPF_CALL_REL(3), 5565 BPF_CALL_REL(5), 5566 BPF_MOV64_IMM(BPF_REG_0, 0), 5567 BPF_EXIT_INSN(), 5568 BPF_MOV64_IMM(BPF_REG_0, 0), 5569 BPF_CALL_REL(1), 5570 BPF_EXIT_INSN(), 5571 BPF_MOV64_REG(BPF_REG_0, 2), 5572 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1), 5573 BPF_EXIT_INSN(), 5574 }, 5575 .prog_type = BPF_PROG_TYPE_TRACEPOINT, 5576 .func_info_cnt = 3, 5577 .func_info_rec_size = 8, 5578 .func_info = { {0, 4}, {6, 3}, {9, 5} }, 5579 .line_info = { 5580 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10), 5581 BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 1, 10), 5582 BPF_LINE_INFO_ENC(4, 0, NAME_TBD, 1, 10), 5583 BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 1, 10), 5584 BPF_LINE_INFO_ENC(6, 0, NAME_TBD, 1, 10), 5585 BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 1, 10), 5586 BPF_LINE_INFO_ENC(8, 0, NAME_TBD, 1, 10), 5587 BPF_LINE_INFO_ENC(9, 0, NAME_TBD, 1, 10), 5588 BPF_LINE_INFO_ENC(10, 0, NAME_TBD, 1, 10), 5589 BPF_LINE_INFO_ENC(11, 0, NAME_TBD, 2, 9), 5590 BTF_END_RAW, 5591 }, 5592 .line_info_rec_size = sizeof(struct bpf_line_info), 5593 .nr_jited_ksyms = 2, 5594 .dead_code_cnt = 3, 5595 .dead_code_mask = 0x70, 5596 .dead_func_cnt = 1, 5597 .dead_func_mask = 0x2, 5598}, 5599 5600{ 5601 .descr = "line_info (dead last subprog)", 5602 .raw_types = { 5603 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 5604 BTF_FUNC_PROTO_ENC(1, 1), /* [2] */ 5605 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1), 5606 BTF_FUNC_ENC(NAME_TBD, 2), /* [3] */ 5607 BTF_FUNC_ENC(NAME_TBD, 2), /* [5] */ 5608 BTF_END_RAW, 5609 }, 5610 BTF_STR_SEC("\0int\0x\0dead\0main\0int a=1+1;\0/* live call */" 5611 "\0return 0;\0/* dead */\0/* dead */"), 5612 .insns = { 5613 BPF_MOV64_IMM(BPF_REG_2, 1), 5614 BPF_JMP_IMM(BPF_JGE, BPF_REG_2, 0, 1), 5615 BPF_CALL_REL(2), 5616 BPF_MOV64_IMM(BPF_REG_0, 0), 5617 BPF_EXIT_INSN(), 5618 BPF_MOV64_IMM(BPF_REG_0, 0), 5619 BPF_EXIT_INSN(), 5620 }, 5621 .prog_type = BPF_PROG_TYPE_TRACEPOINT, 5622 .func_info_cnt = 2, 5623 .func_info_rec_size = 8, 5624 .func_info = { {0, 4}, {5, 3} }, 5625 .line_info = { 5626 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10), 5627 BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 1, 10), 5628 BPF_LINE_INFO_ENC(4, 0, NAME_TBD, 1, 10), 5629 BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 1, 10), 5630 BPF_LINE_INFO_ENC(6, 0, NAME_TBD, 1, 10), 5631 BTF_END_RAW, 5632 }, 5633 .line_info_rec_size = sizeof(struct bpf_line_info), 5634 .nr_jited_ksyms = 1, 5635 .dead_code_cnt = 2, 5636 .dead_code_mask = 0x18, 5637 .dead_func_cnt = 1, 5638 .dead_func_mask = 0x2, 5639}, 5640 5641{ 5642 .descr = "line_info (dead subprog + dead start)", 5643 .raw_types = { 5644 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 5645 BTF_FUNC_PROTO_ENC(1, 1), /* [2] */ 5646 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1), 5647 BTF_FUNC_ENC(NAME_TBD, 2), /* [3] */ 5648 BTF_FUNC_ENC(NAME_TBD, 2), /* [4] */ 5649 BTF_FUNC_ENC(NAME_TBD, 2), /* [5] */ 5650 BTF_END_RAW, 5651 }, 5652 BTF_STR_SEC("\0int\0x\0dead\0main\0func\0int a=1+1;\0/* dead */" 5653 "\0return 0;\0return 0;\0return 0;" 5654 "\0/* dead */\0/* dead */\0/* dead */\0/* dead */" 5655 "\0return b + 1;\0return b + 1;\0return b + 1;"), 5656 .insns = { 5657 BPF_JMP_IMM(BPF_JA, 0, 0, 0), 5658 BPF_MOV64_IMM(BPF_REG_2, 1), 5659 BPF_JMP_IMM(BPF_JGE, BPF_REG_2, 0, 1), 5660 BPF_CALL_REL(3), 5661 BPF_CALL_REL(5), 5662 BPF_MOV64_IMM(BPF_REG_0, 0), 5663 BPF_EXIT_INSN(), 5664 BPF_MOV64_IMM(BPF_REG_0, 0), 5665 BPF_CALL_REL(1), 5666 BPF_EXIT_INSN(), 5667 BPF_JMP_IMM(BPF_JA, 0, 0, 0), 5668 BPF_MOV64_REG(BPF_REG_0, 2), 5669 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1), 5670 BPF_EXIT_INSN(), 5671 }, 5672 .prog_type = BPF_PROG_TYPE_TRACEPOINT, 5673 .func_info_cnt = 3, 5674 .func_info_rec_size = 8, 5675 .func_info = { {0, 4}, {7, 3}, {10, 5} }, 5676 .line_info = { 5677 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10), 5678 BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 1, 10), 5679 BPF_LINE_INFO_ENC(4, 0, NAME_TBD, 1, 10), 5680 BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 1, 10), 5681 BPF_LINE_INFO_ENC(6, 0, NAME_TBD, 1, 10), 5682 BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 1, 10), 5683 BPF_LINE_INFO_ENC(8, 0, NAME_TBD, 1, 10), 5684 BPF_LINE_INFO_ENC(9, 0, NAME_TBD, 1, 10), 5685 BPF_LINE_INFO_ENC(10, 0, NAME_TBD, 1, 10), 5686 BPF_LINE_INFO_ENC(11, 0, NAME_TBD, 2, 9), 5687 BPF_LINE_INFO_ENC(12, 0, NAME_TBD, 2, 9), 5688 BPF_LINE_INFO_ENC(13, 0, NAME_TBD, 2, 9), 5689 BTF_END_RAW, 5690 }, 5691 .line_info_rec_size = sizeof(struct bpf_line_info), 5692 .nr_jited_ksyms = 2, 5693 .dead_code_cnt = 5, 5694 .dead_code_mask = 0x1e2, 5695 .dead_func_cnt = 1, 5696 .dead_func_mask = 0x2, 5697}, 5698 5699{ 5700 .descr = "line_info (dead subprog + dead start w/ move)", 5701 .raw_types = { 5702 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 5703 BTF_FUNC_PROTO_ENC(1, 1), /* [2] */ 5704 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1), 5705 BTF_FUNC_ENC(NAME_TBD, 2), /* [3] */ 5706 BTF_FUNC_ENC(NAME_TBD, 2), /* [4] */ 5707 BTF_FUNC_ENC(NAME_TBD, 2), /* [5] */ 5708 BTF_END_RAW, 5709 }, 5710 BTF_STR_SEC("\0int\0x\0dead\0main\0func\0int a=1+1;\0/* live call */" 5711 "\0return 0;\0return 0;\0/* dead */\0/* dead */" 5712 "\0/* dead */\0return bla + 1;\0return bla + 1;" 5713 "\0return bla + 1;\0return func(a);\0b+=1;\0return b;"), 5714 .insns = { 5715 BPF_MOV64_IMM(BPF_REG_2, 1), 5716 BPF_JMP_IMM(BPF_JGE, BPF_REG_2, 0, 1), 5717 BPF_CALL_REL(3), 5718 BPF_CALL_REL(5), 5719 BPF_MOV64_IMM(BPF_REG_0, 0), 5720 BPF_EXIT_INSN(), 5721 BPF_MOV64_IMM(BPF_REG_0, 0), 5722 BPF_CALL_REL(1), 5723 BPF_EXIT_INSN(), 5724 BPF_JMP_IMM(BPF_JA, 0, 0, 0), 5725 BPF_MOV64_REG(BPF_REG_0, 2), 5726 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1), 5727 BPF_EXIT_INSN(), 5728 }, 5729 .prog_type = BPF_PROG_TYPE_TRACEPOINT, 5730 .func_info_cnt = 3, 5731 .func_info_rec_size = 8, 5732 .func_info = { {0, 4}, {6, 3}, {9, 5} }, 5733 .line_info = { 5734 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10), 5735 BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 1, 10), 5736 BPF_LINE_INFO_ENC(4, 0, NAME_TBD, 1, 10), 5737 BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 1, 10), 5738 BPF_LINE_INFO_ENC(6, 0, NAME_TBD, 1, 10), 5739 BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 1, 10), 5740 BPF_LINE_INFO_ENC(8, 0, NAME_TBD, 1, 10), 5741 BPF_LINE_INFO_ENC(9, 0, NAME_TBD, 1, 10), 5742 BPF_LINE_INFO_ENC(11, 0, NAME_TBD, 1, 10), 5743 BPF_LINE_INFO_ENC(12, 0, NAME_TBD, 2, 9), 5744 BTF_END_RAW, 5745 }, 5746 .line_info_rec_size = sizeof(struct bpf_line_info), 5747 .nr_jited_ksyms = 2, 5748 .dead_code_cnt = 3, 5749 .dead_code_mask = 0x70, 5750 .dead_func_cnt = 1, 5751 .dead_func_mask = 0x2, 5752}, 5753 5754{ 5755 .descr = "line_info (dead end + subprog start w/ no linfo)", 5756 .raw_types = { 5757 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 5758 BTF_FUNC_PROTO_ENC(1, 1), /* [2] */ 5759 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1), 5760 BTF_FUNC_ENC(NAME_TBD, 2), /* [3] */ 5761 BTF_FUNC_ENC(NAME_TBD, 2), /* [4] */ 5762 BTF_END_RAW, 5763 }, 5764 BTF_STR_SEC("\0int\0x\0main\0func\0/* main linfo */\0/* func linfo */"), 5765 .insns = { 5766 BPF_MOV64_IMM(BPF_REG_0, 0), 5767 BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 1, 3), 5768 BPF_CALL_REL(3), 5769 BPF_MOV64_IMM(BPF_REG_0, 0), 5770 BPF_EXIT_INSN(), 5771 BPF_EXIT_INSN(), 5772 BPF_JMP_IMM(BPF_JA, 0, 0, 0), 5773 BPF_EXIT_INSN(), 5774 }, 5775 .prog_type = BPF_PROG_TYPE_TRACEPOINT, 5776 .func_info_cnt = 2, 5777 .func_info_rec_size = 8, 5778 .func_info = { {0, 3}, {6, 4}, }, 5779 .line_info = { 5780 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10), 5781 BPF_LINE_INFO_ENC(6, 0, NAME_TBD, 1, 10), 5782 BTF_END_RAW, 5783 }, 5784 .line_info_rec_size = sizeof(struct bpf_line_info), 5785 .nr_jited_ksyms = 2, 5786}, 5787 5788}; 5789 5790static size_t probe_prog_length(const struct bpf_insn *fp) 5791{ 5792 size_t len; 5793 5794 for (len = MAX_INSNS - 1; len > 0; --len) 5795 if (fp[len].code != 0 || fp[len].imm != 0) 5796 break; 5797 return len + 1; 5798} 5799 5800static __u32 *patch_name_tbd(const __u32 *raw_u32, 5801 const char *str, __u32 str_off, 5802 unsigned int str_sec_size, 5803 unsigned int *ret_size) 5804{ 5805 int i, raw_u32_size = get_raw_sec_size(raw_u32); 5806 const char *end_str = str + str_sec_size; 5807 const char *next_str = str + str_off; 5808 __u32 *new_u32 = NULL; 5809 5810 if (raw_u32_size == -1) 5811 return ERR_PTR(-EINVAL); 5812 5813 if (!raw_u32_size) { 5814 *ret_size = 0; 5815 return NULL; 5816 } 5817 5818 new_u32 = malloc(raw_u32_size); 5819 if (!new_u32) 5820 return ERR_PTR(-ENOMEM); 5821 5822 for (i = 0; i < raw_u32_size / sizeof(raw_u32[0]); i++) { 5823 if (raw_u32[i] == NAME_TBD) { 5824 next_str = get_next_str(next_str, end_str); 5825 if (CHECK(!next_str, "Error in getting next_str\n")) { 5826 free(new_u32); 5827 return ERR_PTR(-EINVAL); 5828 } 5829 new_u32[i] = next_str - str; 5830 next_str += strlen(next_str); 5831 } else { 5832 new_u32[i] = raw_u32[i]; 5833 } 5834 } 5835 5836 *ret_size = raw_u32_size; 5837 return new_u32; 5838} 5839 5840static int test_get_finfo(const struct prog_info_raw_test *test, 5841 int prog_fd) 5842{ 5843 struct bpf_prog_info info = {}; 5844 struct bpf_func_info *finfo; 5845 __u32 info_len, rec_size, i; 5846 void *func_info = NULL; 5847 __u32 nr_func_info; 5848 int err; 5849 5850 /* get necessary lens */ 5851 info_len = sizeof(struct bpf_prog_info); 5852 err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len); 5853 if (CHECK(err == -1, "invalid get info (1st) errno:%d", errno)) { 5854 fprintf(stderr, "%s\n", btf_log_buf); 5855 return -1; 5856 } 5857 nr_func_info = test->func_info_cnt - test->dead_func_cnt; 5858 if (CHECK(info.nr_func_info != nr_func_info, 5859 "incorrect info.nr_func_info (1st) %d", 5860 info.nr_func_info)) { 5861 return -1; 5862 } 5863 5864 rec_size = info.func_info_rec_size; 5865 if (CHECK(rec_size != sizeof(struct bpf_func_info), 5866 "incorrect info.func_info_rec_size (1st) %d", rec_size)) { 5867 return -1; 5868 } 5869 5870 if (!info.nr_func_info) 5871 return 0; 5872 5873 func_info = malloc(info.nr_func_info * rec_size); 5874 if (CHECK(!func_info, "out of memory")) 5875 return -1; 5876 5877 /* reset info to only retrieve func_info related data */ 5878 memset(&info, 0, sizeof(info)); 5879 info.nr_func_info = nr_func_info; 5880 info.func_info_rec_size = rec_size; 5881 info.func_info = ptr_to_u64(func_info); 5882 err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len); 5883 if (CHECK(err == -1, "invalid get info (2nd) errno:%d", errno)) { 5884 fprintf(stderr, "%s\n", btf_log_buf); 5885 err = -1; 5886 goto done; 5887 } 5888 if (CHECK(info.nr_func_info != nr_func_info, 5889 "incorrect info.nr_func_info (2nd) %d", 5890 info.nr_func_info)) { 5891 err = -1; 5892 goto done; 5893 } 5894 if (CHECK(info.func_info_rec_size != rec_size, 5895 "incorrect info.func_info_rec_size (2nd) %d", 5896 info.func_info_rec_size)) { 5897 err = -1; 5898 goto done; 5899 } 5900 5901 finfo = func_info; 5902 for (i = 0; i < nr_func_info; i++) { 5903 if (test->dead_func_mask & (1 << i)) 5904 continue; 5905 if (CHECK(finfo->type_id != test->func_info[i][1], 5906 "incorrect func_type %u expected %u", 5907 finfo->type_id, test->func_info[i][1])) { 5908 err = -1; 5909 goto done; 5910 } 5911 finfo = (void *)finfo + rec_size; 5912 } 5913 5914 err = 0; 5915 5916done: 5917 free(func_info); 5918 return err; 5919} 5920 5921static int test_get_linfo(const struct prog_info_raw_test *test, 5922 const void *patched_linfo, 5923 __u32 cnt, int prog_fd) 5924{ 5925 __u32 i, info_len, nr_jited_ksyms, nr_jited_func_lens; 5926 __u64 *jited_linfo = NULL, *jited_ksyms = NULL; 5927 __u32 rec_size, jited_rec_size, jited_cnt; 5928 struct bpf_line_info *linfo = NULL; 5929 __u32 cur_func_len, ksyms_found; 5930 struct bpf_prog_info info = {}; 5931 __u32 *jited_func_lens = NULL; 5932 __u64 cur_func_ksyms; 5933 __u32 dead_insns; 5934 int err; 5935 5936 jited_cnt = cnt; 5937 rec_size = sizeof(*linfo); 5938 jited_rec_size = sizeof(*jited_linfo); 5939 if (test->nr_jited_ksyms) 5940 nr_jited_ksyms = test->nr_jited_ksyms; 5941 else 5942 nr_jited_ksyms = test->func_info_cnt - test->dead_func_cnt; 5943 nr_jited_func_lens = nr_jited_ksyms; 5944 5945 info_len = sizeof(struct bpf_prog_info); 5946 err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len); 5947 if (CHECK(err == -1, "err:%d errno:%d", err, errno)) { 5948 err = -1; 5949 goto done; 5950 } 5951 5952 if (!info.jited_prog_len) { 5953 /* prog is not jited */ 5954 jited_cnt = 0; 5955 nr_jited_ksyms = 1; 5956 nr_jited_func_lens = 1; 5957 } 5958 5959 if (CHECK(info.nr_line_info != cnt || 5960 info.nr_jited_line_info != jited_cnt || 5961 info.nr_jited_ksyms != nr_jited_ksyms || 5962 info.nr_jited_func_lens != nr_jited_func_lens || 5963 (!info.nr_line_info && info.nr_jited_line_info), 5964 "info: nr_line_info:%u(expected:%u) nr_jited_line_info:%u(expected:%u) nr_jited_ksyms:%u(expected:%u) nr_jited_func_lens:%u(expected:%u)", 5965 info.nr_line_info, cnt, 5966 info.nr_jited_line_info, jited_cnt, 5967 info.nr_jited_ksyms, nr_jited_ksyms, 5968 info.nr_jited_func_lens, nr_jited_func_lens)) { 5969 err = -1; 5970 goto done; 5971 } 5972 5973 if (CHECK(info.line_info_rec_size != sizeof(struct bpf_line_info) || 5974 info.jited_line_info_rec_size != sizeof(__u64), 5975 "info: line_info_rec_size:%u(userspace expected:%u) jited_line_info_rec_size:%u(userspace expected:%u)", 5976 info.line_info_rec_size, rec_size, 5977 info.jited_line_info_rec_size, jited_rec_size)) { 5978 err = -1; 5979 goto done; 5980 } 5981 5982 if (!cnt) 5983 return 0; 5984 5985 rec_size = info.line_info_rec_size; 5986 jited_rec_size = info.jited_line_info_rec_size; 5987 5988 memset(&info, 0, sizeof(info)); 5989 5990 linfo = calloc(cnt, rec_size); 5991 if (CHECK(!linfo, "!linfo")) { 5992 err = -1; 5993 goto done; 5994 } 5995 info.nr_line_info = cnt; 5996 info.line_info_rec_size = rec_size; 5997 info.line_info = ptr_to_u64(linfo); 5998 5999 if (jited_cnt) { 6000 jited_linfo = calloc(jited_cnt, jited_rec_size); 6001 jited_ksyms = calloc(nr_jited_ksyms, sizeof(*jited_ksyms)); 6002 jited_func_lens = calloc(nr_jited_func_lens, 6003 sizeof(*jited_func_lens)); 6004 if (CHECK(!jited_linfo || !jited_ksyms || !jited_func_lens, 6005 "jited_linfo:%p jited_ksyms:%p jited_func_lens:%p", 6006 jited_linfo, jited_ksyms, jited_func_lens)) { 6007 err = -1; 6008 goto done; 6009 } 6010 6011 info.nr_jited_line_info = jited_cnt; 6012 info.jited_line_info_rec_size = jited_rec_size; 6013 info.jited_line_info = ptr_to_u64(jited_linfo); 6014 info.nr_jited_ksyms = nr_jited_ksyms; 6015 info.jited_ksyms = ptr_to_u64(jited_ksyms); 6016 info.nr_jited_func_lens = nr_jited_func_lens; 6017 info.jited_func_lens = ptr_to_u64(jited_func_lens); 6018 } 6019 6020 err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len); 6021 6022 /* 6023 * Only recheck the info.*line_info* fields. 6024 * Other fields are not the concern of this test. 6025 */ 6026 if (CHECK(err == -1 || 6027 info.nr_line_info != cnt || 6028 (jited_cnt && !info.jited_line_info) || 6029 info.nr_jited_line_info != jited_cnt || 6030 info.line_info_rec_size != rec_size || 6031 info.jited_line_info_rec_size != jited_rec_size, 6032 "err:%d errno:%d info: nr_line_info:%u(expected:%u) nr_jited_line_info:%u(expected:%u) line_info_rec_size:%u(expected:%u) jited_linfo_rec_size:%u(expected:%u) line_info:%p jited_line_info:%p", 6033 err, errno, 6034 info.nr_line_info, cnt, 6035 info.nr_jited_line_info, jited_cnt, 6036 info.line_info_rec_size, rec_size, 6037 info.jited_line_info_rec_size, jited_rec_size, 6038 (void *)(long)info.line_info, 6039 (void *)(long)info.jited_line_info)) { 6040 err = -1; 6041 goto done; 6042 } 6043 6044 dead_insns = 0; 6045 while (test->dead_code_mask & (1 << dead_insns)) 6046 dead_insns++; 6047 6048 CHECK(linfo[0].insn_off, "linfo[0].insn_off:%u", 6049 linfo[0].insn_off); 6050 for (i = 1; i < cnt; i++) { 6051 const struct bpf_line_info *expected_linfo; 6052 6053 while (test->dead_code_mask & (1 << (i + dead_insns))) 6054 dead_insns++; 6055 6056 expected_linfo = patched_linfo + 6057 ((i + dead_insns) * test->line_info_rec_size); 6058 if (CHECK(linfo[i].insn_off <= linfo[i - 1].insn_off, 6059 "linfo[%u].insn_off:%u <= linfo[%u].insn_off:%u", 6060 i, linfo[i].insn_off, 6061 i - 1, linfo[i - 1].insn_off)) { 6062 err = -1; 6063 goto done; 6064 } 6065 if (CHECK(linfo[i].file_name_off != expected_linfo->file_name_off || 6066 linfo[i].line_off != expected_linfo->line_off || 6067 linfo[i].line_col != expected_linfo->line_col, 6068 "linfo[%u] (%u, %u, %u) != (%u, %u, %u)", i, 6069 linfo[i].file_name_off, 6070 linfo[i].line_off, 6071 linfo[i].line_col, 6072 expected_linfo->file_name_off, 6073 expected_linfo->line_off, 6074 expected_linfo->line_col)) { 6075 err = -1; 6076 goto done; 6077 } 6078 } 6079 6080 if (!jited_cnt) { 6081 fprintf(stderr, "not jited. skipping jited_line_info check. "); 6082 err = 0; 6083 goto done; 6084 } 6085 6086 if (CHECK(jited_linfo[0] != jited_ksyms[0], 6087 "jited_linfo[0]:%lx != jited_ksyms[0]:%lx", 6088 (long)(jited_linfo[0]), (long)(jited_ksyms[0]))) { 6089 err = -1; 6090 goto done; 6091 } 6092 6093 ksyms_found = 1; 6094 cur_func_len = jited_func_lens[0]; 6095 cur_func_ksyms = jited_ksyms[0]; 6096 for (i = 1; i < jited_cnt; i++) { 6097 if (ksyms_found < nr_jited_ksyms && 6098 jited_linfo[i] == jited_ksyms[ksyms_found]) { 6099 cur_func_ksyms = jited_ksyms[ksyms_found]; 6100 cur_func_len = jited_ksyms[ksyms_found]; 6101 ksyms_found++; 6102 continue; 6103 } 6104 6105 if (CHECK(jited_linfo[i] <= jited_linfo[i - 1], 6106 "jited_linfo[%u]:%lx <= jited_linfo[%u]:%lx", 6107 i, (long)jited_linfo[i], 6108 i - 1, (long)(jited_linfo[i - 1]))) { 6109 err = -1; 6110 goto done; 6111 } 6112 6113 if (CHECK(jited_linfo[i] - cur_func_ksyms > cur_func_len, 6114 "jited_linfo[%u]:%lx - %lx > %u", 6115 i, (long)jited_linfo[i], (long)cur_func_ksyms, 6116 cur_func_len)) { 6117 err = -1; 6118 goto done; 6119 } 6120 } 6121 6122 if (CHECK(ksyms_found != nr_jited_ksyms, 6123 "ksyms_found:%u != nr_jited_ksyms:%u", 6124 ksyms_found, nr_jited_ksyms)) { 6125 err = -1; 6126 goto done; 6127 } 6128 6129 err = 0; 6130 6131done: 6132 free(linfo); 6133 free(jited_linfo); 6134 free(jited_ksyms); 6135 free(jited_func_lens); 6136 return err; 6137} 6138 6139static int do_test_info_raw(unsigned int test_num) 6140{ 6141 const struct prog_info_raw_test *test = &info_raw_tests[test_num - 1]; 6142 unsigned int raw_btf_size, linfo_str_off, linfo_size; 6143 int btf_fd = -1, prog_fd = -1, err = 0; 6144 void *raw_btf, *patched_linfo = NULL; 6145 const char *ret_next_str; 6146 union bpf_attr attr = {}; 6147 6148 fprintf(stderr, "BTF prog info raw test[%u] (%s): ", test_num, test->descr); 6149 raw_btf = btf_raw_create(&hdr_tmpl, test->raw_types, 6150 test->str_sec, test->str_sec_size, 6151 &raw_btf_size, &ret_next_str); 6152 6153 if (!raw_btf) 6154 return -1; 6155 6156 *btf_log_buf = '\0'; 6157 btf_fd = bpf_load_btf(raw_btf, raw_btf_size, 6158 btf_log_buf, BTF_LOG_BUF_SIZE, 6159 args.always_log); 6160 free(raw_btf); 6161 6162 if (CHECK(btf_fd == -1, "invalid btf_fd errno:%d", errno)) { 6163 err = -1; 6164 goto done; 6165 } 6166 6167 if (*btf_log_buf && args.always_log) 6168 fprintf(stderr, "\n%s", btf_log_buf); 6169 *btf_log_buf = '\0'; 6170 6171 linfo_str_off = ret_next_str - test->str_sec; 6172 patched_linfo = patch_name_tbd(test->line_info, 6173 test->str_sec, linfo_str_off, 6174 test->str_sec_size, &linfo_size); 6175 if (IS_ERR(patched_linfo)) { 6176 fprintf(stderr, "error in creating raw bpf_line_info"); 6177 err = -1; 6178 goto done; 6179 } 6180 6181 attr.prog_type = test->prog_type; 6182 attr.insns = ptr_to_u64(test->insns); 6183 attr.insn_cnt = probe_prog_length(test->insns); 6184 attr.license = ptr_to_u64("GPL"); 6185 attr.prog_btf_fd = btf_fd; 6186 attr.func_info_rec_size = test->func_info_rec_size; 6187 attr.func_info_cnt = test->func_info_cnt; 6188 attr.func_info = ptr_to_u64(test->func_info); 6189 attr.log_buf = ptr_to_u64(btf_log_buf); 6190 attr.log_size = BTF_LOG_BUF_SIZE; 6191 attr.log_level = 1; 6192 if (linfo_size) { 6193 attr.line_info_rec_size = test->line_info_rec_size; 6194 attr.line_info = ptr_to_u64(patched_linfo); 6195 attr.line_info_cnt = linfo_size / attr.line_info_rec_size; 6196 } 6197 6198 prog_fd = syscall(__NR_bpf, BPF_PROG_LOAD, &attr, sizeof(attr)); 6199 err = ((prog_fd == -1) != test->expected_prog_load_failure); 6200 if (CHECK(err, "prog_fd:%d expected_prog_load_failure:%u errno:%d", 6201 prog_fd, test->expected_prog_load_failure, errno) || 6202 CHECK(test->err_str && !strstr(btf_log_buf, test->err_str), 6203 "expected err_str:%s", test->err_str)) { 6204 err = -1; 6205 goto done; 6206 } 6207 6208 if (prog_fd == -1) 6209 goto done; 6210 6211 err = test_get_finfo(test, prog_fd); 6212 if (err) 6213 goto done; 6214 6215 err = test_get_linfo(test, patched_linfo, 6216 attr.line_info_cnt - test->dead_code_cnt, 6217 prog_fd); 6218 if (err) 6219 goto done; 6220 6221done: 6222 if (!err) 6223 fprintf(stderr, "OK"); 6224 6225 if (*btf_log_buf && (err || args.always_log)) 6226 fprintf(stderr, "\n%s", btf_log_buf); 6227 6228 if (btf_fd != -1) 6229 close(btf_fd); 6230 if (prog_fd != -1) 6231 close(prog_fd); 6232 6233 if (!IS_ERR(patched_linfo)) 6234 free(patched_linfo); 6235 6236 return err; 6237} 6238 6239static int test_info_raw(void) 6240{ 6241 unsigned int i; 6242 int err = 0; 6243 6244 if (args.info_raw_test_num) 6245 return count_result(do_test_info_raw(args.info_raw_test_num)); 6246 6247 for (i = 1; i <= ARRAY_SIZE(info_raw_tests); i++) 6248 err |= count_result(do_test_info_raw(i)); 6249 6250 return err; 6251} 6252 6253struct btf_raw_data { 6254 __u32 raw_types[MAX_NR_RAW_U32]; 6255 const char *str_sec; 6256 __u32 str_sec_size; 6257}; 6258 6259struct btf_dedup_test { 6260 const char *descr; 6261 struct btf_raw_data input; 6262 struct btf_raw_data expect; 6263 struct btf_dedup_opts opts; 6264}; 6265 6266const struct btf_dedup_test dedup_tests[] = { 6267 6268{ 6269 .descr = "dedup: unused strings filtering", 6270 .input = { 6271 .raw_types = { 6272 BTF_TYPE_INT_ENC(NAME_NTH(2), BTF_INT_SIGNED, 0, 32, 4), 6273 BTF_TYPE_INT_ENC(NAME_NTH(5), BTF_INT_SIGNED, 0, 64, 8), 6274 BTF_END_RAW, 6275 }, 6276 BTF_STR_SEC("\0unused\0int\0foo\0bar\0long"), 6277 }, 6278 .expect = { 6279 .raw_types = { 6280 BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4), 6281 BTF_TYPE_INT_ENC(NAME_NTH(2), BTF_INT_SIGNED, 0, 64, 8), 6282 BTF_END_RAW, 6283 }, 6284 BTF_STR_SEC("\0int\0long"), 6285 }, 6286 .opts = { 6287 .dont_resolve_fwds = false, 6288 }, 6289}, 6290{ 6291 .descr = "dedup: strings deduplication", 6292 .input = { 6293 .raw_types = { 6294 BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4), 6295 BTF_TYPE_INT_ENC(NAME_NTH(2), BTF_INT_SIGNED, 0, 64, 8), 6296 BTF_TYPE_INT_ENC(NAME_NTH(3), BTF_INT_SIGNED, 0, 32, 4), 6297 BTF_TYPE_INT_ENC(NAME_NTH(4), BTF_INT_SIGNED, 0, 64, 8), 6298 BTF_TYPE_INT_ENC(NAME_NTH(5), BTF_INT_SIGNED, 0, 32, 4), 6299 BTF_END_RAW, 6300 }, 6301 BTF_STR_SEC("\0int\0long int\0int\0long int\0int"), 6302 }, 6303 .expect = { 6304 .raw_types = { 6305 BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4), 6306 BTF_TYPE_INT_ENC(NAME_NTH(2), BTF_INT_SIGNED, 0, 64, 8), 6307 BTF_END_RAW, 6308 }, 6309 BTF_STR_SEC("\0int\0long int"), 6310 }, 6311 .opts = { 6312 .dont_resolve_fwds = false, 6313 }, 6314}, 6315{ 6316 .descr = "dedup: struct example #1", 6317 /* 6318 * struct s { 6319 * struct s *next; 6320 * const int *a; 6321 * int b[16]; 6322 * int c; 6323 * } 6324 */ 6325 .input = { 6326 .raw_types = { 6327 /* int */ 6328 BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 6329 /* int[16] */ 6330 BTF_TYPE_ARRAY_ENC(1, 1, 16), /* [2] */ 6331 /* struct s { */ 6332 BTF_STRUCT_ENC(NAME_NTH(2), 4, 84), /* [3] */ 6333 BTF_MEMBER_ENC(NAME_NTH(3), 4, 0), /* struct s *next; */ 6334 BTF_MEMBER_ENC(NAME_NTH(4), 5, 64), /* const int *a; */ 6335 BTF_MEMBER_ENC(NAME_NTH(5), 2, 128), /* int b[16]; */ 6336 BTF_MEMBER_ENC(NAME_NTH(6), 1, 640), /* int c; */ 6337 /* ptr -> [3] struct s */ 6338 BTF_PTR_ENC(3), /* [4] */ 6339 /* ptr -> [6] const int */ 6340 BTF_PTR_ENC(6), /* [5] */ 6341 /* const -> [1] int */ 6342 BTF_CONST_ENC(1), /* [6] */ 6343 6344 /* full copy of the above */ 6345 BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4), /* [7] */ 6346 BTF_TYPE_ARRAY_ENC(7, 7, 16), /* [8] */ 6347 BTF_STRUCT_ENC(NAME_NTH(2), 4, 84), /* [9] */ 6348 BTF_MEMBER_ENC(NAME_NTH(3), 10, 0), 6349 BTF_MEMBER_ENC(NAME_NTH(4), 11, 64), 6350 BTF_MEMBER_ENC(NAME_NTH(5), 8, 128), 6351 BTF_MEMBER_ENC(NAME_NTH(6), 7, 640), 6352 BTF_PTR_ENC(9), /* [10] */ 6353 BTF_PTR_ENC(12), /* [11] */ 6354 BTF_CONST_ENC(7), /* [12] */ 6355 BTF_END_RAW, 6356 }, 6357 BTF_STR_SEC("\0int\0s\0next\0a\0b\0c\0"), 6358 }, 6359 .expect = { 6360 .raw_types = { 6361 /* int */ 6362 BTF_TYPE_INT_ENC(NAME_NTH(4), BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 6363 /* int[16] */ 6364 BTF_TYPE_ARRAY_ENC(1, 1, 16), /* [2] */ 6365 /* struct s { */ 6366 BTF_STRUCT_ENC(NAME_NTH(6), 4, 84), /* [3] */ 6367 BTF_MEMBER_ENC(NAME_NTH(5), 4, 0), /* struct s *next; */ 6368 BTF_MEMBER_ENC(NAME_NTH(1), 5, 64), /* const int *a; */ 6369 BTF_MEMBER_ENC(NAME_NTH(2), 2, 128), /* int b[16]; */ 6370 BTF_MEMBER_ENC(NAME_NTH(3), 1, 640), /* int c; */ 6371 /* ptr -> [3] struct s */ 6372 BTF_PTR_ENC(3), /* [4] */ 6373 /* ptr -> [6] const int */ 6374 BTF_PTR_ENC(6), /* [5] */ 6375 /* const -> [1] int */ 6376 BTF_CONST_ENC(1), /* [6] */ 6377 BTF_END_RAW, 6378 }, 6379 BTF_STR_SEC("\0a\0b\0c\0int\0next\0s"), 6380 }, 6381 .opts = { 6382 .dont_resolve_fwds = false, 6383 }, 6384}, 6385{ 6386 .descr = "dedup: struct <-> fwd resolution w/ hash collision", 6387 /* 6388 * // CU 1: 6389 * struct x; 6390 * struct s { 6391 * struct x *x; 6392 * }; 6393 * // CU 2: 6394 * struct x {}; 6395 * struct s { 6396 * struct x *x; 6397 * }; 6398 */ 6399 .input = { 6400 .raw_types = { 6401 /* CU 1 */ 6402 BTF_FWD_ENC(NAME_TBD, 0 /* struct fwd */), /* [1] fwd x */ 6403 BTF_PTR_ENC(1), /* [2] ptr -> [1] */ 6404 BTF_STRUCT_ENC(NAME_TBD, 1, 8), /* [3] struct s */ 6405 BTF_MEMBER_ENC(NAME_TBD, 2, 0), 6406 /* CU 2 */ 6407 BTF_STRUCT_ENC(NAME_TBD, 0, 0), /* [4] struct x */ 6408 BTF_PTR_ENC(4), /* [5] ptr -> [4] */ 6409 BTF_STRUCT_ENC(NAME_TBD, 1, 8), /* [6] struct s */ 6410 BTF_MEMBER_ENC(NAME_TBD, 5, 0), 6411 BTF_END_RAW, 6412 }, 6413 BTF_STR_SEC("\0x\0s\0x\0x\0s\0x\0"), 6414 }, 6415 .expect = { 6416 .raw_types = { 6417 BTF_PTR_ENC(3), /* [1] ptr -> [3] */ 6418 BTF_STRUCT_ENC(NAME_TBD, 1, 8), /* [2] struct s */ 6419 BTF_MEMBER_ENC(NAME_TBD, 1, 0), 6420 BTF_STRUCT_ENC(NAME_NTH(2), 0, 0), /* [3] struct x */ 6421 BTF_END_RAW, 6422 }, 6423 BTF_STR_SEC("\0s\0x"), 6424 }, 6425 .opts = { 6426 .dont_resolve_fwds = false, 6427 .dedup_table_size = 1, /* force hash collisions */ 6428 }, 6429}, 6430{ 6431 .descr = "dedup: void equiv check", 6432 /* 6433 * // CU 1: 6434 * struct s { 6435 * struct {} *x; 6436 * }; 6437 * // CU 2: 6438 * struct s { 6439 * int *x; 6440 * }; 6441 */ 6442 .input = { 6443 .raw_types = { 6444 /* CU 1 */ 6445 BTF_STRUCT_ENC(0, 0, 1), /* [1] struct {} */ 6446 BTF_PTR_ENC(1), /* [2] ptr -> [1] */ 6447 BTF_STRUCT_ENC(NAME_NTH(1), 1, 8), /* [3] struct s */ 6448 BTF_MEMBER_ENC(NAME_NTH(2), 2, 0), 6449 /* CU 2 */ 6450 BTF_PTR_ENC(0), /* [4] ptr -> void */ 6451 BTF_STRUCT_ENC(NAME_NTH(1), 1, 8), /* [5] struct s */ 6452 BTF_MEMBER_ENC(NAME_NTH(2), 4, 0), 6453 BTF_END_RAW, 6454 }, 6455 BTF_STR_SEC("\0s\0x"), 6456 }, 6457 .expect = { 6458 .raw_types = { 6459 /* CU 1 */ 6460 BTF_STRUCT_ENC(0, 0, 1), /* [1] struct {} */ 6461 BTF_PTR_ENC(1), /* [2] ptr -> [1] */ 6462 BTF_STRUCT_ENC(NAME_NTH(1), 1, 8), /* [3] struct s */ 6463 BTF_MEMBER_ENC(NAME_NTH(2), 2, 0), 6464 /* CU 2 */ 6465 BTF_PTR_ENC(0), /* [4] ptr -> void */ 6466 BTF_STRUCT_ENC(NAME_NTH(1), 1, 8), /* [5] struct s */ 6467 BTF_MEMBER_ENC(NAME_NTH(2), 4, 0), 6468 BTF_END_RAW, 6469 }, 6470 BTF_STR_SEC("\0s\0x"), 6471 }, 6472 .opts = { 6473 .dont_resolve_fwds = false, 6474 .dedup_table_size = 1, /* force hash collisions */ 6475 }, 6476}, 6477{ 6478 .descr = "dedup: all possible kinds (no duplicates)", 6479 .input = { 6480 .raw_types = { 6481 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 8), /* [1] int */ 6482 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 2), 4), /* [2] enum */ 6483 BTF_ENUM_ENC(NAME_TBD, 0), 6484 BTF_ENUM_ENC(NAME_TBD, 1), 6485 BTF_FWD_ENC(NAME_TBD, 1 /* union kind_flag */), /* [3] fwd */ 6486 BTF_TYPE_ARRAY_ENC(2, 1, 7), /* [4] array */ 6487 BTF_STRUCT_ENC(NAME_TBD, 1, 4), /* [5] struct */ 6488 BTF_MEMBER_ENC(NAME_TBD, 1, 0), 6489 BTF_UNION_ENC(NAME_TBD, 1, 4), /* [6] union */ 6490 BTF_MEMBER_ENC(NAME_TBD, 1, 0), 6491 BTF_TYPEDEF_ENC(NAME_TBD, 1), /* [7] typedef */ 6492 BTF_PTR_ENC(0), /* [8] ptr */ 6493 BTF_CONST_ENC(8), /* [9] const */ 6494 BTF_VOLATILE_ENC(8), /* [10] volatile */ 6495 BTF_RESTRICT_ENC(8), /* [11] restrict */ 6496 BTF_FUNC_PROTO_ENC(1, 2), /* [12] func_proto */ 6497 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1), 6498 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 8), 6499 BTF_FUNC_ENC(NAME_TBD, 12), /* [13] func */ 6500 BTF_END_RAW, 6501 }, 6502 BTF_STR_SEC("\0A\0B\0C\0D\0E\0F\0G\0H\0I\0J\0K\0L\0M"), 6503 }, 6504 .expect = { 6505 .raw_types = { 6506 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 8), /* [1] int */ 6507 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 2), 4), /* [2] enum */ 6508 BTF_ENUM_ENC(NAME_TBD, 0), 6509 BTF_ENUM_ENC(NAME_TBD, 1), 6510 BTF_FWD_ENC(NAME_TBD, 1 /* union kind_flag */), /* [3] fwd */ 6511 BTF_TYPE_ARRAY_ENC(2, 1, 7), /* [4] array */ 6512 BTF_STRUCT_ENC(NAME_TBD, 1, 4), /* [5] struct */ 6513 BTF_MEMBER_ENC(NAME_TBD, 1, 0), 6514 BTF_UNION_ENC(NAME_TBD, 1, 4), /* [6] union */ 6515 BTF_MEMBER_ENC(NAME_TBD, 1, 0), 6516 BTF_TYPEDEF_ENC(NAME_TBD, 1), /* [7] typedef */ 6517 BTF_PTR_ENC(0), /* [8] ptr */ 6518 BTF_CONST_ENC(8), /* [9] const */ 6519 BTF_VOLATILE_ENC(8), /* [10] volatile */ 6520 BTF_RESTRICT_ENC(8), /* [11] restrict */ 6521 BTF_FUNC_PROTO_ENC(1, 2), /* [12] func_proto */ 6522 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1), 6523 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 8), 6524 BTF_FUNC_ENC(NAME_TBD, 12), /* [13] func */ 6525 BTF_END_RAW, 6526 }, 6527 BTF_STR_SEC("\0A\0B\0C\0D\0E\0F\0G\0H\0I\0J\0K\0L\0M"), 6528 }, 6529 .opts = { 6530 .dont_resolve_fwds = false, 6531 }, 6532}, 6533{ 6534 .descr = "dedup: no int duplicates", 6535 .input = { 6536 .raw_types = { 6537 BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 8), 6538 /* different name */ 6539 BTF_TYPE_INT_ENC(NAME_NTH(2), BTF_INT_SIGNED, 0, 32, 8), 6540 /* different encoding */ 6541 BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_CHAR, 0, 32, 8), 6542 BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_BOOL, 0, 32, 8), 6543 /* different bit offset */ 6544 BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 8, 32, 8), 6545 /* different bit size */ 6546 BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 27, 8), 6547 /* different byte size */ 6548 BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4), 6549 BTF_END_RAW, 6550 }, 6551 BTF_STR_SEC("\0int\0some other int"), 6552 }, 6553 .expect = { 6554 .raw_types = { 6555 BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 8), 6556 /* different name */ 6557 BTF_TYPE_INT_ENC(NAME_NTH(2), BTF_INT_SIGNED, 0, 32, 8), 6558 /* different encoding */ 6559 BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_CHAR, 0, 32, 8), 6560 BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_BOOL, 0, 32, 8), 6561 /* different bit offset */ 6562 BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 8, 32, 8), 6563 /* different bit size */ 6564 BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 27, 8), 6565 /* different byte size */ 6566 BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4), 6567 BTF_END_RAW, 6568 }, 6569 BTF_STR_SEC("\0int\0some other int"), 6570 }, 6571 .opts = { 6572 .dont_resolve_fwds = false, 6573 }, 6574}, 6575{ 6576 .descr = "dedup: enum fwd resolution", 6577 .input = { 6578 .raw_types = { 6579 /* [1] fwd enum 'e1' before full enum */ 6580 BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 0), 4), 6581 /* [2] full enum 'e1' after fwd */ 6582 BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4), 6583 BTF_ENUM_ENC(NAME_NTH(2), 123), 6584 /* [3] full enum 'e2' before fwd */ 6585 BTF_TYPE_ENC(NAME_NTH(3), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4), 6586 BTF_ENUM_ENC(NAME_NTH(4), 456), 6587 /* [4] fwd enum 'e2' after full enum */ 6588 BTF_TYPE_ENC(NAME_NTH(3), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 0), 4), 6589 /* [5] incompatible fwd enum with different size */ 6590 BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 0), 1), 6591 /* [6] incompatible full enum with different value */ 6592 BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4), 6593 BTF_ENUM_ENC(NAME_NTH(2), 321), 6594 BTF_END_RAW, 6595 }, 6596 BTF_STR_SEC("\0e1\0e1_val\0e2\0e2_val"), 6597 }, 6598 .expect = { 6599 .raw_types = { 6600 /* [1] full enum 'e1' */ 6601 BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4), 6602 BTF_ENUM_ENC(NAME_NTH(2), 123), 6603 /* [2] full enum 'e2' */ 6604 BTF_TYPE_ENC(NAME_NTH(3), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4), 6605 BTF_ENUM_ENC(NAME_NTH(4), 456), 6606 /* [3] incompatible fwd enum with different size */ 6607 BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 0), 1), 6608 /* [4] incompatible full enum with different value */ 6609 BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4), 6610 BTF_ENUM_ENC(NAME_NTH(2), 321), 6611 BTF_END_RAW, 6612 }, 6613 BTF_STR_SEC("\0e1\0e1_val\0e2\0e2_val"), 6614 }, 6615 .opts = { 6616 .dont_resolve_fwds = false, 6617 }, 6618}, 6619{ 6620 .descr = "dedup: datasec and vars pass-through", 6621 .input = { 6622 .raw_types = { 6623 /* int */ 6624 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 6625 /* static int t */ 6626 BTF_VAR_ENC(NAME_NTH(2), 1, 0), /* [2] */ 6627 /* .bss section */ /* [3] */ 6628 BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4), 6629 BTF_VAR_SECINFO_ENC(2, 0, 4), 6630 /* int, referenced from [5] */ 6631 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [4] */ 6632 /* another static int t */ 6633 BTF_VAR_ENC(NAME_NTH(2), 4, 0), /* [5] */ 6634 /* another .bss section */ /* [6] */ 6635 BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4), 6636 BTF_VAR_SECINFO_ENC(5, 0, 4), 6637 BTF_END_RAW, 6638 }, 6639 BTF_STR_SEC("\0.bss\0t"), 6640 }, 6641 .expect = { 6642 .raw_types = { 6643 /* int */ 6644 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 6645 /* static int t */ 6646 BTF_VAR_ENC(NAME_NTH(2), 1, 0), /* [2] */ 6647 /* .bss section */ /* [3] */ 6648 BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4), 6649 BTF_VAR_SECINFO_ENC(2, 0, 4), 6650 /* another static int t */ 6651 BTF_VAR_ENC(NAME_NTH(2), 1, 0), /* [4] */ 6652 /* another .bss section */ /* [5] */ 6653 BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4), 6654 BTF_VAR_SECINFO_ENC(4, 0, 4), 6655 BTF_END_RAW, 6656 }, 6657 BTF_STR_SEC("\0.bss\0t"), 6658 }, 6659 .opts = { 6660 .dont_resolve_fwds = false, 6661 .dedup_table_size = 1 6662 }, 6663}, 6664 6665}; 6666 6667static int btf_type_size(const struct btf_type *t) 6668{ 6669 int base_size = sizeof(struct btf_type); 6670 __u16 vlen = BTF_INFO_VLEN(t->info); 6671 __u16 kind = BTF_INFO_KIND(t->info); 6672 6673 switch (kind) { 6674 case BTF_KIND_FWD: 6675 case BTF_KIND_CONST: 6676 case BTF_KIND_VOLATILE: 6677 case BTF_KIND_RESTRICT: 6678 case BTF_KIND_PTR: 6679 case BTF_KIND_TYPEDEF: 6680 case BTF_KIND_FUNC: 6681 return base_size; 6682 case BTF_KIND_INT: 6683 return base_size + sizeof(__u32); 6684 case BTF_KIND_ENUM: 6685 return base_size + vlen * sizeof(struct btf_enum); 6686 case BTF_KIND_ARRAY: 6687 return base_size + sizeof(struct btf_array); 6688 case BTF_KIND_STRUCT: 6689 case BTF_KIND_UNION: 6690 return base_size + vlen * sizeof(struct btf_member); 6691 case BTF_KIND_FUNC_PROTO: 6692 return base_size + vlen * sizeof(struct btf_param); 6693 case BTF_KIND_VAR: 6694 return base_size + sizeof(struct btf_var); 6695 case BTF_KIND_DATASEC: 6696 return base_size + vlen * sizeof(struct btf_var_secinfo); 6697 default: 6698 fprintf(stderr, "Unsupported BTF_KIND:%u\n", kind); 6699 return -EINVAL; 6700 } 6701} 6702 6703static void dump_btf_strings(const char *strs, __u32 len) 6704{ 6705 const char *cur = strs; 6706 int i = 0; 6707 6708 while (cur < strs + len) { 6709 fprintf(stderr, "string #%d: '%s'\n", i, cur); 6710 cur += strlen(cur) + 1; 6711 i++; 6712 } 6713} 6714 6715static int do_test_dedup(unsigned int test_num) 6716{ 6717 const struct btf_dedup_test *test = &dedup_tests[test_num - 1]; 6718 __u32 test_nr_types, expect_nr_types, test_btf_size, expect_btf_size; 6719 const struct btf_header *test_hdr, *expect_hdr; 6720 struct btf *test_btf = NULL, *expect_btf = NULL; 6721 const void *test_btf_data, *expect_btf_data; 6722 const char *ret_test_next_str, *ret_expect_next_str; 6723 const char *test_strs, *expect_strs; 6724 const char *test_str_cur, *test_str_end; 6725 const char *expect_str_cur, *expect_str_end; 6726 unsigned int raw_btf_size; 6727 void *raw_btf; 6728 int err = 0, i; 6729 6730 fprintf(stderr, "BTF dedup test[%u] (%s):", test_num, test->descr); 6731 6732 raw_btf = btf_raw_create(&hdr_tmpl, test->input.raw_types, 6733 test->input.str_sec, test->input.str_sec_size, 6734 &raw_btf_size, &ret_test_next_str); 6735 if (!raw_btf) 6736 return -1; 6737 test_btf = btf__new((__u8 *)raw_btf, raw_btf_size); 6738 free(raw_btf); 6739 if (CHECK(IS_ERR(test_btf), "invalid test_btf errno:%ld", 6740 PTR_ERR(test_btf))) { 6741 err = -1; 6742 goto done; 6743 } 6744 6745 raw_btf = btf_raw_create(&hdr_tmpl, test->expect.raw_types, 6746 test->expect.str_sec, 6747 test->expect.str_sec_size, 6748 &raw_btf_size, &ret_expect_next_str); 6749 if (!raw_btf) 6750 return -1; 6751 expect_btf = btf__new((__u8 *)raw_btf, raw_btf_size); 6752 free(raw_btf); 6753 if (CHECK(IS_ERR(expect_btf), "invalid expect_btf errno:%ld", 6754 PTR_ERR(expect_btf))) { 6755 err = -1; 6756 goto done; 6757 } 6758 6759 err = btf__dedup(test_btf, NULL, &test->opts); 6760 if (CHECK(err, "btf_dedup failed errno:%d", err)) { 6761 err = -1; 6762 goto done; 6763 } 6764 6765 test_btf_data = btf__get_raw_data(test_btf, &test_btf_size); 6766 expect_btf_data = btf__get_raw_data(expect_btf, &expect_btf_size); 6767 if (CHECK(test_btf_size != expect_btf_size, 6768 "test_btf_size:%u != expect_btf_size:%u", 6769 test_btf_size, expect_btf_size)) { 6770 err = -1; 6771 goto done; 6772 } 6773 6774 test_hdr = test_btf_data; 6775 test_strs = test_btf_data + sizeof(*test_hdr) + test_hdr->str_off; 6776 expect_hdr = expect_btf_data; 6777 expect_strs = expect_btf_data + sizeof(*test_hdr) + expect_hdr->str_off; 6778 if (CHECK(test_hdr->str_len != expect_hdr->str_len, 6779 "test_hdr->str_len:%u != expect_hdr->str_len:%u", 6780 test_hdr->str_len, expect_hdr->str_len)) { 6781 fprintf(stderr, "\ntest strings:\n"); 6782 dump_btf_strings(test_strs, test_hdr->str_len); 6783 fprintf(stderr, "\nexpected strings:\n"); 6784 dump_btf_strings(expect_strs, expect_hdr->str_len); 6785 err = -1; 6786 goto done; 6787 } 6788 6789 test_str_cur = test_strs; 6790 test_str_end = test_strs + test_hdr->str_len; 6791 expect_str_cur = expect_strs; 6792 expect_str_end = expect_strs + expect_hdr->str_len; 6793 while (test_str_cur < test_str_end && expect_str_cur < expect_str_end) { 6794 size_t test_len, expect_len; 6795 6796 test_len = strlen(test_str_cur); 6797 expect_len = strlen(expect_str_cur); 6798 if (CHECK(test_len != expect_len, 6799 "test_len:%zu != expect_len:%zu " 6800 "(test_str:%s, expect_str:%s)", 6801 test_len, expect_len, test_str_cur, expect_str_cur)) { 6802 err = -1; 6803 goto done; 6804 } 6805 if (CHECK(strcmp(test_str_cur, expect_str_cur), 6806 "test_str:%s != expect_str:%s", 6807 test_str_cur, expect_str_cur)) { 6808 err = -1; 6809 goto done; 6810 } 6811 test_str_cur += test_len + 1; 6812 expect_str_cur += expect_len + 1; 6813 } 6814 if (CHECK(test_str_cur != test_str_end, 6815 "test_str_cur:%p != test_str_end:%p", 6816 test_str_cur, test_str_end)) { 6817 err = -1; 6818 goto done; 6819 } 6820 6821 test_nr_types = btf__get_nr_types(test_btf); 6822 expect_nr_types = btf__get_nr_types(expect_btf); 6823 if (CHECK(test_nr_types != expect_nr_types, 6824 "test_nr_types:%u != expect_nr_types:%u", 6825 test_nr_types, expect_nr_types)) { 6826 err = -1; 6827 goto done; 6828 } 6829 6830 for (i = 1; i <= test_nr_types; i++) { 6831 const struct btf_type *test_type, *expect_type; 6832 int test_size, expect_size; 6833 6834 test_type = btf__type_by_id(test_btf, i); 6835 expect_type = btf__type_by_id(expect_btf, i); 6836 test_size = btf_type_size(test_type); 6837 expect_size = btf_type_size(expect_type); 6838 6839 if (CHECK(test_size != expect_size, 6840 "type #%d: test_size:%d != expect_size:%u", 6841 i, test_size, expect_size)) { 6842 err = -1; 6843 goto done; 6844 } 6845 if (CHECK(memcmp((void *)test_type, 6846 (void *)expect_type, 6847 test_size), 6848 "type #%d: contents differ", i)) { 6849 err = -1; 6850 goto done; 6851 } 6852 } 6853 6854done: 6855 if (!err) 6856 fprintf(stderr, "OK"); 6857 if (!IS_ERR(test_btf)) 6858 btf__free(test_btf); 6859 if (!IS_ERR(expect_btf)) 6860 btf__free(expect_btf); 6861 6862 return err; 6863} 6864 6865static int test_dedup(void) 6866{ 6867 unsigned int i; 6868 int err = 0; 6869 6870 if (args.dedup_test_num) 6871 return count_result(do_test_dedup(args.dedup_test_num)); 6872 6873 for (i = 1; i <= ARRAY_SIZE(dedup_tests); i++) 6874 err |= count_result(do_test_dedup(i)); 6875 6876 return err; 6877} 6878 6879static void usage(const char *cmd) 6880{ 6881 fprintf(stderr, "Usage: %s [-l] [[-r btf_raw_test_num (1 - %zu)] |\n" 6882 "\t[-g btf_get_info_test_num (1 - %zu)] |\n" 6883 "\t[-f btf_file_test_num (1 - %zu)] |\n" 6884 "\t[-k btf_prog_info_raw_test_num (1 - %zu)] |\n" 6885 "\t[-p (pretty print test)] |\n" 6886 "\t[-d btf_dedup_test_num (1 - %zu)]]\n", 6887 cmd, ARRAY_SIZE(raw_tests), ARRAY_SIZE(get_info_tests), 6888 ARRAY_SIZE(file_tests), ARRAY_SIZE(info_raw_tests), 6889 ARRAY_SIZE(dedup_tests)); 6890} 6891 6892static int parse_args(int argc, char **argv) 6893{ 6894 const char *optstr = "hlpk:f:r:g:d:"; 6895 int opt; 6896 6897 while ((opt = getopt(argc, argv, optstr)) != -1) { 6898 switch (opt) { 6899 case 'l': 6900 args.always_log = true; 6901 break; 6902 case 'f': 6903 args.file_test_num = atoi(optarg); 6904 args.file_test = true; 6905 break; 6906 case 'r': 6907 args.raw_test_num = atoi(optarg); 6908 args.raw_test = true; 6909 break; 6910 case 'g': 6911 args.get_info_test_num = atoi(optarg); 6912 args.get_info_test = true; 6913 break; 6914 case 'p': 6915 args.pprint_test = true; 6916 break; 6917 case 'k': 6918 args.info_raw_test_num = atoi(optarg); 6919 args.info_raw_test = true; 6920 break; 6921 case 'd': 6922 args.dedup_test_num = atoi(optarg); 6923 args.dedup_test = true; 6924 break; 6925 case 'h': 6926 usage(argv[0]); 6927 exit(0); 6928 default: 6929 usage(argv[0]); 6930 return -1; 6931 } 6932 } 6933 6934 if (args.raw_test_num && 6935 (args.raw_test_num < 1 || 6936 args.raw_test_num > ARRAY_SIZE(raw_tests))) { 6937 fprintf(stderr, "BTF raw test number must be [1 - %zu]\n", 6938 ARRAY_SIZE(raw_tests)); 6939 return -1; 6940 } 6941 6942 if (args.file_test_num && 6943 (args.file_test_num < 1 || 6944 args.file_test_num > ARRAY_SIZE(file_tests))) { 6945 fprintf(stderr, "BTF file test number must be [1 - %zu]\n", 6946 ARRAY_SIZE(file_tests)); 6947 return -1; 6948 } 6949 6950 if (args.get_info_test_num && 6951 (args.get_info_test_num < 1 || 6952 args.get_info_test_num > ARRAY_SIZE(get_info_tests))) { 6953 fprintf(stderr, "BTF get info test number must be [1 - %zu]\n", 6954 ARRAY_SIZE(get_info_tests)); 6955 return -1; 6956 } 6957 6958 if (args.info_raw_test_num && 6959 (args.info_raw_test_num < 1 || 6960 args.info_raw_test_num > ARRAY_SIZE(info_raw_tests))) { 6961 fprintf(stderr, "BTF prog info raw test number must be [1 - %zu]\n", 6962 ARRAY_SIZE(info_raw_tests)); 6963 return -1; 6964 } 6965 6966 if (args.dedup_test_num && 6967 (args.dedup_test_num < 1 || 6968 args.dedup_test_num > ARRAY_SIZE(dedup_tests))) { 6969 fprintf(stderr, "BTF dedup test number must be [1 - %zu]\n", 6970 ARRAY_SIZE(dedup_tests)); 6971 return -1; 6972 } 6973 6974 return 0; 6975} 6976 6977static void print_summary(void) 6978{ 6979 fprintf(stderr, "PASS:%u SKIP:%u FAIL:%u\n", 6980 pass_cnt - skip_cnt, skip_cnt, error_cnt); 6981} 6982 6983int main(int argc, char **argv) 6984{ 6985 int err = 0; 6986 6987 err = parse_args(argc, argv); 6988 if (err) 6989 return err; 6990 6991 if (args.always_log) 6992 libbpf_set_print(__base_pr); 6993 6994 if (args.raw_test) 6995 err |= test_raw(); 6996 6997 if (args.get_info_test) 6998 err |= test_get_info(); 6999 7000 if (args.file_test) 7001 err |= test_file(); 7002 7003 if (args.pprint_test) 7004 err |= test_pprint(); 7005 7006 if (args.info_raw_test) 7007 err |= test_info_raw(); 7008 7009 if (args.dedup_test) 7010 err |= test_dedup(); 7011 7012 if (args.raw_test || args.get_info_test || args.file_test || 7013 args.pprint_test || args.info_raw_test || args.dedup_test) 7014 goto done; 7015 7016 err |= test_raw(); 7017 err |= test_get_info(); 7018 err |= test_file(); 7019 err |= test_info_raw(); 7020 err |= test_dedup(); 7021 7022done: 7023 print_summary(); 7024 return err; 7025}