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 struct flavors tests

Add tests verifying that BPF program can use various struct/union
"flavors" to extract data from the same target struct/union.

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
002d3afc df36e621

+117
+34
tools/testing/selftests/bpf/prog_tests/core_reloc.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 2 2 #include <test_progs.h> 3 + #include "progs/core_reloc_types.h" 4 + 5 + #define STRUCT_TO_CHAR_PTR(struct_name) (const char *)&(struct struct_name) 6 + 7 + #define FLAVORS_DATA(struct_name) STRUCT_TO_CHAR_PTR(struct_name) { \ 8 + .a = 42, \ 9 + .b = 0xc001, \ 10 + .c = 0xbeef, \ 11 + } 12 + 13 + #define FLAVORS_CASE_COMMON(name) \ 14 + .case_name = #name, \ 15 + .bpf_obj_file = "test_core_reloc_flavors.o", \ 16 + .btf_src_file = "btf__core_reloc_" #name ".o" \ 17 + 18 + #define FLAVORS_CASE(name) { \ 19 + FLAVORS_CASE_COMMON(name), \ 20 + .input = FLAVORS_DATA(core_reloc_##name), \ 21 + .input_len = sizeof(struct core_reloc_##name), \ 22 + .output = FLAVORS_DATA(core_reloc_flavors), \ 23 + .output_len = sizeof(struct core_reloc_flavors), \ 24 + } 25 + 26 + #define FLAVORS_ERR_CASE(name) { \ 27 + FLAVORS_CASE_COMMON(name), \ 28 + .fails = true, \ 29 + } 3 30 4 31 struct core_reloc_test_case { 5 32 const char *case_name; ··· 50 23 .output = "\1", /* true */ 51 24 .output_len = 1, 52 25 }, 26 + 27 + /* validate BPF program can use multiple flavors to match against 28 + * single target BTF type 29 + */ 30 + FLAVORS_CASE(flavors), 31 + 32 + FLAVORS_ERR_CASE(flavors__err_wrong_name), 53 33 }; 54 34 55 35 struct data {
+3
tools/testing/selftests/bpf/progs/btf__core_reloc_flavors.c
··· 1 + #include "core_reloc_types.h" 2 + 3 + void f(struct core_reloc_flavors x) {}
+3
tools/testing/selftests/bpf/progs/btf__core_reloc_flavors__err_wrong_name.c
··· 1 + #include "core_reloc_types.h" 2 + 3 + void f(struct core_reloc_flavors__err_wrong_name x) {}
+15
tools/testing/selftests/bpf/progs/core_reloc_types.h
··· 1 + /* 2 + * FLAVORS 3 + */ 4 + struct core_reloc_flavors { 5 + int a; 6 + int b; 7 + int c; 8 + }; 9 + 10 + /* this is not a flavor, as it doesn't have triple underscore */ 11 + struct core_reloc_flavors__err_wrong_name { 12 + int a; 13 + int b; 14 + int c; 15 + };
+62
tools/testing/selftests/bpf/progs/test_core_reloc_flavors.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_flavors { 16 + int a; 17 + int b; 18 + int c; 19 + }; 20 + 21 + /* local flavor with reversed layout */ 22 + struct core_reloc_flavors___reversed { 23 + int c; 24 + int b; 25 + int a; 26 + }; 27 + 28 + /* local flavor with nested/overlapping layout */ 29 + struct core_reloc_flavors___weird { 30 + struct { 31 + int b; 32 + }; 33 + /* a and c overlap in local flavor, but this should still work 34 + * correctly with target original flavor 35 + */ 36 + union { 37 + int a; 38 + int c; 39 + }; 40 + }; 41 + 42 + SEC("raw_tracepoint/sys_enter") 43 + int test_core_flavors(void *ctx) 44 + { 45 + struct core_reloc_flavors *in_orig = (void *)&data.in; 46 + struct core_reloc_flavors___reversed *in_rev = (void *)&data.in; 47 + struct core_reloc_flavors___weird *in_weird = (void *)&data.in; 48 + struct core_reloc_flavors *out = (void *)&data.out; 49 + 50 + /* read a using weird layout */ 51 + if (BPF_CORE_READ(&out->a, &in_weird->a)) 52 + return 1; 53 + /* read b using reversed layout */ 54 + if (BPF_CORE_READ(&out->b, &in_rev->b)) 55 + return 1; 56 + /* read c using original layout */ 57 + if (BPF_CORE_READ(&out->c, &in_orig->c)) 58 + return 1; 59 + 60 + return 0; 61 + } 62 +