14836bf5eSAndrii Nakryiko // SPDX-License-Identifier: GPL-2.0
24836bf5eSAndrii Nakryiko // Copyright (c) 2020 Facebook
34836bf5eSAndrii Nakryiko 
44836bf5eSAndrii Nakryiko #include <linux/bpf.h>
54836bf5eSAndrii Nakryiko #include <stdint.h>
64836bf5eSAndrii Nakryiko #include <stdbool.h>
74836bf5eSAndrii Nakryiko #include <bpf/bpf_helpers.h>
84836bf5eSAndrii Nakryiko #include <bpf/bpf_core_read.h>
94836bf5eSAndrii Nakryiko 
104836bf5eSAndrii Nakryiko char _license[] SEC("license") = "GPL";
114836bf5eSAndrii Nakryiko 
124836bf5eSAndrii Nakryiko struct {
134836bf5eSAndrii Nakryiko 	char in[256];
144836bf5eSAndrii Nakryiko 	char out[256];
154836bf5eSAndrii Nakryiko 	bool skip;
164836bf5eSAndrii Nakryiko } data = {};
174836bf5eSAndrii Nakryiko 
184836bf5eSAndrii Nakryiko /* some types are shared with test_core_reloc_type_based.c */
194836bf5eSAndrii Nakryiko struct a_struct {
204836bf5eSAndrii Nakryiko 	int x;
214836bf5eSAndrii Nakryiko };
224836bf5eSAndrii Nakryiko 
234836bf5eSAndrii Nakryiko union a_union {
244836bf5eSAndrii Nakryiko 	int y;
254836bf5eSAndrii Nakryiko 	int z;
264836bf5eSAndrii Nakryiko };
274836bf5eSAndrii Nakryiko 
284836bf5eSAndrii Nakryiko enum an_enum {
294836bf5eSAndrii Nakryiko 	AN_ENUM_VAL1 = 1,
304836bf5eSAndrii Nakryiko 	AN_ENUM_VAL2 = 2,
314836bf5eSAndrii Nakryiko 	AN_ENUM_VAL3 = 3,
324836bf5eSAndrii Nakryiko };
334836bf5eSAndrii Nakryiko 
344836bf5eSAndrii Nakryiko typedef struct a_struct named_struct_typedef;
354836bf5eSAndrii Nakryiko 
364836bf5eSAndrii Nakryiko typedef int (*func_proto_typedef)(long);
374836bf5eSAndrii Nakryiko 
384836bf5eSAndrii Nakryiko typedef char arr_typedef[20];
394836bf5eSAndrii Nakryiko 
404836bf5eSAndrii Nakryiko struct core_reloc_type_id_output {
414836bf5eSAndrii Nakryiko 	int local_anon_struct;
424836bf5eSAndrii Nakryiko 	int local_anon_union;
434836bf5eSAndrii Nakryiko 	int local_anon_enum;
444836bf5eSAndrii Nakryiko 	int local_anon_func_proto_ptr;
454836bf5eSAndrii Nakryiko 	int local_anon_void_ptr;
464836bf5eSAndrii Nakryiko 	int local_anon_arr;
474836bf5eSAndrii Nakryiko 
484836bf5eSAndrii Nakryiko 	int local_struct;
494836bf5eSAndrii Nakryiko 	int local_union;
504836bf5eSAndrii Nakryiko 	int local_enum;
514836bf5eSAndrii Nakryiko 	int local_int;
524836bf5eSAndrii Nakryiko 	int local_struct_typedef;
534836bf5eSAndrii Nakryiko 	int local_func_proto_typedef;
544836bf5eSAndrii Nakryiko 	int local_arr_typedef;
554836bf5eSAndrii Nakryiko 
564836bf5eSAndrii Nakryiko 	int targ_struct;
574836bf5eSAndrii Nakryiko 	int targ_union;
584836bf5eSAndrii Nakryiko 	int targ_enum;
594836bf5eSAndrii Nakryiko 	int targ_int;
604836bf5eSAndrii Nakryiko 	int targ_struct_typedef;
614836bf5eSAndrii Nakryiko 	int targ_func_proto_typedef;
624836bf5eSAndrii Nakryiko 	int targ_arr_typedef;
634836bf5eSAndrii Nakryiko };
644836bf5eSAndrii Nakryiko 
654836bf5eSAndrii Nakryiko /* preserve types even if Clang doesn't support built-in */
664836bf5eSAndrii Nakryiko struct a_struct t1 = {};
674836bf5eSAndrii Nakryiko union a_union t2 = {};
684836bf5eSAndrii Nakryiko enum an_enum t3 = 0;
694836bf5eSAndrii Nakryiko named_struct_typedef t4 = {};
704836bf5eSAndrii Nakryiko func_proto_typedef t5 = 0;
714836bf5eSAndrii Nakryiko arr_typedef t6 = {};
724836bf5eSAndrii Nakryiko 
734836bf5eSAndrii Nakryiko SEC("raw_tracepoint/sys_enter")
test_core_type_id(void * ctx)744836bf5eSAndrii Nakryiko int test_core_type_id(void *ctx)
754836bf5eSAndrii Nakryiko {
764836bf5eSAndrii Nakryiko 	/* We use __builtin_btf_type_id() in this tests, but up until the time
774836bf5eSAndrii Nakryiko 	 * __builtin_preserve_type_info() was added it contained a bug that
78149cb339SAndrii Nakryiko 	 * would make this test fail. The bug was fixed ([0]) with addition of
794836bf5eSAndrii Nakryiko 	 * __builtin_preserve_type_info(), though, so that's what we are using
804836bf5eSAndrii Nakryiko 	 * to detect whether this test has to be executed, however strange
814836bf5eSAndrii Nakryiko 	 * that might look like.
82149cb339SAndrii Nakryiko 	 *
83149cb339SAndrii Nakryiko 	 *   [0] https://reviews.llvm.org/D85174
844836bf5eSAndrii Nakryiko 	 */
854836bf5eSAndrii Nakryiko #if __has_builtin(__builtin_preserve_type_info)
864836bf5eSAndrii Nakryiko 	struct core_reloc_type_id_output *out = (void *)&data.out;
874836bf5eSAndrii Nakryiko 
884836bf5eSAndrii Nakryiko 	out->local_anon_struct = bpf_core_type_id_local(struct { int marker_field; });
894836bf5eSAndrii Nakryiko 	out->local_anon_union = bpf_core_type_id_local(union { int marker_field; });
904836bf5eSAndrii Nakryiko 	out->local_anon_enum = bpf_core_type_id_local(enum { MARKER_ENUM_VAL = 123 });
914836bf5eSAndrii Nakryiko 	out->local_anon_func_proto_ptr = bpf_core_type_id_local(_Bool(*)(int));
924836bf5eSAndrii Nakryiko 	out->local_anon_void_ptr = bpf_core_type_id_local(void *);
934836bf5eSAndrii Nakryiko 	out->local_anon_arr = bpf_core_type_id_local(_Bool[47]);
944836bf5eSAndrii Nakryiko 
954836bf5eSAndrii Nakryiko 	out->local_struct = bpf_core_type_id_local(struct a_struct);
964836bf5eSAndrii Nakryiko 	out->local_union = bpf_core_type_id_local(union a_union);
974836bf5eSAndrii Nakryiko 	out->local_enum = bpf_core_type_id_local(enum an_enum);
984836bf5eSAndrii Nakryiko 	out->local_int = bpf_core_type_id_local(int);
994836bf5eSAndrii Nakryiko 	out->local_struct_typedef = bpf_core_type_id_local(named_struct_typedef);
1004836bf5eSAndrii Nakryiko 	out->local_func_proto_typedef = bpf_core_type_id_local(func_proto_typedef);
1014836bf5eSAndrii Nakryiko 	out->local_arr_typedef = bpf_core_type_id_local(arr_typedef);
1024836bf5eSAndrii Nakryiko 
1034836bf5eSAndrii Nakryiko 	out->targ_struct = bpf_core_type_id_kernel(struct a_struct);
1044836bf5eSAndrii Nakryiko 	out->targ_union = bpf_core_type_id_kernel(union a_union);
1054836bf5eSAndrii Nakryiko 	out->targ_enum = bpf_core_type_id_kernel(enum an_enum);
1064836bf5eSAndrii Nakryiko 	out->targ_int = bpf_core_type_id_kernel(int);
1074836bf5eSAndrii Nakryiko 	out->targ_struct_typedef = bpf_core_type_id_kernel(named_struct_typedef);
1084836bf5eSAndrii Nakryiko 	out->targ_func_proto_typedef = bpf_core_type_id_kernel(func_proto_typedef);
1094836bf5eSAndrii Nakryiko 	out->targ_arr_typedef = bpf_core_type_id_kernel(arr_typedef);
1104836bf5eSAndrii Nakryiko #else
1114836bf5eSAndrii Nakryiko 	data.skip = true;
1124836bf5eSAndrii Nakryiko #endif
1134836bf5eSAndrii Nakryiko 
1144836bf5eSAndrii Nakryiko 	return 0;
1154836bf5eSAndrii Nakryiko }
116