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 Nakryiko int 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