@@ -76,9 +76,11 @@ const char PRINT_TYPE_FMT_NAME(string)[] = "\\\"%s\\\"";
7676/* Fetch type information table */
7777static const struct fetch_type probe_fetch_types [] = {
7878 /* Special types */
79- __ASSIGN_FETCH_TYPE ("string" , string , string , sizeof (u32 ), 1 ,
79+ __ASSIGN_FETCH_TYPE ("string" , string , string , sizeof (u32 ), 1 , 1 ,
8080 "__data_loc char[]" ),
81- __ASSIGN_FETCH_TYPE ("ustring" , string , string , sizeof (u32 ), 1 ,
81+ __ASSIGN_FETCH_TYPE ("ustring" , string , string , sizeof (u32 ), 1 , 1 ,
82+ "__data_loc char[]" ),
83+ __ASSIGN_FETCH_TYPE ("symstr" , string , string , sizeof (u32 ), 1 , 1 ,
8284 "__data_loc char[]" ),
8385 /* Basic types */
8486 ASSIGN_FETCH_TYPE (u8 , u8 , 0 ),
@@ -98,10 +100,15 @@ static const struct fetch_type probe_fetch_types[] = {
98100 ASSIGN_FETCH_TYPE_END
99101};
100102
101- static const struct fetch_type * find_fetch_type (const char * type )
103+ static const struct fetch_type * find_fetch_type (const char * type , unsigned long flags )
102104{
103105 int i ;
104106
107+ /* Reject the symbol/symstr for uprobes */
108+ if (type && (flags & TPARG_FL_USER ) &&
109+ (!strcmp (type , "symbol" ) || !strcmp (type , "symstr" )))
110+ return NULL ;
111+
105112 if (!type )
106113 type = DEFAULT_FETCH_TYPE_STR ;
107114
@@ -119,13 +126,13 @@ static const struct fetch_type *find_fetch_type(const char *type)
119126
120127 switch (bs ) {
121128 case 8 :
122- return find_fetch_type ("u8" );
129+ return find_fetch_type ("u8" , flags );
123130 case 16 :
124- return find_fetch_type ("u16" );
131+ return find_fetch_type ("u16" , flags );
125132 case 32 :
126- return find_fetch_type ("u32" );
133+ return find_fetch_type ("u32" , flags );
127134 case 64 :
128- return find_fetch_type ("u64" );
135+ return find_fetch_type ("u64" , flags );
129136 default :
130137 goto fail ;
131138 }
@@ -478,7 +485,7 @@ parse_probe_arg(char *arg, const struct fetch_type *type,
478485 DEREF_OPEN_BRACE );
479486 return - EINVAL ;
480487 } else {
481- const struct fetch_type * t2 = find_fetch_type (NULL );
488+ const struct fetch_type * t2 = find_fetch_type (NULL , flags );
482489
483490 * tmp = '\0' ;
484491 ret = parse_probe_arg (arg , t2 , & code , end , flags , offs );
@@ -630,9 +637,9 @@ static int traceprobe_parse_probe_arg_body(const char *argv, ssize_t *size,
630637 /* The type of $comm must be "string", and not an array. */
631638 if (parg -> count || (t && strcmp (t , "string" )))
632639 goto out ;
633- parg -> type = find_fetch_type ("string" );
640+ parg -> type = find_fetch_type ("string" , flags );
634641 } else
635- parg -> type = find_fetch_type (t );
642+ parg -> type = find_fetch_type (t , flags );
636643 if (!parg -> type ) {
637644 trace_probe_log_err (offset + (t ? (t - arg ) : 0 ), BAD_TYPE );
638645 goto out ;
@@ -662,23 +669,35 @@ static int traceprobe_parse_probe_arg_body(const char *argv, ssize_t *size,
662669
663670 ret = - EINVAL ;
664671 /* Store operation */
665- if (!strcmp (parg -> type -> name , "string" ) ||
666- !strcmp (parg -> type -> name , "ustring" )) {
667- if (code -> op != FETCH_OP_DEREF && code -> op != FETCH_OP_UDEREF &&
668- code -> op != FETCH_OP_IMM && code -> op != FETCH_OP_COMM &&
669- code -> op != FETCH_OP_DATA && code -> op != FETCH_OP_TP_ARG ) {
670- trace_probe_log_err (offset + (t ? (t - arg ) : 0 ),
671- BAD_STRING );
672- goto fail ;
672+ if (parg -> type -> is_string ) {
673+ if (!strcmp (parg -> type -> name , "symstr" )) {
674+ if (code -> op != FETCH_OP_REG && code -> op != FETCH_OP_STACK &&
675+ code -> op != FETCH_OP_RETVAL && code -> op != FETCH_OP_ARG &&
676+ code -> op != FETCH_OP_DEREF && code -> op != FETCH_OP_TP_ARG ) {
677+ trace_probe_log_err (offset + (t ? (t - arg ) : 0 ),
678+ BAD_SYMSTRING );
679+ goto fail ;
680+ }
681+ } else {
682+ if (code -> op != FETCH_OP_DEREF && code -> op != FETCH_OP_UDEREF &&
683+ code -> op != FETCH_OP_IMM && code -> op != FETCH_OP_COMM &&
684+ code -> op != FETCH_OP_DATA && code -> op != FETCH_OP_TP_ARG ) {
685+ trace_probe_log_err (offset + (t ? (t - arg ) : 0 ),
686+ BAD_STRING );
687+ goto fail ;
688+ }
673689 }
674- if ((code -> op == FETCH_OP_IMM || code -> op == FETCH_OP_COMM ||
690+ if (!strcmp (parg -> type -> name , "symstr" ) ||
691+ (code -> op == FETCH_OP_IMM || code -> op == FETCH_OP_COMM ||
675692 code -> op == FETCH_OP_DATA ) || code -> op == FETCH_OP_TP_ARG ||
676693 parg -> count ) {
677694 /*
678695 * IMM, DATA and COMM is pointing actual address, those
679696 * must be kept, and if parg->count != 0, this is an
680697 * array of string pointers instead of string address
681698 * itself.
699+ * For the symstr, it doesn't need to dereference, thus
700+ * it just get the value.
682701 */
683702 code ++ ;
684703 if (code -> op != FETCH_OP_NOP ) {
@@ -690,6 +709,8 @@ static int traceprobe_parse_probe_arg_body(const char *argv, ssize_t *size,
690709 if (!strcmp (parg -> type -> name , "ustring" ) ||
691710 code -> op == FETCH_OP_UDEREF )
692711 code -> op = FETCH_OP_ST_USTRING ;
712+ else if (!strcmp (parg -> type -> name , "symstr" ))
713+ code -> op = FETCH_OP_ST_SYMSTR ;
693714 else
694715 code -> op = FETCH_OP_ST_STRING ;
695716 code -> size = parg -> type -> size ;
@@ -919,17 +940,15 @@ static int __set_print_fmt(struct trace_probe *tp, char *buf, int len,
919940 for (i = 0 ; i < tp -> nr_args ; i ++ ) {
920941 parg = tp -> args + i ;
921942 if (parg -> count ) {
922- if ((strcmp (parg -> type -> name , "string" ) == 0 ) ||
923- (strcmp (parg -> type -> name , "ustring" ) == 0 ))
943+ if (parg -> type -> is_string )
924944 fmt = ", __get_str(%s[%d])" ;
925945 else
926946 fmt = ", REC->%s[%d]" ;
927947 for (j = 0 ; j < parg -> count ; j ++ )
928948 pos += snprintf (buf + pos , LEN_OR_ZERO ,
929949 fmt , parg -> name , j );
930950 } else {
931- if ((strcmp (parg -> type -> name , "string" ) == 0 ) ||
932- (strcmp (parg -> type -> name , "ustring" ) == 0 ))
951+ if (parg -> type -> is_string )
933952 fmt = ", __get_str(%s)" ;
934953 else
935954 fmt = ", REC->%s" ;
0 commit comments