Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

selftests/bpf: add CO-RE relocs modifiers/typedef tests

Add tests validating correct handling of various combinations of
typedefs and const/volatile/restrict modifiers.

Signed-off-by: Andrii Nakryiko <andriin@fb.com>
Acked-by: Song Liu <songliubraving@fb.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>

authored by

Andrii Nakryiko and committed by
Alexei Starovoitov
9654e2ae d9db3550

+170
+27
tools/testing/selftests/bpf/prog_tests/core_reloc.c
··· 107 107 .fails = true, \ 108 108 } 109 109 110 + #define MODS_CASE(name) { \ 111 + .case_name = #name, \ 112 + .bpf_obj_file = "test_core_reloc_mods.o", \ 113 + .btf_src_file = "btf__core_reloc_" #name ".o", \ 114 + .input = STRUCT_TO_CHAR_PTR(core_reloc_##name) { \ 115 + .a = 1, \ 116 + .b = 2, \ 117 + .c = (void *)3, \ 118 + .d = (void *)4, \ 119 + .e = { [2] = 5 }, \ 120 + .f = { [1] = 6 }, \ 121 + .g = { .x = 7 }, \ 122 + .h = { .y = 8 }, \ 123 + }, \ 124 + .input_len = sizeof(struct core_reloc_##name), \ 125 + .output = STRUCT_TO_CHAR_PTR(core_reloc_mods_output) { \ 126 + .a = 1, .b = 2, .c = 3, .d = 4, \ 127 + .e = 5, .f = 6, .g = 7, .h = 8, \ 128 + }, \ 129 + .output_len = sizeof(struct core_reloc_mods_output), \ 130 + } 131 + 110 132 struct core_reloc_test_case { 111 133 const char *case_name; 112 134 const char *bpf_obj_file; ··· 195 173 PRIMITIVES_ERR_CASE(primitives___err_non_enum), 196 174 PRIMITIVES_ERR_CASE(primitives___err_non_int), 197 175 PRIMITIVES_ERR_CASE(primitives___err_non_ptr), 176 + 177 + /* const/volatile/restrict and typedefs scenarios */ 178 + MODS_CASE(mods), 179 + MODS_CASE(mods___mod_swap), 180 + MODS_CASE(mods___typedefs), 198 181 }; 199 182 200 183 struct data {
+3
tools/testing/selftests/bpf/progs/btf__core_reloc_mods.c
··· 1 + #include "core_reloc_types.h" 2 + 3 + void f(struct core_reloc_mods x) {}
+3
tools/testing/selftests/bpf/progs/btf__core_reloc_mods___mod_swap.c
··· 1 + #include "core_reloc_types.h" 2 + 3 + void f(struct core_reloc_mods___mod_swap x) {}
+3
tools/testing/selftests/bpf/progs/btf__core_reloc_mods___typedefs.c
··· 1 + #include "core_reloc_types.h" 2 + 3 + void f(struct core_reloc_mods___typedefs x) {}
+72
tools/testing/selftests/bpf/progs/core_reloc_types.h
··· 454 454 int d; /* int instead of ptr */ 455 455 int (*f)(const char *); 456 456 }; 457 + 458 + /* 459 + * MODS 460 + */ 461 + struct core_reloc_mods_output { 462 + int a, b, c, d, e, f, g, h; 463 + }; 464 + 465 + typedef const int int_t; 466 + typedef const char *char_ptr_t; 467 + typedef const int arr_t[7]; 468 + 469 + struct core_reloc_mods_substruct { 470 + int x; 471 + int y; 472 + }; 473 + 474 + typedef struct { 475 + int x; 476 + int y; 477 + } core_reloc_mods_substruct_t; 478 + 479 + struct core_reloc_mods { 480 + int a; 481 + int_t b; 482 + char *c; 483 + char_ptr_t d; 484 + int e[3]; 485 + arr_t f; 486 + struct core_reloc_mods_substruct g; 487 + core_reloc_mods_substruct_t h; 488 + }; 489 + 490 + /* a/b, c/d, e/f, and g/h pairs are swapped */ 491 + struct core_reloc_mods___mod_swap { 492 + int b; 493 + int_t a; 494 + char *d; 495 + char_ptr_t c; 496 + int f[3]; 497 + arr_t e; 498 + struct { 499 + int y; 500 + int x; 501 + } h; 502 + core_reloc_mods_substruct_t g; 503 + }; 504 + 505 + typedef int int1_t; 506 + typedef int1_t int2_t; 507 + typedef int2_t int3_t; 508 + 509 + typedef int arr1_t[5]; 510 + typedef arr1_t arr2_t; 511 + typedef arr2_t arr3_t; 512 + typedef arr3_t arr4_t; 513 + 514 + typedef const char * const volatile restrict fancy_char_ptr_t; 515 + 516 + typedef core_reloc_mods_substruct_t core_reloc_mods_substruct_tt; 517 + 518 + /* we need more typedefs */ 519 + struct core_reloc_mods___typedefs { 520 + core_reloc_mods_substruct_tt g; 521 + core_reloc_mods_substruct_tt h; 522 + arr4_t f; 523 + arr4_t e; 524 + fancy_char_ptr_t d; 525 + fancy_char_ptr_t c; 526 + int3_t b; 527 + int3_t a; 528 + };
+62
tools/testing/selftests/bpf/progs/test_core_reloc_mods.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // Copyright (c) 2019 Facebook 3 + 4 + #include <linux/bpf.h> 5 + #include <stdint.h> 6 + #include "bpf_helpers.h" 7 + 8 + char _license[] SEC("license") = "GPL"; 9 + 10 + static volatile struct data { 11 + char in[256]; 12 + char out[256]; 13 + } data; 14 + 15 + struct core_reloc_mods_output { 16 + int a, b, c, d, e, f, g, h; 17 + }; 18 + 19 + typedef const int int_t; 20 + typedef const char *char_ptr_t; 21 + typedef const int arr_t[7]; 22 + 23 + struct core_reloc_mods_substruct { 24 + int x; 25 + int y; 26 + }; 27 + 28 + typedef struct { 29 + int x; 30 + int y; 31 + } core_reloc_mods_substruct_t; 32 + 33 + struct core_reloc_mods { 34 + int a; 35 + int_t b; 36 + char *c; 37 + char_ptr_t d; 38 + int e[3]; 39 + arr_t f; 40 + struct core_reloc_mods_substruct g; 41 + core_reloc_mods_substruct_t h; 42 + }; 43 + 44 + SEC("raw_tracepoint/sys_enter") 45 + int test_core_mods(void *ctx) 46 + { 47 + struct core_reloc_mods *in = (void *)&data.in; 48 + struct core_reloc_mods_output *out = (void *)&data.out; 49 + 50 + if (BPF_CORE_READ(&out->a, &in->a) || 51 + BPF_CORE_READ(&out->b, &in->b) || 52 + BPF_CORE_READ(&out->c, &in->c) || 53 + BPF_CORE_READ(&out->d, &in->d) || 54 + BPF_CORE_READ(&out->e, &in->e[2]) || 55 + BPF_CORE_READ(&out->f, &in->f[1]) || 56 + BPF_CORE_READ(&out->g, &in->g.x) || 57 + BPF_CORE_READ(&out->h, &in->h.y)) 58 + return 1; 59 + 60 + return 0; 61 + } 62 +