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>
16 #include <linux/zalloc.h>
20 #include "parse-events.h"
21 #include "parse-events-bison.h"
23 int parse_events_lex(YYSTYPE * yylval_param, YYLTYPE * yylloc_param , void *yyscanner);
24 void parse_events_error(YYLTYPE *loc, void *parse_state, void *scanner, char const *msg);
26 #define PE_ABORT(val) \
33 static struct list_head* alloc_list(void)
35 struct list_head *list;
37 list = malloc(sizeof(*list));
45 static void free_list_evsel(struct list_head* list_evsel)
47 struct evsel *evsel, *tmp;
49 list_for_each_entry_safe(evsel, tmp, list_evsel, core.node) {
50 list_del_init(&evsel->core.node);
58 %token PE_START_EVENTS PE_START_TERMS
59 %token PE_VALUE PE_VALUE_SYM_HW PE_VALUE_SYM_SW PE_TERM
60 %token PE_VALUE_SYM_TOOL
63 %token PE_BPF_OBJECT PE_BPF_SOURCE
64 %token PE_MODIFIER_EVENT PE_MODIFIER_BP PE_BP_COLON PE_BP_SLASH
65 %token PE_LEGACY_CACHE
68 %token PE_DRV_CFG_TERM
71 %type <num> PE_VALUE_SYM_HW
72 %type <num> PE_VALUE_SYM_SW
73 %type <num> PE_VALUE_SYM_TOOL
78 %type <str> PE_BPF_OBJECT
79 %type <str> PE_BPF_SOURCE
80 %type <str> PE_LEGACY_CACHE
81 %type <str> PE_MODIFIER_EVENT
82 %type <str> PE_MODIFIER_BP
83 %type <str> PE_EVENT_NAME
84 %type <str> PE_DRV_CFG_TERM
85 %type <str> name_or_raw name_or_legacy
86 %destructor { free ($$); } <str>
87 %type <term> event_term
88 %destructor { parse_events_term__delete ($$); } <term>
89 %type <list_terms> event_config
90 %type <list_terms> opt_event_config
91 %type <list_terms> opt_pmu_config
92 %destructor { parse_events_terms__delete ($$); } <list_terms>
93 %type <list_evsel> event_pmu
94 %type <list_evsel> event_legacy_symbol
95 %type <list_evsel> event_legacy_cache
96 %type <list_evsel> event_legacy_mem
97 %type <list_evsel> event_legacy_tracepoint
98 %type <list_evsel> event_legacy_numeric
99 %type <list_evsel> event_legacy_raw
100 %type <list_evsel> event_bpf_file
101 %type <list_evsel> event_def
102 %type <list_evsel> event_mod
103 %type <list_evsel> event_name
104 %type <list_evsel> event
105 %type <list_evsel> events
106 %type <list_evsel> group_def
107 %type <list_evsel> group
108 %type <list_evsel> groups
109 %destructor { free_list_evsel ($$); } <list_evsel>
110 %type <tracepoint_name> tracepoint_name
111 %type <hardware_term> PE_TERM_HW
112 %destructor { free ($$.str); } <hardware_term>
118 struct list_head *list_evsel;
119 struct list_head *list_terms;
120 struct parse_events_term *term;
121 struct tracepoint_name {
125 struct hardware_term {
133 PE_START_EVENTS start_events
135 PE_START_TERMS start_terms
139 struct parse_events_state *parse_state = _parse_state;
142 parse_events_update_lists($1, &parse_state->list);
148 struct list_head *list = $1;
149 struct list_head *group = $3;
152 parse_events_update_lists(group, list);
158 struct list_head *list = $1;
159 struct list_head *event = $3;
162 parse_events_update_lists(event, list);
171 group_def ':' PE_MODIFIER_EVENT
173 struct list_head *list = $1;
176 err = parse_events__modifier_group(list, $3);
179 struct parse_events_state *parse_state = _parse_state;
180 struct parse_events_error *error = parse_state->error;
182 parse_events_error__handle(error, @3.first_column,
183 strdup("Bad modifier"), NULL);
184 free_list_evsel(list);
193 PE_NAME '{' events '}'
195 struct list_head *list = $3;
197 /* Takes ownership of $1. */
198 parse_events__set_leader($1, list);
204 struct list_head *list = $2;
206 parse_events__set_leader(NULL, list);
213 struct list_head *event = $3;
214 struct list_head *list = $1;
217 parse_events_update_lists(event, list);
226 event_name PE_MODIFIER_EVENT
228 struct list_head *list = $1;
232 * Apply modifier on all events added by single event definition
233 * (there could be more events added for multiple tracepoint
234 * definitions via '*?'.
236 err = parse_events__modifier_event(list, $2, false);
239 struct parse_events_state *parse_state = _parse_state;
240 struct parse_events_error *error = parse_state->error;
242 parse_events_error__handle(error, @2.first_column,
243 strdup("Bad modifier"), NULL);
244 free_list_evsel(list);
253 PE_EVENT_NAME event_def
257 err = parse_events_name($2, $1);
268 event_def: event_pmu |
269 event_legacy_symbol |
270 event_legacy_cache sep_dc |
271 event_legacy_mem sep_dc |
272 event_legacy_tracepoint sep_dc |
273 event_legacy_numeric sep_dc |
274 event_legacy_raw sep_dc |
278 PE_NAME opt_pmu_config
280 struct parse_events_state *parse_state = _parse_state;
281 struct list_head *list = NULL, *orig_terms = NULL, *terms= NULL;
282 char *pattern = NULL;
286 parse_events_terms__delete($2); \
287 parse_events_terms__delete(orig_terms); \
293 if (parse_events_copy_term_list($2, &orig_terms)) {
303 /* Attempt to add to list assuming $1 is a PMU name. */
304 if (parse_events_add_pmu(parse_state, list, $1, $2, /*auto_merge_stats=*/false, &@1)) {
305 struct perf_pmu *pmu = NULL;
308 /* Failure to add, try wildcard expansion of $1 as a PMU name. */
309 if (asprintf(&pattern, "%s*", $1) < 0) {
314 while ((pmu = perf_pmus__scan(pmu)) != NULL) {
315 char *name = pmu->name;
317 if (parse_events__filter_pmu(parse_state, pmu))
320 if (!strncmp(name, "uncore_", 7) &&
321 strncmp($1, "uncore_", 7))
323 if (!perf_pmu__match(pattern, name, $1) ||
324 !perf_pmu__match(pattern, pmu->alias_name, $1)) {
325 bool auto_merge_stats = perf_pmu__auto_merge_stats(pmu);
327 if (parse_events_copy_term_list(orig_terms, &terms)) {
331 if (!parse_events_add_pmu(parse_state, list, pmu->name, terms,
332 auto_merge_stats, &@1)) {
334 parse_state->wild_card_pmus = true;
336 parse_events_terms__delete(terms);
341 /* Failure to add, assume $1 is an event name. */
343 ok = !parse_events_multi_pmu_add(parse_state, $1, $2, &list, &@1);
347 struct parse_events_error *error = parse_state->error;
350 if (asprintf(&help, "Unabled to find PMU or event on a PMU of '%s'", $1) < 0)
352 parse_events_error__handle(error, @1.first_column,
353 strdup("Bad event or PMU"),
367 struct list_head *list;
370 err = parse_events_multi_pmu_add(_parse_state, $1, NULL, &list, &@1);
372 struct parse_events_state *parse_state = _parse_state;
373 struct parse_events_error *error = parse_state->error;
376 if (asprintf(&help, "Unabled to find PMU or event on a PMU of '%s'", $1) < 0)
378 parse_events_error__handle(error, @1.first_column, strdup("Bad event name"), help);
392 value_sym '/' event_config '/'
394 struct list_head *list;
396 int config = $1 & 255;
398 bool wildcard = (type == PERF_TYPE_HARDWARE || type == PERF_TYPE_HW_CACHE);
403 err = parse_events_add_numeric(_parse_state, list, type, config, $3, wildcard);
404 parse_events_terms__delete($3);
406 free_list_evsel(list);
412 value_sym sep_slash_slash_dc
414 struct list_head *list;
416 int config = $1 & 255;
417 bool wildcard = (type == PERF_TYPE_HARDWARE || type == PERF_TYPE_HW_CACHE);
423 err = parse_events_add_numeric(_parse_state, list, type, config, /*head_config=*/NULL, wildcard);
429 PE_VALUE_SYM_TOOL sep_slash_slash_dc
431 struct list_head *list;
437 err = parse_events_add_tool(_parse_state, list, $1);
444 PE_LEGACY_CACHE opt_event_config
446 struct parse_events_state *parse_state = _parse_state;
447 struct list_head *list;
454 err = parse_events_add_cache(list, &parse_state->idx, $1, parse_state, $2);
456 parse_events_terms__delete($2);
459 free_list_evsel(list);
466 PE_PREFIX_MEM PE_VALUE PE_BP_SLASH PE_VALUE PE_BP_COLON PE_MODIFIER_BP opt_event_config
468 struct list_head *list;
475 err = parse_events_add_breakpoint(_parse_state, list,
477 parse_events_terms__delete($7);
486 PE_PREFIX_MEM PE_VALUE PE_BP_SLASH PE_VALUE opt_event_config
488 struct list_head *list;
495 err = parse_events_add_breakpoint(_parse_state, list,
497 parse_events_terms__delete($5);
505 PE_PREFIX_MEM PE_VALUE PE_BP_COLON PE_MODIFIER_BP opt_event_config
507 struct list_head *list;
514 err = parse_events_add_breakpoint(_parse_state, list,
516 parse_events_terms__delete($5);
525 PE_PREFIX_MEM PE_VALUE opt_event_config
527 struct list_head *list;
533 err = parse_events_add_breakpoint(_parse_state, list,
535 parse_events_terms__delete($3);
543 event_legacy_tracepoint:
544 tracepoint_name opt_event_config
546 struct parse_events_state *parse_state = _parse_state;
547 struct parse_events_error *error = parse_state->error;
548 struct list_head *list;
555 error->idx = @1.first_column;
557 err = parse_events_add_tracepoint(list, &parse_state->idx, $1.sys, $1.event,
560 parse_events_terms__delete($2);
573 struct tracepoint_name tracepoint = {$1, $3};
578 event_legacy_numeric:
579 PE_VALUE ':' PE_VALUE opt_event_config
581 struct list_head *list;
587 err = parse_events_add_numeric(_parse_state, list, (u32)$1, $3, $4,
589 parse_events_terms__delete($4);
598 PE_RAW opt_event_config
600 struct list_head *list;
608 num = strtoull($1 + 1, NULL, 16);
609 /* Given the lexer will only give [a-fA-F0-9]+ a failure here should be impossible. */
613 err = parse_events_add_numeric(_parse_state, list, PERF_TYPE_RAW, num, $2,
615 parse_events_terms__delete($2);
624 PE_BPF_OBJECT opt_event_config
626 struct parse_events_state *parse_state = _parse_state;
627 struct list_head *list;
633 err = parse_events_load_bpf(parse_state, list, $1, false, $2, &@1);
634 parse_events_terms__delete($2);
643 PE_BPF_SOURCE opt_event_config
645 struct list_head *list;
651 err = parse_events_load_bpf(_parse_state, list, $1, true, $2, &@1);
652 parse_events_terms__delete($2);
686 start_terms: event_config
688 struct parse_events_state *parse_state = _parse_state;
689 if (parse_state->terms) {
690 parse_events_terms__delete ($1);
693 parse_state->terms = $1;
697 event_config ',' event_term
699 struct list_head *head = $1;
700 struct parse_events_term *term = $3;
703 parse_events_term__delete(term);
706 list_add_tail(&term->list, head);
712 struct list_head *head = malloc(sizeof(*head));
713 struct parse_events_term *term = $1;
717 INIT_LIST_HEAD(head);
718 list_add_tail(&term->list, head);
722 name_or_raw: PE_RAW | PE_NAME | PE_LEGACY_CACHE
724 name_or_legacy: PE_NAME | PE_LEGACY_CACHE
729 struct parse_events_term *term;
730 int err = parse_events_term__str(&term, PARSE_EVENTS__TERM_TYPE_RAW,
731 strdup("raw"), $1, &@1, &@1);
740 name_or_raw '=' name_or_legacy
742 struct parse_events_term *term;
743 int err = parse_events_term__str(&term, PARSE_EVENTS__TERM_TYPE_USER, $1, $3, &@1, &@3);
753 name_or_raw '=' PE_VALUE
755 struct parse_events_term *term;
756 int err = parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER,
757 $1, $3, false, &@1, &@3);
766 name_or_raw '=' PE_TERM_HW
768 struct parse_events_term *term;
769 int err = parse_events_term__str(&term, PARSE_EVENTS__TERM_TYPE_USER,
770 $1, $3.str, &@1, &@3);
782 struct parse_events_term *term;
783 int err = parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_LEGACY_CACHE,
784 $1, 1, true, &@1, NULL);
795 struct parse_events_term *term;
796 int err = parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER,
797 $1, 1, true, &@1, NULL);
808 struct parse_events_term *term;
809 int err = parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_HARDWARE,
810 $1.str, $1.num & 255, false, &@1, NULL);
819 PE_TERM '=' name_or_legacy
821 struct parse_events_term *term;
822 int err = parse_events_term__str(&term, (int)$1, NULL, $3, &@1, &@3);
831 PE_TERM '=' PE_TERM_HW
833 struct parse_events_term *term;
834 int err = parse_events_term__str(&term, (int)$1, NULL, $3.str, &@1, &@3);
845 struct parse_events_term *term;
846 int err = parse_events_term__term(&term, (int)$1, (int)$3, &@1, &@3);
856 struct parse_events_term *term;
857 int err = parse_events_term__num(&term, (int)$1, NULL, $3, false, &@1, &@3);
867 struct parse_events_term *term;
868 int err = parse_events_term__num(&term, (int)$1, NULL, 1, true, &@1, NULL);
878 sep_slash_slash_dc: '/' '/' | ':' |
882 void parse_events_error(YYLTYPE *loc, void *parse_state,
883 void *scanner __maybe_unused,
884 char const *msg __maybe_unused)
886 parse_events_evlist_error(parse_state, loc->last_column, "parser error");