1124a892dSAndrii Nakryiko // SPDX-License-Identifier: GPL-2.0 2124a892dSAndrii Nakryiko // Copyright (c) 2020 Facebook 3124a892dSAndrii Nakryiko 4124a892dSAndrii Nakryiko #include <linux/bpf.h> 5124a892dSAndrii Nakryiko #include <stdint.h> 6124a892dSAndrii Nakryiko #include <stdbool.h> 7124a892dSAndrii Nakryiko #include <bpf/bpf_helpers.h> 8124a892dSAndrii Nakryiko #include <bpf/bpf_core_read.h> 9124a892dSAndrii Nakryiko 10124a892dSAndrii Nakryiko char _license[] SEC("license") = "GPL"; 11124a892dSAndrii Nakryiko 12124a892dSAndrii Nakryiko struct { 13124a892dSAndrii Nakryiko char in[256]; 14124a892dSAndrii Nakryiko char out[256]; 15124a892dSAndrii Nakryiko bool skip; 16124a892dSAndrii Nakryiko } data = {}; 17124a892dSAndrii Nakryiko 18124a892dSAndrii Nakryiko struct a_struct { 19124a892dSAndrii Nakryiko int x; 20124a892dSAndrii Nakryiko }; 21124a892dSAndrii Nakryiko 22537905c4SDaniel Müller struct a_complex_struct { 23537905c4SDaniel Müller union { 24537905c4SDaniel Müller struct a_struct *a; 25537905c4SDaniel Müller void *b; 26537905c4SDaniel Müller } x; 27537905c4SDaniel Müller volatile long y; 28537905c4SDaniel Müller }; 29537905c4SDaniel Müller 30124a892dSAndrii Nakryiko union a_union { 31124a892dSAndrii Nakryiko int y; 32124a892dSAndrii Nakryiko int z; 33124a892dSAndrii Nakryiko }; 34124a892dSAndrii Nakryiko 35124a892dSAndrii Nakryiko typedef struct a_struct named_struct_typedef; 36124a892dSAndrii Nakryiko 37124a892dSAndrii Nakryiko typedef struct { int x, y, z; } anon_struct_typedef; 38124a892dSAndrii Nakryiko 39124a892dSAndrii Nakryiko typedef struct { 40124a892dSAndrii Nakryiko int a, b, c; 41124a892dSAndrii Nakryiko } *struct_ptr_typedef; 42124a892dSAndrii Nakryiko 43124a892dSAndrii Nakryiko enum an_enum { 44124a892dSAndrii Nakryiko AN_ENUM_VAL1 = 1, 45124a892dSAndrii Nakryiko AN_ENUM_VAL2 = 2, 46124a892dSAndrii Nakryiko AN_ENUM_VAL3 = 3, 47124a892dSAndrii Nakryiko }; 48124a892dSAndrii Nakryiko 49124a892dSAndrii Nakryiko typedef int int_typedef; 50124a892dSAndrii Nakryiko 51124a892dSAndrii Nakryiko typedef enum { TYPEDEF_ENUM_VAL1, TYPEDEF_ENUM_VAL2 } enum_typedef; 52124a892dSAndrii Nakryiko 53124a892dSAndrii Nakryiko typedef void *void_ptr_typedef; 54*32e0d9b3SDaniel Müller typedef int *restrict restrict_ptr_typedef; 55124a892dSAndrii Nakryiko 56124a892dSAndrii Nakryiko typedef int (*func_proto_typedef)(long); 57124a892dSAndrii Nakryiko 58124a892dSAndrii Nakryiko typedef char arr_typedef[20]; 59124a892dSAndrii Nakryiko 60124a892dSAndrii Nakryiko struct core_reloc_type_based_output { 61124a892dSAndrii Nakryiko bool struct_exists; 62537905c4SDaniel Müller bool complex_struct_exists; 63124a892dSAndrii Nakryiko bool union_exists; 64124a892dSAndrii Nakryiko bool enum_exists; 65124a892dSAndrii Nakryiko bool typedef_named_struct_exists; 66124a892dSAndrii Nakryiko bool typedef_anon_struct_exists; 67124a892dSAndrii Nakryiko bool typedef_struct_ptr_exists; 68124a892dSAndrii Nakryiko bool typedef_int_exists; 69124a892dSAndrii Nakryiko bool typedef_enum_exists; 70124a892dSAndrii Nakryiko bool typedef_void_ptr_exists; 71*32e0d9b3SDaniel Müller bool typedef_restrict_ptr_exists; 72124a892dSAndrii Nakryiko bool typedef_func_proto_exists; 73124a892dSAndrii Nakryiko bool typedef_arr_exists; 74124a892dSAndrii Nakryiko 7567d8ed42SDaniel Müller bool struct_matches; 76537905c4SDaniel Müller bool complex_struct_matches; 7767d8ed42SDaniel Müller bool union_matches; 7867d8ed42SDaniel Müller bool enum_matches; 7967d8ed42SDaniel Müller bool typedef_named_struct_matches; 8067d8ed42SDaniel Müller bool typedef_anon_struct_matches; 8167d8ed42SDaniel Müller bool typedef_struct_ptr_matches; 8267d8ed42SDaniel Müller bool typedef_int_matches; 8367d8ed42SDaniel Müller bool typedef_enum_matches; 8467d8ed42SDaniel Müller bool typedef_void_ptr_matches; 85*32e0d9b3SDaniel Müller bool typedef_restrict_ptr_matches; 8667d8ed42SDaniel Müller bool typedef_func_proto_matches; 8767d8ed42SDaniel Müller bool typedef_arr_matches; 8867d8ed42SDaniel Müller 89124a892dSAndrii Nakryiko int struct_sz; 90124a892dSAndrii Nakryiko int union_sz; 91124a892dSAndrii Nakryiko int enum_sz; 92124a892dSAndrii Nakryiko int typedef_named_struct_sz; 93124a892dSAndrii Nakryiko int typedef_anon_struct_sz; 94124a892dSAndrii Nakryiko int typedef_struct_ptr_sz; 95124a892dSAndrii Nakryiko int typedef_int_sz; 96124a892dSAndrii Nakryiko int typedef_enum_sz; 97124a892dSAndrii Nakryiko int typedef_void_ptr_sz; 98124a892dSAndrii Nakryiko int typedef_func_proto_sz; 99124a892dSAndrii Nakryiko int typedef_arr_sz; 100124a892dSAndrii Nakryiko }; 101124a892dSAndrii Nakryiko 102124a892dSAndrii Nakryiko SEC("raw_tracepoint/sys_enter") test_core_type_based(void * ctx)103124a892dSAndrii Nakryikoint test_core_type_based(void *ctx) 104124a892dSAndrii Nakryiko { 10567d8ed42SDaniel Müller /* Support for the BPF_TYPE_MATCHES argument to the 10667d8ed42SDaniel Müller * __builtin_preserve_type_info builtin was added at some point during 10767d8ed42SDaniel Müller * development of clang 15 and it's what we require for this test. Part of it 10867d8ed42SDaniel Müller * could run with merely __builtin_preserve_type_info (which could be checked 10967d8ed42SDaniel Müller * separately), but we have to find an upper bound. 11067d8ed42SDaniel Müller */ 11167d8ed42SDaniel Müller #if __has_builtin(__builtin_preserve_type_info) && __clang_major__ >= 15 112124a892dSAndrii Nakryiko struct core_reloc_type_based_output *out = (void *)&data.out; 113124a892dSAndrii Nakryiko 114124a892dSAndrii Nakryiko out->struct_exists = bpf_core_type_exists(struct a_struct); 115537905c4SDaniel Müller out->complex_struct_exists = bpf_core_type_exists(struct a_complex_struct); 116124a892dSAndrii Nakryiko out->union_exists = bpf_core_type_exists(union a_union); 117124a892dSAndrii Nakryiko out->enum_exists = bpf_core_type_exists(enum an_enum); 118124a892dSAndrii Nakryiko out->typedef_named_struct_exists = bpf_core_type_exists(named_struct_typedef); 119124a892dSAndrii Nakryiko out->typedef_anon_struct_exists = bpf_core_type_exists(anon_struct_typedef); 120124a892dSAndrii Nakryiko out->typedef_struct_ptr_exists = bpf_core_type_exists(struct_ptr_typedef); 121124a892dSAndrii Nakryiko out->typedef_int_exists = bpf_core_type_exists(int_typedef); 122124a892dSAndrii Nakryiko out->typedef_enum_exists = bpf_core_type_exists(enum_typedef); 123124a892dSAndrii Nakryiko out->typedef_void_ptr_exists = bpf_core_type_exists(void_ptr_typedef); 124*32e0d9b3SDaniel Müller out->typedef_restrict_ptr_exists = bpf_core_type_exists(restrict_ptr_typedef); 125124a892dSAndrii Nakryiko out->typedef_func_proto_exists = bpf_core_type_exists(func_proto_typedef); 126124a892dSAndrii Nakryiko out->typedef_arr_exists = bpf_core_type_exists(arr_typedef); 127124a892dSAndrii Nakryiko 12867d8ed42SDaniel Müller out->struct_matches = bpf_core_type_matches(struct a_struct); 129537905c4SDaniel Müller out->complex_struct_matches = bpf_core_type_matches(struct a_complex_struct); 13067d8ed42SDaniel Müller out->union_matches = bpf_core_type_matches(union a_union); 13167d8ed42SDaniel Müller out->enum_matches = bpf_core_type_matches(enum an_enum); 13267d8ed42SDaniel Müller out->typedef_named_struct_matches = bpf_core_type_matches(named_struct_typedef); 13367d8ed42SDaniel Müller out->typedef_anon_struct_matches = bpf_core_type_matches(anon_struct_typedef); 13467d8ed42SDaniel Müller out->typedef_struct_ptr_matches = bpf_core_type_matches(struct_ptr_typedef); 13567d8ed42SDaniel Müller out->typedef_int_matches = bpf_core_type_matches(int_typedef); 13667d8ed42SDaniel Müller out->typedef_enum_matches = bpf_core_type_matches(enum_typedef); 13767d8ed42SDaniel Müller out->typedef_void_ptr_matches = bpf_core_type_matches(void_ptr_typedef); 138*32e0d9b3SDaniel Müller out->typedef_restrict_ptr_matches = bpf_core_type_matches(restrict_ptr_typedef); 13967d8ed42SDaniel Müller out->typedef_func_proto_matches = bpf_core_type_matches(func_proto_typedef); 14067d8ed42SDaniel Müller out->typedef_arr_matches = bpf_core_type_matches(arr_typedef); 14167d8ed42SDaniel Müller 142124a892dSAndrii Nakryiko out->struct_sz = bpf_core_type_size(struct a_struct); 143124a892dSAndrii Nakryiko out->union_sz = bpf_core_type_size(union a_union); 144124a892dSAndrii Nakryiko out->enum_sz = bpf_core_type_size(enum an_enum); 145124a892dSAndrii Nakryiko out->typedef_named_struct_sz = bpf_core_type_size(named_struct_typedef); 146124a892dSAndrii Nakryiko out->typedef_anon_struct_sz = bpf_core_type_size(anon_struct_typedef); 147124a892dSAndrii Nakryiko out->typedef_struct_ptr_sz = bpf_core_type_size(struct_ptr_typedef); 148124a892dSAndrii Nakryiko out->typedef_int_sz = bpf_core_type_size(int_typedef); 149124a892dSAndrii Nakryiko out->typedef_enum_sz = bpf_core_type_size(enum_typedef); 150124a892dSAndrii Nakryiko out->typedef_void_ptr_sz = bpf_core_type_size(void_ptr_typedef); 151124a892dSAndrii Nakryiko out->typedef_func_proto_sz = bpf_core_type_size(func_proto_typedef); 152124a892dSAndrii Nakryiko out->typedef_arr_sz = bpf_core_type_size(arr_typedef); 153124a892dSAndrii Nakryiko #else 154124a892dSAndrii Nakryiko data.skip = true; 155124a892dSAndrii Nakryiko #endif 156124a892dSAndrii Nakryiko return 0; 157124a892dSAndrii Nakryiko } 158