@@ -898,6 +898,46 @@ static struct tracepoint *find_tracepoint(const char *tp_name)
898
898
return data .tpoint ;
899
899
}
900
900
901
+ static int parse_symbol_and_return (int argc , const char * argv [],
902
+ char * * symbol , bool * is_return ,
903
+ bool is_tracepoint )
904
+ {
905
+ char * tmp = strchr (argv [1 ], '%' );
906
+ int i ;
907
+
908
+ if (tmp ) {
909
+ int len = tmp - argv [1 ];
910
+
911
+ if (!is_tracepoint && !strcmp (tmp , "%return" )) {
912
+ * is_return = true;
913
+ } else {
914
+ trace_probe_log_err (len , BAD_ADDR_SUFFIX );
915
+ return - EINVAL ;
916
+ }
917
+ * symbol = kmemdup_nul (argv [1 ], len , GFP_KERNEL );
918
+ } else
919
+ * symbol = kstrdup (argv [1 ], GFP_KERNEL );
920
+ if (!* symbol )
921
+ return - ENOMEM ;
922
+
923
+ if (* is_return )
924
+ return 0 ;
925
+
926
+ /* If there is $retval, this should be a return fprobe. */
927
+ for (i = 2 ; i < argc ; i ++ ) {
928
+ tmp = strstr (argv [i ], "$retval" );
929
+ if (tmp && !isalnum (tmp [7 ]) && tmp [7 ] != '_' ) {
930
+ * is_return = true;
931
+ /*
932
+ * NOTE: Don't check is_tracepoint here, because it will
933
+ * be checked when the argument is parsed.
934
+ */
935
+ break ;
936
+ }
937
+ }
938
+ return 0 ;
939
+ }
940
+
901
941
static int __trace_fprobe_create (int argc , const char * argv [])
902
942
{
903
943
/*
@@ -927,7 +967,7 @@ static int __trace_fprobe_create(int argc, const char *argv[])
927
967
struct trace_fprobe * tf = NULL ;
928
968
int i , len , new_argc = 0 , ret = 0 ;
929
969
bool is_return = false;
930
- char * symbol = NULL , * tmp = NULL ;
970
+ char * symbol = NULL ;
931
971
const char * event = NULL , * group = FPROBE_EVENT_SYSTEM ;
932
972
const char * * new_argv = NULL ;
933
973
int maxactive = 0 ;
@@ -983,20 +1023,10 @@ static int __trace_fprobe_create(int argc, const char *argv[])
983
1023
trace_probe_log_set_index (1 );
984
1024
985
1025
/* a symbol(or tracepoint) must be specified */
986
- symbol = kstrdup ( argv [ 1 ], GFP_KERNEL );
987
- if (! symbol )
988
- return - ENOMEM ;
1026
+ ret = parse_symbol_and_return ( argc , argv , & symbol , & is_return , is_tracepoint );
1027
+ if (ret < 0 )
1028
+ goto parse_error ;
989
1029
990
- tmp = strchr (symbol , '%' );
991
- if (tmp ) {
992
- if (!is_tracepoint && !strcmp (tmp , "%return" )) {
993
- * tmp = '\0' ;
994
- is_return = true;
995
- } else {
996
- trace_probe_log_err (tmp - symbol , BAD_ADDR_SUFFIX );
997
- goto parse_error ;
998
- }
999
- }
1000
1030
if (!is_return && maxactive ) {
1001
1031
trace_probe_log_set_index (0 );
1002
1032
trace_probe_log_err (1 , BAD_MAXACT_TYPE );
0 commit comments