Home | History | Annotate | Line # | Download | only in libbpfjit
t_cop.c revision 1.3
      1 /*	$NetBSD: t_cop.c,v 1.3 2014/07/08 21:13:01 alnsn Exp $ */
      2 
      3 /*-
      4  * Copyright (c) 2013-2014 Alexander Nasonov.
      5  * All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  *
     11  * 1. Redistributions of source code must retain the above copyright
     12  *    notice, this list of conditions and the following disclaimer.
     13  * 2. Redistributions in binary form must reproduce the above copyright
     14  *    notice, this list of conditions and the following disclaimer in
     15  *    the documentation and/or other materials provided with the
     16  *    distribution.
     17  *
     18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     19  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
     21  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
     22  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
     23  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
     24  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     25  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
     26  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
     27  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
     28  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     29  * SUCH DAMAGE.
     30  */
     31 
     32 #include <sys/cdefs.h>
     33 __RCSID("$NetBSD: t_cop.c,v 1.3 2014/07/08 21:13:01 alnsn Exp $");
     34 
     35 #include <atf-c.h>
     36 #include <stdint.h>
     37 #include <string.h>
     38 
     39 #define __BPF_PRIVATE
     40 #include <net/bpf.h>
     41 #include <net/bpfjit.h>
     42 
     43 static uint32_t retA(const bpf_ctx_t *bc, bpf_args_t *args, uint32_t A);
     44 static uint32_t retBL(const bpf_ctx_t *bc, bpf_args_t *args, uint32_t A);
     45 static uint32_t retWL(const bpf_ctx_t *bc, bpf_args_t *args, uint32_t A);
     46 static uint32_t retNF(const bpf_ctx_t *bc, bpf_args_t *args, uint32_t A);
     47 static uint32_t setARG(const bpf_ctx_t *bc, bpf_args_t *args, uint32_t A);
     48 
     49 static const bpf_copfunc_t copfuncs[] = {
     50 	&retA,
     51 	&retBL,
     52 	&retWL,
     53 	&retNF,
     54 	&setARG
     55 };
     56 
     57 static const bpf_ctx_t ctx = {
     58 	.copfuncs = copfuncs,
     59 	.nfuncs = sizeof(copfuncs) / sizeof(copfuncs[0]),
     60 	.extwords = 0
     61 };
     62 
     63 static uint32_t
     64 retA(const bpf_ctx_t *bc, bpf_args_t *args, uint32_t A)
     65 {
     66 
     67 	return A;
     68 }
     69 
     70 static uint32_t
     71 retBL(const bpf_ctx_t *bc, bpf_args_t *args, uint32_t A)
     72 {
     73 
     74 	return args->buflen;
     75 }
     76 
     77 static uint32_t
     78 retWL(const bpf_ctx_t *bc, bpf_args_t *args, uint32_t A)
     79 {
     80 
     81 	return args->wirelen;
     82 }
     83 
     84 static uint32_t
     85 retNF(const bpf_ctx_t *bc, bpf_args_t *args, uint32_t A)
     86 {
     87 
     88 	return bc->nfuncs;
     89 }
     90 
     91 /*
     92  * COP function with a side effect.
     93  */
     94 static uint32_t
     95 setARG(const bpf_ctx_t *bc, bpf_args_t *args, uint32_t A)
     96 {
     97 	bool *arg = (bool *)args->arg;
     98 	bool old = *arg;
     99 
    100 	*arg = true;
    101 	return old;
    102 }
    103 
    104 ATF_TC(libbpfjit_cop_no_ctx);
    105 ATF_TC_HEAD(libbpfjit_cop_no_ctx, tc)
    106 {
    107 	atf_tc_set_md_var(tc, "descr", "Test that bpf program with BPF_COP "
    108 	    "instruction isn't valid without a context");
    109 }
    110 
    111 ATF_TC_BODY(libbpfjit_cop_no_ctx, tc)
    112 {
    113 	static struct bpf_insn insns[] = {
    114 		BPF_STMT(BPF_MISC+BPF_COP, 0),
    115 		BPF_STMT(BPF_RET+BPF_K, 7)
    116 	};
    117 
    118 	bpfjit_func_t code;
    119 
    120 	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
    121 
    122 	ATF_CHECK(!bpf_validate(insns, insn_count));
    123 
    124 	code = bpfjit_generate_code(NULL, insns, insn_count);
    125 	ATF_CHECK(code == NULL);
    126 }
    127 
    128 ATF_TC(libbpfjit_cop_ret_A);
    129 ATF_TC_HEAD(libbpfjit_cop_ret_A, tc)
    130 {
    131 	atf_tc_set_md_var(tc, "descr", "Test coprocessor function "
    132 	    "that returns a content of the A register");
    133 }
    134 
    135 ATF_TC_BODY(libbpfjit_cop_ret_A, tc)
    136 {
    137 	static struct bpf_insn insns[] = {
    138 		BPF_STMT(BPF_LD+BPF_IMM, 13),
    139 		BPF_STMT(BPF_MISC+BPF_COP, 0), // retA
    140 		BPF_STMT(BPF_RET+BPF_A, 0)
    141 	};
    142 
    143 	bpfjit_func_t code;
    144 	uint8_t pkt[1] = { 0 };
    145 	bpf_args_t args = {
    146 		.pkt = pkt,
    147 		.buflen = sizeof(pkt),
    148 		.wirelen = sizeof(pkt),
    149 	};
    150 
    151 	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
    152 
    153 	code = bpfjit_generate_code(&ctx, insns, insn_count);
    154 	ATF_REQUIRE(code != NULL);
    155 
    156 	ATF_CHECK(code(&ctx, &args) == 13);
    157 
    158 	bpfjit_free_code(code);
    159 }
    160 
    161 ATF_TC(libbpfjit_cop_ret_buflen);
    162 ATF_TC_HEAD(libbpfjit_cop_ret_buflen, tc)
    163 {
    164 	atf_tc_set_md_var(tc, "descr", "Test coprocessor function "
    165 	    "that returns the buflen argument");
    166 }
    167 
    168 ATF_TC_BODY(libbpfjit_cop_ret_buflen, tc)
    169 {
    170 	static struct bpf_insn insns[] = {
    171 		BPF_STMT(BPF_LD+BPF_IMM, 13),
    172 		BPF_STMT(BPF_MISC+BPF_COP, 1), // retBL
    173 		BPF_STMT(BPF_RET+BPF_A, 0)
    174 	};
    175 
    176 	bpfjit_func_t code;
    177 	uint8_t pkt[1] = { 0 };
    178 	bpf_args_t args = {
    179 		.pkt = pkt,
    180 		.buflen = sizeof(pkt),
    181 		.wirelen = sizeof(pkt)
    182 	};
    183 
    184 	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
    185 
    186 	code = bpfjit_generate_code(&ctx, insns, insn_count);
    187 	ATF_REQUIRE(code != NULL);
    188 
    189 	ATF_CHECK(code(&ctx, &args) == sizeof(pkt));
    190 
    191 	bpfjit_free_code(code);
    192 }
    193 
    194 ATF_TC(libbpfjit_cop_ret_wirelen);
    195 ATF_TC_HEAD(libbpfjit_cop_ret_wirelen, tc)
    196 {
    197 	atf_tc_set_md_var(tc, "descr", "Test coprocessor function "
    198 	    "that returns the wirelen argument");
    199 }
    200 
    201 ATF_TC_BODY(libbpfjit_cop_ret_wirelen, tc)
    202 {
    203 	static struct bpf_insn insns[] = {
    204 		BPF_STMT(BPF_LD+BPF_IMM, 13),
    205 		BPF_STMT(BPF_MISC+BPF_COP, 2), // retWL
    206 		BPF_STMT(BPF_RET+BPF_A, 0)
    207 	};
    208 
    209 	bpfjit_func_t code;
    210 	uint8_t pkt[1] = { 0 };
    211 	bpf_args_t args = {
    212 		.pkt = pkt,
    213 		.buflen = sizeof(pkt),
    214 		.wirelen = sizeof(pkt)
    215 	};
    216 
    217 	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
    218 
    219 	code = bpfjit_generate_code(&ctx, insns, insn_count);
    220 	ATF_REQUIRE(code != NULL);
    221 
    222 	ATF_CHECK(code(&ctx, &args) == sizeof(pkt));
    223 
    224 	bpfjit_free_code(code);
    225 }
    226 
    227 ATF_TC(libbpfjit_cop_ret_nfuncs);
    228 ATF_TC_HEAD(libbpfjit_cop_ret_nfuncs, tc)
    229 {
    230 	atf_tc_set_md_var(tc, "descr", "Test coprocessor function "
    231 	    "that returns nfuncs member of the context argument");
    232 }
    233 
    234 ATF_TC_BODY(libbpfjit_cop_ret_nfuncs, tc)
    235 {
    236 	static struct bpf_insn insns[] = {
    237 		BPF_STMT(BPF_LD+BPF_IMM, 13),
    238 		BPF_STMT(BPF_MISC+BPF_COP, 3), // retNF
    239 		BPF_STMT(BPF_RET+BPF_A, 0)
    240 	};
    241 
    242 	bpfjit_func_t code;
    243 	uint8_t pkt[1] = { 0 };
    244 	bpf_args_t args = {
    245 		.pkt = pkt,
    246 		.buflen = sizeof(pkt),
    247 		.wirelen = sizeof(pkt)
    248 	};
    249 
    250 	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
    251 
    252 	code = bpfjit_generate_code(&ctx, insns, insn_count);
    253 	ATF_REQUIRE(code != NULL);
    254 
    255 	ATF_CHECK(code(&ctx, &args) == ctx.nfuncs);
    256 
    257 	bpfjit_free_code(code);
    258 }
    259 
    260 ATF_TC(libbpfjit_cop_side_effect);
    261 ATF_TC_HEAD(libbpfjit_cop_side_effect, tc)
    262 {
    263 	atf_tc_set_md_var(tc, "descr",
    264 	    "Test that ABC optimization doesn't skip BPF_COP call");
    265 }
    266 
    267 ATF_TC_BODY(libbpfjit_cop_side_effect, tc)
    268 {
    269 	static struct bpf_insn insns[] = {
    270 		BPF_STMT(BPF_LD+BPF_IMM, 13),
    271 		BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 0),
    272 		BPF_STMT(BPF_MISC+BPF_COP, 4), // setARG
    273 		BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 99999),
    274 		BPF_STMT(BPF_RET+BPF_A, 0)
    275 	};
    276 
    277 	bpfjit_func_t code;
    278 	bool arg = false;
    279 	uint8_t pkt[1] = { 0 };
    280 	bpf_args_t args = {
    281 		.pkt = pkt,
    282 		.buflen = sizeof(pkt),
    283 		.wirelen = sizeof(pkt),
    284 		.mem = NULL,
    285 		.arg = &arg
    286 	};
    287 
    288 	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
    289 
    290 	code = bpfjit_generate_code(&ctx, insns, insn_count);
    291 	ATF_REQUIRE(code != NULL);
    292 
    293 	ATF_CHECK(code(&ctx, &args) == 0);
    294 	ATF_CHECK(arg == true);
    295 
    296 	bpfjit_free_code(code);
    297 }
    298 
    299 ATF_TC(libbpfjit_cop_invalid_index);
    300 ATF_TC_HEAD(libbpfjit_cop_invalid_index, tc)
    301 {
    302 	atf_tc_set_md_var(tc, "descr",
    303 	    "Test that out-of-range coprocessor function fails validation");
    304 }
    305 
    306 ATF_TC_BODY(libbpfjit_cop_invalid_index, tc)
    307 {
    308 	static struct bpf_insn insns[] = {
    309 		BPF_STMT(BPF_LD+BPF_IMM, 13),
    310 		BPF_STMT(BPF_MISC+BPF_COP, 6), // invalid index
    311 		BPF_STMT(BPF_RET+BPF_K, 27)
    312 	};
    313 
    314 	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
    315 
    316 	ATF_CHECK(bpfjit_generate_code(&ctx, insns, insn_count) == NULL);
    317 }
    318 
    319 ATF_TC(libbpfjit_copx_no_ctx);
    320 ATF_TC_HEAD(libbpfjit_copx_no_ctx, tc)
    321 {
    322 	atf_tc_set_md_var(tc, "descr", "Test that bpf program with BPF_COPX "
    323 	    "instruction isn't valid without a context");
    324 }
    325 
    326 ATF_TC_BODY(libbpfjit_copx_no_ctx, tc)
    327 {
    328 	static struct bpf_insn insns[] = {
    329 		BPF_STMT(BPF_MISC+BPF_COP, 0),
    330 		BPF_STMT(BPF_RET+BPF_K, 7)
    331 	};
    332 
    333 	bpfjit_func_t code;
    334 
    335 	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
    336 
    337 	ATF_CHECK(!bpf_validate(insns, insn_count));
    338 
    339 	code = bpfjit_generate_code(NULL, insns, insn_count);
    340 	ATF_CHECK(code == NULL);
    341 }
    342 
    343 ATF_TC(libbpfjit_copx_ret_A);
    344 ATF_TC_HEAD(libbpfjit_copx_ret_A, tc)
    345 {
    346 	atf_tc_set_md_var(tc, "descr", "Test coprocessor function "
    347 	    "that returns a content of the A register");
    348 }
    349 
    350 ATF_TC_BODY(libbpfjit_copx_ret_A, tc)
    351 {
    352 	static struct bpf_insn insns[] = {
    353 		BPF_STMT(BPF_LD+BPF_IMM, 13),
    354 		BPF_STMT(BPF_LDX+BPF_IMM, 0), // retA
    355 		BPF_STMT(BPF_MISC+BPF_COPX, 0),
    356 		BPF_STMT(BPF_RET+BPF_A, 0)
    357 	};
    358 
    359 	bpfjit_func_t code;
    360 	uint8_t pkt[1] = { 0 };
    361 	bpf_args_t args = {
    362 		.pkt = pkt,
    363 		.buflen = sizeof(pkt),
    364 		.wirelen = sizeof(pkt),
    365 	};
    366 
    367 	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
    368 
    369 	code = bpfjit_generate_code(&ctx, insns, insn_count);
    370 	ATF_REQUIRE(code != NULL);
    371 
    372 	ATF_CHECK(code(&ctx, &args) == 13);
    373 
    374 	bpfjit_free_code(code);
    375 }
    376 
    377 ATF_TC(libbpfjit_copx_ret_buflen);
    378 ATF_TC_HEAD(libbpfjit_copx_ret_buflen, tc)
    379 {
    380 	atf_tc_set_md_var(tc, "descr", "Test coprocessor function "
    381 	    "that returns the buflen argument");
    382 }
    383 
    384 ATF_TC_BODY(libbpfjit_copx_ret_buflen, tc)
    385 {
    386 	static struct bpf_insn insns[] = {
    387 		BPF_STMT(BPF_LD+BPF_IMM, 13),
    388 		BPF_STMT(BPF_LDX+BPF_IMM, 1), // retBL
    389 		BPF_STMT(BPF_MISC+BPF_COPX, 0),
    390 		BPF_STMT(BPF_RET+BPF_A, 0)
    391 	};
    392 
    393 	bpfjit_func_t code;
    394 	uint8_t pkt[1] = { 0 };
    395 	bpf_args_t args = {
    396 		.pkt = pkt,
    397 		.buflen = sizeof(pkt),
    398 		.wirelen = sizeof(pkt)
    399 	};
    400 
    401 	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
    402 
    403 	code = bpfjit_generate_code(&ctx, insns, insn_count);
    404 	ATF_REQUIRE(code != NULL);
    405 
    406 	ATF_CHECK(code(&ctx, &args) == sizeof(pkt));
    407 
    408 	bpfjit_free_code(code);
    409 }
    410 
    411 ATF_TC(libbpfjit_copx_ret_wirelen);
    412 ATF_TC_HEAD(libbpfjit_copx_ret_wirelen, tc)
    413 {
    414 	atf_tc_set_md_var(tc, "descr", "Test coprocessor function "
    415 	    "that returns the wirelen argument");
    416 }
    417 
    418 ATF_TC_BODY(libbpfjit_copx_ret_wirelen, tc)
    419 {
    420 	static struct bpf_insn insns[] = {
    421 		BPF_STMT(BPF_LDX+BPF_IMM, 2), // retWL
    422 		BPF_STMT(BPF_LD+BPF_IMM, 13),
    423 		BPF_STMT(BPF_MISC+BPF_COPX, 0),
    424 		BPF_STMT(BPF_RET+BPF_A, 0)
    425 	};
    426 
    427 	bpfjit_func_t code;
    428 	uint8_t pkt[1] = { 0 };
    429 	bpf_args_t args = {
    430 		.pkt = pkt,
    431 		.buflen = sizeof(pkt),
    432 		.wirelen = sizeof(pkt)
    433 	};
    434 
    435 	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
    436 
    437 	code = bpfjit_generate_code(&ctx, insns, insn_count);
    438 	ATF_REQUIRE(code != NULL);
    439 
    440 	ATF_CHECK(code(&ctx, &args) == sizeof(pkt));
    441 
    442 	bpfjit_free_code(code);
    443 }
    444 
    445 ATF_TC(libbpfjit_copx_ret_nfuncs);
    446 ATF_TC_HEAD(libbpfjit_copx_ret_nfuncs, tc)
    447 {
    448 	atf_tc_set_md_var(tc, "descr", "Test coprocessor function "
    449 	    "that returns nfuncs member of the context argument");
    450 }
    451 
    452 ATF_TC_BODY(libbpfjit_copx_ret_nfuncs, tc)
    453 {
    454 	static struct bpf_insn insns[] = {
    455 		BPF_STMT(BPF_LD+BPF_IMM, 13),
    456 		BPF_STMT(BPF_LDX+BPF_IMM, 3), // retNF
    457 		BPF_STMT(BPF_MISC+BPF_COPX, 0),
    458 		BPF_STMT(BPF_RET+BPF_A, 0)
    459 	};
    460 
    461 	bpfjit_func_t code;
    462 	uint8_t pkt[1] = { 0 };
    463 	bpf_args_t args = {
    464 		.pkt = pkt,
    465 		.buflen = sizeof(pkt),
    466 		.wirelen = sizeof(pkt)
    467 	};
    468 
    469 	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
    470 
    471 	code = bpfjit_generate_code(&ctx, insns, insn_count);
    472 	ATF_REQUIRE(code != NULL);
    473 
    474 	ATF_CHECK(code(&ctx, &args) == ctx.nfuncs);
    475 
    476 	bpfjit_free_code(code);
    477 }
    478 
    479 ATF_TC(libbpfjit_copx_side_effect);
    480 ATF_TC_HEAD(libbpfjit_copx_side_effect, tc)
    481 {
    482 	atf_tc_set_md_var(tc, "descr",
    483 	    "Test that ABC optimization doesn't skip BPF_COPX call");
    484 }
    485 
    486 ATF_TC_BODY(libbpfjit_copx_side_effect, tc)
    487 {
    488 	static struct bpf_insn insns[] = {
    489 		BPF_STMT(BPF_LD+BPF_IMM, 13),
    490 		BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 0),
    491 		BPF_STMT(BPF_LDX+BPF_IMM, 4), // setARG
    492 		BPF_STMT(BPF_MISC+BPF_COPX, 0),
    493 		BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 99999),
    494 		BPF_STMT(BPF_RET+BPF_A, 0)
    495 	};
    496 
    497 	bpfjit_func_t code;
    498 	bool arg = false;
    499 	uint8_t pkt[1] = { 0 };
    500 	bpf_args_t args = {
    501 		.pkt = pkt,
    502 		.buflen = sizeof(pkt),
    503 		.wirelen = sizeof(pkt),
    504 		.mem = NULL,
    505 		.arg = &arg
    506 	};
    507 
    508 	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
    509 
    510 	code = bpfjit_generate_code(&ctx, insns, insn_count);
    511 	ATF_REQUIRE(code != NULL);
    512 
    513 	ATF_CHECK(code(&ctx, &args) == 0);
    514 	ATF_CHECK(arg == true);
    515 
    516 	bpfjit_free_code(code);
    517 }
    518 
    519 ATF_TC(libbpfjit_copx_invalid_index);
    520 ATF_TC_HEAD(libbpfjit_copx_invalid_index, tc)
    521 {
    522 	atf_tc_set_md_var(tc, "descr",
    523 	    "Test that out-of-range BPF_COPX call fails at runtime");
    524 }
    525 
    526 ATF_TC_BODY(libbpfjit_copx_invalid_index, tc)
    527 {
    528 	static struct bpf_insn insns[] = {
    529 		BPF_STMT(BPF_LDX+BPF_IMM, 5), // invalid index
    530 		BPF_STMT(BPF_MISC+BPF_COPX, 0),
    531 		BPF_STMT(BPF_RET+BPF_K, 27)
    532 	};
    533 
    534 	bpfjit_func_t code;
    535 	uint8_t pkt[1] = { 0 };
    536 	bpf_args_t args = {
    537 		.pkt = pkt,
    538 		.buflen = sizeof(pkt),
    539 		.wirelen = sizeof(pkt)
    540 	};
    541 
    542 	size_t insn_count = sizeof(insns) / sizeof(insns[0]);
    543 
    544 	code = bpfjit_generate_code(&ctx, insns, insn_count);
    545 	ATF_REQUIRE(code != NULL);
    546 
    547 	ATF_CHECK(code(&ctx, &args) == 0);
    548 
    549 	bpfjit_free_code(code);
    550 }
    551 
    552 ATF_TP_ADD_TCS(tp)
    553 {
    554 
    555 	ATF_TP_ADD_TC(tp, libbpfjit_cop_no_ctx);
    556 	ATF_TP_ADD_TC(tp, libbpfjit_cop_ret_A);
    557 	ATF_TP_ADD_TC(tp, libbpfjit_cop_ret_buflen);
    558 	ATF_TP_ADD_TC(tp, libbpfjit_cop_ret_wirelen);
    559 	ATF_TP_ADD_TC(tp, libbpfjit_cop_ret_nfuncs);
    560 	ATF_TP_ADD_TC(tp, libbpfjit_cop_side_effect);
    561 	ATF_TP_ADD_TC(tp, libbpfjit_cop_invalid_index);
    562 
    563 	ATF_TP_ADD_TC(tp, libbpfjit_copx_no_ctx);
    564 	ATF_TP_ADD_TC(tp, libbpfjit_copx_ret_A);
    565 	ATF_TP_ADD_TC(tp, libbpfjit_copx_ret_buflen);
    566 	ATF_TP_ADD_TC(tp, libbpfjit_copx_ret_wirelen);
    567 	ATF_TP_ADD_TC(tp, libbpfjit_copx_ret_nfuncs);
    568 	ATF_TP_ADD_TC(tp, libbpfjit_copx_side_effect);
    569 	ATF_TP_ADD_TC(tp, libbpfjit_copx_invalid_index);
    570 
    571 	return atf_no_error();
    572 }
    573