Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 #include <test_progs.h>
0003 #include "progs/core_reloc_types.h"
0004 #include "bpf_testmod/bpf_testmod.h"
0005 #include <linux/limits.h>
0006 #include <sys/mman.h>
0007 #include <sys/syscall.h>
0008 #include <bpf/btf.h>
0009 
0010 static int duration = 0;
0011 
0012 #define STRUCT_TO_CHAR_PTR(struct_name) (const char *)&(struct struct_name)
0013 
0014 #define MODULES_CASE(name, pg_name, tp_name) {              \
0015     .case_name = name,                      \
0016     .bpf_obj_file = "test_core_reloc_module.o",         \
0017     .btf_src_file = NULL, /* find in kernel module BTFs */      \
0018     .input = "",                            \
0019     .input_len = 0,                         \
0020     .output = STRUCT_TO_CHAR_PTR(core_reloc_module_output) {    \
0021         .read_ctx_sz = sizeof(struct bpf_testmod_test_read_ctx),\
0022         .read_ctx_exists = true,                \
0023         .buf_exists = true,                 \
0024         .len_exists = true,                 \
0025         .off_exists = true,                 \
0026         .len = 123,                     \
0027         .off = 0,                       \
0028         .comm = "test_progs",                   \
0029         .comm_len = sizeof("test_progs"),           \
0030     },                              \
0031     .output_len = sizeof(struct core_reloc_module_output),      \
0032     .prog_name = pg_name,                       \
0033     .raw_tp_name = tp_name,                     \
0034     .trigger = __trigger_module_test_read,              \
0035     .needs_testmod = true,                      \
0036 }
0037 
0038 #define FLAVORS_DATA(struct_name) STRUCT_TO_CHAR_PTR(struct_name) { \
0039     .a = 42,                            \
0040     .b = 0xc001,                            \
0041     .c = 0xbeef,                            \
0042 }
0043 
0044 #define FLAVORS_CASE_COMMON(name)                   \
0045     .case_name = #name,                     \
0046     .bpf_obj_file = "test_core_reloc_flavors.o",            \
0047     .btf_src_file = "btf__core_reloc_" #name ".o",          \
0048     .raw_tp_name = "sys_enter",                 \
0049     .prog_name = "test_core_flavors"                \
0050 
0051 #define FLAVORS_CASE(name) {                        \
0052     FLAVORS_CASE_COMMON(name),                  \
0053     .input = FLAVORS_DATA(core_reloc_##name),           \
0054     .input_len = sizeof(struct core_reloc_##name),          \
0055     .output = FLAVORS_DATA(core_reloc_flavors),         \
0056     .output_len = sizeof(struct core_reloc_flavors),        \
0057 }
0058 
0059 #define FLAVORS_ERR_CASE(name) {                    \
0060     FLAVORS_CASE_COMMON(name),                  \
0061     .fails = true,                          \
0062 }
0063 
0064 #define NESTING_DATA(struct_name) STRUCT_TO_CHAR_PTR(struct_name) { \
0065     .a = { .a = { .a = 42 } },                  \
0066     .b = { .b = { .b = 0xc001 } },                  \
0067 }
0068 
0069 #define NESTING_CASE_COMMON(name)                   \
0070     .case_name = #name,                     \
0071     .bpf_obj_file = "test_core_reloc_nesting.o",            \
0072     .btf_src_file = "btf__core_reloc_" #name ".o",          \
0073     .raw_tp_name = "sys_enter",                 \
0074     .prog_name = "test_core_nesting"                \
0075 
0076 #define NESTING_CASE(name) {                        \
0077     NESTING_CASE_COMMON(name),                  \
0078     .input = NESTING_DATA(core_reloc_##name),           \
0079     .input_len = sizeof(struct core_reloc_##name),          \
0080     .output = NESTING_DATA(core_reloc_nesting),         \
0081     .output_len = sizeof(struct core_reloc_nesting)         \
0082 }
0083 
0084 #define NESTING_ERR_CASE(name) {                    \
0085     NESTING_CASE_COMMON(name),                  \
0086     .fails = true,                          \
0087     .run_btfgen_fails = true,                           \
0088 }
0089 
0090 #define ARRAYS_DATA(struct_name) STRUCT_TO_CHAR_PTR(struct_name) {  \
0091     .a = { [2] = 1 },                       \
0092     .b = { [1] = { [2] = { [3] = 2 } } },               \
0093     .c = { [1] = { .c =  3 } },                 \
0094     .d = { [0] = { [0] = { .d = 4 } } },                \
0095 }
0096 
0097 #define ARRAYS_CASE_COMMON(name)                    \
0098     .case_name = #name,                     \
0099     .bpf_obj_file = "test_core_reloc_arrays.o",         \
0100     .btf_src_file = "btf__core_reloc_" #name ".o",          \
0101     .raw_tp_name = "sys_enter",                 \
0102     .prog_name = "test_core_arrays"                 \
0103 
0104 #define ARRAYS_CASE(name) {                     \
0105     ARRAYS_CASE_COMMON(name),                   \
0106     .input = ARRAYS_DATA(core_reloc_##name),            \
0107     .input_len = sizeof(struct core_reloc_##name),          \
0108     .output = STRUCT_TO_CHAR_PTR(core_reloc_arrays_output) {    \
0109         .a2   = 1,                      \
0110         .b123 = 2,                      \
0111         .c1c  = 3,                      \
0112         .d00d = 4,                      \
0113         .f10c = 0,                      \
0114     },                              \
0115     .output_len = sizeof(struct core_reloc_arrays_output)       \
0116 }
0117 
0118 #define ARRAYS_ERR_CASE(name) {                     \
0119     ARRAYS_CASE_COMMON(name),                   \
0120     .fails = true,                          \
0121 }
0122 
0123 #define PRIMITIVES_DATA(struct_name) STRUCT_TO_CHAR_PTR(struct_name) {  \
0124     .a = 1,                             \
0125     .b = 2,                             \
0126     .c = 3,                             \
0127     .d = (void *)4,                         \
0128     .f = (void *)5,                         \
0129 }
0130 
0131 #define PRIMITIVES_CASE_COMMON(name)                    \
0132     .case_name = #name,                     \
0133     .bpf_obj_file = "test_core_reloc_primitives.o",         \
0134     .btf_src_file = "btf__core_reloc_" #name ".o",          \
0135     .raw_tp_name = "sys_enter",                 \
0136     .prog_name = "test_core_primitives"             \
0137 
0138 #define PRIMITIVES_CASE(name) {                     \
0139     PRIMITIVES_CASE_COMMON(name),                   \
0140     .input = PRIMITIVES_DATA(core_reloc_##name),            \
0141     .input_len = sizeof(struct core_reloc_##name),          \
0142     .output = PRIMITIVES_DATA(core_reloc_primitives),       \
0143     .output_len = sizeof(struct core_reloc_primitives),     \
0144 }
0145 
0146 #define PRIMITIVES_ERR_CASE(name) {                 \
0147     PRIMITIVES_CASE_COMMON(name),                   \
0148     .fails = true,                          \
0149 }
0150 
0151 #define MODS_CASE(name) {                       \
0152     .case_name = #name,                     \
0153     .bpf_obj_file = "test_core_reloc_mods.o",           \
0154     .btf_src_file = "btf__core_reloc_" #name ".o",          \
0155     .input = STRUCT_TO_CHAR_PTR(core_reloc_##name) {        \
0156         .a = 1,                         \
0157         .b = 2,                         \
0158         .c = (void *)3,                     \
0159         .d = (void *)4,                     \
0160         .e = { [2] = 5 },                   \
0161         .f = { [1] = 6 },                   \
0162         .g = { .x = 7 },                    \
0163         .h = { .y = 8 },                    \
0164     },                              \
0165     .input_len = sizeof(struct core_reloc_##name),          \
0166     .output = STRUCT_TO_CHAR_PTR(core_reloc_mods_output) {      \
0167         .a = 1, .b = 2, .c = 3, .d = 4,             \
0168         .e = 5, .f = 6, .g = 7, .h = 8,             \
0169     },                              \
0170     .output_len = sizeof(struct core_reloc_mods_output),        \
0171     .raw_tp_name = "sys_enter",                 \
0172     .prog_name = "test_core_mods",                  \
0173 }
0174 
0175 #define PTR_AS_ARR_CASE(name) {                     \
0176     .case_name = #name,                     \
0177     .bpf_obj_file = "test_core_reloc_ptr_as_arr.o",         \
0178     .btf_src_file = "btf__core_reloc_" #name ".o",          \
0179     .input = (const char *)&(struct core_reloc_##name []){      \
0180         { .a = 1 },                     \
0181         { .a = 2 },                     \
0182         { .a = 3 },                     \
0183     },                              \
0184     .input_len = 3 * sizeof(struct core_reloc_##name),      \
0185     .output = STRUCT_TO_CHAR_PTR(core_reloc_ptr_as_arr) {       \
0186         .a = 3,                         \
0187     },                              \
0188     .output_len = sizeof(struct core_reloc_ptr_as_arr),     \
0189     .raw_tp_name = "sys_enter",                 \
0190     .prog_name = "test_core_ptr_as_arr",                \
0191 }
0192 
0193 #define INTS_DATA(struct_name) STRUCT_TO_CHAR_PTR(struct_name) {    \
0194     .u8_field = 1,                          \
0195     .s8_field = 2,                          \
0196     .u16_field = 3,                         \
0197     .s16_field = 4,                         \
0198     .u32_field = 5,                         \
0199     .s32_field = 6,                         \
0200     .u64_field = 7,                         \
0201     .s64_field = 8,                         \
0202 }
0203 
0204 #define INTS_CASE_COMMON(name)                      \
0205     .case_name = #name,                     \
0206     .bpf_obj_file = "test_core_reloc_ints.o",           \
0207     .btf_src_file = "btf__core_reloc_" #name ".o",          \
0208     .raw_tp_name = "sys_enter",                 \
0209     .prog_name = "test_core_ints"
0210 
0211 #define INTS_CASE(name) {                       \
0212     INTS_CASE_COMMON(name),                     \
0213     .input = INTS_DATA(core_reloc_##name),              \
0214     .input_len = sizeof(struct core_reloc_##name),          \
0215     .output = INTS_DATA(core_reloc_ints),               \
0216     .output_len = sizeof(struct core_reloc_ints),           \
0217 }
0218 
0219 #define INTS_ERR_CASE(name) {                       \
0220     INTS_CASE_COMMON(name),                     \
0221     .fails = true,                          \
0222 }
0223 
0224 #define FIELD_EXISTS_CASE_COMMON(name)                  \
0225     .case_name = #name,                     \
0226     .bpf_obj_file = "test_core_reloc_existence.o",          \
0227     .btf_src_file = "btf__core_reloc_" #name ".o",          \
0228     .raw_tp_name = "sys_enter",                 \
0229     .prog_name = "test_core_existence"
0230 
0231 #define BITFIELDS_CASE_COMMON(objfile, test_name_prefix,  name)     \
0232     .case_name = test_name_prefix#name,             \
0233     .bpf_obj_file = objfile,                    \
0234     .btf_src_file = "btf__core_reloc_" #name ".o"
0235 
0236 #define BITFIELDS_CASE(name, ...) {                 \
0237     BITFIELDS_CASE_COMMON("test_core_reloc_bitfields_probed.o", \
0238                   "probed:", name),             \
0239     .input = STRUCT_TO_CHAR_PTR(core_reloc_##name) __VA_ARGS__, \
0240     .input_len = sizeof(struct core_reloc_##name),          \
0241     .output = STRUCT_TO_CHAR_PTR(core_reloc_bitfields_output)   \
0242         __VA_ARGS__,                        \
0243     .output_len = sizeof(struct core_reloc_bitfields_output),   \
0244     .raw_tp_name = "sys_enter",                 \
0245     .prog_name = "test_core_bitfields",             \
0246 }, {                                    \
0247     BITFIELDS_CASE_COMMON("test_core_reloc_bitfields_direct.o", \
0248                   "direct:", name),             \
0249     .input = STRUCT_TO_CHAR_PTR(core_reloc_##name) __VA_ARGS__, \
0250     .input_len = sizeof(struct core_reloc_##name),          \
0251     .output = STRUCT_TO_CHAR_PTR(core_reloc_bitfields_output)   \
0252         __VA_ARGS__,                        \
0253     .output_len = sizeof(struct core_reloc_bitfields_output),   \
0254     .prog_name = "test_core_bitfields_direct",          \
0255 }
0256 
0257 
0258 #define BITFIELDS_ERR_CASE(name) {                  \
0259     BITFIELDS_CASE_COMMON("test_core_reloc_bitfields_probed.o", \
0260                   "probed:", name),             \
0261     .fails = true,                          \
0262     .run_btfgen_fails = true,                           \
0263     .raw_tp_name = "sys_enter",                 \
0264     .prog_name = "test_core_bitfields",             \
0265 }, {                                    \
0266     BITFIELDS_CASE_COMMON("test_core_reloc_bitfields_direct.o", \
0267                   "direct:", name),             \
0268     .fails = true,                          \
0269     .run_btfgen_fails = true,                           \
0270     .prog_name = "test_core_bitfields_direct",          \
0271 }
0272 
0273 #define SIZE_CASE_COMMON(name)                      \
0274     .case_name = #name,                     \
0275     .bpf_obj_file = "test_core_reloc_size.o",           \
0276     .btf_src_file = "btf__core_reloc_" #name ".o",          \
0277     .raw_tp_name = "sys_enter",                 \
0278     .prog_name = "test_core_size"
0279 
0280 #define SIZE_OUTPUT_DATA(type)                      \
0281     STRUCT_TO_CHAR_PTR(core_reloc_size_output) {            \
0282         .int_sz = sizeof(((type *)0)->int_field),       \
0283         .int_off = offsetof(type, int_field),           \
0284         .struct_sz = sizeof(((type *)0)->struct_field),     \
0285         .struct_off = offsetof(type, struct_field),     \
0286         .union_sz = sizeof(((type *)0)->union_field),       \
0287         .union_off = offsetof(type, union_field),       \
0288         .arr_sz = sizeof(((type *)0)->arr_field),       \
0289         .arr_off = offsetof(type, arr_field),           \
0290         .arr_elem_sz = sizeof(((type *)0)->arr_field[1]),   \
0291         .arr_elem_off = offsetof(type, arr_field[1]),       \
0292         .ptr_sz = 8, /* always 8-byte pointer for BPF */    \
0293         .ptr_off = offsetof(type, ptr_field),           \
0294         .enum_sz = sizeof(((type *)0)->enum_field),     \
0295         .enum_off = offsetof(type, enum_field),         \
0296         .float_sz = sizeof(((type *)0)->float_field),       \
0297         .float_off = offsetof(type, float_field),       \
0298     }
0299 
0300 #define SIZE_CASE(name) {                       \
0301     SIZE_CASE_COMMON(name),                     \
0302     .input_len = 0,                         \
0303     .output = SIZE_OUTPUT_DATA(struct core_reloc_##name),       \
0304     .output_len = sizeof(struct core_reloc_size_output),        \
0305 }
0306 
0307 #define SIZE_ERR_CASE(name) {                       \
0308     SIZE_CASE_COMMON(name),                     \
0309     .fails = true,                          \
0310     .run_btfgen_fails = true,                           \
0311 }
0312 
0313 #define TYPE_BASED_CASE_COMMON(name)                    \
0314     .case_name = #name,                     \
0315     .bpf_obj_file = "test_core_reloc_type_based.o",         \
0316     .btf_src_file = "btf__core_reloc_" #name ".o",          \
0317     .raw_tp_name = "sys_enter",                 \
0318     .prog_name = "test_core_type_based"
0319 
0320 #define TYPE_BASED_CASE(name, ...) {                    \
0321     TYPE_BASED_CASE_COMMON(name),                   \
0322     .output = STRUCT_TO_CHAR_PTR(core_reloc_type_based_output)  \
0323             __VA_ARGS__,                    \
0324     .output_len = sizeof(struct core_reloc_type_based_output),  \
0325 }
0326 
0327 #define TYPE_BASED_ERR_CASE(name) {                 \
0328     TYPE_BASED_CASE_COMMON(name),                   \
0329     .fails = true,                          \
0330 }
0331 
0332 #define TYPE_ID_CASE_COMMON(name)                   \
0333     .case_name = #name,                     \
0334     .bpf_obj_file = "test_core_reloc_type_id.o",            \
0335     .btf_src_file = "btf__core_reloc_" #name ".o",          \
0336     .raw_tp_name = "sys_enter",                 \
0337     .prog_name = "test_core_type_id"
0338 
0339 #define TYPE_ID_CASE(name, setup_fn) {                  \
0340     TYPE_ID_CASE_COMMON(name),                  \
0341     .output = STRUCT_TO_CHAR_PTR(core_reloc_type_id_output) {}, \
0342     .output_len = sizeof(struct core_reloc_type_id_output),     \
0343     .setup = setup_fn,                      \
0344 }
0345 
0346 #define TYPE_ID_ERR_CASE(name) {                    \
0347     TYPE_ID_CASE_COMMON(name),                  \
0348     .fails = true,                          \
0349 }
0350 
0351 #define ENUMVAL_CASE_COMMON(name)                   \
0352     .case_name = #name,                     \
0353     .bpf_obj_file = "test_core_reloc_enumval.o",            \
0354     .btf_src_file = "btf__core_reloc_" #name ".o",          \
0355     .raw_tp_name = "sys_enter",                 \
0356     .prog_name = "test_core_enumval"
0357 
0358 #define ENUMVAL_CASE(name, ...) {                   \
0359     ENUMVAL_CASE_COMMON(name),                  \
0360     .output = STRUCT_TO_CHAR_PTR(core_reloc_enumval_output)     \
0361             __VA_ARGS__,                    \
0362     .output_len = sizeof(struct core_reloc_enumval_output),     \
0363 }
0364 
0365 #define ENUMVAL_ERR_CASE(name) {                    \
0366     ENUMVAL_CASE_COMMON(name),                  \
0367     .fails = true,                          \
0368 }
0369 
0370 #define ENUM64VAL_CASE_COMMON(name)                 \
0371     .case_name = #name,                     \
0372     .bpf_obj_file = "test_core_reloc_enum64val.o",          \
0373     .btf_src_file = "btf__core_reloc_" #name ".o",          \
0374     .raw_tp_name = "sys_enter",                 \
0375     .prog_name = "test_core_enum64val"
0376 
0377 #define ENUM64VAL_CASE(name, ...) {                 \
0378     ENUM64VAL_CASE_COMMON(name),                    \
0379     .output = STRUCT_TO_CHAR_PTR(core_reloc_enum64val_output)   \
0380             __VA_ARGS__,                    \
0381     .output_len = sizeof(struct core_reloc_enum64val_output),   \
0382 }
0383 
0384 #define ENUM64VAL_ERR_CASE(name) {                  \
0385     ENUM64VAL_CASE_COMMON(name),                    \
0386     .fails = true,                          \
0387 }
0388 
0389 struct core_reloc_test_case;
0390 
0391 typedef int (*setup_test_fn)(struct core_reloc_test_case *test);
0392 typedef int (*trigger_test_fn)(const struct core_reloc_test_case *test);
0393 
0394 struct core_reloc_test_case {
0395     const char *case_name;
0396     const char *bpf_obj_file;
0397     const char *btf_src_file;
0398     const char *input;
0399     int input_len;
0400     const char *output;
0401     int output_len;
0402     bool fails;
0403     bool run_btfgen_fails;
0404     bool needs_testmod;
0405     bool relaxed_core_relocs;
0406     const char *prog_name;
0407     const char *raw_tp_name;
0408     setup_test_fn setup;
0409     trigger_test_fn trigger;
0410 };
0411 
0412 static int find_btf_type(const struct btf *btf, const char *name, __u32 kind)
0413 {
0414     int id;
0415 
0416     id = btf__find_by_name_kind(btf, name, kind);
0417     if (CHECK(id <= 0, "find_type_id", "failed to find '%s', kind %d: %d\n", name, kind, id))
0418         return -1;
0419 
0420     return id;
0421 }
0422 
0423 static int setup_type_id_case_local(struct core_reloc_test_case *test)
0424 {
0425     struct core_reloc_type_id_output *exp = (void *)test->output;
0426     struct btf *local_btf = btf__parse(test->bpf_obj_file, NULL);
0427     struct btf *targ_btf = btf__parse(test->btf_src_file, NULL);
0428     const struct btf_type *t;
0429     const char *name;
0430     int i;
0431 
0432     if (!ASSERT_OK_PTR(local_btf, "local_btf") || !ASSERT_OK_PTR(targ_btf, "targ_btf")) {
0433         btf__free(local_btf);
0434         btf__free(targ_btf);
0435         return -EINVAL;
0436     }
0437 
0438     exp->local_anon_struct = -1;
0439     exp->local_anon_union = -1;
0440     exp->local_anon_enum = -1;
0441     exp->local_anon_func_proto_ptr = -1;
0442     exp->local_anon_void_ptr = -1;
0443     exp->local_anon_arr = -1;
0444 
0445     for (i = 1; i < btf__type_cnt(local_btf); i++)
0446     {
0447         t = btf__type_by_id(local_btf, i);
0448         /* we are interested only in anonymous types */
0449         if (t->name_off)
0450             continue;
0451 
0452         if (btf_is_struct(t) && btf_vlen(t) &&
0453             (name = btf__name_by_offset(local_btf, btf_members(t)[0].name_off)) &&
0454             strcmp(name, "marker_field") == 0) {
0455             exp->local_anon_struct = i;
0456         } else if (btf_is_union(t) && btf_vlen(t) &&
0457              (name = btf__name_by_offset(local_btf, btf_members(t)[0].name_off)) &&
0458              strcmp(name, "marker_field") == 0) {
0459             exp->local_anon_union = i;
0460         } else if (btf_is_enum(t) && btf_vlen(t) &&
0461              (name = btf__name_by_offset(local_btf, btf_enum(t)[0].name_off)) &&
0462              strcmp(name, "MARKER_ENUM_VAL") == 0) {
0463             exp->local_anon_enum = i;
0464         } else if (btf_is_ptr(t) && (t = btf__type_by_id(local_btf, t->type))) {
0465             if (btf_is_func_proto(t) && (t = btf__type_by_id(local_btf, t->type)) &&
0466                 btf_is_int(t) && (name = btf__name_by_offset(local_btf, t->name_off)) &&
0467                 strcmp(name, "_Bool") == 0) {
0468                 /* ptr -> func_proto -> _Bool */
0469                 exp->local_anon_func_proto_ptr = i;
0470             } else if (btf_is_void(t)) {
0471                 /* ptr -> void */
0472                 exp->local_anon_void_ptr = i;
0473             }
0474         } else if (btf_is_array(t) && (t = btf__type_by_id(local_btf, btf_array(t)->type)) &&
0475                btf_is_int(t) && (name = btf__name_by_offset(local_btf, t->name_off)) &&
0476                strcmp(name, "_Bool") == 0) {
0477             /* _Bool[] */
0478             exp->local_anon_arr = i;
0479         }
0480     }
0481 
0482     exp->local_struct = find_btf_type(local_btf, "a_struct", BTF_KIND_STRUCT);
0483     exp->local_union = find_btf_type(local_btf, "a_union", BTF_KIND_UNION);
0484     exp->local_enum = find_btf_type(local_btf, "an_enum", BTF_KIND_ENUM);
0485     exp->local_int = find_btf_type(local_btf, "int", BTF_KIND_INT);
0486     exp->local_struct_typedef = find_btf_type(local_btf, "named_struct_typedef", BTF_KIND_TYPEDEF);
0487     exp->local_func_proto_typedef = find_btf_type(local_btf, "func_proto_typedef", BTF_KIND_TYPEDEF);
0488     exp->local_arr_typedef = find_btf_type(local_btf, "arr_typedef", BTF_KIND_TYPEDEF);
0489 
0490     btf__free(local_btf);
0491     btf__free(targ_btf);
0492     return 0;
0493 }
0494 
0495 static int setup_type_id_case_success(struct core_reloc_test_case *test) {
0496     struct core_reloc_type_id_output *exp = (void *)test->output;
0497     struct btf *targ_btf;
0498     int err;
0499 
0500     err = setup_type_id_case_local(test);
0501     if (err)
0502         return err;
0503 
0504     targ_btf = btf__parse(test->btf_src_file, NULL);
0505 
0506     exp->targ_struct = find_btf_type(targ_btf, "a_struct", BTF_KIND_STRUCT);
0507     exp->targ_union = find_btf_type(targ_btf, "a_union", BTF_KIND_UNION);
0508     exp->targ_enum = find_btf_type(targ_btf, "an_enum", BTF_KIND_ENUM);
0509     exp->targ_int = find_btf_type(targ_btf, "int", BTF_KIND_INT);
0510     exp->targ_struct_typedef = find_btf_type(targ_btf, "named_struct_typedef", BTF_KIND_TYPEDEF);
0511     exp->targ_func_proto_typedef = find_btf_type(targ_btf, "func_proto_typedef", BTF_KIND_TYPEDEF);
0512     exp->targ_arr_typedef = find_btf_type(targ_btf, "arr_typedef", BTF_KIND_TYPEDEF);
0513 
0514     btf__free(targ_btf);
0515     return 0;
0516 }
0517 
0518 static int setup_type_id_case_failure(struct core_reloc_test_case *test)
0519 {
0520     struct core_reloc_type_id_output *exp = (void *)test->output;
0521     int err;
0522 
0523     err = setup_type_id_case_local(test);
0524     if (err)
0525         return err;
0526 
0527     exp->targ_struct = 0;
0528     exp->targ_union = 0;
0529     exp->targ_enum = 0;
0530     exp->targ_int = 0;
0531     exp->targ_struct_typedef = 0;
0532     exp->targ_func_proto_typedef = 0;
0533     exp->targ_arr_typedef = 0;
0534 
0535     return 0;
0536 }
0537 
0538 static int __trigger_module_test_read(const struct core_reloc_test_case *test)
0539 {
0540     struct core_reloc_module_output *exp = (void *)test->output;
0541 
0542     trigger_module_test_read(exp->len);
0543     return 0;
0544 }
0545 
0546 static const struct core_reloc_test_case test_cases[] = {
0547     /* validate we can find kernel image and use its BTF for relocs */
0548     {
0549         .case_name = "kernel",
0550         .bpf_obj_file = "test_core_reloc_kernel.o",
0551         .btf_src_file = NULL, /* load from /lib/modules/$(uname -r) */
0552         .input = "",
0553         .input_len = 0,
0554         .output = STRUCT_TO_CHAR_PTR(core_reloc_kernel_output) {
0555             .valid = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, },
0556             .comm = "test_progs",
0557             .comm_len = sizeof("test_progs"),
0558             .local_task_struct_matches = true,
0559         },
0560         .output_len = sizeof(struct core_reloc_kernel_output),
0561         .raw_tp_name = "sys_enter",
0562         .prog_name = "test_core_kernel",
0563     },
0564 
0565     /* validate we can find kernel module BTF types for relocs/attach */
0566     MODULES_CASE("module_probed", "test_core_module_probed", "bpf_testmod_test_read"),
0567     MODULES_CASE("module_direct", "test_core_module_direct", NULL),
0568 
0569     /* validate BPF program can use multiple flavors to match against
0570      * single target BTF type
0571      */
0572     FLAVORS_CASE(flavors),
0573 
0574     FLAVORS_ERR_CASE(flavors__err_wrong_name),
0575 
0576     /* various struct/enum nesting and resolution scenarios */
0577     NESTING_CASE(nesting),
0578     NESTING_CASE(nesting___anon_embed),
0579     NESTING_CASE(nesting___struct_union_mixup),
0580     NESTING_CASE(nesting___extra_nesting),
0581     NESTING_CASE(nesting___dup_compat_types),
0582 
0583     NESTING_ERR_CASE(nesting___err_missing_field),
0584     NESTING_ERR_CASE(nesting___err_array_field),
0585     NESTING_ERR_CASE(nesting___err_missing_container),
0586     NESTING_ERR_CASE(nesting___err_nonstruct_container),
0587     NESTING_ERR_CASE(nesting___err_array_container),
0588     NESTING_ERR_CASE(nesting___err_dup_incompat_types),
0589     NESTING_ERR_CASE(nesting___err_partial_match_dups),
0590     NESTING_ERR_CASE(nesting___err_too_deep),
0591 
0592     /* various array access relocation scenarios */
0593     ARRAYS_CASE(arrays),
0594     ARRAYS_CASE(arrays___diff_arr_dim),
0595     ARRAYS_CASE(arrays___diff_arr_val_sz),
0596     ARRAYS_CASE(arrays___equiv_zero_sz_arr),
0597     ARRAYS_CASE(arrays___fixed_arr),
0598 
0599     ARRAYS_ERR_CASE(arrays___err_too_small),
0600     ARRAYS_ERR_CASE(arrays___err_too_shallow),
0601     ARRAYS_ERR_CASE(arrays___err_non_array),
0602     ARRAYS_ERR_CASE(arrays___err_wrong_val_type),
0603     ARRAYS_ERR_CASE(arrays___err_bad_zero_sz_arr),
0604 
0605     /* enum/ptr/int handling scenarios */
0606     PRIMITIVES_CASE(primitives),
0607     PRIMITIVES_CASE(primitives___diff_enum_def),
0608     PRIMITIVES_CASE(primitives___diff_func_proto),
0609     PRIMITIVES_CASE(primitives___diff_ptr_type),
0610 
0611     PRIMITIVES_ERR_CASE(primitives___err_non_enum),
0612     PRIMITIVES_ERR_CASE(primitives___err_non_int),
0613     PRIMITIVES_ERR_CASE(primitives___err_non_ptr),
0614 
0615     /* const/volatile/restrict and typedefs scenarios */
0616     MODS_CASE(mods),
0617     MODS_CASE(mods___mod_swap),
0618     MODS_CASE(mods___typedefs),
0619 
0620     /* handling "ptr is an array" semantics */
0621     PTR_AS_ARR_CASE(ptr_as_arr),
0622     PTR_AS_ARR_CASE(ptr_as_arr___diff_sz),
0623 
0624     /* int signedness/sizing/bitfield handling */
0625     INTS_CASE(ints),
0626     INTS_CASE(ints___bool),
0627     INTS_CASE(ints___reverse_sign),
0628 
0629     /* validate edge cases of capturing relocations */
0630     {
0631         .case_name = "misc",
0632         .bpf_obj_file = "test_core_reloc_misc.o",
0633         .btf_src_file = "btf__core_reloc_misc.o",
0634         .input = (const char *)&(struct core_reloc_misc_extensible[]){
0635             { .a = 1 },
0636             { .a = 2 }, /* not read */
0637             { .a = 3 },
0638         },
0639         .input_len = 4 * sizeof(int),
0640         .output = STRUCT_TO_CHAR_PTR(core_reloc_misc_output) {
0641             .a = 1,
0642             .b = 1,
0643             .c = 0, /* BUG in clang, should be 3 */
0644         },
0645         .output_len = sizeof(struct core_reloc_misc_output),
0646         .raw_tp_name = "sys_enter",
0647         .prog_name = "test_core_misc",
0648     },
0649 
0650     /* validate field existence checks */
0651     {
0652         FIELD_EXISTS_CASE_COMMON(existence),
0653         .input = STRUCT_TO_CHAR_PTR(core_reloc_existence) {
0654             .a = 1,
0655             .b = 2,
0656             .c = 3,
0657             .arr = { 4 },
0658             .s = { .x = 5 },
0659         },
0660         .input_len = sizeof(struct core_reloc_existence),
0661         .output = STRUCT_TO_CHAR_PTR(core_reloc_existence_output) {
0662             .a_exists = 1,
0663             .b_exists = 1,
0664             .c_exists = 1,
0665             .arr_exists = 1,
0666             .s_exists = 1,
0667             .a_value = 1,
0668             .b_value = 2,
0669             .c_value = 3,
0670             .arr_value = 4,
0671             .s_value = 5,
0672         },
0673         .output_len = sizeof(struct core_reloc_existence_output),
0674     },
0675     {
0676         FIELD_EXISTS_CASE_COMMON(existence___minimal),
0677         .input = STRUCT_TO_CHAR_PTR(core_reloc_existence___minimal) {
0678             .a = 42,
0679         },
0680         .input_len = sizeof(struct core_reloc_existence___minimal),
0681         .output = STRUCT_TO_CHAR_PTR(core_reloc_existence_output) {
0682             .a_exists = 1,
0683             .b_exists = 0,
0684             .c_exists = 0,
0685             .arr_exists = 0,
0686             .s_exists = 0,
0687             .a_value = 42,
0688             .b_value = 0xff000002u,
0689             .c_value = 0xff000003u,
0690             .arr_value = 0xff000004u,
0691             .s_value = 0xff000005u,
0692         },
0693         .output_len = sizeof(struct core_reloc_existence_output),
0694     },
0695     {
0696         FIELD_EXISTS_CASE_COMMON(existence___wrong_field_defs),
0697         .input = STRUCT_TO_CHAR_PTR(core_reloc_existence___wrong_field_defs) {
0698         },
0699         .input_len = sizeof(struct core_reloc_existence___wrong_field_defs),
0700         .output = STRUCT_TO_CHAR_PTR(core_reloc_existence_output) {
0701             .a_exists = 0,
0702             .b_exists = 0,
0703             .c_exists = 0,
0704             .arr_exists = 0,
0705             .s_exists = 0,
0706             .a_value = 0xff000001u,
0707             .b_value = 0xff000002u,
0708             .c_value = 0xff000003u,
0709             .arr_value = 0xff000004u,
0710             .s_value = 0xff000005u,
0711         },
0712         .output_len = sizeof(struct core_reloc_existence_output),
0713     },
0714 
0715     /* bitfield relocation checks */
0716     BITFIELDS_CASE(bitfields, {
0717         .ub1 = 1,
0718         .ub2 = 2,
0719         .ub7 = 96,
0720         .sb4 = -7,
0721         .sb20 = -0x76543,
0722         .u32 = 0x80000000,
0723         .s32 = -0x76543210,
0724     }),
0725     BITFIELDS_CASE(bitfields___bit_sz_change, {
0726         .ub1 = 6,
0727         .ub2 = 0xABCDE,
0728         .ub7 = 1,
0729         .sb4 = -1,
0730         .sb20 = -0x17654321,
0731         .u32 = 0xBEEF,
0732         .s32 = -0x3FEDCBA987654321LL,
0733     }),
0734     BITFIELDS_CASE(bitfields___bitfield_vs_int, {
0735         .ub1 = 0xFEDCBA9876543210LL,
0736         .ub2 = 0xA6,
0737         .ub7 = -0x7EDCBA987654321LL,
0738         .sb4 = -0x6123456789ABCDELL,
0739         .sb20 = 0xD00DLL,
0740         .u32 = -0x76543,
0741         .s32 = 0x0ADEADBEEFBADB0BLL,
0742     }),
0743     BITFIELDS_CASE(bitfields___just_big_enough, {
0744         .ub1 = 0xFLL,
0745         .ub2 = 0x0812345678FEDCBALL,
0746     }),
0747     BITFIELDS_ERR_CASE(bitfields___err_too_big_bitfield),
0748 
0749     /* field size and offset relocation checks */
0750     SIZE_CASE(size),
0751     SIZE_CASE(size___diff_sz),
0752     SIZE_CASE(size___diff_offs),
0753     SIZE_ERR_CASE(size___err_ambiguous),
0754 
0755     /* validate type existence, match, and size relocations */
0756     TYPE_BASED_CASE(type_based, {
0757         .struct_exists = 1,
0758         .complex_struct_exists = 1,
0759         .union_exists = 1,
0760         .enum_exists = 1,
0761         .typedef_named_struct_exists = 1,
0762         .typedef_anon_struct_exists = 1,
0763         .typedef_struct_ptr_exists = 1,
0764         .typedef_int_exists = 1,
0765         .typedef_enum_exists = 1,
0766         .typedef_void_ptr_exists = 1,
0767         .typedef_restrict_ptr_exists = 1,
0768         .typedef_func_proto_exists = 1,
0769         .typedef_arr_exists = 1,
0770 
0771         .struct_matches = 1,
0772         .complex_struct_matches = 1,
0773         .union_matches = 1,
0774         .enum_matches = 1,
0775         .typedef_named_struct_matches = 1,
0776         .typedef_anon_struct_matches = 1,
0777         .typedef_struct_ptr_matches = 1,
0778         .typedef_int_matches = 1,
0779         .typedef_enum_matches = 1,
0780         .typedef_void_ptr_matches = 1,
0781         .typedef_restrict_ptr_matches = 1,
0782         .typedef_func_proto_matches = 1,
0783         .typedef_arr_matches = 1,
0784 
0785         .struct_sz = sizeof(struct a_struct),
0786         .union_sz = sizeof(union a_union),
0787         .enum_sz = sizeof(enum an_enum),
0788         .typedef_named_struct_sz = sizeof(named_struct_typedef),
0789         .typedef_anon_struct_sz = sizeof(anon_struct_typedef),
0790         .typedef_struct_ptr_sz = sizeof(struct_ptr_typedef),
0791         .typedef_int_sz = sizeof(int_typedef),
0792         .typedef_enum_sz = sizeof(enum_typedef),
0793         .typedef_void_ptr_sz = sizeof(void_ptr_typedef),
0794         .typedef_func_proto_sz = sizeof(func_proto_typedef),
0795         .typedef_arr_sz = sizeof(arr_typedef),
0796     }),
0797     TYPE_BASED_CASE(type_based___all_missing, {
0798         /* all zeros */
0799     }),
0800     TYPE_BASED_CASE(type_based___diff, {
0801         .struct_exists = 1,
0802         .complex_struct_exists = 1,
0803         .union_exists = 1,
0804         .enum_exists = 1,
0805         .typedef_named_struct_exists = 1,
0806         .typedef_anon_struct_exists = 1,
0807         .typedef_struct_ptr_exists = 1,
0808         .typedef_int_exists = 1,
0809         .typedef_enum_exists = 1,
0810         .typedef_void_ptr_exists = 1,
0811         .typedef_func_proto_exists = 1,
0812         .typedef_arr_exists = 1,
0813 
0814         .struct_matches = 1,
0815         .complex_struct_matches = 1,
0816         .union_matches = 1,
0817         .enum_matches = 1,
0818         .typedef_named_struct_matches = 1,
0819         .typedef_anon_struct_matches = 1,
0820         .typedef_struct_ptr_matches = 1,
0821         .typedef_int_matches = 0,
0822         .typedef_enum_matches = 1,
0823         .typedef_void_ptr_matches = 1,
0824         .typedef_func_proto_matches = 0,
0825         .typedef_arr_matches = 0,
0826 
0827         .struct_sz = sizeof(struct a_struct___diff),
0828         .union_sz = sizeof(union a_union___diff),
0829         .enum_sz = sizeof(enum an_enum___diff),
0830         .typedef_named_struct_sz = sizeof(named_struct_typedef___diff),
0831         .typedef_anon_struct_sz = sizeof(anon_struct_typedef___diff),
0832         .typedef_struct_ptr_sz = sizeof(struct_ptr_typedef___diff),
0833         .typedef_int_sz = sizeof(int_typedef___diff),
0834         .typedef_enum_sz = sizeof(enum_typedef___diff),
0835         .typedef_void_ptr_sz = sizeof(void_ptr_typedef___diff),
0836         .typedef_func_proto_sz = sizeof(func_proto_typedef___diff),
0837         .typedef_arr_sz = sizeof(arr_typedef___diff),
0838     }),
0839     TYPE_BASED_CASE(type_based___diff_sz, {
0840         .struct_exists = 1,
0841         .union_exists = 1,
0842         .enum_exists = 1,
0843         .typedef_named_struct_exists = 1,
0844         .typedef_anon_struct_exists = 1,
0845         .typedef_struct_ptr_exists = 1,
0846         .typedef_int_exists = 1,
0847         .typedef_enum_exists = 1,
0848         .typedef_void_ptr_exists = 1,
0849         .typedef_func_proto_exists = 1,
0850         .typedef_arr_exists = 1,
0851 
0852         .struct_matches = 0,
0853         .union_matches = 0,
0854         .enum_matches = 0,
0855         .typedef_named_struct_matches = 0,
0856         .typedef_anon_struct_matches = 0,
0857         .typedef_struct_ptr_matches = 1,
0858         .typedef_int_matches = 0,
0859         .typedef_enum_matches = 0,
0860         .typedef_void_ptr_matches = 1,
0861         .typedef_func_proto_matches = 0,
0862         .typedef_arr_matches = 0,
0863 
0864         .struct_sz = sizeof(struct a_struct___diff_sz),
0865         .union_sz = sizeof(union a_union___diff_sz),
0866         .enum_sz = sizeof(enum an_enum___diff_sz),
0867         .typedef_named_struct_sz = sizeof(named_struct_typedef___diff_sz),
0868         .typedef_anon_struct_sz = sizeof(anon_struct_typedef___diff_sz),
0869         .typedef_struct_ptr_sz = sizeof(struct_ptr_typedef___diff_sz),
0870         .typedef_int_sz = sizeof(int_typedef___diff_sz),
0871         .typedef_enum_sz = sizeof(enum_typedef___diff_sz),
0872         .typedef_void_ptr_sz = sizeof(void_ptr_typedef___diff_sz),
0873         .typedef_func_proto_sz = sizeof(func_proto_typedef___diff_sz),
0874         .typedef_arr_sz = sizeof(arr_typedef___diff_sz),
0875     }),
0876     TYPE_BASED_CASE(type_based___incompat, {
0877         .enum_exists = 1,
0878         .enum_matches = 1,
0879         .enum_sz = sizeof(enum an_enum),
0880     }),
0881     TYPE_BASED_CASE(type_based___fn_wrong_args, {
0882         .struct_exists = 1,
0883         .struct_matches = 1,
0884         .struct_sz = sizeof(struct a_struct),
0885     }),
0886 
0887     /* BTF_TYPE_ID_LOCAL/BTF_TYPE_ID_TARGET tests */
0888     TYPE_ID_CASE(type_id, setup_type_id_case_success),
0889     TYPE_ID_CASE(type_id___missing_targets, setup_type_id_case_failure),
0890 
0891     /* Enumerator value existence and value relocations */
0892     ENUMVAL_CASE(enumval, {
0893         .named_val1_exists = true,
0894         .named_val2_exists = true,
0895         .named_val3_exists = true,
0896         .anon_val1_exists = true,
0897         .anon_val2_exists = true,
0898         .anon_val3_exists = true,
0899         .named_val1 = 1,
0900         .named_val2 = 2,
0901         .anon_val1 = 0x10,
0902         .anon_val2 = 0x20,
0903     }),
0904     ENUMVAL_CASE(enumval___diff, {
0905         .named_val1_exists = true,
0906         .named_val2_exists = true,
0907         .named_val3_exists = true,
0908         .anon_val1_exists = true,
0909         .anon_val2_exists = true,
0910         .anon_val3_exists = true,
0911         .named_val1 = 101,
0912         .named_val2 = 202,
0913         .anon_val1 = 0x11,
0914         .anon_val2 = 0x22,
0915     }),
0916     ENUMVAL_CASE(enumval___val3_missing, {
0917         .named_val1_exists = true,
0918         .named_val2_exists = true,
0919         .named_val3_exists = false,
0920         .anon_val1_exists = true,
0921         .anon_val2_exists = true,
0922         .anon_val3_exists = false,
0923         .named_val1 = 111,
0924         .named_val2 = 222,
0925         .anon_val1 = 0x111,
0926         .anon_val2 = 0x222,
0927     }),
0928     ENUMVAL_ERR_CASE(enumval___err_missing),
0929 
0930     /* 64bit enumerator value existence and value relocations */
0931     ENUM64VAL_CASE(enum64val, {
0932         .unsigned_val1_exists = true,
0933         .unsigned_val2_exists = true,
0934         .unsigned_val3_exists = true,
0935         .signed_val1_exists = true,
0936         .signed_val2_exists = true,
0937         .signed_val3_exists = true,
0938         .unsigned_val1 = 0x1ffffffffULL,
0939         .unsigned_val2 = 0x2,
0940         .signed_val1 = 0x1ffffffffLL,
0941         .signed_val2 = -2,
0942     }),
0943     ENUM64VAL_CASE(enum64val___diff, {
0944         .unsigned_val1_exists = true,
0945         .unsigned_val2_exists = true,
0946         .unsigned_val3_exists = true,
0947         .signed_val1_exists = true,
0948         .signed_val2_exists = true,
0949         .signed_val3_exists = true,
0950         .unsigned_val1 = 0x101ffffffffULL,
0951         .unsigned_val2 = 0x202ffffffffULL,
0952         .signed_val1 = -101,
0953         .signed_val2 = -202,
0954     }),
0955     ENUM64VAL_CASE(enum64val___val3_missing, {
0956         .unsigned_val1_exists = true,
0957         .unsigned_val2_exists = true,
0958         .unsigned_val3_exists = false,
0959         .signed_val1_exists = true,
0960         .signed_val2_exists = true,
0961         .signed_val3_exists = false,
0962         .unsigned_val1 = 0x111ffffffffULL,
0963         .unsigned_val2 = 0x222,
0964         .signed_val1 = 0x111ffffffffLL,
0965         .signed_val2 = -222,
0966     }),
0967     ENUM64VAL_ERR_CASE(enum64val___err_missing),
0968 };
0969 
0970 struct data {
0971     char in[256];
0972     char out[256];
0973     bool skip;
0974     uint64_t my_pid_tgid;
0975 };
0976 
0977 static size_t roundup_page(size_t sz)
0978 {
0979     long page_size = sysconf(_SC_PAGE_SIZE);
0980     return (sz + page_size - 1) / page_size * page_size;
0981 }
0982 
0983 static int run_btfgen(const char *src_btf, const char *dst_btf, const char *objpath)
0984 {
0985     char command[4096];
0986     int n;
0987 
0988     n = snprintf(command, sizeof(command),
0989              "./bpftool gen min_core_btf %s %s %s",
0990              src_btf, dst_btf, objpath);
0991     if (n < 0 || n >= sizeof(command))
0992         return -1;
0993 
0994     return system(command);
0995 }
0996 
0997 static void run_core_reloc_tests(bool use_btfgen)
0998 {
0999     const size_t mmap_sz = roundup_page(sizeof(struct data));
1000     DECLARE_LIBBPF_OPTS(bpf_object_open_opts, open_opts);
1001     struct core_reloc_test_case *test_case, test_case_copy;
1002     const char *tp_name, *probe_name;
1003     int err, i, equal, fd;
1004     struct bpf_link *link = NULL;
1005     struct bpf_map *data_map;
1006     struct bpf_program *prog;
1007     struct bpf_object *obj;
1008     uint64_t my_pid_tgid;
1009     struct data *data;
1010     void *mmap_data = NULL;
1011 
1012     my_pid_tgid = getpid() | ((uint64_t)syscall(SYS_gettid) << 32);
1013 
1014     for (i = 0; i < ARRAY_SIZE(test_cases); i++) {
1015         char btf_file[] = "/tmp/core_reloc.btf.XXXXXX";
1016 
1017         test_case_copy = test_cases[i];
1018         test_case = &test_case_copy;
1019 
1020         if (!test__start_subtest(test_case->case_name))
1021             continue;
1022 
1023         if (test_case->needs_testmod && !env.has_testmod) {
1024             test__skip();
1025             continue;
1026         }
1027 
1028         /* generate a "minimal" BTF file and use it as source */
1029         if (use_btfgen) {
1030 
1031             if (!test_case->btf_src_file || test_case->run_btfgen_fails) {
1032                 test__skip();
1033                 continue;
1034             }
1035 
1036             fd = mkstemp(btf_file);
1037             if (!ASSERT_GE(fd, 0, "btf_tmp"))
1038                 continue;
1039             close(fd); /* we only need the path */
1040             err = run_btfgen(test_case->btf_src_file, btf_file,
1041                      test_case->bpf_obj_file);
1042             if (!ASSERT_OK(err, "run_btfgen"))
1043                 continue;
1044 
1045             test_case->btf_src_file = btf_file;
1046         }
1047 
1048         if (test_case->setup) {
1049             err = test_case->setup(test_case);
1050             if (CHECK(err, "test_setup", "test #%d setup failed: %d\n", i, err))
1051                 continue;
1052         }
1053 
1054         if (test_case->btf_src_file) {
1055             err = access(test_case->btf_src_file, R_OK);
1056             if (!ASSERT_OK(err, "btf_src_file"))
1057                 continue;
1058         }
1059 
1060         open_opts.btf_custom_path = test_case->btf_src_file;
1061         obj = bpf_object__open_file(test_case->bpf_obj_file, &open_opts);
1062         if (!ASSERT_OK_PTR(obj, "obj_open"))
1063             goto cleanup;
1064 
1065         probe_name = test_case->prog_name;
1066         tp_name = test_case->raw_tp_name; /* NULL for tp_btf */
1067         prog = bpf_object__find_program_by_name(obj, probe_name);
1068         if (CHECK(!prog, "find_probe",
1069               "prog '%s' not found\n", probe_name))
1070             goto cleanup;
1071 
1072         err = bpf_object__load(obj);
1073         if (err) {
1074             if (!test_case->fails)
1075                 ASSERT_OK(err, "obj_load");
1076             goto cleanup;
1077         }
1078 
1079         data_map = bpf_object__find_map_by_name(obj, ".bss");
1080         if (CHECK(!data_map, "find_data_map", "data map not found\n"))
1081             goto cleanup;
1082 
1083         mmap_data = mmap(NULL, mmap_sz, PROT_READ | PROT_WRITE,
1084                  MAP_SHARED, bpf_map__fd(data_map), 0);
1085         if (CHECK(mmap_data == MAP_FAILED, "mmap",
1086               ".bss mmap failed: %d", errno)) {
1087             mmap_data = NULL;
1088             goto cleanup;
1089         }
1090         data = mmap_data;
1091 
1092         memset(mmap_data, 0, sizeof(*data));
1093         if (test_case->input_len)
1094             memcpy(data->in, test_case->input, test_case->input_len);
1095         data->my_pid_tgid = my_pid_tgid;
1096 
1097         link = bpf_program__attach_raw_tracepoint(prog, tp_name);
1098         if (!ASSERT_OK_PTR(link, "attach_raw_tp"))
1099             goto cleanup;
1100 
1101         /* trigger test run */
1102         if (test_case->trigger) {
1103             if (!ASSERT_OK(test_case->trigger(test_case), "test_trigger"))
1104                 goto cleanup;
1105         } else {
1106             usleep(1);
1107         }
1108 
1109         if (data->skip) {
1110             test__skip();
1111             goto cleanup;
1112         }
1113 
1114         if (!ASSERT_FALSE(test_case->fails, "obj_load_should_fail"))
1115             goto cleanup;
1116 
1117         equal = memcmp(data->out, test_case->output,
1118                    test_case->output_len) == 0;
1119         if (CHECK(!equal, "check_result",
1120               "input/output data don't match\n")) {
1121             int j;
1122 
1123             for (j = 0; j < test_case->input_len; j++) {
1124                 printf("input byte #%d: 0x%02hhx\n",
1125                        j, test_case->input[j]);
1126             }
1127             for (j = 0; j < test_case->output_len; j++) {
1128                 printf("output byte #%d: EXP 0x%02hhx GOT 0x%02hhx\n",
1129                        j, test_case->output[j], data->out[j]);
1130             }
1131             goto cleanup;
1132         }
1133 
1134 cleanup:
1135         if (mmap_data) {
1136             CHECK_FAIL(munmap(mmap_data, mmap_sz));
1137             mmap_data = NULL;
1138         }
1139         if (use_btfgen)
1140             remove(test_case->btf_src_file);
1141         bpf_link__destroy(link);
1142         link = NULL;
1143         bpf_object__close(obj);
1144     }
1145 }
1146 
1147 void test_core_reloc(void)
1148 {
1149     run_core_reloc_tests(false);
1150 }
1151 
1152 void test_core_reloc_btfgen(void)
1153 {
1154     run_core_reloc_tests(true);
1155 }