@@ -364,45 +364,54 @@ static const char *fetch_type_from_btf_type(struct btf *btf,
364
364
return NULL ;
365
365
}
366
366
367
- static const struct btf_param * find_btf_func_param (const char * funcname , s32 * nr ,
368
- struct btf * * btf_p , bool tracepoint )
367
+ static int query_btf_context (struct traceprobe_parse_context * ctx )
369
368
{
370
369
const struct btf_param * param ;
371
- const struct btf_type * t ;
370
+ const struct btf_type * type ;
372
371
struct btf * btf ;
372
+ s32 nr ;
373
373
374
- if (! funcname || ! nr )
375
- return ERR_PTR ( - EINVAL ) ;
374
+ if (ctx -> btf )
375
+ return 0 ;
376
376
377
- t = btf_find_func_proto (funcname , & btf );
378
- if (!t )
379
- return (const struct btf_param * )t ;
377
+ if (!ctx -> funcname )
378
+ return - EINVAL ;
380
379
381
- param = btf_get_func_param ( t , nr );
382
- if (IS_ERR_OR_NULL ( param ) )
383
- goto err ;
380
+ type = btf_find_func_proto ( ctx -> funcname , & btf );
381
+ if (! type )
382
+ return - ENOENT ;
384
383
385
- /* Hide the first 'data' argument of tracepoint */
386
- if (tracepoint ) {
387
- (* nr )-- ;
388
- param ++ ;
384
+ ctx -> btf = btf ;
385
+ ctx -> proto = type ;
386
+
387
+ /* ctx->params is optional, since func(void) will not have params. */
388
+ nr = 0 ;
389
+ param = btf_get_func_param (type , & nr );
390
+ if (!IS_ERR_OR_NULL (param )) {
391
+ /* Hide the first 'data' argument of tracepoint */
392
+ if (ctx -> flags & TPARG_FL_TPOINT ) {
393
+ nr -- ;
394
+ param ++ ;
395
+ }
389
396
}
390
397
391
- if (* nr > 0 ) {
392
- * btf_p = btf ;
393
- return param ;
398
+ if (nr > 0 ) {
399
+ ctx -> nr_params = nr ;
400
+ ctx -> params = param ;
401
+ } else {
402
+ ctx -> nr_params = 0 ;
403
+ ctx -> params = NULL ;
394
404
}
395
405
396
- err :
397
- btf_put (btf );
398
- return NULL ;
406
+ return 0 ;
399
407
}
400
408
401
409
static void clear_btf_context (struct traceprobe_parse_context * ctx )
402
410
{
403
411
if (ctx -> btf ) {
404
412
btf_put (ctx -> btf );
405
413
ctx -> btf = NULL ;
414
+ ctx -> proto = NULL ;
406
415
ctx -> params = NULL ;
407
416
ctx -> nr_params = 0 ;
408
417
}
@@ -522,7 +531,7 @@ static int parse_btf_arg(char *varname,
522
531
const struct btf_param * params ;
523
532
const struct btf_type * type ;
524
533
char * field = NULL ;
525
- int i , is_ptr ;
534
+ int i , is_ptr , ret ;
526
535
u32 tid ;
527
536
528
537
if (WARN_ON_ONCE (!ctx -> funcname ))
@@ -538,17 +547,37 @@ static int parse_btf_arg(char *varname,
538
547
return - EOPNOTSUPP ;
539
548
}
540
549
541
- if (!ctx -> params ) {
542
- params = find_btf_func_param (ctx -> funcname ,
543
- & ctx -> nr_params , & ctx -> btf ,
544
- ctx -> flags & TPARG_FL_TPOINT );
545
- if (IS_ERR_OR_NULL (params )) {
550
+ if (ctx -> flags & TPARG_FL_RETURN ) {
551
+ if (strcmp (varname , "$retval" ) != 0 ) {
552
+ trace_probe_log_err (ctx -> offset , NO_BTFARG );
553
+ return - ENOENT ;
554
+ }
555
+ code -> op = FETCH_OP_RETVAL ;
556
+ /* Check whether the function return type is not void */
557
+ if (query_btf_context (ctx ) == 0 ) {
558
+ if (ctx -> proto -> type == 0 ) {
559
+ trace_probe_log_err (ctx -> offset , NO_RETVAL );
560
+ return - ENOENT ;
561
+ }
562
+ tid = ctx -> proto -> type ;
563
+ goto found ;
564
+ }
565
+ if (field ) {
566
+ trace_probe_log_err (ctx -> offset + field - varname ,
567
+ NO_BTF_ENTRY );
568
+ return - ENOENT ;
569
+ }
570
+ return 0 ;
571
+ }
572
+
573
+ if (!ctx -> btf ) {
574
+ ret = query_btf_context (ctx );
575
+ if (ret < 0 || ctx -> nr_params == 0 ) {
546
576
trace_probe_log_err (ctx -> offset , NO_BTF_ENTRY );
547
577
return PTR_ERR (params );
548
578
}
549
- ctx -> params = params ;
550
- } else
551
- params = ctx -> params ;
579
+ }
580
+ params = ctx -> params ;
552
581
553
582
for (i = 0 ; i < ctx -> nr_params ; i ++ ) {
554
583
const char * name = btf_name_by_offset (ctx -> btf , params [i ].name_off );
@@ -559,7 +588,6 @@ static int parse_btf_arg(char *varname,
559
588
code -> param = i + 1 ;
560
589
else
561
590
code -> param = i ;
562
-
563
591
tid = params [i ].type ;
564
592
goto found ;
565
593
}
@@ -584,7 +612,7 @@ static int parse_btf_arg(char *varname,
584
612
return 0 ;
585
613
}
586
614
587
- static const struct fetch_type * parse_btf_arg_type (
615
+ static const struct fetch_type * find_fetch_type_from_btf_type (
588
616
struct traceprobe_parse_context * ctx )
589
617
{
590
618
struct btf * btf = ctx -> btf ;
@@ -596,27 +624,6 @@ static const struct fetch_type *parse_btf_arg_type(
596
624
return find_fetch_type (typestr , ctx -> flags );
597
625
}
598
626
599
- static const struct fetch_type * parse_btf_retval_type (
600
- struct traceprobe_parse_context * ctx )
601
- {
602
- const char * typestr = NULL ;
603
- const struct btf_type * type ;
604
- struct btf * btf ;
605
-
606
- if (ctx -> funcname ) {
607
- /* Do not use ctx->btf, because it must be used with ctx->param */
608
- type = btf_find_func_proto (ctx -> funcname , & btf );
609
- if (type ) {
610
- type = btf_type_skip_modifiers (btf , type -> type , NULL );
611
- if (!IS_ERR_OR_NULL (type ))
612
- typestr = fetch_type_from_btf_type (btf , type , ctx );
613
- btf_put (btf );
614
- }
615
- }
616
-
617
- return find_fetch_type (typestr , ctx -> flags );
618
- }
619
-
620
627
static int parse_btf_bitfield (struct fetch_insn * * pcode ,
621
628
struct traceprobe_parse_context * ctx )
622
629
{
@@ -639,30 +646,15 @@ static int parse_btf_bitfield(struct fetch_insn **pcode,
639
646
return 0 ;
640
647
}
641
648
642
- static bool is_btf_retval_void (const char * funcname )
643
- {
644
- const struct btf_type * t ;
645
- struct btf * btf ;
646
- bool ret ;
647
-
648
- t = btf_find_func_proto (funcname , & btf );
649
- if (!t )
650
- return false;
651
-
652
- ret = (t -> type == 0 );
653
- btf_put (btf );
654
- return ret ;
655
- }
656
649
#else
657
650
static void clear_btf_context (struct traceprobe_parse_context * ctx )
658
651
{
659
652
ctx -> btf = NULL ;
660
653
}
661
654
662
- static const struct btf_param * find_btf_func_param (const char * funcname , s32 * nr ,
663
- struct btf * * btf_p , bool tracepoint )
655
+ static int query_btf_context (struct traceprobe_parse_context * ctx )
664
656
{
665
- return ERR_PTR ( - EOPNOTSUPP ) ;
657
+ return - EOPNOTSUPP ;
666
658
}
667
659
668
660
static int parse_btf_arg (char * varname ,
@@ -680,24 +672,23 @@ static int parse_btf_bitfield(struct fetch_insn **pcode,
680
672
return - EOPNOTSUPP ;
681
673
}
682
674
683
- #define parse_btf_arg_type (ctx ) \
684
- find_fetch_type(NULL, ctx->flags)
685
-
686
- #define parse_btf_retval_type (ctx ) \
675
+ #define find_fetch_type_from_btf_type (ctx ) \
687
676
find_fetch_type(NULL, ctx->flags)
688
677
689
- #define is_btf_retval_void (funcname ) (false)
690
-
691
678
#endif
692
679
693
680
#define PARAM_MAX_STACK (THREAD_SIZE / sizeof(unsigned long))
694
681
695
- static int parse_probe_vars (char * arg , const struct fetch_type * t ,
696
- struct fetch_insn * code ,
682
+ /* Parse $vars. @orig_arg points '$', which syncs to @ctx->offset */
683
+ static int parse_probe_vars (char * orig_arg , const struct fetch_type * t ,
684
+ struct fetch_insn * * pcode ,
685
+ struct fetch_insn * end ,
697
686
struct traceprobe_parse_context * ctx )
698
687
{
699
- unsigned long param ;
688
+ struct fetch_insn * code = * pcode ;
700
689
int err = TP_ERR_BAD_VAR ;
690
+ char * arg = orig_arg + 1 ;
691
+ unsigned long param ;
701
692
int ret = 0 ;
702
693
int len ;
703
694
@@ -716,18 +707,17 @@ static int parse_probe_vars(char *arg, const struct fetch_type *t,
716
707
goto inval ;
717
708
}
718
709
719
- if (strcmp (arg , "retval" ) == 0 ) {
720
- if (ctx -> flags & TPARG_FL_RETURN ) {
721
- if (( ctx -> flags & TPARG_FL_KERNEL ) &&
722
- is_btf_retval_void ( ctx -> funcname )) {
723
- err = TP_ERR_NO_RETVAL ;
724
- goto inval ;
725
- }
710
+ if (str_has_prefix (arg , "retval" )) {
711
+ if (!( ctx -> flags & TPARG_FL_RETURN ) ) {
712
+ err = TP_ERR_RETVAL_ON_PROBE ;
713
+ goto inval ;
714
+ }
715
+ if (!( ctx -> flags & TPARG_FL_KERNEL ) ||
716
+ ! IS_ENABLED ( CONFIG_PROBE_EVENTS_BTF_ARGS )) {
726
717
code -> op = FETCH_OP_RETVAL ;
727
718
return 0 ;
728
719
}
729
- err = TP_ERR_RETVAL_ON_PROBE ;
730
- goto inval ;
720
+ return parse_btf_arg (orig_arg , pcode , end , ctx );
731
721
}
732
722
733
723
len = str_has_prefix (arg , "stack" );
@@ -829,7 +819,7 @@ parse_probe_arg(char *arg, const struct fetch_type *type,
829
819
830
820
switch (arg [0 ]) {
831
821
case '$' :
832
- ret = parse_probe_vars (arg + 1 , type , code , ctx );
822
+ ret = parse_probe_vars (arg , type , pcode , end , ctx );
833
823
break ;
834
824
835
825
case '%' : /* named register */
@@ -1126,12 +1116,9 @@ static int traceprobe_parse_probe_arg_body(const char *argv, ssize_t *size,
1126
1116
goto fail ;
1127
1117
1128
1118
/* Update storing type if BTF is available */
1129
- if (IS_ENABLED (CONFIG_PROBE_EVENTS_BTF_ARGS ) && !t ) {
1130
- if (ctx -> last_type )
1131
- parg -> type = parse_btf_arg_type (ctx );
1132
- else if (ctx -> flags & TPARG_FL_RETURN )
1133
- parg -> type = parse_btf_retval_type (ctx );
1134
- }
1119
+ if (IS_ENABLED (CONFIG_PROBE_EVENTS_BTF_ARGS ) &&
1120
+ !t && ctx -> last_type )
1121
+ parg -> type = find_fetch_type_from_btf_type (ctx );
1135
1122
1136
1123
ret = - EINVAL ;
1137
1124
/* Store operation */
@@ -1420,7 +1407,6 @@ const char **traceprobe_expand_meta_args(int argc, const char *argv[],
1420
1407
const struct btf_param * params = NULL ;
1421
1408
int i , j , n , used , ret , args_idx = -1 ;
1422
1409
const char * * new_argv = NULL ;
1423
- int nr_params ;
1424
1410
1425
1411
ret = argv_has_var_arg (argc , argv , & args_idx , ctx );
1426
1412
if (ret < 0 )
@@ -1431,9 +1417,8 @@ const char **traceprobe_expand_meta_args(int argc, const char *argv[],
1431
1417
return NULL ;
1432
1418
}
1433
1419
1434
- params = find_btf_func_param (ctx -> funcname , & nr_params , & ctx -> btf ,
1435
- ctx -> flags & TPARG_FL_TPOINT );
1436
- if (IS_ERR_OR_NULL (params )) {
1420
+ ret = query_btf_context (ctx );
1421
+ if (ret < 0 || ctx -> nr_params == 0 ) {
1437
1422
if (args_idx != -1 ) {
1438
1423
/* $arg* requires BTF info */
1439
1424
trace_probe_log_err (0 , NOSUP_BTFARG );
@@ -1442,8 +1427,6 @@ const char **traceprobe_expand_meta_args(int argc, const char *argv[],
1442
1427
* new_argc = argc ;
1443
1428
return NULL ;
1444
1429
}
1445
- ctx -> params = params ;
1446
- ctx -> nr_params = nr_params ;
1447
1430
1448
1431
if (args_idx >= 0 )
1449
1432
* new_argc = argc + ctx -> nr_params - 1 ;
@@ -1458,7 +1441,7 @@ const char **traceprobe_expand_meta_args(int argc, const char *argv[],
1458
1441
for (i = 0 , j = 0 ; i < argc ; i ++ ) {
1459
1442
trace_probe_log_set_index (i + 2 );
1460
1443
if (i == args_idx ) {
1461
- for (n = 0 ; n < nr_params ; n ++ ) {
1444
+ for (n = 0 ; n < ctx -> nr_params ; n ++ ) {
1462
1445
ret = sprint_nth_btf_arg (n , "" , buf + used ,
1463
1446
bufsize - used , ctx );
1464
1447
if (ret < 0 )
0 commit comments