...
1#include "../../testdata/common.h"
2#include "bpf_core_read.h"
3
4enum e {
5 // clang-12 doesn't allow enum relocations with zero value.
6 // See https://reviews.llvm.org/D97659
7 ONE = 1,
8 TWO,
9};
10
11typedef enum e e_t;
12
13struct s {
14 int _1;
15 char _2;
16};
17
18typedef struct s s_t;
19
20union u {
21 int *_1;
22 char *_2;
23};
24
25typedef union u u_t;
26
27#define local_id_zero(expr) \
28 ({ \
29 if (bpf_core_type_id_local(expr) != 0) { \
30 return __LINE__; \
31 } \
32 })
33
34#define local_id_not_zero(expr) \
35 ({ \
36 if (bpf_core_type_id_local(expr) == 0) { \
37 return __LINE__; \
38 } \
39 })
40
41#define target_and_local_id_match(expr) \
42 ({ \
43 if (bpf_core_type_id_kernel(expr) != bpf_core_type_id_local(expr)) { \
44 return __LINE__; \
45 } \
46 })
47
48__section("socket_filter/type_ids") int type_ids() {
49 local_id_not_zero(int);
50 local_id_not_zero(struct { int frob; });
51 local_id_not_zero(enum {FRAP});
52 local_id_not_zero(union { char bar; });
53
54 local_id_not_zero(struct s);
55 local_id_not_zero(s_t);
56 local_id_not_zero(const s_t);
57 local_id_not_zero(volatile s_t);
58 local_id_not_zero(enum e);
59 local_id_not_zero(e_t);
60 local_id_not_zero(const e_t);
61 local_id_not_zero(volatile e_t);
62 local_id_not_zero(union u);
63 local_id_not_zero(u_t);
64 local_id_not_zero(const u_t);
65 local_id_not_zero(volatile u_t);
66
67 // Qualifiers on types crash clang.
68 target_and_local_id_match(struct s);
69 target_and_local_id_match(s_t);
70 // target_and_local_id_match(const s_t);
71 // target_and_local_id_match(volatile s_t);
72 target_and_local_id_match(enum e);
73 target_and_local_id_match(e_t);
74 // target_and_local_id_match(const e_t);
75 // target_and_local_id_match(volatile e_t);
76 target_and_local_id_match(union u);
77 target_and_local_id_match(u_t);
78 // target_and_local_id_match(const u_t);
79 // target_and_local_id_match(volatile u_t);
80
81 return 0;
82}
83
84#define type_exists(expr) \
85 ({ \
86 if (!bpf_core_type_exists(expr)) { \
87 return __LINE__; \
88 } \
89 })
90
91#define type_size_matches(expr) \
92 ({ \
93 if (bpf_core_type_size(expr) != sizeof(expr)) { \
94 return __LINE__; \
95 } \
96 })
97
98__section("socket_filter/types") int types() {
99 type_exists(struct s);
100 type_exists(s_t);
101 type_exists(const s_t);
102 type_exists(volatile s_t);
103 type_exists(enum e);
104 type_exists(e_t);
105 type_exists(const e_t);
106 type_exists(volatile e_t);
107 type_exists(union u);
108 type_exists(u_t);
109 type_exists(const u_t);
110 type_exists(volatile u_t);
111 // TODO: Check non-existence.
112
113 type_size_matches(struct s);
114 type_size_matches(s_t);
115 type_size_matches(const s_t);
116 type_size_matches(volatile s_t);
117 type_size_matches(enum e);
118 type_size_matches(e_t);
119 type_size_matches(const e_t);
120 type_size_matches(volatile e_t);
121 type_size_matches(union u);
122 type_size_matches(u_t);
123 type_size_matches(const u_t);
124 type_size_matches(volatile u_t);
125
126 return 0;
127}
128
129#define enum_value_exists(t, v) \
130 ({ \
131 if (!bpf_core_enum_value_exists(t, v)) { \
132 return __LINE__; \
133 } \
134 })
135
136#define enum_value_matches(t, v) \
137 ({ \
138 if (v != bpf_core_enum_value(t, v)) { \
139 return __LINE__; \
140 } \
141 })
142
143__section("socket_filter/enums") int enums() {
144 enum_value_exists(enum e, ONE);
145 enum_value_exists(volatile enum e, ONE);
146 enum_value_exists(const enum e, ONE);
147 enum_value_exists(e_t, TWO);
148 // TODO: Check non-existence.
149
150 enum_value_matches(enum e, TWO);
151 enum_value_matches(e_t, ONE);
152 enum_value_matches(volatile e_t, ONE);
153 enum_value_matches(const e_t, ONE);
154
155 return 0;
156}
157
158#define field_exists(f) \
159 ({ \
160 if (!bpf_core_field_exists(f)) { \
161 return __LINE__; \
162 } \
163 })
164
165#define field_size_matches(f) \
166 ({ \
167 if (sizeof(f) != bpf_core_field_size(f)) { \
168 return __LINE__; \
169 } \
170 })
171
172#define field_offset_matches(t, f) \
173 ({ \
174 if (__builtin_offsetof(t, f) != __builtin_preserve_field_info(((typeof(t) *)0)->f, BPF_FIELD_BYTE_OFFSET)) { \
175 return __LINE__; \
176 } \
177 })
178
179__section("socket_filter/fields") int fields() {
180 field_exists((struct s){}._1);
181 field_exists((s_t){}._2);
182 field_exists((union u){}._1);
183 field_exists((u_t){}._2);
184
185 field_size_matches((struct s){}._1);
186 field_size_matches((s_t){}._2);
187 field_size_matches((union u){}._1);
188 field_size_matches((u_t){}._2);
189
190 field_offset_matches(struct s, _1);
191 field_offset_matches(s_t, _2);
192 field_offset_matches(union u, _1);
193 field_offset_matches(u_t, _2);
194
195 struct t {
196 union {
197 s_t s[10];
198 };
199 struct {
200 union u u;
201 };
202 } bar, *barp = &bar;
203
204 field_exists(bar.s[2]._1);
205 field_exists(bar.s[1]._2);
206 field_exists(bar.u._1);
207 field_exists(bar.u._2);
208 field_exists(barp[1].u._2);
209
210 field_size_matches(bar.s[2]._1);
211 field_size_matches(bar.s[1]._2);
212 field_size_matches(bar.u._1);
213 field_size_matches(bar.u._2);
214 field_size_matches(barp[1].u._2);
215
216 field_offset_matches(struct t, s[2]._1);
217 field_offset_matches(struct t, s[1]._2);
218 field_offset_matches(struct t, u._1);
219 field_offset_matches(struct t, u._2);
220
221 return 0;
222}
223
224struct ambiguous {
225 int _1;
226 char _2;
227};
228
229struct ambiguous___flavour {
230 char _1;
231 int _2;
232};
233
234__section("socket_filter/err_ambiguous") int err_ambiguous() {
235 return bpf_core_type_id_kernel(struct ambiguous);
236}
237
238__section("socket_filter/err_ambiguous_flavour") int err_ambiguous_flavour() {
239 return bpf_core_type_id_kernel(struct ambiguous___flavour);
240}
View as plain text