10
10
#include "disasm_helpers.h"
11
11
#include "unpriv_helpers.h"
12
12
#include "cap_helpers.h"
13
+ #include "jit_disasm_helpers.h"
13
14
14
15
#define str_has_pfx (str , pfx ) \
15
16
(strncmp(str, pfx, __builtin_constant_p(pfx) ? sizeof(pfx) - 1 : strlen(pfx)) == 0)
33
34
#define TEST_TAG_AUXILIARY_UNPRIV "comment:test_auxiliary_unpriv"
34
35
#define TEST_BTF_PATH "comment:test_btf_path="
35
36
#define TEST_TAG_ARCH "comment:test_arch="
37
+ #define TEST_TAG_JITED_PFX "comment:test_jited="
38
+ #define TEST_TAG_JITED_PFX_UNPRIV "comment:test_jited_unpriv="
36
39
37
40
/* Warning: duplicated in bpf_misc.h */
38
41
#define POINTER_VALUE 0xcafe4all
@@ -68,6 +71,7 @@ struct test_subspec {
68
71
bool expect_failure ;
69
72
struct expected_msgs expect_msgs ;
70
73
struct expected_msgs expect_xlated ;
74
+ struct expected_msgs jited ;
71
75
int retval ;
72
76
bool execute ;
73
77
};
@@ -124,6 +128,8 @@ static void free_test_spec(struct test_spec *spec)
124
128
free_msgs (& spec -> unpriv .expect_msgs );
125
129
free_msgs (& spec -> priv .expect_xlated );
126
130
free_msgs (& spec -> unpriv .expect_xlated );
131
+ free_msgs (& spec -> priv .jited );
132
+ free_msgs (& spec -> unpriv .jited );
127
133
128
134
free (spec -> priv .name );
129
135
free (spec -> unpriv .name );
@@ -237,6 +243,21 @@ static int push_msg(const char *substr, struct expected_msgs *msgs)
237
243
return __push_msg (substr , false, msgs );
238
244
}
239
245
246
+ static int push_disasm_msg (const char * regex_str , bool * on_next_line , struct expected_msgs * msgs )
247
+ {
248
+ int err ;
249
+
250
+ if (strcmp (regex_str , "..." ) == 0 ) {
251
+ * on_next_line = false;
252
+ return 0 ;
253
+ }
254
+ err = __push_msg (regex_str , * on_next_line , msgs );
255
+ if (err )
256
+ return err ;
257
+ * on_next_line = true;
258
+ return 0 ;
259
+ }
260
+
240
261
static int parse_int (const char * str , int * val , const char * name )
241
262
{
242
263
char * end ;
@@ -320,6 +341,18 @@ enum arch {
320
341
ARCH_RISCV64 = 0x4 ,
321
342
};
322
343
344
+ static int get_current_arch (void )
345
+ {
346
+ #if defined(__x86_64__ )
347
+ return ARCH_X86_64 ;
348
+ #elif defined(__aarch64__ )
349
+ return ARCH_ARM64 ;
350
+ #elif defined(__riscv ) && __riscv_xlen == 64
351
+ return ARCH_RISCV64 ;
352
+ #endif
353
+ return 0 ;
354
+ }
355
+
323
356
/* Uses btf_decl_tag attributes to describe the expected test
324
357
* behavior, see bpf_misc.h for detailed description of each attribute
325
358
* and attribute combinations.
@@ -332,9 +365,13 @@ static int parse_test_spec(struct test_loader *tester,
332
365
const char * description = NULL ;
333
366
bool has_unpriv_result = false;
334
367
bool has_unpriv_retval = false;
368
+ bool unpriv_jit_on_next_line ;
369
+ bool jit_on_next_line ;
370
+ bool collect_jit = false;
335
371
int func_id , i , err = 0 ;
336
372
u32 arch_mask = 0 ;
337
373
struct btf * btf ;
374
+ enum arch arch ;
338
375
339
376
memset (spec , 0 , sizeof (* spec ));
340
377
@@ -399,6 +436,30 @@ static int parse_test_spec(struct test_loader *tester,
399
436
if (err )
400
437
goto cleanup ;
401
438
spec -> mode_mask |= UNPRIV ;
439
+ } else if ((msg = skip_dynamic_pfx (s , TEST_TAG_JITED_PFX ))) {
440
+ if (arch_mask == 0 ) {
441
+ PRINT_FAIL ("__jited used before __arch_*" );
442
+ goto cleanup ;
443
+ }
444
+ if (collect_jit ) {
445
+ err = push_disasm_msg (msg , & jit_on_next_line ,
446
+ & spec -> priv .jited );
447
+ if (err )
448
+ goto cleanup ;
449
+ spec -> mode_mask |= PRIV ;
450
+ }
451
+ } else if ((msg = skip_dynamic_pfx (s , TEST_TAG_JITED_PFX_UNPRIV ))) {
452
+ if (arch_mask == 0 ) {
453
+ PRINT_FAIL ("__unpriv_jited used before __arch_*" );
454
+ goto cleanup ;
455
+ }
456
+ if (collect_jit ) {
457
+ err = push_disasm_msg (msg , & unpriv_jit_on_next_line ,
458
+ & spec -> unpriv .jited );
459
+ if (err )
460
+ goto cleanup ;
461
+ spec -> mode_mask |= UNPRIV ;
462
+ }
402
463
} else if ((msg = skip_dynamic_pfx (s , TEST_TAG_EXPECT_XLATED_PFX ))) {
403
464
err = push_msg (msg , & spec -> priv .expect_xlated );
404
465
if (err )
@@ -459,16 +520,20 @@ static int parse_test_spec(struct test_loader *tester,
459
520
} else if (str_has_pfx (s , TEST_TAG_ARCH )) {
460
521
val = s + sizeof (TEST_TAG_ARCH ) - 1 ;
461
522
if (strcmp (val , "X86_64" ) == 0 ) {
462
- arch_mask | = ARCH_X86_64 ;
523
+ arch = ARCH_X86_64 ;
463
524
} else if (strcmp (val , "ARM64" ) == 0 ) {
464
- arch_mask | = ARCH_ARM64 ;
525
+ arch = ARCH_ARM64 ;
465
526
} else if (strcmp (val , "RISCV64" ) == 0 ) {
466
- arch_mask | = ARCH_RISCV64 ;
527
+ arch = ARCH_RISCV64 ;
467
528
} else {
468
529
PRINT_FAIL ("bad arch spec: '%s'" , val );
469
530
err = - EINVAL ;
470
531
goto cleanup ;
471
532
}
533
+ arch_mask |= arch ;
534
+ collect_jit = get_current_arch () == arch ;
535
+ unpriv_jit_on_next_line = true;
536
+ jit_on_next_line = true;
472
537
} else if (str_has_pfx (s , TEST_BTF_PATH )) {
473
538
spec -> btf_custom_path = s + sizeof (TEST_BTF_PATH ) - 1 ;
474
539
}
@@ -521,6 +586,8 @@ static int parse_test_spec(struct test_loader *tester,
521
586
clone_msgs (& spec -> priv .expect_msgs , & spec -> unpriv .expect_msgs );
522
587
if (spec -> unpriv .expect_xlated .cnt == 0 )
523
588
clone_msgs (& spec -> priv .expect_xlated , & spec -> unpriv .expect_xlated );
589
+ if (spec -> unpriv .jited .cnt == 0 )
590
+ clone_msgs (& spec -> priv .jited , & spec -> unpriv .jited );
524
591
}
525
592
526
593
spec -> valid = true;
@@ -575,16 +642,29 @@ static void emit_xlated(const char *xlated, bool force)
575
642
fprintf (stdout , "XLATED:\n=============\n%s=============\n" , xlated );
576
643
}
577
644
645
+ static void emit_jited (const char * jited , bool force )
646
+ {
647
+ if (!force && env .verbosity == VERBOSE_NONE )
648
+ return ;
649
+ fprintf (stdout , "JITED:\n=============\n%s=============\n" , jited );
650
+ }
651
+
578
652
static void validate_msgs (char * log_buf , struct expected_msgs * msgs ,
579
653
void (* emit_fn )(const char * buf , bool force ))
580
654
{
655
+ const char * log = log_buf , * prev_match ;
581
656
regmatch_t reg_match [1 ];
582
- const char * log = log_buf ;
657
+ int prev_match_line ;
658
+ int match_line ;
583
659
int i , j , err ;
584
660
661
+ prev_match_line = -1 ;
662
+ match_line = 0 ;
663
+ prev_match = log ;
585
664
for (i = 0 ; i < msgs -> cnt ; i ++ ) {
586
665
struct expect_msg * msg = & msgs -> patterns [i ];
587
- const char * match = NULL ;
666
+ const char * match = NULL , * pat_status ;
667
+ bool wrong_line = false;
588
668
589
669
if (!msg -> is_regex ) {
590
670
match = strstr (log , msg -> substr );
@@ -598,19 +678,41 @@ static void validate_msgs(char *log_buf, struct expected_msgs *msgs,
598
678
}
599
679
}
600
680
601
- if (!match ) {
681
+ if (match ) {
682
+ for (; prev_match < match ; ++ prev_match )
683
+ if (* prev_match == '\n' )
684
+ ++ match_line ;
685
+ wrong_line = msg -> on_next_line && prev_match_line >= 0 &&
686
+ prev_match_line + 1 != match_line ;
687
+ }
688
+
689
+ if (!match || wrong_line ) {
602
690
PRINT_FAIL ("expect_msg\n" );
603
691
if (env .verbosity == VERBOSE_NONE )
604
692
emit_fn (log_buf , true /*force*/ );
605
693
for (j = 0 ; j <= i ; j ++ ) {
606
694
msg = & msgs -> patterns [j ];
695
+ if (j < i )
696
+ pat_status = "MATCHED " ;
697
+ else if (wrong_line )
698
+ pat_status = "WRONG LINE" ;
699
+ else
700
+ pat_status = "EXPECTED " ;
701
+ msg = & msgs -> patterns [j ];
607
702
fprintf (stderr , "%s %s: '%s'\n" ,
608
- j < i ? "MATCHED " : "EXPECTED" ,
703
+ pat_status ,
609
704
msg -> is_regex ? " REGEX" : "SUBSTR" ,
610
705
msg -> substr );
611
706
}
612
- return ;
707
+ if (wrong_line ) {
708
+ fprintf (stderr ,
709
+ "expecting match at line %d, actual match is at line %d\n" ,
710
+ prev_match_line + 1 , match_line );
711
+ }
712
+ break ;
613
713
}
714
+
715
+ prev_match_line = match_line ;
614
716
}
615
717
}
616
718
@@ -769,20 +871,6 @@ static int get_xlated_program_text(int prog_fd, char *text, size_t text_sz)
769
871
return err ;
770
872
}
771
873
772
- static bool run_on_current_arch (int arch_mask )
773
- {
774
- if (arch_mask == 0 )
775
- return true;
776
- #if defined(__x86_64__ )
777
- return arch_mask & ARCH_X86_64 ;
778
- #elif defined(__aarch64__ )
779
- return arch_mask & ARCH_ARM64 ;
780
- #elif defined(__riscv ) && __riscv_xlen == 64
781
- return arch_mask & ARCH_RISCV64 ;
782
- #endif
783
- return false;
784
- }
785
-
786
874
/* this function is forced noinline and has short generic name to look better
787
875
* in test_progs output (in case of a failure)
788
876
*/
@@ -807,7 +895,7 @@ void run_subtest(struct test_loader *tester,
807
895
if (!test__start_subtest (subspec -> name ))
808
896
return ;
809
897
810
- if (! run_on_current_arch ( spec -> arch_mask )) {
898
+ if (( get_current_arch () & spec -> arch_mask ) == 0 ) {
811
899
test__skip ();
812
900
return ;
813
901
}
@@ -884,6 +972,21 @@ void run_subtest(struct test_loader *tester,
884
972
validate_msgs (tester -> log_buf , & subspec -> expect_xlated , emit_xlated );
885
973
}
886
974
975
+ if (subspec -> jited .cnt ) {
976
+ err = get_jited_program_text (bpf_program__fd (tprog ),
977
+ tester -> log_buf , tester -> log_buf_sz );
978
+ if (err == - EOPNOTSUPP ) {
979
+ printf ("%s:SKIP: jited programs disassembly is not supported,\n" , __func__ );
980
+ printf ("%s:SKIP: tests are built w/o LLVM development libs\n" , __func__ );
981
+ test__skip ();
982
+ goto tobj_cleanup ;
983
+ }
984
+ if (!ASSERT_EQ (err , 0 , "get_jited_program_text" ))
985
+ goto tobj_cleanup ;
986
+ emit_jited (tester -> log_buf , false /*force*/ );
987
+ validate_msgs (tester -> log_buf , & subspec -> jited , emit_jited );
988
+ }
989
+
887
990
if (should_do_test_run (spec , subspec )) {
888
991
/* For some reason test_verifier executes programs
889
992
* with all capabilities restored. Do the same here.
0 commit comments