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

selftests/bpf: Add type-match checks to type-based tests

Now that we have type-match logic in both libbpf and the kernel, this
change adjusts the existing BPF self tests to check this functionality.
Specifically, we extend the existing type-based tests to check the
previously introduced bpf_core_type_matches macro.

Signed-off-by: Daniel Müller <deso@posteo.net>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Link: https://lore.kernel.org/bpf/20220628160127.607834-8-deso@posteo.net

authored by

Daniel Müller and committed by
Andrii Nakryiko
67d8ed42 b8a195dc

+73 -4
+29 -2
tools/testing/selftests/bpf/prog_tests/core_reloc.c
··· 543 543 return 0; 544 544 } 545 545 546 - 547 546 static const struct core_reloc_test_case test_cases[] = { 548 547 /* validate we can find kernel image and use its BTF for relocs */ 549 548 { ··· 751 752 SIZE_CASE(size___diff_offs), 752 753 SIZE_ERR_CASE(size___err_ambiguous), 753 754 754 - /* validate type existence and size relocations */ 755 + /* validate type existence, match, and size relocations */ 755 756 TYPE_BASED_CASE(type_based, { 756 757 .struct_exists = 1, 757 758 .union_exists = 1, ··· 764 765 .typedef_void_ptr_exists = 1, 765 766 .typedef_func_proto_exists = 1, 766 767 .typedef_arr_exists = 1, 768 + 769 + .struct_matches = 1, 770 + .union_matches = 1, 771 + .enum_matches = 1, 772 + .typedef_named_struct_matches = 1, 773 + .typedef_anon_struct_matches = 1, 774 + .typedef_struct_ptr_matches = 1, 775 + .typedef_int_matches = 1, 776 + .typedef_enum_matches = 1, 777 + .typedef_void_ptr_matches = 1, 778 + .typedef_func_proto_matches = 1, 779 + .typedef_arr_matches = 1, 780 + 767 781 .struct_sz = sizeof(struct a_struct), 768 782 .union_sz = sizeof(union a_union), 769 783 .enum_sz = sizeof(enum an_enum), ··· 804 792 .typedef_void_ptr_exists = 1, 805 793 .typedef_func_proto_exists = 1, 806 794 .typedef_arr_exists = 1, 795 + 796 + .struct_matches = 0, 797 + .union_matches = 0, 798 + .enum_matches = 0, 799 + .typedef_named_struct_matches = 0, 800 + .typedef_anon_struct_matches = 0, 801 + .typedef_struct_ptr_matches = 1, 802 + .typedef_int_matches = 0, 803 + .typedef_enum_matches = 0, 804 + .typedef_void_ptr_matches = 1, 805 + .typedef_func_proto_matches = 0, 806 + .typedef_arr_matches = 0, 807 + 807 808 .struct_sz = sizeof(struct a_struct___diff_sz), 808 809 .union_sz = sizeof(union a_union___diff_sz), 809 810 .enum_sz = sizeof(enum an_enum___diff_sz), ··· 831 806 }), 832 807 TYPE_BASED_CASE(type_based___incompat, { 833 808 .enum_exists = 1, 809 + .enum_matches = 1, 834 810 .enum_sz = sizeof(enum an_enum), 835 811 }), 836 812 TYPE_BASED_CASE(type_based___fn_wrong_args, { 837 813 .struct_exists = 1, 814 + .struct_matches = 1, 838 815 .struct_sz = sizeof(struct a_struct), 839 816 }), 840 817
+13 -1
tools/testing/selftests/bpf/progs/core_reloc_types.h
··· 860 860 }; 861 861 862 862 /* 863 - * TYPE EXISTENCE & SIZE 863 + * TYPE EXISTENCE, MATCH & SIZE 864 864 */ 865 865 struct core_reloc_type_based_output { 866 866 bool struct_exists; ··· 874 874 bool typedef_void_ptr_exists; 875 875 bool typedef_func_proto_exists; 876 876 bool typedef_arr_exists; 877 + 878 + bool struct_matches; 879 + bool union_matches; 880 + bool enum_matches; 881 + bool typedef_named_struct_matches; 882 + bool typedef_anon_struct_matches; 883 + bool typedef_struct_ptr_matches; 884 + bool typedef_int_matches; 885 + bool typedef_enum_matches; 886 + bool typedef_void_ptr_matches; 887 + bool typedef_func_proto_matches; 888 + bool typedef_arr_matches; 877 889 878 890 int struct_sz; 879 891 int union_sz;
+31 -1
tools/testing/selftests/bpf/progs/test_core_reloc_type_based.c
··· 61 61 bool typedef_func_proto_exists; 62 62 bool typedef_arr_exists; 63 63 64 + bool struct_matches; 65 + bool union_matches; 66 + bool enum_matches; 67 + bool typedef_named_struct_matches; 68 + bool typedef_anon_struct_matches; 69 + bool typedef_struct_ptr_matches; 70 + bool typedef_int_matches; 71 + bool typedef_enum_matches; 72 + bool typedef_void_ptr_matches; 73 + bool typedef_func_proto_matches; 74 + bool typedef_arr_matches; 75 + 64 76 int struct_sz; 65 77 int union_sz; 66 78 int enum_sz; ··· 89 77 SEC("raw_tracepoint/sys_enter") 90 78 int test_core_type_based(void *ctx) 91 79 { 92 - #if __has_builtin(__builtin_preserve_type_info) 80 + /* Support for the BPF_TYPE_MATCHES argument to the 81 + * __builtin_preserve_type_info builtin was added at some point during 82 + * development of clang 15 and it's what we require for this test. Part of it 83 + * could run with merely __builtin_preserve_type_info (which could be checked 84 + * separately), but we have to find an upper bound. 85 + */ 86 + #if __has_builtin(__builtin_preserve_type_info) && __clang_major__ >= 15 93 87 struct core_reloc_type_based_output *out = (void *)&data.out; 94 88 95 89 out->struct_exists = bpf_core_type_exists(struct a_struct); ··· 109 91 out->typedef_void_ptr_exists = bpf_core_type_exists(void_ptr_typedef); 110 92 out->typedef_func_proto_exists = bpf_core_type_exists(func_proto_typedef); 111 93 out->typedef_arr_exists = bpf_core_type_exists(arr_typedef); 94 + 95 + out->struct_matches = bpf_core_type_matches(struct a_struct); 96 + out->union_matches = bpf_core_type_matches(union a_union); 97 + out->enum_matches = bpf_core_type_matches(enum an_enum); 98 + out->typedef_named_struct_matches = bpf_core_type_matches(named_struct_typedef); 99 + out->typedef_anon_struct_matches = bpf_core_type_matches(anon_struct_typedef); 100 + out->typedef_struct_ptr_matches = bpf_core_type_matches(struct_ptr_typedef); 101 + out->typedef_int_matches = bpf_core_type_matches(int_typedef); 102 + out->typedef_enum_matches = bpf_core_type_matches(enum_typedef); 103 + out->typedef_void_ptr_matches = bpf_core_type_matches(void_ptr_typedef); 104 + out->typedef_func_proto_matches = bpf_core_type_matches(func_proto_typedef); 105 + out->typedef_arr_matches = bpf_core_type_matches(arr_typedef); 112 106 113 107 out->struct_sz = bpf_core_type_size(struct a_struct); 114 108 out->union_sz = bpf_core_type_size(union a_union);