1 // SPDX-License-Identifier: GPL-2.0 2 // Copyright (c) 2020 Facebook 3 4 #include <linux/bpf.h> 5 #include <stdint.h> 6 #include <stdbool.h> 7 #include <bpf/bpf_helpers.h> 8 #include <bpf/bpf_core_read.h> 9 10 char _license[] SEC("license") = "GPL"; 11 12 struct { 13 char in[256]; 14 char out[256]; 15 bool skip; 16 } data = {}; 17 18 struct a_struct { 19 int x; 20 }; 21 22 struct a_complex_struct { 23 union { 24 struct a_struct *a; 25 void *b; 26 } x; 27 volatile long y; 28 }; 29 30 union a_union { 31 int y; 32 int z; 33 }; 34 35 typedef struct a_struct named_struct_typedef; 36 37 typedef struct { int x, y, z; } anon_struct_typedef; 38 39 typedef struct { 40 int a, b, c; 41 } *struct_ptr_typedef; 42 43 enum an_enum { 44 AN_ENUM_VAL1 = 1, 45 AN_ENUM_VAL2 = 2, 46 AN_ENUM_VAL3 = 3, 47 }; 48 49 typedef int int_typedef; 50 51 typedef enum { TYPEDEF_ENUM_VAL1, TYPEDEF_ENUM_VAL2 } enum_typedef; 52 53 typedef void *void_ptr_typedef; 54 typedef int *restrict restrict_ptr_typedef; 55 56 typedef int (*func_proto_typedef)(long); 57 58 typedef char arr_typedef[20]; 59 60 struct core_reloc_type_based_output { 61 bool struct_exists; 62 bool complex_struct_exists; 63 bool union_exists; 64 bool enum_exists; 65 bool typedef_named_struct_exists; 66 bool typedef_anon_struct_exists; 67 bool typedef_struct_ptr_exists; 68 bool typedef_int_exists; 69 bool typedef_enum_exists; 70 bool typedef_void_ptr_exists; 71 bool typedef_restrict_ptr_exists; 72 bool typedef_func_proto_exists; 73 bool typedef_arr_exists; 74 75 bool struct_matches; 76 bool complex_struct_matches; 77 bool union_matches; 78 bool enum_matches; 79 bool typedef_named_struct_matches; 80 bool typedef_anon_struct_matches; 81 bool typedef_struct_ptr_matches; 82 bool typedef_int_matches; 83 bool typedef_enum_matches; 84 bool typedef_void_ptr_matches; 85 bool typedef_restrict_ptr_matches; 86 bool typedef_func_proto_matches; 87 bool typedef_arr_matches; 88 89 int struct_sz; 90 int union_sz; 91 int enum_sz; 92 int typedef_named_struct_sz; 93 int typedef_anon_struct_sz; 94 int typedef_struct_ptr_sz; 95 int typedef_int_sz; 96 int typedef_enum_sz; 97 int typedef_void_ptr_sz; 98 int typedef_func_proto_sz; 99 int typedef_arr_sz; 100 }; 101 102 SEC("raw_tracepoint/sys_enter") 103 int test_core_type_based(void *ctx) 104 { 105 /* Support for the BPF_TYPE_MATCHES argument to the 106 * __builtin_preserve_type_info builtin was added at some point during 107 * development of clang 15 and it's what we require for this test. Part of it 108 * could run with merely __builtin_preserve_type_info (which could be checked 109 * separately), but we have to find an upper bound. 110 */ 111 #if __has_builtin(__builtin_preserve_type_info) && __clang_major__ >= 15 112 struct core_reloc_type_based_output *out = (void *)&data.out; 113 114 out->struct_exists = bpf_core_type_exists(struct a_struct); 115 out->complex_struct_exists = bpf_core_type_exists(struct a_complex_struct); 116 out->union_exists = bpf_core_type_exists(union a_union); 117 out->enum_exists = bpf_core_type_exists(enum an_enum); 118 out->typedef_named_struct_exists = bpf_core_type_exists(named_struct_typedef); 119 out->typedef_anon_struct_exists = bpf_core_type_exists(anon_struct_typedef); 120 out->typedef_struct_ptr_exists = bpf_core_type_exists(struct_ptr_typedef); 121 out->typedef_int_exists = bpf_core_type_exists(int_typedef); 122 out->typedef_enum_exists = bpf_core_type_exists(enum_typedef); 123 out->typedef_void_ptr_exists = bpf_core_type_exists(void_ptr_typedef); 124 out->typedef_restrict_ptr_exists = bpf_core_type_exists(restrict_ptr_typedef); 125 out->typedef_func_proto_exists = bpf_core_type_exists(func_proto_typedef); 126 out->typedef_arr_exists = bpf_core_type_exists(arr_typedef); 127 128 out->struct_matches = bpf_core_type_matches(struct a_struct); 129 out->complex_struct_matches = bpf_core_type_matches(struct a_complex_struct); 130 out->union_matches = bpf_core_type_matches(union a_union); 131 out->enum_matches = bpf_core_type_matches(enum an_enum); 132 out->typedef_named_struct_matches = bpf_core_type_matches(named_struct_typedef); 133 out->typedef_anon_struct_matches = bpf_core_type_matches(anon_struct_typedef); 134 out->typedef_struct_ptr_matches = bpf_core_type_matches(struct_ptr_typedef); 135 out->typedef_int_matches = bpf_core_type_matches(int_typedef); 136 out->typedef_enum_matches = bpf_core_type_matches(enum_typedef); 137 out->typedef_void_ptr_matches = bpf_core_type_matches(void_ptr_typedef); 138 out->typedef_restrict_ptr_matches = bpf_core_type_matches(restrict_ptr_typedef); 139 out->typedef_func_proto_matches = bpf_core_type_matches(func_proto_typedef); 140 out->typedef_arr_matches = bpf_core_type_matches(arr_typedef); 141 142 out->struct_sz = bpf_core_type_size(struct a_struct); 143 out->union_sz = bpf_core_type_size(union a_union); 144 out->enum_sz = bpf_core_type_size(enum an_enum); 145 out->typedef_named_struct_sz = bpf_core_type_size(named_struct_typedef); 146 out->typedef_anon_struct_sz = bpf_core_type_size(anon_struct_typedef); 147 out->typedef_struct_ptr_sz = bpf_core_type_size(struct_ptr_typedef); 148 out->typedef_int_sz = bpf_core_type_size(int_typedef); 149 out->typedef_enum_sz = bpf_core_type_size(enum_typedef); 150 out->typedef_void_ptr_sz = bpf_core_type_size(void_ptr_typedef); 151 out->typedef_func_proto_sz = bpf_core_type_size(func_proto_typedef); 152 out->typedef_arr_sz = bpf_core_type_size(arr_typedef); 153 #else 154 data.skip = true; 155 #endif 156 return 0; 157 } 158