@@ -932,6 +932,37 @@ static int syscall_arg_fmt__cache_btf_enum(struct syscall_arg_fmt *arg_fmt, stru
932932 return arg_fmt -> type == NULL ? -1 : 0 ;
933933}
934934
935+ static bool syscall_arg__strtoul_btf_enum (char * bf , size_t size , struct syscall_arg * arg , u64 * val )
936+ {
937+ const struct btf_type * bt ;
938+ char * type = arg -> parm ;
939+ struct btf_enum * be ;
940+ struct btf * btf ;
941+
942+ trace__load_vmlinux_btf (arg -> trace );
943+
944+ btf = arg -> trace -> btf ;
945+ if (btf == NULL )
946+ return false;
947+
948+ if (syscall_arg_fmt__cache_btf_enum (arg -> fmt , btf , type ) < 0 )
949+ return false;
950+
951+ bt = arg -> fmt -> type ;
952+ be = btf_enum (bt );
953+ for (int i = 0 ; i < btf_vlen (bt ); ++ i , ++ be ) {
954+ const char * name = btf__name_by_offset (btf , be -> name_off );
955+ int max_len = max (size , strlen (name ));
956+
957+ if (strncmp (name , bf , max_len ) == 0 ) {
958+ * val = be -> val ;
959+ return true;
960+ }
961+ }
962+
963+ return false;
964+ }
965+
935966static size_t btf_enum_scnprintf (const struct btf_type * type , struct btf * btf , char * bf , size_t size , int val )
936967{
937968 struct btf_enum * be = btf_enum (type );
@@ -965,8 +996,16 @@ static size_t trace__btf_enum_scnprintf(struct trace *trace __maybe_unused, stru
965996{
966997 return 0 ;
967998}
999+
1000+ static bool syscall_arg__strtoul_btf_enum (char * bf __maybe_unused , size_t size __maybe_unused ,
1001+ struct syscall_arg * arg __maybe_unused , u64 * val __maybe_unused )
1002+ {
1003+ return false;
1004+ }
9681005#endif // HAVE_LIBBPF_SUPPORT
9691006
1007+ #define STUL_BTF_ENUM syscall_arg__strtoul_btf_enum
1008+
9701009#define STRARRAY (name , array ) \
9711010 { .scnprintf = SCA_STRARRAY, \
9721011 .strtoul = STUL_STRARRAY, \
@@ -1867,6 +1906,7 @@ syscall_arg_fmt__init_array(struct syscall_arg_fmt *arg, struct tep_format_field
18671906 arg -> scnprintf = SCA_FD ;
18681907 } else if (strstr (field -> type , "enum" ) && use_btf != NULL ) {
18691908 * use_btf = arg -> is_enum = true;
1909+ arg -> strtoul = STUL_BTF_ENUM ;
18701910 } else {
18711911 const struct syscall_arg_fmt * fmt =
18721912 syscall_arg_fmt__find_by_name (field -> name );
@@ -3792,7 +3832,8 @@ static int ordered_events__deliver_event(struct ordered_events *oe,
37923832 return __trace__deliver_event (trace , event -> event );
37933833}
37943834
3795- static struct syscall_arg_fmt * evsel__find_syscall_arg_fmt_by_name (struct evsel * evsel , char * arg )
3835+ static struct syscall_arg_fmt * evsel__find_syscall_arg_fmt_by_name (struct evsel * evsel , char * arg ,
3836+ char * * type )
37963837{
37973838 struct tep_format_field * field ;
37983839 struct syscall_arg_fmt * fmt = __evsel__syscall_arg_fmt (evsel );
@@ -3801,13 +3842,15 @@ static struct syscall_arg_fmt *evsel__find_syscall_arg_fmt_by_name(struct evsel
38013842 return NULL ;
38023843
38033844 for (field = evsel -> tp_format -> format .fields ; field ; field = field -> next , ++ fmt )
3804- if (strcmp (field -> name , arg ) == 0 )
3845+ if (strcmp (field -> name , arg ) == 0 ) {
3846+ * type = field -> type ;
38053847 return fmt ;
3848+ }
38063849
38073850 return NULL ;
38083851}
38093852
3810- static int trace__expand_filter (struct trace * trace __maybe_unused , struct evsel * evsel )
3853+ static int trace__expand_filter (struct trace * trace , struct evsel * evsel )
38113854{
38123855 char * tok , * left = evsel -> filter , * new_filter = evsel -> filter ;
38133856
@@ -3840,14 +3883,14 @@ static int trace__expand_filter(struct trace *trace __maybe_unused, struct evsel
38403883 struct syscall_arg_fmt * fmt ;
38413884 int left_size = tok - left ,
38423885 right_size = right_end - right ;
3843- char arg [128 ];
3886+ char arg [128 ], * type ;
38443887
38453888 while (isspace (left [left_size - 1 ]))
38463889 -- left_size ;
38473890
38483891 scnprintf (arg , sizeof (arg ), "%.*s" , left_size , left );
38493892
3850- fmt = evsel__find_syscall_arg_fmt_by_name (evsel , arg );
3893+ fmt = evsel__find_syscall_arg_fmt_by_name (evsel , arg , & type );
38513894 if (fmt == NULL ) {
38523895 pr_err ("\"%s\" not found in \"%s\", can't set filter \"%s\"\n" ,
38533896 arg , evsel -> name , evsel -> filter );
@@ -3860,9 +3903,16 @@ static int trace__expand_filter(struct trace *trace __maybe_unused, struct evsel
38603903 if (fmt -> strtoul ) {
38613904 u64 val ;
38623905 struct syscall_arg syscall_arg = {
3863- .parm = fmt -> parm ,
3906+ .trace = trace ,
3907+ .fmt = fmt ,
38643908 };
38653909
3910+ if (fmt -> is_enum ) {
3911+ syscall_arg .parm = type ;
3912+ } else {
3913+ syscall_arg .parm = fmt -> parm ;
3914+ }
3915+
38663916 if (fmt -> strtoul (right , right_size , & syscall_arg , & val )) {
38673917 char * n , expansion [19 ];
38683918 int expansion_lenght = scnprintf (expansion , sizeof (expansion ), "%#" PRIx64 , val );
0 commit comments