6
6
#include <linux/err.h>
7
7
#include <linux/kernel.h>
8
8
#include <linux/filter.h>
9
+ #include <linux/unistd.h>
9
10
#include <bpf/bpf.h>
10
11
#include <sys/resource.h>
11
12
#include <libelf.h>
@@ -114,12 +115,13 @@ static struct args {
114
115
unsigned int raw_test_num ;
115
116
unsigned int file_test_num ;
116
117
unsigned int get_info_test_num ;
118
+ unsigned int info_raw_test_num ;
117
119
bool raw_test ;
118
120
bool file_test ;
119
121
bool get_info_test ;
120
122
bool pprint_test ;
121
123
bool always_log ;
122
- bool func_type_test ;
124
+ bool info_raw_test ;
123
125
} args ;
124
126
125
127
static char btf_log_buf [BTF_LOG_BUF_SIZE ];
@@ -3051,7 +3053,7 @@ static int test_pprint(void)
3051
3053
return err ;
3052
3054
}
3053
3055
3054
- static struct btf_func_type_test {
3056
+ static struct prog_info_raw_test {
3055
3057
const char * descr ;
3056
3058
const char * str_sec ;
3057
3059
__u32 raw_types [MAX_NR_RAW_TYPES ];
@@ -3062,7 +3064,7 @@ static struct btf_func_type_test {
3062
3064
__u32 func_info_rec_size ;
3063
3065
__u32 func_info_cnt ;
3064
3066
bool expected_prog_load_failure ;
3065
- } func_type_test [] = {
3067
+ } info_raw_tests [] = {
3066
3068
{
3067
3069
.descr = "func_type (main func + one sub)" ,
3068
3070
.raw_types = {
@@ -3198,90 +3200,44 @@ static size_t probe_prog_length(const struct bpf_insn *fp)
3198
3200
return len + 1 ;
3199
3201
}
3200
3202
3201
- static int do_test_func_type (int test_num )
3203
+ static int test_get_finfo (const struct prog_info_raw_test * test ,
3204
+ int prog_fd )
3202
3205
{
3203
- const struct btf_func_type_test * test = & func_type_test [test_num ];
3204
- unsigned int raw_btf_size , info_len , rec_size ;
3205
- int i , btf_fd = -1 , prog_fd = -1 , err = 0 ;
3206
- struct bpf_load_program_attr attr = {};
3207
- void * raw_btf , * func_info = NULL ;
3208
3206
struct bpf_prog_info info = {};
3209
3207
struct bpf_func_info * finfo ;
3210
-
3211
- fprintf (stderr , "%s......" , test -> descr );
3212
- raw_btf = btf_raw_create (& hdr_tmpl , test -> raw_types ,
3213
- test -> str_sec , test -> str_sec_size ,
3214
- & raw_btf_size );
3215
-
3216
- if (!raw_btf )
3217
- return -1 ;
3218
-
3219
- * btf_log_buf = '\0' ;
3220
- btf_fd = bpf_load_btf (raw_btf , raw_btf_size ,
3221
- btf_log_buf , BTF_LOG_BUF_SIZE ,
3222
- args .always_log );
3223
- free (raw_btf );
3224
-
3225
- if (CHECK (btf_fd == -1 , "invalid btf_fd errno:%d" , errno )) {
3226
- err = -1 ;
3227
- goto done ;
3228
- }
3229
-
3230
- if (* btf_log_buf && args .always_log )
3231
- fprintf (stderr , "\n%s" , btf_log_buf );
3232
-
3233
- attr .prog_type = test -> prog_type ;
3234
- attr .insns = test -> insns ;
3235
- attr .insns_cnt = probe_prog_length (attr .insns );
3236
- attr .license = "GPL" ;
3237
- attr .prog_btf_fd = btf_fd ;
3238
- attr .func_info_rec_size = test -> func_info_rec_size ;
3239
- attr .func_info_cnt = test -> func_info_cnt ;
3240
- attr .func_info = test -> func_info ;
3241
-
3242
- * btf_log_buf = '\0' ;
3243
- prog_fd = bpf_load_program_xattr (& attr , btf_log_buf ,
3244
- BTF_LOG_BUF_SIZE );
3245
- if (test -> expected_prog_load_failure && prog_fd == -1 ) {
3246
- err = 0 ;
3247
- goto done ;
3248
- }
3249
- if (CHECK (prog_fd == -1 , "invalid prog_id errno:%d" , errno )) {
3250
- fprintf (stderr , "%s\n" , btf_log_buf );
3251
- err = -1 ;
3252
- goto done ;
3253
- }
3208
+ __u32 info_len , rec_size , i ;
3209
+ void * func_info = NULL ;
3210
+ int err ;
3254
3211
3255
3212
/* get necessary lens */
3256
3213
info_len = sizeof (struct bpf_prog_info );
3257
3214
err = bpf_obj_get_info_by_fd (prog_fd , & info , & info_len );
3258
3215
if (CHECK (err == -1 , "invalid get info (1st) errno:%d" , errno )) {
3259
3216
fprintf (stderr , "%s\n" , btf_log_buf );
3260
- err = -1 ;
3261
- goto done ;
3217
+ return -1 ;
3262
3218
}
3263
- if (CHECK (info .func_info_cnt != 2 ,
3264
- "incorrect info.func_info_cnt (1st) %d\n " ,
3219
+ if (CHECK (info .func_info_cnt != test -> func_info_cnt ,
3220
+ "incorrect info.func_info_cnt (1st) %d" ,
3265
3221
info .func_info_cnt )) {
3266
- err = -1 ;
3267
- goto done ;
3222
+ return -1 ;
3268
3223
}
3224
+
3269
3225
rec_size = info .func_info_rec_size ;
3270
- if (CHECK (rec_size < 4 ,
3271
- "incorrect info.func_info_rec_size (1st) %d\n" , rec_size )) {
3272
- err = -1 ;
3273
- goto done ;
3226
+ if (CHECK (rec_size < 8 ,
3227
+ "incorrect info.func_info_rec_size (1st) %d" , rec_size )) {
3228
+ return -1 ;
3274
3229
}
3275
3230
3231
+ if (!info .func_info_cnt )
3232
+ return 0 ;
3233
+
3276
3234
func_info = malloc (info .func_info_cnt * rec_size );
3277
- if (CHECK (!func_info , "out of memory" )) {
3278
- err = -1 ;
3279
- goto done ;
3280
- }
3235
+ if (CHECK (!func_info , "out of memory" ))
3236
+ return -1 ;
3281
3237
3282
3238
/* reset info to only retrieve func_info related data */
3283
3239
memset (& info , 0 , sizeof (info ));
3284
- info .func_info_cnt = 2 ;
3240
+ info .func_info_cnt = test -> func_info_cnt ;
3285
3241
info .func_info_rec_size = rec_size ;
3286
3242
info .func_info = ptr_to_u64 (func_info );
3287
3243
err = bpf_obj_get_info_by_fd (prog_fd , & info , & info_len );
@@ -3290,14 +3246,14 @@ static int do_test_func_type(int test_num)
3290
3246
err = -1 ;
3291
3247
goto done ;
3292
3248
}
3293
- if (CHECK (info .func_info_cnt != 2 ,
3294
- "incorrect info.func_info_cnt (2nd) %d\n " ,
3249
+ if (CHECK (info .func_info_cnt != test -> func_info_cnt ,
3250
+ "incorrect info.func_info_cnt (2nd) %d" ,
3295
3251
info .func_info_cnt )) {
3296
3252
err = -1 ;
3297
3253
goto done ;
3298
3254
}
3299
- if (CHECK (info .func_info_rec_size != rec_size ,
3300
- "incorrect info.func_info_rec_size (2nd) %d\n " ,
3255
+ if (CHECK (info .func_info_rec_size < 8 ,
3256
+ "incorrect info.func_info_rec_size (2nd) %d" ,
3301
3257
info .func_info_rec_size )) {
3302
3258
err = -1 ;
3303
3259
goto done ;
@@ -3310,7 +3266,7 @@ static int do_test_func_type(int test_num)
3310
3266
}
3311
3267
3312
3268
finfo = func_info ;
3313
- for (i = 0 ; i < 2 ; i ++ ) {
3269
+ for (i = 0 ; i < test -> func_info_cnt ; i ++ ) {
3314
3270
if (CHECK (finfo -> type_id != test -> func_info [i ][1 ],
3315
3271
"incorrect func_type %u expected %u" ,
3316
3272
finfo -> type_id , test -> func_info [i ][1 ])) {
@@ -3320,41 +3276,114 @@ static int do_test_func_type(int test_num)
3320
3276
finfo = (void * )finfo + rec_size ;
3321
3277
}
3322
3278
3279
+ err = 0 ;
3280
+
3281
+ done :
3282
+ free (func_info );
3283
+ return err ;
3284
+ }
3285
+
3286
+ static int do_test_info_raw (unsigned int test_num )
3287
+ {
3288
+ const struct prog_info_raw_test * test = & info_raw_tests [test_num - 1 ];
3289
+ int btf_fd = -1 , prog_fd = -1 , err = 0 ;
3290
+ unsigned int raw_btf_size ;
3291
+ union bpf_attr attr = {};
3292
+ void * raw_btf ;
3293
+
3294
+ fprintf (stderr , "BTF prog info raw test[%u] (%s): " , test_num , test -> descr );
3295
+ raw_btf = btf_raw_create (& hdr_tmpl , test -> raw_types ,
3296
+ test -> str_sec , test -> str_sec_size ,
3297
+ & raw_btf_size );
3298
+
3299
+ if (!raw_btf )
3300
+ return -1 ;
3301
+
3302
+ * btf_log_buf = '\0' ;
3303
+ btf_fd = bpf_load_btf (raw_btf , raw_btf_size ,
3304
+ btf_log_buf , BTF_LOG_BUF_SIZE ,
3305
+ args .always_log );
3306
+ free (raw_btf );
3307
+
3308
+ if (CHECK (btf_fd == -1 , "invalid btf_fd errno:%d" , errno )) {
3309
+ err = -1 ;
3310
+ goto done ;
3311
+ }
3312
+
3313
+ if (* btf_log_buf && args .always_log )
3314
+ fprintf (stderr , "\n%s" , btf_log_buf );
3315
+ * btf_log_buf = '\0' ;
3316
+
3317
+ attr .prog_type = test -> prog_type ;
3318
+ attr .insns = ptr_to_u64 (test -> insns );
3319
+ attr .insn_cnt = probe_prog_length (test -> insns );
3320
+ attr .license = ptr_to_u64 ("GPL" );
3321
+ attr .prog_btf_fd = btf_fd ;
3322
+ attr .func_info_rec_size = test -> func_info_rec_size ;
3323
+ attr .func_info_cnt = test -> func_info_cnt ;
3324
+ attr .func_info = ptr_to_u64 (test -> func_info );
3325
+ attr .log_buf = ptr_to_u64 (btf_log_buf );
3326
+ attr .log_size = BTF_LOG_BUF_SIZE ;
3327
+ attr .log_level = 1 ;
3328
+
3329
+ prog_fd = syscall (__NR_bpf , BPF_PROG_LOAD , & attr , sizeof (attr ));
3330
+ err = ((prog_fd == -1 ) != test -> expected_prog_load_failure );
3331
+ if (CHECK (err , "prog_fd:%d expected_prog_load_failure:%u errno:%d" ,
3332
+ prog_fd , test -> expected_prog_load_failure , errno )) {
3333
+ err = -1 ;
3334
+ goto done ;
3335
+ }
3336
+
3337
+ if (prog_fd == -1 )
3338
+ goto done ;
3339
+
3340
+ err = test_get_finfo (test , prog_fd );
3341
+ if (err )
3342
+ goto done ;
3343
+
3323
3344
done :
3345
+ if (!err )
3346
+ fprintf (stderr , "OK" );
3347
+
3324
3348
if (* btf_log_buf && (err || args .always_log ))
3325
3349
fprintf (stderr , "\n%s" , btf_log_buf );
3326
3350
3327
3351
if (btf_fd != -1 )
3328
3352
close (btf_fd );
3329
3353
if (prog_fd != -1 )
3330
3354
close (prog_fd );
3331
- free ( func_info );
3355
+
3332
3356
return err ;
3333
3357
}
3334
3358
3335
- static int test_func_type (void )
3359
+ static int test_info_raw (void )
3336
3360
{
3337
3361
unsigned int i ;
3338
3362
int err = 0 ;
3339
3363
3340
- for (i = 0 ; i < ARRAY_SIZE (func_type_test ); i ++ )
3341
- err |= count_result (do_test_func_type (i ));
3364
+ if (args .info_raw_test_num )
3365
+ return count_result (do_test_info_raw (args .info_raw_test_num ));
3366
+
3367
+ for (i = 1 ; i <= ARRAY_SIZE (info_raw_tests ); i ++ )
3368
+ err |= count_result (do_test_info_raw (i ));
3342
3369
3343
3370
return err ;
3344
3371
}
3345
3372
3346
3373
static void usage (const char * cmd )
3347
3374
{
3348
- fprintf (stderr , "Usage: %s [-l] [[-r test_num (1 - %zu)] |"
3349
- " [-g test_num (1 - %zu)] |"
3350
- " [-f test_num (1 - %zu)] | [-p] | [-k] ]\n" ,
3375
+ fprintf (stderr , "Usage: %s [-l] [[-r btf_raw_test_num (1 - %zu)] |\n"
3376
+ "\t[-g btf_get_info_test_num (1 - %zu)] |\n"
3377
+ "\t[-f btf_file_test_num (1 - %zu)] |\n"
3378
+ "\t[-k btf_prog_info_raw_test_num (1 - %zu)] |\n"
3379
+ "\t[-p (pretty print test)]]\n" ,
3351
3380
cmd , ARRAY_SIZE (raw_tests ), ARRAY_SIZE (get_info_tests ),
3352
- ARRAY_SIZE (file_tests ));
3381
+ ARRAY_SIZE (file_tests ), ARRAY_SIZE ( info_raw_tests ) );
3353
3382
}
3354
3383
3355
3384
static int parse_args (int argc , char * * argv )
3356
3385
{
3357
- const char * optstr = "lpkf :r:g:" ;
3386
+ const char * optstr = "lpk:f :r:g:" ;
3358
3387
int opt ;
3359
3388
3360
3389
while ((opt = getopt (argc , argv , optstr )) != -1 ) {
@@ -3378,7 +3407,8 @@ static int parse_args(int argc, char **argv)
3378
3407
args .pprint_test = true;
3379
3408
break ;
3380
3409
case 'k' :
3381
- args .func_type_test = true;
3410
+ args .info_raw_test_num = atoi (optarg );
3411
+ args .info_raw_test = true;
3382
3412
break ;
3383
3413
case 'h' :
3384
3414
usage (argv [0 ]);
@@ -3413,6 +3443,14 @@ static int parse_args(int argc, char **argv)
3413
3443
return -1 ;
3414
3444
}
3415
3445
3446
+ if (args .info_raw_test_num &&
3447
+ (args .info_raw_test_num < 1 ||
3448
+ args .info_raw_test_num > ARRAY_SIZE (info_raw_tests ))) {
3449
+ fprintf (stderr , "BTF prog info raw test number must be [1 - %zu]\n" ,
3450
+ ARRAY_SIZE (info_raw_tests ));
3451
+ return -1 ;
3452
+ }
3453
+
3416
3454
return 0 ;
3417
3455
}
3418
3456
@@ -3445,16 +3483,17 @@ int main(int argc, char **argv)
3445
3483
if (args .pprint_test )
3446
3484
err |= test_pprint ();
3447
3485
3448
- if (args .func_type_test )
3449
- err |= test_func_type ();
3486
+ if (args .info_raw_test )
3487
+ err |= test_info_raw ();
3450
3488
3451
3489
if (args .raw_test || args .get_info_test || args .file_test ||
3452
- args .pprint_test || args .func_type_test )
3490
+ args .pprint_test || args .info_raw_test )
3453
3491
goto done ;
3454
3492
3455
3493
err |= test_raw ();
3456
3494
err |= test_get_info ();
3457
3495
err |= test_file ();
3496
+ err |= test_info_raw ();
3458
3497
3459
3498
done :
3460
3499
print_summary ();
0 commit comments