aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/parse-events.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/parse-events.c')
-rw-r--r--tools/perf/util/parse-events.c54
1 files changed, 50 insertions, 4 deletions
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 6b6d03e93c3d..2d8d53bec17e 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -722,6 +722,27 @@ static int get_event_modifier(struct event_modifier *mod, char *str,
722 return 0; 722 return 0;
723} 723}
724 724
725/*
726 * Basic modifier sanity check to validate it contains only one
727 * instance of any modifier (apart from 'p') present.
728 */
729static int check_modifier(char *str)
730{
731 char *p = str;
732
733 /* The sizeof includes 0 byte as well. */
734 if (strlen(str) > (sizeof("ukhGHppp") - 1))
735 return -1;
736
737 while (*p) {
738 if (*p != 'p' && strchr(p + 1, *p))
739 return -1;
740 p++;
741 }
742
743 return 0;
744}
745
725int parse_events__modifier_event(struct list_head *list, char *str, bool add) 746int parse_events__modifier_event(struct list_head *list, char *str, bool add)
726{ 747{
727 struct perf_evsel *evsel; 748 struct perf_evsel *evsel;
@@ -730,6 +751,9 @@ int parse_events__modifier_event(struct list_head *list, char *str, bool add)
730 if (str == NULL) 751 if (str == NULL)
731 return 0; 752 return 0;
732 753
754 if (check_modifier(str))
755 return -EINVAL;
756
733 if (!add && get_event_modifier(&mod, str, NULL)) 757 if (!add && get_event_modifier(&mod, str, NULL))
734 return -EINVAL; 758 return -EINVAL;
735 759
@@ -827,8 +851,6 @@ int parse_events(struct perf_evlist *evlist, const char *str,
827 * Both call perf_evlist__delete in case of error, so we dont 851 * Both call perf_evlist__delete in case of error, so we dont
828 * need to bother. 852 * need to bother.
829 */ 853 */
830 fprintf(stderr, "invalid or unsupported event: '%s'\n", str);
831 fprintf(stderr, "Run 'perf list' for a list of valid events\n");
832 return ret; 854 return ret;
833} 855}
834 856
@@ -836,7 +858,13 @@ int parse_events_option(const struct option *opt, const char *str,
836 int unset __maybe_unused) 858 int unset __maybe_unused)
837{ 859{
838 struct perf_evlist *evlist = *(struct perf_evlist **)opt->value; 860 struct perf_evlist *evlist = *(struct perf_evlist **)opt->value;
839 return parse_events(evlist, str, unset); 861 int ret = parse_events(evlist, str, unset);
862
863 if (ret) {
864 fprintf(stderr, "invalid or unsupported event: '%s'\n", str);
865 fprintf(stderr, "Run 'perf list' for a list of valid events\n");
866 }
867 return ret;
840} 868}
841 869
842int parse_filter(const struct option *opt, const char *str, 870int parse_filter(const struct option *opt, const char *str,
@@ -1081,7 +1109,7 @@ void print_events(const char *event_glob, bool name_only)
1081 printf(" %-50s [%s]\n", 1109 printf(" %-50s [%s]\n",
1082 "cpu/t1=v1[,t2=v2,t3 ...]/modifier", 1110 "cpu/t1=v1[,t2=v2,t3 ...]/modifier",
1083 event_type_descriptors[PERF_TYPE_RAW]); 1111 event_type_descriptors[PERF_TYPE_RAW]);
1084 printf(" (see 'perf list --help' on how to encode it)\n"); 1112 printf(" (see 'man perf-list' on how to encode it)\n");
1085 printf("\n"); 1113 printf("\n");
1086 1114
1087 printf(" %-50s [%s]\n", 1115 printf(" %-50s [%s]\n",
@@ -1142,6 +1170,24 @@ int parse_events__term_str(struct parse_events__term **term,
1142 config, str, 0); 1170 config, str, 0);
1143} 1171}
1144 1172
1173int parse_events__term_sym_hw(struct parse_events__term **term,
1174 char *config, unsigned idx)
1175{
1176 struct event_symbol *sym;
1177
1178 BUG_ON(idx >= PERF_COUNT_HW_MAX);
1179 sym = &event_symbols_hw[idx];
1180
1181 if (config)
1182 return new_term(term, PARSE_EVENTS__TERM_TYPE_STR,
1183 PARSE_EVENTS__TERM_TYPE_USER, config,
1184 (char *) sym->symbol, 0);
1185 else
1186 return new_term(term, PARSE_EVENTS__TERM_TYPE_STR,
1187 PARSE_EVENTS__TERM_TYPE_USER,
1188 (char *) "event", (char *) sym->symbol, 0);
1189}
1190
1145int parse_events__term_clone(struct parse_events__term **new, 1191int parse_events__term_clone(struct parse_events__term **new,
1146 struct parse_events__term *term) 1192 struct parse_events__term *term)
1147{ 1193{