@@ -332,6 +332,23 @@ static int parse_trace_event_arg(char *arg, struct fetch_insn *code,
332332 return - ENOENT ;
333333}
334334
335+ static int parse_trace_event (char * arg , struct fetch_insn * code ,
336+ struct traceprobe_parse_context * ctx )
337+ {
338+ int ret ;
339+
340+ if (code -> data )
341+ return - EFAULT ;
342+ ret = parse_trace_event_arg (arg , code , ctx );
343+ if (!ret )
344+ return 0 ;
345+ if (strcmp (arg , "comm" ) == 0 || strcmp (arg , "COMM" ) == 0 ) {
346+ code -> op = FETCH_OP_COMM ;
347+ return 0 ;
348+ }
349+ return - EINVAL ;
350+ }
351+
335352#ifdef CONFIG_PROBE_EVENTS_BTF_ARGS
336353
337354static u32 btf_type_int (const struct btf_type * t )
@@ -376,11 +393,16 @@ static bool btf_type_is_char_array(struct btf *btf, const struct btf_type *type)
376393 && BTF_INT_BITS (intdata ) == 8 ;
377394}
378395
396+ static struct btf * ctx_btf (struct traceprobe_parse_context * ctx )
397+ {
398+ return ctx -> struct_btf ? : ctx -> btf ;
399+ }
400+
379401static int check_prepare_btf_string_fetch (char * typename ,
380402 struct fetch_insn * * pcode ,
381403 struct traceprobe_parse_context * ctx )
382404{
383- struct btf * btf = ctx -> btf ;
405+ struct btf * btf = ctx_btf ( ctx ) ;
384406
385407 if (!btf || !ctx -> last_type )
386408 return 0 ;
@@ -506,6 +528,15 @@ static int query_btf_context(struct traceprobe_parse_context *ctx)
506528 return 0 ;
507529}
508530
531+ static void clear_struct_btf (struct traceprobe_parse_context * ctx )
532+ {
533+ if (ctx -> struct_btf ) {
534+ btf_put (ctx -> struct_btf );
535+ ctx -> struct_btf = NULL ;
536+ ctx -> last_struct = NULL ;
537+ }
538+ }
539+
509540static void clear_btf_context (struct traceprobe_parse_context * ctx )
510541{
511542 if (ctx -> btf ) {
@@ -554,22 +585,29 @@ static int parse_btf_field(char *fieldname, const struct btf_type *type,
554585 struct fetch_insn * code = * pcode ;
555586 const struct btf_member * field ;
556587 u32 bitoffs , anon_offs ;
588+ bool is_struct = ctx -> struct_btf != NULL ;
589+ struct btf * btf = ctx_btf (ctx );
557590 char * next ;
558591 int is_ptr ;
559592 s32 tid ;
560593
561594 do {
562- /* Outer loop for solving arrow operator ('->') */
563- if (BTF_INFO_KIND (type -> info ) != BTF_KIND_PTR ) {
564- trace_probe_log_err (ctx -> offset , NO_PTR_STRCT );
565- return - EINVAL ;
566- }
567- /* Convert a struct pointer type to a struct type */
568- type = btf_type_skip_modifiers (ctx -> btf , type -> type , & tid );
569- if (!type ) {
570- trace_probe_log_err (ctx -> offset , BAD_BTF_TID );
571- return - EINVAL ;
595+ if (!is_struct ) {
596+ /* Outer loop for solving arrow operator ('->') */
597+ if (BTF_INFO_KIND (type -> info ) != BTF_KIND_PTR ) {
598+ trace_probe_log_err (ctx -> offset , NO_PTR_STRCT );
599+ return - EINVAL ;
600+ }
601+
602+ /* Convert a struct pointer type to a struct type */
603+ type = btf_type_skip_modifiers (btf , type -> type , & tid );
604+ if (!type ) {
605+ trace_probe_log_err (ctx -> offset , BAD_BTF_TID );
606+ return - EINVAL ;
607+ }
572608 }
609+ /* Only the first type can skip being a pointer */
610+ is_struct = false;
573611
574612 bitoffs = 0 ;
575613 do {
@@ -580,7 +618,7 @@ static int parse_btf_field(char *fieldname, const struct btf_type *type,
580618 return is_ptr ;
581619
582620 anon_offs = 0 ;
583- field = btf_find_struct_member (ctx -> btf , type , fieldname ,
621+ field = btf_find_struct_member (btf , type , fieldname ,
584622 & anon_offs );
585623 if (IS_ERR (field )) {
586624 trace_probe_log_err (ctx -> offset , BAD_BTF_TID );
@@ -602,7 +640,7 @@ static int parse_btf_field(char *fieldname, const struct btf_type *type,
602640 ctx -> last_bitsize = 0 ;
603641 }
604642
605- type = btf_type_skip_modifiers (ctx -> btf , field -> type , & tid );
643+ type = btf_type_skip_modifiers (btf , field -> type , & tid );
606644 if (!type ) {
607645 trace_probe_log_err (ctx -> offset , BAD_BTF_TID );
608646 return - EINVAL ;
@@ -640,7 +678,7 @@ static int parse_btf_arg(char *varname,
640678 int i , is_ptr , ret ;
641679 u32 tid ;
642680
643- if (WARN_ON_ONCE (!ctx -> funcname ))
681+ if (WARN_ON_ONCE (!ctx -> funcname && !( ctx -> flags & TPARG_FL_TEVENT ) ))
644682 return - EINVAL ;
645683
646684 is_ptr = split_next_field (varname , & field , ctx );
@@ -653,6 +691,19 @@ static int parse_btf_arg(char *varname,
653691 return - EOPNOTSUPP ;
654692 }
655693
694+ if (ctx -> flags & TPARG_FL_TEVENT ) {
695+ ret = parse_trace_event (varname , code , ctx );
696+ if (ret < 0 ) {
697+ trace_probe_log_err (ctx -> offset , BAD_ATTACH_ARG );
698+ return ret ;
699+ }
700+ /* TEVENT is only here via a typecast */
701+ if (WARN_ON_ONCE (ctx -> struct_btf == NULL ))
702+ return - EINVAL ;
703+ type = ctx -> last_struct ;
704+ goto found_type ;
705+ }
706+
656707 if (ctx -> flags & TPARG_FL_RETURN && !strcmp (varname , "$retval" )) {
657708 code -> op = FETCH_OP_RETVAL ;
658709 /* Check whether the function return type is not void */
@@ -709,6 +760,7 @@ static int parse_btf_arg(char *varname,
709760
710761found :
711762 type = btf_type_skip_modifiers (ctx -> btf , tid , & tid );
763+ found_type :
712764 if (!type ) {
713765 trace_probe_log_err (ctx -> offset , BAD_BTF_TID );
714766 return - EINVAL ;
@@ -727,7 +779,7 @@ static int parse_btf_arg(char *varname,
727779static const struct fetch_type * find_fetch_type_from_btf_type (
728780 struct traceprobe_parse_context * ctx )
729781{
730- struct btf * btf = ctx -> btf ;
782+ struct btf * btf = ctx_btf ( ctx ) ;
731783 const char * typestr = NULL ;
732784
733785 if (btf && ctx -> last_type )
@@ -758,7 +810,67 @@ static int parse_btf_bitfield(struct fetch_insn **pcode,
758810 return 0 ;
759811}
760812
761- #else
813+ static int query_btf_struct (const char * sname , struct traceprobe_parse_context * ctx )
814+ {
815+ struct btf * btf = NULL ;
816+ int id ;
817+
818+ /* A struct_btf should only be used by a single argument */
819+ if (WARN_ON_ONCE (ctx -> struct_btf )) {
820+ btf_put (ctx -> struct_btf );
821+ ctx -> struct_btf = NULL ;
822+ }
823+
824+ id = bpf_find_btf_id (sname , BTF_KIND_STRUCT , & btf );
825+ if (id < 0 )
826+ return id ;
827+ ctx -> struct_btf = btf ;
828+ ctx -> last_struct = btf_type_by_id (ctx -> struct_btf , id );
829+ return 0 ;
830+ }
831+
832+ static int handle_typecast (char * arg , struct fetch_insn * * pcode ,
833+ struct fetch_insn * end ,
834+ struct traceprobe_parse_context * ctx )
835+ {
836+ char * tmp ;
837+ int ret ;
838+
839+ /* Currently this only works for eprobes */
840+ if (!(ctx -> flags & TPARG_FL_TEVENT )) {
841+ trace_probe_log_err (ctx -> offset , TYPECAST_NOT_EVENT );
842+ return - EINVAL ;
843+ }
844+
845+ tmp = strchr (arg , ')' );
846+ if (!tmp ) {
847+ trace_probe_log_err (ctx -> offset + strlen (arg ),
848+ DEREF_OPEN_BRACE );
849+ return - EINVAL ;
850+ }
851+ * tmp = '\0' ;
852+ ret = query_btf_struct (arg + 1 , ctx );
853+ * tmp = ')' ;
854+
855+ if (ret < 0 ) {
856+ trace_probe_log_err (ctx -> offset + 1 , NO_PTR_STRCT );
857+ return - EINVAL ;
858+ }
859+
860+ tmp ++ ;
861+
862+ ctx -> offset += tmp - arg ;
863+ ret = parse_btf_arg (tmp , pcode , end , ctx );
864+ return ret ;
865+ }
866+
867+ #else /* !CONFIG_PROBE_EVENTS_BTF_ARGS */
868+
869+ static void clear_struct_btf (struct traceprobe_parse_context * ctx )
870+ {
871+ ctx -> struct_btf = NULL ;
872+ }
873+
762874static void clear_btf_context (struct traceprobe_parse_context * ctx )
763875{
764876 ctx -> btf = NULL ;
@@ -794,7 +906,15 @@ static int check_prepare_btf_string_fetch(char *typename,
794906 return 0 ;
795907}
796908
797- #endif
909+ static int handle_typecast (char * arg , struct fetch_insn * * pcode ,
910+ struct fetch_insn * end ,
911+ struct traceprobe_parse_context * ctx )
912+ {
913+ trace_probe_log_err (ctx -> offset , NOSUP_BTFARG );
914+ return - EOPNOTSUPP ;
915+ }
916+
917+ #endif /* CONFIG_PROBE_EVENTS_BTF_ARGS */
798918
799919#ifdef CONFIG_HAVE_FUNCTION_ARG_ACCESS_API
800920
@@ -838,15 +958,10 @@ static int __store_entry_arg(struct trace_probe *tp, int argnum)
838958 int i , offset , last_offset = 0 ;
839959
840960 if (!earg ) {
841- earg = kzalloc_obj ( * tp -> entry_arg );
961+ earg = kzalloc_flex ( * earg , code , 2 * tp -> nr_args + 1 );
842962 if (!earg )
843963 return - ENOMEM ;
844964 earg -> size = 2 * tp -> nr_args + 1 ;
845- earg -> code = kzalloc_objs (struct fetch_insn , earg -> size );
846- if (!earg -> code ) {
847- kfree (earg );
848- return - ENOMEM ;
849- }
850965 /* Fill the code buffer with 'end' to simplify it */
851966 for (i = 0 ; i < earg -> size ; i ++ )
852967 earg -> code [i ].op = FETCH_OP_END ;
@@ -953,16 +1068,9 @@ static int parse_probe_vars(char *orig_arg, const struct fetch_type *t,
9531068 int len ;
9541069
9551070 if (ctx -> flags & TPARG_FL_TEVENT ) {
956- if (code -> data )
957- return - EFAULT ;
958- ret = parse_trace_event_arg (arg , code , ctx );
959- if (!ret )
960- return 0 ;
961- if (strcmp (arg , "comm" ) == 0 || strcmp (arg , "COMM" ) == 0 ) {
962- code -> op = FETCH_OP_COMM ;
963- return 0 ;
964- }
965- goto inval ;
1071+ if (parse_trace_event (arg , code , ctx ) < 0 )
1072+ goto inval ;
1073+ return 0 ;
9661074 }
9671075
9681076 if (str_has_prefix (arg , "retval" )) {
@@ -1229,6 +1337,9 @@ parse_probe_arg(char *arg, const struct fetch_type *type,
12291337 code -> op = FETCH_OP_IMM ;
12301338 }
12311339 break ;
1340+ case '(' :
1341+ ret = handle_typecast (arg , pcode , end , ctx );
1342+ break ;
12321343 default :
12331344 if (isalpha (arg [0 ]) || arg [0 ] == '_' ) { /* BTF variable */
12341345 if (!tparg_is_function_entry (ctx -> flags ) &&
@@ -1561,6 +1672,9 @@ static int traceprobe_parse_probe_arg_body(const char *argv, ssize_t *size,
15611672 }
15621673 kfree (tmp );
15631674
1675+ /* struct_btf should not be passed to other arguments */
1676+ clear_struct_btf (ctx );
1677+
15641678 return ret ;
15651679}
15661680
@@ -2049,7 +2163,6 @@ void trace_probe_cleanup(struct trace_probe *tp)
20492163 traceprobe_free_probe_arg (& tp -> args [i ]);
20502164
20512165 if (tp -> entry_arg ) {
2052- kfree (tp -> entry_arg -> code );
20532166 kfree (tp -> entry_arg );
20542167 tp -> entry_arg = NULL ;
20552168 }
0 commit comments