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 /* some types are shared with test_core_reloc_type_based.c */
19 struct a_struct {
20 	int x;
21 };
22 
23 union a_union {
24 	int y;
25 	int z;
26 };
27 
28 enum an_enum {
29 	AN_ENUM_VAL1 = 1,
30 	AN_ENUM_VAL2 = 2,
31 	AN_ENUM_VAL3 = 3,
32 };
33 
34 typedef struct a_struct named_struct_typedef;
35 
36 typedef int (*func_proto_typedef)(long);
37 
38 typedef char arr_typedef[20];
39 
40 struct core_reloc_type_id_output {
41 	int local_anon_struct;
42 	int local_anon_union;
43 	int local_anon_enum;
44 	int local_anon_func_proto_ptr;
45 	int local_anon_void_ptr;
46 	int local_anon_arr;
47 
48 	int local_struct;
49 	int local_union;
50 	int local_enum;
51 	int local_int;
52 	int local_struct_typedef;
53 	int local_func_proto_typedef;
54 	int local_arr_typedef;
55 
56 	int targ_struct;
57 	int targ_union;
58 	int targ_enum;
59 	int targ_int;
60 	int targ_struct_typedef;
61 	int targ_func_proto_typedef;
62 	int targ_arr_typedef;
63 };
64 
65 /* preserve types even if Clang doesn't support built-in */
66 struct a_struct t1 = {};
67 union a_union t2 = {};
68 enum an_enum t3 = 0;
69 named_struct_typedef t4 = {};
70 func_proto_typedef t5 = 0;
71 arr_typedef t6 = {};
72 
73 SEC("raw_tracepoint/sys_enter")
test_core_type_id(void * ctx)74 int test_core_type_id(void *ctx)
75 {
76 	/* We use __builtin_btf_type_id() in this tests, but up until the time
77 	 * __builtin_preserve_type_info() was added it contained a bug that
78 	 * would make this test fail. The bug was fixed ([0]) with addition of
79 	 * __builtin_preserve_type_info(), though, so that's what we are using
80 	 * to detect whether this test has to be executed, however strange
81 	 * that might look like.
82 	 *
83 	 *   [0] https://reviews.llvm.org/D85174
84 	 */
85 #if __has_builtin(__builtin_preserve_type_info)
86 	struct core_reloc_type_id_output *out = (void *)&data.out;
87 
88 	out->local_anon_struct = bpf_core_type_id_local(struct { int marker_field; });
89 	out->local_anon_union = bpf_core_type_id_local(union { int marker_field; });
90 	out->local_anon_enum = bpf_core_type_id_local(enum { MARKER_ENUM_VAL = 123 });
91 	out->local_anon_func_proto_ptr = bpf_core_type_id_local(_Bool(*)(int));
92 	out->local_anon_void_ptr = bpf_core_type_id_local(void *);
93 	out->local_anon_arr = bpf_core_type_id_local(_Bool[47]);
94 
95 	out->local_struct = bpf_core_type_id_local(struct a_struct);
96 	out->local_union = bpf_core_type_id_local(union a_union);
97 	out->local_enum = bpf_core_type_id_local(enum an_enum);
98 	out->local_int = bpf_core_type_id_local(int);
99 	out->local_struct_typedef = bpf_core_type_id_local(named_struct_typedef);
100 	out->local_func_proto_typedef = bpf_core_type_id_local(func_proto_typedef);
101 	out->local_arr_typedef = bpf_core_type_id_local(arr_typedef);
102 
103 	out->targ_struct = bpf_core_type_id_kernel(struct a_struct);
104 	out->targ_union = bpf_core_type_id_kernel(union a_union);
105 	out->targ_enum = bpf_core_type_id_kernel(enum an_enum);
106 	out->targ_int = bpf_core_type_id_kernel(int);
107 	out->targ_struct_typedef = bpf_core_type_id_kernel(named_struct_typedef);
108 	out->targ_func_proto_typedef = bpf_core_type_id_kernel(func_proto_typedef);
109 	out->targ_arr_typedef = bpf_core_type_id_kernel(arr_typedef);
110 #else
111 	data.skip = true;
112 #endif
113 
114 	return 0;
115 }
116