Merge branch 'address-masking'
[linux-2.6-microblaze.git] / tools / testing / selftests / bpf / prog_tests / core_reloc.c
1 // SPDX-License-Identifier: GPL-2.0
2 #define _GNU_SOURCE
3 #include <test_progs.h>
4 #include "progs/core_reloc_types.h"
5 #include "bpf_testmod/bpf_testmod.h"
6 #include <linux/limits.h>
7 #include <sys/mman.h>
8 #include <sys/syscall.h>
9 #include <bpf/btf.h>
10
11 static int duration = 0;
12
13 #define STRUCT_TO_CHAR_PTR(struct_name) (const char *)&(struct struct_name)
14
15 #define MODULES_CASE(name, pg_name, tp_name) {                          \
16         .case_name = name,                                              \
17         .bpf_obj_file = "test_core_reloc_module.bpf.o",                 \
18         .btf_src_file = NULL, /* find in kernel module BTFs */          \
19         .input = "",                                                    \
20         .input_len = 0,                                                 \
21         .output = STRUCT_TO_CHAR_PTR(core_reloc_module_output) {        \
22                 .read_ctx_sz = sizeof(struct bpf_testmod_test_read_ctx),\
23                 .read_ctx_exists = true,                                \
24                 .buf_exists = true,                                     \
25                 .len_exists = true,                                     \
26                 .off_exists = true,                                     \
27                 .len = 123,                                             \
28                 .off = 0,                                               \
29                 .comm = "test_progs",                                   \
30                 .comm_len = sizeof("test_progs"),                       \
31         },                                                              \
32         .output_len = sizeof(struct core_reloc_module_output),          \
33         .prog_name = pg_name,                                           \
34         .raw_tp_name = tp_name,                                         \
35         .trigger = __trigger_module_test_read,                          \
36         .needs_testmod = true,                                          \
37 }
38
39 #define FLAVORS_DATA(struct_name) STRUCT_TO_CHAR_PTR(struct_name) {     \
40         .a = 42,                                                        \
41         .b = 0xc001,                                                    \
42         .c = 0xbeef,                                                    \
43 }
44
45 #define FLAVORS_CASE_COMMON(name)                                       \
46         .case_name = #name,                                             \
47         .bpf_obj_file = "test_core_reloc_flavors.bpf.o",                \
48         .btf_src_file = "btf__core_reloc_" #name ".bpf.o",              \
49         .raw_tp_name = "sys_enter",                                     \
50         .prog_name = "test_core_flavors"                                \
51
52 #define FLAVORS_CASE(name) {                                            \
53         FLAVORS_CASE_COMMON(name),                                      \
54         .input = FLAVORS_DATA(core_reloc_##name),                       \
55         .input_len = sizeof(struct core_reloc_##name),                  \
56         .output = FLAVORS_DATA(core_reloc_flavors),                     \
57         .output_len = sizeof(struct core_reloc_flavors),                \
58 }
59
60 #define FLAVORS_ERR_CASE(name) {                                        \
61         FLAVORS_CASE_COMMON(name),                                      \
62         .fails = true,                                                  \
63 }
64
65 #define NESTING_DATA(struct_name) STRUCT_TO_CHAR_PTR(struct_name) {     \
66         .a = { .a = { .a = 42 } },                                      \
67         .b = { .b = { .b = 0xc001 } },                                  \
68 }
69
70 #define NESTING_CASE_COMMON(name)                                       \
71         .case_name = #name,                                             \
72         .bpf_obj_file = "test_core_reloc_nesting.bpf.o",                \
73         .btf_src_file = "btf__core_reloc_" #name ".bpf.o",              \
74         .raw_tp_name = "sys_enter",                                     \
75         .prog_name = "test_core_nesting"                                \
76
77 #define NESTING_CASE(name) {                                            \
78         NESTING_CASE_COMMON(name),                                      \
79         .input = NESTING_DATA(core_reloc_##name),                       \
80         .input_len = sizeof(struct core_reloc_##name),                  \
81         .output = NESTING_DATA(core_reloc_nesting),                     \
82         .output_len = sizeof(struct core_reloc_nesting)                 \
83 }
84
85 #define NESTING_ERR_CASE(name) {                                        \
86         NESTING_CASE_COMMON(name),                                      \
87         .fails = true,                                                  \
88         .run_btfgen_fails = true,                                                       \
89 }
90
91 #define ARRAYS_DATA(struct_name) STRUCT_TO_CHAR_PTR(struct_name) {      \
92         .a = { [2] = 1 },                                               \
93         .b = { [1] = { [2] = { [3] = 2 } } },                           \
94         .c = { [1] = { .c =  3 } },                                     \
95         .d = { [0] = { [0] = { .d = 4 } } },                            \
96 }
97
98 #define ARRAYS_CASE_COMMON(name)                                        \
99         .case_name = #name,                                             \
100         .bpf_obj_file = "test_core_reloc_arrays.bpf.o",                 \
101         .btf_src_file = "btf__core_reloc_" #name ".bpf.o",              \
102         .raw_tp_name = "sys_enter",                                     \
103         .prog_name = "test_core_arrays"                                 \
104
105 #define ARRAYS_CASE(name) {                                             \
106         ARRAYS_CASE_COMMON(name),                                       \
107         .input = ARRAYS_DATA(core_reloc_##name),                        \
108         .input_len = sizeof(struct core_reloc_##name),                  \
109         .output = STRUCT_TO_CHAR_PTR(core_reloc_arrays_output) {        \
110                 .a2   = 1,                                              \
111                 .b123 = 2,                                              \
112                 .c1c  = 3,                                              \
113                 .d00d = 4,                                              \
114                 .f10c = 0,                                              \
115         },                                                              \
116         .output_len = sizeof(struct core_reloc_arrays_output)           \
117 }
118
119 #define ARRAYS_ERR_CASE(name) {                                         \
120         ARRAYS_CASE_COMMON(name),                                       \
121         .fails = true,                                                  \
122 }
123
124 #define PRIMITIVES_DATA(struct_name) STRUCT_TO_CHAR_PTR(struct_name) {  \
125         .a = 1,                                                         \
126         .b = 2,                                                         \
127         .c = 3,                                                         \
128         .d = (void *)4,                                                 \
129         .f = (void *)5,                                                 \
130 }
131
132 #define PRIMITIVES_CASE_COMMON(name)                                    \
133         .case_name = #name,                                             \
134         .bpf_obj_file = "test_core_reloc_primitives.bpf.o",             \
135         .btf_src_file = "btf__core_reloc_" #name ".bpf.o",              \
136         .raw_tp_name = "sys_enter",                                     \
137         .prog_name = "test_core_primitives"                             \
138
139 #define PRIMITIVES_CASE(name) {                                         \
140         PRIMITIVES_CASE_COMMON(name),                                   \
141         .input = PRIMITIVES_DATA(core_reloc_##name),                    \
142         .input_len = sizeof(struct core_reloc_##name),                  \
143         .output = PRIMITIVES_DATA(core_reloc_primitives),               \
144         .output_len = sizeof(struct core_reloc_primitives),             \
145 }
146
147 #define PRIMITIVES_ERR_CASE(name) {                                     \
148         PRIMITIVES_CASE_COMMON(name),                                   \
149         .fails = true,                                                  \
150 }
151
152 #define MODS_CASE(name) {                                               \
153         .case_name = #name,                                             \
154         .bpf_obj_file = "test_core_reloc_mods.bpf.o",                   \
155         .btf_src_file = "btf__core_reloc_" #name ".bpf.o",              \
156         .input = STRUCT_TO_CHAR_PTR(core_reloc_##name) {                \
157                 .a = 1,                                                 \
158                 .b = 2,                                                 \
159                 .c = (void *)3,                                         \
160                 .d = (void *)4,                                         \
161                 .e = { [2] = 5 },                                       \
162                 .f = { [1] = 6 },                                       \
163                 .g = { .x = 7 },                                        \
164                 .h = { .y = 8 },                                        \
165         },                                                              \
166         .input_len = sizeof(struct core_reloc_##name),                  \
167         .output = STRUCT_TO_CHAR_PTR(core_reloc_mods_output) {          \
168                 .a = 1, .b = 2, .c = 3, .d = 4,                         \
169                 .e = 5, .f = 6, .g = 7, .h = 8,                         \
170         },                                                              \
171         .output_len = sizeof(struct core_reloc_mods_output),            \
172         .raw_tp_name = "sys_enter",                                     \
173         .prog_name = "test_core_mods",                                  \
174 }
175
176 #define PTR_AS_ARR_CASE(name) {                                         \
177         .case_name = #name,                                             \
178         .bpf_obj_file = "test_core_reloc_ptr_as_arr.bpf.o",             \
179         .btf_src_file = "btf__core_reloc_" #name ".bpf.o",              \
180         .input = (const char *)&(struct core_reloc_##name []){          \
181                 { .a = 1 },                                             \
182                 { .a = 2 },                                             \
183                 { .a = 3 },                                             \
184         },                                                              \
185         .input_len = 3 * sizeof(struct core_reloc_##name),              \
186         .output = STRUCT_TO_CHAR_PTR(core_reloc_ptr_as_arr) {           \
187                 .a = 3,                                                 \
188         },                                                              \
189         .output_len = sizeof(struct core_reloc_ptr_as_arr),             \
190         .raw_tp_name = "sys_enter",                                     \
191         .prog_name = "test_core_ptr_as_arr",                            \
192 }
193
194 #define INTS_DATA(struct_name) STRUCT_TO_CHAR_PTR(struct_name) {        \
195         .u8_field = 1,                                                  \
196         .s8_field = 2,                                                  \
197         .u16_field = 3,                                                 \
198         .s16_field = 4,                                                 \
199         .u32_field = 5,                                                 \
200         .s32_field = 6,                                                 \
201         .u64_field = 7,                                                 \
202         .s64_field = 8,                                                 \
203 }
204
205 #define INTS_CASE_COMMON(name)                                          \
206         .case_name = #name,                                             \
207         .bpf_obj_file = "test_core_reloc_ints.bpf.o",                   \
208         .btf_src_file = "btf__core_reloc_" #name ".bpf.o",              \
209         .raw_tp_name = "sys_enter",                                     \
210         .prog_name = "test_core_ints"
211
212 #define INTS_CASE(name) {                                               \
213         INTS_CASE_COMMON(name),                                         \
214         .input = INTS_DATA(core_reloc_##name),                          \
215         .input_len = sizeof(struct core_reloc_##name),                  \
216         .output = INTS_DATA(core_reloc_ints),                           \
217         .output_len = sizeof(struct core_reloc_ints),                   \
218 }
219
220 #define INTS_ERR_CASE(name) {                                           \
221         INTS_CASE_COMMON(name),                                         \
222         .fails = true,                                                  \
223 }
224
225 #define FIELD_EXISTS_CASE_COMMON(name)                                  \
226         .case_name = #name,                                             \
227         .bpf_obj_file = "test_core_reloc_existence.bpf.o",              \
228         .btf_src_file = "btf__core_reloc_" #name ".bpf.o",              \
229         .raw_tp_name = "sys_enter",                                     \
230         .prog_name = "test_core_existence"
231
232 #define BITFIELDS_CASE_COMMON(objfile, test_name_prefix,  name)         \
233         .case_name = test_name_prefix#name,                             \
234         .bpf_obj_file = objfile,                                        \
235         .btf_src_file = "btf__core_reloc_" #name ".bpf.o"
236
237 #define BITFIELDS_CASE(name, ...) {                                     \
238         BITFIELDS_CASE_COMMON("test_core_reloc_bitfields_probed.bpf.o", \
239                               "probed:", name),                         \
240         .input = STRUCT_TO_CHAR_PTR(core_reloc_##name) __VA_ARGS__,     \
241         .input_len = sizeof(struct core_reloc_##name),                  \
242         .output = STRUCT_TO_CHAR_PTR(core_reloc_bitfields_output)       \
243                 __VA_ARGS__,                                            \
244         .output_len = sizeof(struct core_reloc_bitfields_output),       \
245         .raw_tp_name = "sys_enter",                                     \
246         .prog_name = "test_core_bitfields",                             \
247 }, {                                                                    \
248         BITFIELDS_CASE_COMMON("test_core_reloc_bitfields_direct.bpf.o", \
249                               "direct:", name),                         \
250         .input = STRUCT_TO_CHAR_PTR(core_reloc_##name) __VA_ARGS__,     \
251         .input_len = sizeof(struct core_reloc_##name),                  \
252         .output = STRUCT_TO_CHAR_PTR(core_reloc_bitfields_output)       \
253                 __VA_ARGS__,                                            \
254         .output_len = sizeof(struct core_reloc_bitfields_output),       \
255         .prog_name = "test_core_bitfields_direct",                      \
256 }
257
258
259 #define BITFIELDS_ERR_CASE(name) {                                      \
260         BITFIELDS_CASE_COMMON("test_core_reloc_bitfields_probed.bpf.o", \
261                               "probed:", name),                         \
262         .fails = true,                                                  \
263         .run_btfgen_fails = true,                                       \
264         .raw_tp_name = "sys_enter",                                     \
265         .prog_name = "test_core_bitfields",                             \
266 }, {                                                                    \
267         BITFIELDS_CASE_COMMON("test_core_reloc_bitfields_direct.bpf.o", \
268                               "direct:", name),                         \
269         .fails = true,                                                  \
270         .run_btfgen_fails = true,                                                       \
271         .prog_name = "test_core_bitfields_direct",                      \
272 }
273
274 #define SIZE_CASE_COMMON(name)                                          \
275         .case_name = #name,                                             \
276         .bpf_obj_file = "test_core_reloc_size.bpf.o",                   \
277         .btf_src_file = "btf__core_reloc_" #name ".bpf.o",              \
278         .raw_tp_name = "sys_enter",                                     \
279         .prog_name = "test_core_size"
280
281 #define SIZE_OUTPUT_DATA(type)                                          \
282         STRUCT_TO_CHAR_PTR(core_reloc_size_output) {                    \
283                 .int_sz = sizeof(((type *)0)->int_field),               \
284                 .int_off = offsetof(type, int_field),                   \
285                 .struct_sz = sizeof(((type *)0)->struct_field),         \
286                 .struct_off = offsetof(type, struct_field),             \
287                 .union_sz = sizeof(((type *)0)->union_field),           \
288                 .union_off = offsetof(type, union_field),               \
289                 .arr_sz = sizeof(((type *)0)->arr_field),               \
290                 .arr_off = offsetof(type, arr_field),                   \
291                 .arr_elem_sz = sizeof(((type *)0)->arr_field[1]),       \
292                 .arr_elem_off = offsetof(type, arr_field[1]),           \
293                 .ptr_sz = 8, /* always 8-byte pointer for BPF */        \
294                 .ptr_off = offsetof(type, ptr_field),                   \
295                 .enum_sz = sizeof(((type *)0)->enum_field),             \
296                 .enum_off = offsetof(type, enum_field),                 \
297                 .float_sz = sizeof(((type *)0)->float_field),           \
298                 .float_off = offsetof(type, float_field),               \
299         }
300
301 #define SIZE_CASE(name) {                                               \
302         SIZE_CASE_COMMON(name),                                         \
303         .input_len = 0,                                                 \
304         .output = SIZE_OUTPUT_DATA(struct core_reloc_##name),           \
305         .output_len = sizeof(struct core_reloc_size_output),            \
306 }
307
308 #define SIZE_ERR_CASE(name) {                                           \
309         SIZE_CASE_COMMON(name),                                         \
310         .fails = true,                                                  \
311         .run_btfgen_fails = true,                                       \
312 }
313
314 #define TYPE_BASED_CASE_COMMON(name)                                    \
315         .case_name = #name,                                             \
316         .bpf_obj_file = "test_core_reloc_type_based.bpf.o",             \
317         .btf_src_file = "btf__core_reloc_" #name ".bpf.o",              \
318         .raw_tp_name = "sys_enter",                                     \
319         .prog_name = "test_core_type_based"
320
321 #define TYPE_BASED_CASE(name, ...) {                                    \
322         TYPE_BASED_CASE_COMMON(name),                                   \
323         .output = STRUCT_TO_CHAR_PTR(core_reloc_type_based_output)      \
324                         __VA_ARGS__,                                    \
325         .output_len = sizeof(struct core_reloc_type_based_output),      \
326 }
327
328 #define TYPE_BASED_ERR_CASE(name) {                                     \
329         TYPE_BASED_CASE_COMMON(name),                                   \
330         .fails = true,                                                  \
331 }
332
333 #define TYPE_ID_CASE_COMMON(name)                                       \
334         .case_name = #name,                                             \
335         .bpf_obj_file = "test_core_reloc_type_id.bpf.o",                \
336         .btf_src_file = "btf__core_reloc_" #name ".bpf.o",              \
337         .raw_tp_name = "sys_enter",                                     \
338         .prog_name = "test_core_type_id"
339
340 #define TYPE_ID_CASE(name, setup_fn) {                                  \
341         TYPE_ID_CASE_COMMON(name),                                      \
342         .output = STRUCT_TO_CHAR_PTR(core_reloc_type_id_output) {},     \
343         .output_len = sizeof(struct core_reloc_type_id_output),         \
344         .setup = setup_fn,                                              \
345 }
346
347 #define TYPE_ID_ERR_CASE(name) {                                        \
348         TYPE_ID_CASE_COMMON(name),                                      \
349         .fails = true,                                                  \
350 }
351
352 #define ENUMVAL_CASE_COMMON(name)                                       \
353         .case_name = #name,                                             \
354         .bpf_obj_file = "test_core_reloc_enumval.bpf.o",                \
355         .btf_src_file = "btf__core_reloc_" #name ".bpf.o",              \
356         .raw_tp_name = "sys_enter",                                     \
357         .prog_name = "test_core_enumval"
358
359 #define ENUMVAL_CASE(name, ...) {                                       \
360         ENUMVAL_CASE_COMMON(name),                                      \
361         .output = STRUCT_TO_CHAR_PTR(core_reloc_enumval_output)         \
362                         __VA_ARGS__,                                    \
363         .output_len = sizeof(struct core_reloc_enumval_output),         \
364 }
365
366 #define ENUMVAL_ERR_CASE(name) {                                        \
367         ENUMVAL_CASE_COMMON(name),                                      \
368         .fails = true,                                                  \
369 }
370
371 #define ENUM64VAL_CASE_COMMON(name)                                     \
372         .case_name = #name,                                             \
373         .bpf_obj_file = "test_core_reloc_enum64val.bpf.o",              \
374         .btf_src_file = "btf__core_reloc_" #name ".bpf.o",              \
375         .raw_tp_name = "sys_enter",                                     \
376         .prog_name = "test_core_enum64val"
377
378 #define ENUM64VAL_CASE(name, ...) {                                     \
379         ENUM64VAL_CASE_COMMON(name),                                    \
380         .output = STRUCT_TO_CHAR_PTR(core_reloc_enum64val_output)       \
381                         __VA_ARGS__,                                    \
382         .output_len = sizeof(struct core_reloc_enum64val_output),       \
383 }
384
385 #define ENUM64VAL_ERR_CASE(name) {                                      \
386         ENUM64VAL_CASE_COMMON(name),                                    \
387         .fails = true,                                                  \
388 }
389
390 struct core_reloc_test_case;
391
392 typedef int (*setup_test_fn)(struct core_reloc_test_case *test);
393 typedef int (*trigger_test_fn)(const struct core_reloc_test_case *test);
394
395 struct core_reloc_test_case {
396         const char *case_name;
397         const char *bpf_obj_file;
398         const char *btf_src_file;
399         const char *input;
400         int input_len;
401         const char *output;
402         int output_len;
403         bool fails;
404         bool run_btfgen_fails;
405         bool needs_testmod;
406         bool relaxed_core_relocs;
407         const char *prog_name;
408         const char *raw_tp_name;
409         setup_test_fn setup;
410         trigger_test_fn trigger;
411 };
412
413 static int find_btf_type(const struct btf *btf, const char *name, __u32 kind)
414 {
415         int id;
416
417         id = btf__find_by_name_kind(btf, name, kind);
418         if (CHECK(id <= 0, "find_type_id", "failed to find '%s', kind %d: %d\n", name, kind, id))
419                 return -1;
420
421         return id;
422 }
423
424 static int setup_type_id_case_local(struct core_reloc_test_case *test)
425 {
426         struct core_reloc_type_id_output *exp = (void *)test->output;
427         struct btf *local_btf = btf__parse(test->bpf_obj_file, NULL);
428         struct btf *targ_btf = btf__parse(test->btf_src_file, NULL);
429         const struct btf_type *t;
430         const char *name;
431         int i;
432
433         if (!ASSERT_OK_PTR(local_btf, "local_btf") || !ASSERT_OK_PTR(targ_btf, "targ_btf")) {
434                 btf__free(local_btf);
435                 btf__free(targ_btf);
436                 return -EINVAL;
437         }
438
439         exp->local_anon_struct = -1;
440         exp->local_anon_union = -1;
441         exp->local_anon_enum = -1;
442         exp->local_anon_func_proto_ptr = -1;
443         exp->local_anon_void_ptr = -1;
444         exp->local_anon_arr = -1;
445
446         for (i = 1; i < btf__type_cnt(local_btf); i++)
447         {
448                 t = btf__type_by_id(local_btf, i);
449                 /* we are interested only in anonymous types */
450                 if (t->name_off)
451                         continue;
452
453                 if (btf_is_struct(t) && btf_vlen(t) &&
454                     (name = btf__name_by_offset(local_btf, btf_members(t)[0].name_off)) &&
455                     strcmp(name, "marker_field") == 0) {
456                         exp->local_anon_struct = i;
457                 } else if (btf_is_union(t) && btf_vlen(t) &&
458                          (name = btf__name_by_offset(local_btf, btf_members(t)[0].name_off)) &&
459                          strcmp(name, "marker_field") == 0) {
460                         exp->local_anon_union = i;
461                 } else if (btf_is_enum(t) && btf_vlen(t) &&
462                          (name = btf__name_by_offset(local_btf, btf_enum(t)[0].name_off)) &&
463                          strcmp(name, "MARKER_ENUM_VAL") == 0) {
464                         exp->local_anon_enum = i;
465                 } else if (btf_is_ptr(t) && (t = btf__type_by_id(local_btf, t->type))) {
466                         if (btf_is_func_proto(t) && (t = btf__type_by_id(local_btf, t->type)) &&
467                             btf_is_int(t) && (name = btf__name_by_offset(local_btf, t->name_off)) &&
468                             strcmp(name, "_Bool") == 0) {
469                                 /* ptr -> func_proto -> _Bool */
470                                 exp->local_anon_func_proto_ptr = i;
471                         } else if (btf_is_void(t)) {
472                                 /* ptr -> void */
473                                 exp->local_anon_void_ptr = i;
474                         }
475                 } else if (btf_is_array(t) && (t = btf__type_by_id(local_btf, btf_array(t)->type)) &&
476                            btf_is_int(t) && (name = btf__name_by_offset(local_btf, t->name_off)) &&
477                            strcmp(name, "_Bool") == 0) {
478                         /* _Bool[] */
479                         exp->local_anon_arr = i;
480                 }
481         }
482
483         exp->local_struct = find_btf_type(local_btf, "a_struct", BTF_KIND_STRUCT);
484         exp->local_union = find_btf_type(local_btf, "a_union", BTF_KIND_UNION);
485         exp->local_enum = find_btf_type(local_btf, "an_enum", BTF_KIND_ENUM);
486         exp->local_int = find_btf_type(local_btf, "int", BTF_KIND_INT);
487         exp->local_struct_typedef = find_btf_type(local_btf, "named_struct_typedef", BTF_KIND_TYPEDEF);
488         exp->local_func_proto_typedef = find_btf_type(local_btf, "func_proto_typedef", BTF_KIND_TYPEDEF);
489         exp->local_arr_typedef = find_btf_type(local_btf, "arr_typedef", BTF_KIND_TYPEDEF);
490
491         btf__free(local_btf);
492         btf__free(targ_btf);
493         return 0;
494 }
495
496 static int setup_type_id_case_success(struct core_reloc_test_case *test) {
497         struct core_reloc_type_id_output *exp = (void *)test->output;
498         struct btf *targ_btf;
499         int err;
500
501         err = setup_type_id_case_local(test);
502         if (err)
503                 return err;
504
505         targ_btf = btf__parse(test->btf_src_file, NULL);
506
507         exp->targ_struct = find_btf_type(targ_btf, "a_struct", BTF_KIND_STRUCT);
508         exp->targ_union = find_btf_type(targ_btf, "a_union", BTF_KIND_UNION);
509         exp->targ_enum = find_btf_type(targ_btf, "an_enum", BTF_KIND_ENUM);
510         exp->targ_int = find_btf_type(targ_btf, "int", BTF_KIND_INT);
511         exp->targ_struct_typedef = find_btf_type(targ_btf, "named_struct_typedef", BTF_KIND_TYPEDEF);
512         exp->targ_func_proto_typedef = find_btf_type(targ_btf, "func_proto_typedef", BTF_KIND_TYPEDEF);
513         exp->targ_arr_typedef = find_btf_type(targ_btf, "arr_typedef", BTF_KIND_TYPEDEF);
514
515         btf__free(targ_btf);
516         return 0;
517 }
518
519 static int setup_type_id_case_failure(struct core_reloc_test_case *test)
520 {
521         struct core_reloc_type_id_output *exp = (void *)test->output;
522         int err;
523
524         err = setup_type_id_case_local(test);
525         if (err)
526                 return err;
527
528         exp->targ_struct = 0;
529         exp->targ_union = 0;
530         exp->targ_enum = 0;
531         exp->targ_int = 0;
532         exp->targ_struct_typedef = 0;
533         exp->targ_func_proto_typedef = 0;
534         exp->targ_arr_typedef = 0;
535
536         return 0;
537 }
538
539 static int __trigger_module_test_read(const struct core_reloc_test_case *test)
540 {
541         struct core_reloc_module_output *exp = (void *)test->output;
542
543         trigger_module_test_read(exp->len);
544         return 0;
545 }
546
547 static const struct core_reloc_test_case test_cases[] = {
548         /* validate we can find kernel image and use its BTF for relocs */
549         {
550                 .case_name = "kernel",
551                 .bpf_obj_file = "test_core_reloc_kernel.bpf.o",
552                 .btf_src_file = NULL, /* load from /lib/modules/$(uname -r) */
553                 .input = "",
554                 .input_len = 0,
555                 .output = STRUCT_TO_CHAR_PTR(core_reloc_kernel_output) {
556                         .valid = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, },
557                         .comm = "test_progs",
558                         .comm_len = sizeof("test_progs"),
559                         .local_task_struct_matches = true,
560                 },
561                 .output_len = sizeof(struct core_reloc_kernel_output),
562                 .raw_tp_name = "sys_enter",
563                 .prog_name = "test_core_kernel",
564         },
565
566         /* validate we can find kernel module BTF types for relocs/attach */
567         MODULES_CASE("module_probed", "test_core_module_probed", "bpf_testmod_test_read"),
568         MODULES_CASE("module_direct", "test_core_module_direct", NULL),
569
570         /* validate BPF program can use multiple flavors to match against
571          * single target BTF type
572          */
573         FLAVORS_CASE(flavors),
574
575         FLAVORS_ERR_CASE(flavors__err_wrong_name),
576
577         /* various struct/enum nesting and resolution scenarios */
578         NESTING_CASE(nesting),
579         NESTING_CASE(nesting___anon_embed),
580         NESTING_CASE(nesting___struct_union_mixup),
581         NESTING_CASE(nesting___extra_nesting),
582         NESTING_CASE(nesting___dup_compat_types),
583
584         NESTING_ERR_CASE(nesting___err_missing_field),
585         NESTING_ERR_CASE(nesting___err_array_field),
586         NESTING_ERR_CASE(nesting___err_missing_container),
587         NESTING_ERR_CASE(nesting___err_nonstruct_container),
588         NESTING_ERR_CASE(nesting___err_array_container),
589         NESTING_ERR_CASE(nesting___err_dup_incompat_types),
590         NESTING_ERR_CASE(nesting___err_partial_match_dups),
591         NESTING_ERR_CASE(nesting___err_too_deep),
592
593         /* various array access relocation scenarios */
594         ARRAYS_CASE(arrays),
595         ARRAYS_CASE(arrays___diff_arr_dim),
596         ARRAYS_CASE(arrays___diff_arr_val_sz),
597         ARRAYS_CASE(arrays___equiv_zero_sz_arr),
598         ARRAYS_CASE(arrays___fixed_arr),
599
600         ARRAYS_ERR_CASE(arrays___err_too_small),
601         ARRAYS_ERR_CASE(arrays___err_too_shallow),
602         ARRAYS_ERR_CASE(arrays___err_non_array),
603         ARRAYS_ERR_CASE(arrays___err_wrong_val_type),
604         ARRAYS_ERR_CASE(arrays___err_bad_zero_sz_arr),
605
606         /* enum/ptr/int handling scenarios */
607         PRIMITIVES_CASE(primitives),
608         PRIMITIVES_CASE(primitives___diff_enum_def),
609         PRIMITIVES_CASE(primitives___diff_func_proto),
610         PRIMITIVES_CASE(primitives___diff_ptr_type),
611
612         PRIMITIVES_ERR_CASE(primitives___err_non_enum),
613         PRIMITIVES_ERR_CASE(primitives___err_non_int),
614         PRIMITIVES_ERR_CASE(primitives___err_non_ptr),
615
616         /* const/volatile/restrict and typedefs scenarios */
617         MODS_CASE(mods),
618         MODS_CASE(mods___mod_swap),
619         MODS_CASE(mods___typedefs),
620
621         /* handling "ptr is an array" semantics */
622         PTR_AS_ARR_CASE(ptr_as_arr),
623         PTR_AS_ARR_CASE(ptr_as_arr___diff_sz),
624
625         /* int signedness/sizing/bitfield handling */
626         INTS_CASE(ints),
627         INTS_CASE(ints___bool),
628         INTS_CASE(ints___reverse_sign),
629
630         /* validate edge cases of capturing relocations */
631         {
632                 .case_name = "misc",
633                 .bpf_obj_file = "test_core_reloc_misc.bpf.o",
634                 .btf_src_file = "btf__core_reloc_misc.bpf.o",
635                 .input = (const char *)&(struct core_reloc_misc_extensible[]){
636                         { .a = 1 },
637                         { .a = 2 }, /* not read */
638                         { .a = 3 },
639                 },
640                 .input_len = 4 * sizeof(int),
641                 .output = STRUCT_TO_CHAR_PTR(core_reloc_misc_output) {
642                         .a = 1,
643                         .b = 1,
644                         .c = 0, /* BUG in clang, should be 3 */
645                 },
646                 .output_len = sizeof(struct core_reloc_misc_output),
647                 .raw_tp_name = "sys_enter",
648                 .prog_name = "test_core_misc",
649         },
650
651         /* validate field existence checks */
652         {
653                 FIELD_EXISTS_CASE_COMMON(existence),
654                 .input = STRUCT_TO_CHAR_PTR(core_reloc_existence) {
655                         .a = 1,
656                         .b = 2,
657                         .c = 3,
658                         .arr = { 4 },
659                         .s = { .x = 5 },
660                 },
661                 .input_len = sizeof(struct core_reloc_existence),
662                 .output = STRUCT_TO_CHAR_PTR(core_reloc_existence_output) {
663                         .a_exists = 1,
664                         .b_exists = 1,
665                         .c_exists = 1,
666                         .arr_exists = 1,
667                         .s_exists = 1,
668                         .a_value = 1,
669                         .b_value = 2,
670                         .c_value = 3,
671                         .arr_value = 4,
672                         .s_value = 5,
673                 },
674                 .output_len = sizeof(struct core_reloc_existence_output),
675         },
676         {
677                 FIELD_EXISTS_CASE_COMMON(existence___minimal),
678                 .input = STRUCT_TO_CHAR_PTR(core_reloc_existence___minimal) {
679                         .a = 42,
680                 },
681                 .input_len = sizeof(struct core_reloc_existence___minimal),
682                 .output = STRUCT_TO_CHAR_PTR(core_reloc_existence_output) {
683                         .a_exists = 1,
684                         .b_exists = 0,
685                         .c_exists = 0,
686                         .arr_exists = 0,
687                         .s_exists = 0,
688                         .a_value = 42,
689                         .b_value = 0xff000002u,
690                         .c_value = 0xff000003u,
691                         .arr_value = 0xff000004u,
692                         .s_value = 0xff000005u,
693                 },
694                 .output_len = sizeof(struct core_reloc_existence_output),
695         },
696         {
697                 FIELD_EXISTS_CASE_COMMON(existence___wrong_field_defs),
698                 .input = STRUCT_TO_CHAR_PTR(core_reloc_existence___wrong_field_defs) {
699                 },
700                 .input_len = sizeof(struct core_reloc_existence___wrong_field_defs),
701                 .output = STRUCT_TO_CHAR_PTR(core_reloc_existence_output) {
702                         .a_exists = 0,
703                         .b_exists = 0,
704                         .c_exists = 0,
705                         .arr_exists = 0,
706                         .s_exists = 0,
707                         .a_value = 0xff000001u,
708                         .b_value = 0xff000002u,
709                         .c_value = 0xff000003u,
710                         .arr_value = 0xff000004u,
711                         .s_value = 0xff000005u,
712                 },
713                 .output_len = sizeof(struct core_reloc_existence_output),
714         },
715
716         /* bitfield relocation checks */
717         BITFIELDS_CASE(bitfields, {
718                 .ub1 = 1,
719                 .ub2 = 2,
720                 .ub7 = 96,
721                 .sb4 = -7,
722                 .sb20 = -0x76543,
723                 .u32 = 0x80000000,
724                 .s32 = -0x76543210,
725         }),
726         BITFIELDS_CASE(bitfields___bit_sz_change, {
727                 .ub1 = 6,
728                 .ub2 = 0xABCDE,
729                 .ub7 = 1,
730                 .sb4 = -1,
731                 .sb20 = -0x17654321,
732                 .u32 = 0xBEEF,
733                 .s32 = -0x3FEDCBA987654321LL,
734         }),
735         BITFIELDS_CASE(bitfields___bitfield_vs_int, {
736                 .ub1 = 0xFEDCBA9876543210LL,
737                 .ub2 = 0xA6,
738                 .ub7 = -0x7EDCBA987654321LL,
739                 .sb4 = -0x6123456789ABCDELL,
740                 .sb20 = 0xD00DLL,
741                 .u32 = -0x76543,
742                 .s32 = 0x0ADEADBEEFBADB0BLL,
743         }),
744         BITFIELDS_CASE(bitfields___just_big_enough, {
745                 .ub1 = 0xFLL,
746                 .ub2 = 0x0812345678FEDCBALL,
747         }),
748         BITFIELDS_ERR_CASE(bitfields___err_too_big_bitfield),
749
750         /* field size and offset relocation checks */
751         SIZE_CASE(size),
752         SIZE_CASE(size___diff_sz),
753         SIZE_CASE(size___diff_offs),
754         SIZE_ERR_CASE(size___err_ambiguous),
755
756         /* validate type existence, match, and size relocations */
757         TYPE_BASED_CASE(type_based, {
758                 .struct_exists = 1,
759                 .complex_struct_exists = 1,
760                 .union_exists = 1,
761                 .enum_exists = 1,
762                 .typedef_named_struct_exists = 1,
763                 .typedef_anon_struct_exists = 1,
764                 .typedef_struct_ptr_exists = 1,
765                 .typedef_int_exists = 1,
766                 .typedef_enum_exists = 1,
767                 .typedef_void_ptr_exists = 1,
768                 .typedef_restrict_ptr_exists = 1,
769                 .typedef_func_proto_exists = 1,
770                 .typedef_arr_exists = 1,
771
772                 .struct_matches = 1,
773                 .complex_struct_matches = 1,
774                 .union_matches = 1,
775                 .enum_matches = 1,
776                 .typedef_named_struct_matches = 1,
777                 .typedef_anon_struct_matches = 1,
778                 .typedef_struct_ptr_matches = 1,
779                 .typedef_int_matches = 1,
780                 .typedef_enum_matches = 1,
781                 .typedef_void_ptr_matches = 1,
782                 .typedef_restrict_ptr_matches = 1,
783                 .typedef_func_proto_matches = 1,
784                 .typedef_arr_matches = 1,
785
786                 .struct_sz = sizeof(struct a_struct),
787                 .union_sz = sizeof(union a_union),
788                 .enum_sz = sizeof(enum an_enum),
789                 .typedef_named_struct_sz = sizeof(named_struct_typedef),
790                 .typedef_anon_struct_sz = sizeof(anon_struct_typedef),
791                 .typedef_struct_ptr_sz = sizeof(struct_ptr_typedef),
792                 .typedef_int_sz = sizeof(int_typedef),
793                 .typedef_enum_sz = sizeof(enum_typedef),
794                 .typedef_void_ptr_sz = sizeof(void_ptr_typedef),
795                 .typedef_func_proto_sz = sizeof(func_proto_typedef),
796                 .typedef_arr_sz = sizeof(arr_typedef),
797         }),
798         TYPE_BASED_CASE(type_based___all_missing, {
799                 /* all zeros */
800         }),
801         TYPE_BASED_CASE(type_based___diff, {
802                 .struct_exists = 1,
803                 .complex_struct_exists = 1,
804                 .union_exists = 1,
805                 .enum_exists = 1,
806                 .typedef_named_struct_exists = 1,
807                 .typedef_anon_struct_exists = 1,
808                 .typedef_struct_ptr_exists = 1,
809                 .typedef_int_exists = 1,
810                 .typedef_enum_exists = 1,
811                 .typedef_void_ptr_exists = 1,
812                 .typedef_func_proto_exists = 1,
813                 .typedef_arr_exists = 1,
814
815                 .struct_matches = 1,
816                 .complex_struct_matches = 1,
817                 .union_matches = 1,
818                 .enum_matches = 1,
819                 .typedef_named_struct_matches = 1,
820                 .typedef_anon_struct_matches = 1,
821                 .typedef_struct_ptr_matches = 1,
822                 .typedef_int_matches = 0,
823                 .typedef_enum_matches = 1,
824                 .typedef_void_ptr_matches = 1,
825                 .typedef_func_proto_matches = 0,
826                 .typedef_arr_matches = 0,
827
828                 .struct_sz = sizeof(struct a_struct___diff),
829                 .union_sz = sizeof(union a_union___diff),
830                 .enum_sz = sizeof(enum an_enum___diff),
831                 .typedef_named_struct_sz = sizeof(named_struct_typedef___diff),
832                 .typedef_anon_struct_sz = sizeof(anon_struct_typedef___diff),
833                 .typedef_struct_ptr_sz = sizeof(struct_ptr_typedef___diff),
834                 .typedef_int_sz = sizeof(int_typedef___diff),
835                 .typedef_enum_sz = sizeof(enum_typedef___diff),
836                 .typedef_void_ptr_sz = sizeof(void_ptr_typedef___diff),
837                 .typedef_func_proto_sz = sizeof(func_proto_typedef___diff),
838                 .typedef_arr_sz = sizeof(arr_typedef___diff),
839         }),
840         TYPE_BASED_CASE(type_based___diff_sz, {
841                 .struct_exists = 1,
842                 .union_exists = 1,
843                 .enum_exists = 1,
844                 .typedef_named_struct_exists = 1,
845                 .typedef_anon_struct_exists = 1,
846                 .typedef_struct_ptr_exists = 1,
847                 .typedef_int_exists = 1,
848                 .typedef_enum_exists = 1,
849                 .typedef_void_ptr_exists = 1,
850                 .typedef_func_proto_exists = 1,
851                 .typedef_arr_exists = 1,
852
853                 .struct_matches = 0,
854                 .union_matches = 0,
855                 .enum_matches = 0,
856                 .typedef_named_struct_matches = 0,
857                 .typedef_anon_struct_matches = 0,
858                 .typedef_struct_ptr_matches = 1,
859                 .typedef_int_matches = 0,
860                 .typedef_enum_matches = 0,
861                 .typedef_void_ptr_matches = 1,
862                 .typedef_func_proto_matches = 0,
863                 .typedef_arr_matches = 0,
864
865                 .struct_sz = sizeof(struct a_struct___diff_sz),
866                 .union_sz = sizeof(union a_union___diff_sz),
867                 .enum_sz = sizeof(enum an_enum___diff_sz),
868                 .typedef_named_struct_sz = sizeof(named_struct_typedef___diff_sz),
869                 .typedef_anon_struct_sz = sizeof(anon_struct_typedef___diff_sz),
870                 .typedef_struct_ptr_sz = sizeof(struct_ptr_typedef___diff_sz),
871                 .typedef_int_sz = sizeof(int_typedef___diff_sz),
872                 .typedef_enum_sz = sizeof(enum_typedef___diff_sz),
873                 .typedef_void_ptr_sz = sizeof(void_ptr_typedef___diff_sz),
874                 .typedef_func_proto_sz = sizeof(func_proto_typedef___diff_sz),
875                 .typedef_arr_sz = sizeof(arr_typedef___diff_sz),
876         }),
877         TYPE_BASED_CASE(type_based___incompat, {
878                 .enum_exists = 1,
879                 .enum_matches = 1,
880                 .enum_sz = sizeof(enum an_enum),
881         }),
882         TYPE_BASED_CASE(type_based___fn_wrong_args, {
883                 .struct_exists = 1,
884                 .struct_matches = 1,
885                 .struct_sz = sizeof(struct a_struct),
886         }),
887
888         /* BTF_TYPE_ID_LOCAL/BTF_TYPE_ID_TARGET tests */
889         TYPE_ID_CASE(type_id, setup_type_id_case_success),
890         TYPE_ID_CASE(type_id___missing_targets, setup_type_id_case_failure),
891
892         /* Enumerator value existence and value relocations */
893         ENUMVAL_CASE(enumval, {
894                 .named_val1_exists = true,
895                 .named_val2_exists = true,
896                 .named_val3_exists = true,
897                 .anon_val1_exists = true,
898                 .anon_val2_exists = true,
899                 .anon_val3_exists = true,
900                 .named_val1 = 1,
901                 .named_val2 = 2,
902                 .anon_val1 = 0x10,
903                 .anon_val2 = 0x20,
904         }),
905         ENUMVAL_CASE(enumval___diff, {
906                 .named_val1_exists = true,
907                 .named_val2_exists = true,
908                 .named_val3_exists = true,
909                 .anon_val1_exists = true,
910                 .anon_val2_exists = true,
911                 .anon_val3_exists = true,
912                 .named_val1 = 101,
913                 .named_val2 = 202,
914                 .anon_val1 = 0x11,
915                 .anon_val2 = 0x22,
916         }),
917         ENUMVAL_CASE(enumval___val3_missing, {
918                 .named_val1_exists = true,
919                 .named_val2_exists = true,
920                 .named_val3_exists = false,
921                 .anon_val1_exists = true,
922                 .anon_val2_exists = true,
923                 .anon_val3_exists = false,
924                 .named_val1 = 111,
925                 .named_val2 = 222,
926                 .anon_val1 = 0x111,
927                 .anon_val2 = 0x222,
928         }),
929         ENUMVAL_ERR_CASE(enumval___err_missing),
930
931         /* 64bit enumerator value existence and value relocations */
932         ENUM64VAL_CASE(enum64val, {
933                 .unsigned_val1_exists = true,
934                 .unsigned_val2_exists = true,
935                 .unsigned_val3_exists = true,
936                 .signed_val1_exists = true,
937                 .signed_val2_exists = true,
938                 .signed_val3_exists = true,
939                 .unsigned_val1 = 0x1ffffffffULL,
940                 .unsigned_val2 = 0x2,
941                 .signed_val1 = 0x1ffffffffLL,
942                 .signed_val2 = -2,
943         }),
944         ENUM64VAL_CASE(enum64val___diff, {
945                 .unsigned_val1_exists = true,
946                 .unsigned_val2_exists = true,
947                 .unsigned_val3_exists = true,
948                 .signed_val1_exists = true,
949                 .signed_val2_exists = true,
950                 .signed_val3_exists = true,
951                 .unsigned_val1 = 0x101ffffffffULL,
952                 .unsigned_val2 = 0x202ffffffffULL,
953                 .signed_val1 = -101,
954                 .signed_val2 = -202,
955         }),
956         ENUM64VAL_CASE(enum64val___val3_missing, {
957                 .unsigned_val1_exists = true,
958                 .unsigned_val2_exists = true,
959                 .unsigned_val3_exists = false,
960                 .signed_val1_exists = true,
961                 .signed_val2_exists = true,
962                 .signed_val3_exists = false,
963                 .unsigned_val1 = 0x111ffffffffULL,
964                 .unsigned_val2 = 0x222,
965                 .signed_val1 = 0x111ffffffffLL,
966                 .signed_val2 = -222,
967         }),
968         ENUM64VAL_ERR_CASE(enum64val___err_missing),
969 };
970
971 struct data {
972         char in[256];
973         char out[256];
974         bool skip;
975         uint64_t my_pid_tgid;
976 };
977
978 static size_t roundup_page(size_t sz)
979 {
980         long page_size = sysconf(_SC_PAGE_SIZE);
981         return (sz + page_size - 1) / page_size * page_size;
982 }
983
984 static int run_btfgen(const char *src_btf, const char *dst_btf, const char *objpath)
985 {
986         char command[4096];
987         int n;
988
989         n = snprintf(command, sizeof(command),
990                      "./bpftool gen min_core_btf %s %s %s",
991                      src_btf, dst_btf, objpath);
992         if (n < 0 || n >= sizeof(command))
993                 return -1;
994
995         return system(command);
996 }
997
998 static void run_core_reloc_tests(bool use_btfgen)
999 {
1000         const size_t mmap_sz = roundup_page(sizeof(struct data));
1001         DECLARE_LIBBPF_OPTS(bpf_object_open_opts, open_opts);
1002         struct core_reloc_test_case *test_case, test_case_copy;
1003         const char *tp_name, *probe_name;
1004         int err, i, equal, fd;
1005         struct bpf_link *link = NULL;
1006         struct bpf_map *data_map;
1007         struct bpf_program *prog;
1008         struct bpf_object *obj;
1009         uint64_t my_pid_tgid;
1010         struct data *data;
1011         void *mmap_data = NULL;
1012
1013         my_pid_tgid = getpid() | ((uint64_t)syscall(SYS_gettid) << 32);
1014
1015         for (i = 0; i < ARRAY_SIZE(test_cases); i++) {
1016                 char btf_file[] = "/tmp/core_reloc.btf.XXXXXX";
1017
1018                 test_case_copy = test_cases[i];
1019                 test_case = &test_case_copy;
1020
1021                 if (!test__start_subtest(test_case->case_name))
1022                         continue;
1023
1024                 if (test_case->needs_testmod && !env.has_testmod) {
1025                         test__skip();
1026                         continue;
1027                 }
1028
1029                 /* generate a "minimal" BTF file and use it as source */
1030                 if (use_btfgen) {
1031
1032                         if (!test_case->btf_src_file || test_case->run_btfgen_fails) {
1033                                 test__skip();
1034                                 continue;
1035                         }
1036
1037                         fd = mkstemp(btf_file);
1038                         if (!ASSERT_GE(fd, 0, "btf_tmp"))
1039                                 continue;
1040                         close(fd); /* we only need the path */
1041                         err = run_btfgen(test_case->btf_src_file, btf_file,
1042                                          test_case->bpf_obj_file);
1043                         if (!ASSERT_OK(err, "run_btfgen"))
1044                                 continue;
1045
1046                         test_case->btf_src_file = btf_file;
1047                 }
1048
1049                 if (test_case->setup) {
1050                         err = test_case->setup(test_case);
1051                         if (CHECK(err, "test_setup", "test #%d setup failed: %d\n", i, err))
1052                                 continue;
1053                 }
1054
1055                 if (test_case->btf_src_file) {
1056                         err = access(test_case->btf_src_file, R_OK);
1057                         if (!ASSERT_OK(err, "btf_src_file"))
1058                                 continue;
1059                 }
1060
1061                 open_opts.btf_custom_path = test_case->btf_src_file;
1062                 obj = bpf_object__open_file(test_case->bpf_obj_file, &open_opts);
1063                 if (!ASSERT_OK_PTR(obj, "obj_open"))
1064                         goto cleanup;
1065
1066                 probe_name = test_case->prog_name;
1067                 tp_name = test_case->raw_tp_name; /* NULL for tp_btf */
1068                 prog = bpf_object__find_program_by_name(obj, probe_name);
1069                 if (CHECK(!prog, "find_probe",
1070                           "prog '%s' not found\n", probe_name))
1071                         goto cleanup;
1072
1073                 err = bpf_object__load(obj);
1074                 if (err) {
1075                         if (!test_case->fails)
1076                                 ASSERT_OK(err, "obj_load");
1077                         goto cleanup;
1078                 }
1079
1080                 data_map = bpf_object__find_map_by_name(obj, ".bss");
1081                 if (CHECK(!data_map, "find_data_map", "data map not found\n"))
1082                         goto cleanup;
1083
1084                 mmap_data = mmap(NULL, mmap_sz, PROT_READ | PROT_WRITE,
1085                                  MAP_SHARED, bpf_map__fd(data_map), 0);
1086                 if (CHECK(mmap_data == MAP_FAILED, "mmap",
1087                           ".bss mmap failed: %d", errno)) {
1088                         mmap_data = NULL;
1089                         goto cleanup;
1090                 }
1091                 data = mmap_data;
1092
1093                 memset(mmap_data, 0, sizeof(*data));
1094                 if (test_case->input_len)
1095                         memcpy(data->in, test_case->input, test_case->input_len);
1096                 data->my_pid_tgid = my_pid_tgid;
1097
1098                 link = bpf_program__attach_raw_tracepoint(prog, tp_name);
1099                 if (!ASSERT_OK_PTR(link, "attach_raw_tp"))
1100                         goto cleanup;
1101
1102                 /* trigger test run */
1103                 if (test_case->trigger) {
1104                         if (!ASSERT_OK(test_case->trigger(test_case), "test_trigger"))
1105                                 goto cleanup;
1106                 } else {
1107                         usleep(1);
1108                 }
1109
1110                 if (data->skip) {
1111                         test__skip();
1112                         goto cleanup;
1113                 }
1114
1115                 if (!ASSERT_FALSE(test_case->fails, "obj_load_should_fail"))
1116                         goto cleanup;
1117
1118                 equal = memcmp(data->out, test_case->output,
1119                                test_case->output_len) == 0;
1120                 if (CHECK(!equal, "check_result",
1121                           "input/output data don't match\n")) {
1122                         int j;
1123
1124                         for (j = 0; j < test_case->input_len; j++) {
1125                                 printf("input byte #%d: 0x%02hhx\n",
1126                                        j, test_case->input[j]);
1127                         }
1128                         for (j = 0; j < test_case->output_len; j++) {
1129                                 printf("output byte #%d: EXP 0x%02hhx GOT 0x%02hhx\n",
1130                                        j, test_case->output[j], data->out[j]);
1131                         }
1132                         goto cleanup;
1133                 }
1134
1135 cleanup:
1136                 if (mmap_data) {
1137                         CHECK_FAIL(munmap(mmap_data, mmap_sz));
1138                         mmap_data = NULL;
1139                 }
1140                 if (use_btfgen)
1141                         remove(test_case->btf_src_file);
1142                 bpf_link__destroy(link);
1143                 link = NULL;
1144                 bpf_object__close(obj);
1145         }
1146 }
1147
1148 void test_core_reloc(void)
1149 {
1150         run_core_reloc_tests(false);
1151 }
1152
1153 void test_core_reloc_btfgen(void)
1154 {
1155         run_core_reloc_tests(true);
1156 }