2 %parse-param {void *_parse_state}
3 %parse-param {void *scanner}
4 %lex-param {void* scanner}
14 #include <linux/compiler.h>
15 #include <linux/types.h>
19 #include "parse-events.h"
20 #include "parse-events-bison.h"
22 int parse_events_lex(YYSTYPE * yylval_param, YYLTYPE * yylloc_param , void *yyscanner);
23 void parse_events_error(YYLTYPE *loc, void *parse_state, void *scanner, char const *msg);
25 #define PE_ABORT(val) \
32 static struct list_head* alloc_list(void)
34 struct list_head *list;
36 list = malloc(sizeof(*list));
44 static void free_list_evsel(struct list_head* list_evsel)
46 struct evsel *evsel, *tmp;
48 list_for_each_entry_safe(evsel, tmp, list_evsel, core.node) {
49 list_del_init(&evsel->core.node);
57 %token PE_START_EVENTS PE_START_TERMS
58 %token PE_VALUE PE_VALUE_SYM_HW PE_VALUE_SYM_SW PE_TERM
59 %token PE_VALUE_SYM_TOOL
62 %token PE_MODIFIER_EVENT PE_MODIFIER_BP PE_BP_COLON PE_BP_SLASH
63 %token PE_LEGACY_CACHE
66 %token PE_DRV_CFG_TERM
69 %type <num> PE_VALUE_SYM_HW
70 %type <num> PE_VALUE_SYM_SW
71 %type <num> PE_VALUE_SYM_TOOL
72 %type <term_type> PE_TERM
76 %type <str> PE_LEGACY_CACHE
77 %type <str> PE_MODIFIER_EVENT
78 %type <str> PE_MODIFIER_BP
79 %type <str> PE_EVENT_NAME
80 %type <str> PE_DRV_CFG_TERM
81 %type <str> name_or_raw
82 %destructor { free ($$); } <str>
83 %type <term> event_term
84 %destructor { parse_events_term__delete ($$); } <term>
85 %type <list_terms> event_config
86 %type <list_terms> opt_event_config
87 %type <list_terms> opt_pmu_config
88 %destructor { parse_events_terms__delete ($$); } <list_terms>
89 %type <list_evsel> event_pmu
90 %type <list_evsel> event_legacy_symbol
91 %type <list_evsel> event_legacy_cache
92 %type <list_evsel> event_legacy_mem
93 %type <list_evsel> event_legacy_tracepoint
94 %type <list_evsel> event_legacy_numeric
95 %type <list_evsel> event_legacy_raw
96 %type <list_evsel> event_def
97 %type <list_evsel> event_mod
98 %type <list_evsel> event_name
99 %type <list_evsel> event
100 %type <list_evsel> events
101 %type <list_evsel> group_def
102 %type <list_evsel> group
103 %type <list_evsel> groups
104 %destructor { free_list_evsel ($$); } <list_evsel>
105 %type <tracepoint_name> tracepoint_name
106 %destructor { free ($$.sys); free ($$.event); } <tracepoint_name>
107 %type <hardware_term> PE_TERM_HW
108 %destructor { free ($$.str); } <hardware_term>
114 enum parse_events__term_type term_type;
115 struct list_head *list_evsel;
116 struct parse_events_terms *list_terms;
117 struct parse_events_term *term;
118 struct tracepoint_name {
122 struct hardware_term {
130 PE_START_EVENTS start_events
132 PE_START_TERMS start_terms
136 struct parse_events_state *parse_state = _parse_state;
139 parse_events_update_lists($1, &parse_state->list);
145 struct list_head *list = $1;
146 struct list_head *group = $3;
149 parse_events_update_lists(group, list);
155 struct list_head *list = $1;
156 struct list_head *event = $3;
159 parse_events_update_lists(event, list);
168 group_def ':' PE_MODIFIER_EVENT
170 struct list_head *list = $1;
173 err = parse_events__modifier_group(list, $3);
176 struct parse_events_state *parse_state = _parse_state;
177 struct parse_events_error *error = parse_state->error;
179 parse_events_error__handle(error, @3.first_column,
180 strdup("Bad modifier"), NULL);
181 free_list_evsel(list);
190 PE_NAME '{' events '}'
192 struct list_head *list = $3;
194 /* Takes ownership of $1. */
195 parse_events__set_leader($1, list);
201 struct list_head *list = $2;
203 parse_events__set_leader(NULL, list);
210 struct list_head *event = $3;
211 struct list_head *list = $1;
214 parse_events_update_lists(event, list);
223 event_name PE_MODIFIER_EVENT
225 struct list_head *list = $1;
229 * Apply modifier on all events added by single event definition
230 * (there could be more events added for multiple tracepoint
231 * definitions via '*?'.
233 err = parse_events__modifier_event(list, $2, false);
236 struct parse_events_state *parse_state = _parse_state;
237 struct parse_events_error *error = parse_state->error;
239 parse_events_error__handle(error, @2.first_column,
240 strdup("Bad modifier"), NULL);
241 free_list_evsel(list);
250 PE_EVENT_NAME event_def
254 err = parse_events_name($2, $1);
265 event_def: event_pmu |
266 event_legacy_symbol |
267 event_legacy_cache sep_dc |
268 event_legacy_mem sep_dc |
269 event_legacy_tracepoint sep_dc |
270 event_legacy_numeric sep_dc |
271 event_legacy_raw sep_dc
274 PE_NAME opt_pmu_config
276 struct parse_events_state *parse_state = _parse_state;
277 /* List of created evsels. */
278 struct list_head *list = NULL;
279 char *pattern = NULL;
283 parse_events_terms__delete($2); \
294 /* Attempt to add to list assuming $1 is a PMU name. */
295 if (parse_events_add_pmu(parse_state, list, $1, $2, /*auto_merge_stats=*/false, &@1)) {
296 struct perf_pmu *pmu = NULL;
299 /* Failure to add, try wildcard expansion of $1 as a PMU name. */
300 if (asprintf(&pattern, "%s*", $1) < 0) {
305 while ((pmu = perf_pmus__scan(pmu)) != NULL) {
306 const char *name = pmu->name;
308 if (parse_events__filter_pmu(parse_state, pmu))
311 if (!strncmp(name, "uncore_", 7) &&
312 strncmp($1, "uncore_", 7))
314 if (!perf_pmu__match(pattern, name, $1) ||
315 !perf_pmu__match(pattern, pmu->alias_name, $1)) {
316 bool auto_merge_stats = perf_pmu__auto_merge_stats(pmu);
318 if (!parse_events_add_pmu(parse_state, list, pmu->name, $2,
319 auto_merge_stats, &@1)) {
321 parse_state->wild_card_pmus = true;
327 /* Failure to add, assume $1 is an event name. */
329 ok = !parse_events_multi_pmu_add(parse_state, $1, $2, &list, &@1);
332 struct parse_events_error *error = parse_state->error;
335 if (asprintf(&help, "Unable to find PMU or event on a PMU of '%s'", $1) < 0)
337 parse_events_error__handle(error, @1.first_column,
338 strdup("Bad event or PMU"),
352 struct list_head *list;
355 err = parse_events_multi_pmu_add(_parse_state, $1, NULL, &list, &@1);
357 struct parse_events_state *parse_state = _parse_state;
358 struct parse_events_error *error = parse_state->error;
361 if (asprintf(&help, "Unable to find event on a PMU of '%s'", $1) < 0)
363 parse_events_error__handle(error, @1.first_column, strdup("Bad event name"), help);
377 value_sym '/' event_config '/'
379 struct list_head *list;
381 int config = $1 & 255;
383 bool wildcard = (type == PERF_TYPE_HARDWARE || type == PERF_TYPE_HW_CACHE);
388 err = parse_events_add_numeric(_parse_state, list, type, config, $3, wildcard);
389 parse_events_terms__delete($3);
391 free_list_evsel(list);
397 value_sym sep_slash_slash_dc
399 struct list_head *list;
401 int config = $1 & 255;
402 bool wildcard = (type == PERF_TYPE_HARDWARE || type == PERF_TYPE_HW_CACHE);
408 err = parse_events_add_numeric(_parse_state, list, type, config, /*head_config=*/NULL, wildcard);
414 PE_VALUE_SYM_TOOL sep_slash_slash_dc
416 struct list_head *list;
422 err = parse_events_add_tool(_parse_state, list, $1);
429 PE_LEGACY_CACHE opt_event_config
431 struct parse_events_state *parse_state = _parse_state;
432 struct list_head *list;
439 err = parse_events_add_cache(list, &parse_state->idx, $1, parse_state, $2);
441 parse_events_terms__delete($2);
444 free_list_evsel(list);
451 PE_PREFIX_MEM PE_VALUE PE_BP_SLASH PE_VALUE PE_BP_COLON PE_MODIFIER_BP opt_event_config
453 struct list_head *list;
460 err = parse_events_add_breakpoint(_parse_state, list,
462 parse_events_terms__delete($7);
471 PE_PREFIX_MEM PE_VALUE PE_BP_SLASH PE_VALUE opt_event_config
473 struct list_head *list;
480 err = parse_events_add_breakpoint(_parse_state, list,
482 parse_events_terms__delete($5);
490 PE_PREFIX_MEM PE_VALUE PE_BP_COLON PE_MODIFIER_BP opt_event_config
492 struct list_head *list;
499 err = parse_events_add_breakpoint(_parse_state, list,
501 parse_events_terms__delete($5);
510 PE_PREFIX_MEM PE_VALUE opt_event_config
512 struct list_head *list;
518 err = parse_events_add_breakpoint(_parse_state, list,
520 parse_events_terms__delete($3);
528 event_legacy_tracepoint:
529 tracepoint_name opt_event_config
531 struct parse_events_state *parse_state = _parse_state;
532 struct parse_events_error *error = parse_state->error;
533 struct list_head *list;
540 err = parse_events_add_tracepoint(list, &parse_state->idx, $1.sys, $1.event,
543 parse_events_terms__delete($2);
556 struct tracepoint_name tracepoint = {$1, $3};
561 event_legacy_numeric:
562 PE_VALUE ':' PE_VALUE opt_event_config
564 struct list_head *list;
570 err = parse_events_add_numeric(_parse_state, list, (u32)$1, $3, $4,
572 parse_events_terms__delete($4);
581 PE_RAW opt_event_config
583 struct list_head *list;
591 num = strtoull($1 + 1, NULL, 16);
592 /* Given the lexer will only give [a-fA-F0-9]+ a failure here should be impossible. */
596 err = parse_events_add_numeric(_parse_state, list, PERF_TYPE_RAW, num, $2,
598 parse_events_terms__delete($2);
632 start_terms: event_config
634 struct parse_events_state *parse_state = _parse_state;
635 if (parse_state->terms) {
636 parse_events_terms__delete ($1);
639 parse_state->terms = $1;
643 event_config ',' event_term
645 struct parse_events_terms *head = $1;
646 struct parse_events_term *term = $3;
649 parse_events_term__delete(term);
652 list_add_tail(&term->list, &head->terms);
658 struct parse_events_terms *head = malloc(sizeof(*head));
659 struct parse_events_term *term = $1;
663 parse_events_terms__init(head);
664 list_add_tail(&term->list, &head->terms);
668 name_or_raw: PE_RAW | PE_NAME | PE_LEGACY_CACHE
673 struct parse_events_term *term;
674 int err = parse_events_term__str(&term, PARSE_EVENTS__TERM_TYPE_RAW,
675 strdup("raw"), $1, &@1, &@1);
684 name_or_raw '=' name_or_raw
686 struct parse_events_term *term;
687 int err = parse_events_term__str(&term, PARSE_EVENTS__TERM_TYPE_USER, $1, $3, &@1, &@3);
697 name_or_raw '=' PE_VALUE
699 struct parse_events_term *term;
700 int err = parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER,
701 $1, $3, /*novalue=*/false, &@1, &@3);
710 name_or_raw '=' PE_TERM_HW
712 struct parse_events_term *term;
713 int err = parse_events_term__str(&term, PARSE_EVENTS__TERM_TYPE_USER,
714 $1, $3.str, &@1, &@3);
726 struct parse_events_term *term;
727 int err = parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_LEGACY_CACHE,
728 $1, /*num=*/1, /*novalue=*/true, &@1, /*loc_val=*/NULL);
739 struct parse_events_term *term;
740 int err = parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER,
741 $1, /*num=*/1, /*novalue=*/true, &@1, /*loc_val=*/NULL);
752 struct parse_events_term *term;
753 int err = parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_HARDWARE,
754 $1.str, $1.num & 255, /*novalue=*/false,
755 &@1, /*loc_val=*/NULL);
764 PE_TERM '=' name_or_raw
766 struct parse_events_term *term;
767 int err = parse_events_term__str(&term, $1, /*config=*/NULL, $3, &@1, &@3);
776 PE_TERM '=' PE_TERM_HW
778 struct parse_events_term *term;
779 int err = parse_events_term__str(&term, $1, /*config=*/NULL, $3.str, &@1, &@3);
790 struct parse_events_term *term;
791 int err = parse_events_term__term(&term, $1, $3, &@1, &@3);
801 struct parse_events_term *term;
802 int err = parse_events_term__num(&term, $1,
803 /*config=*/NULL, $3, /*novalue=*/false,
814 struct parse_events_term *term;
815 int err = parse_events_term__num(&term, $1,
816 /*config=*/NULL, /*num=*/1, /*novalue=*/true,
817 &@1, /*loc_val=*/NULL);
827 struct parse_events_term *term;
828 char *config = strdup($1);
833 err = parse_events_term__str(&term, PARSE_EVENTS__TERM_TYPE_DRV_CFG, config, $1, &@1, NULL);
844 sep_slash_slash_dc: '/' '/' | ':' |
848 void parse_events_error(YYLTYPE *loc, void *parse_state,
849 void *scanner __maybe_unused,
850 char const *msg __maybe_unused)
852 parse_events_evlist_error(parse_state, loc->last_column, "parser error");