perf parse-events: Name the two term enums
[platform/kernel/linux-starfive.git] / tools / perf / util / parse-events.y
1 %define api.pure full
2 %parse-param {void *_parse_state}
3 %parse-param {void *scanner}
4 %lex-param {void* scanner}
5 %locations
6
7 %{
8
9 #define YYDEBUG 1
10
11 #include <errno.h>
12 #include <fnmatch.h>
13 #include <stdio.h>
14 #include <linux/compiler.h>
15 #include <linux/types.h>
16 #include <linux/zalloc.h>
17 #include "pmu.h"
18 #include "pmus.h"
19 #include "evsel.h"
20 #include "parse-events.h"
21 #include "parse-events-bison.h"
22
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);
25
26 #define PE_ABORT(val) \
27 do { \
28         if (val == -ENOMEM) \
29                 YYNOMEM; \
30         YYABORT; \
31 } while (0)
32
33 static struct list_head* alloc_list(void)
34 {
35         struct list_head *list;
36
37         list = malloc(sizeof(*list));
38         if (!list)
39                 return NULL;
40
41         INIT_LIST_HEAD(list);
42         return list;
43 }
44
45 static void free_list_evsel(struct list_head* list_evsel)
46 {
47         struct evsel *evsel, *tmp;
48
49         list_for_each_entry_safe(evsel, tmp, list_evsel, core.node) {
50                 list_del_init(&evsel->core.node);
51                 evsel__delete(evsel);
52         }
53         free(list_evsel);
54 }
55
56 %}
57
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
61 %token PE_EVENT_NAME
62 %token PE_RAW PE_NAME
63 %token PE_MODIFIER_EVENT PE_MODIFIER_BP PE_BP_COLON PE_BP_SLASH
64 %token PE_LEGACY_CACHE
65 %token PE_PREFIX_MEM
66 %token PE_ERROR
67 %token PE_DRV_CFG_TERM
68 %token PE_TERM_HW
69 %type <num> PE_VALUE
70 %type <num> PE_VALUE_SYM_HW
71 %type <num> PE_VALUE_SYM_SW
72 %type <num> PE_VALUE_SYM_TOOL
73 %type <num> PE_TERM
74 %type <num> value_sym
75 %type <str> PE_RAW
76 %type <str> PE_NAME
77 %type <str> PE_LEGACY_CACHE
78 %type <str> PE_MODIFIER_EVENT
79 %type <str> PE_MODIFIER_BP
80 %type <str> PE_EVENT_NAME
81 %type <str> PE_DRV_CFG_TERM
82 %type <str> name_or_raw name_or_legacy
83 %destructor { free ($$); } <str>
84 %type <term> event_term
85 %destructor { parse_events_term__delete ($$); } <term>
86 %type <list_terms> event_config
87 %type <list_terms> opt_event_config
88 %type <list_terms> opt_pmu_config
89 %destructor { parse_events_terms__delete ($$); } <list_terms>
90 %type <list_evsel> event_pmu
91 %type <list_evsel> event_legacy_symbol
92 %type <list_evsel> event_legacy_cache
93 %type <list_evsel> event_legacy_mem
94 %type <list_evsel> event_legacy_tracepoint
95 %type <list_evsel> event_legacy_numeric
96 %type <list_evsel> event_legacy_raw
97 %type <list_evsel> event_def
98 %type <list_evsel> event_mod
99 %type <list_evsel> event_name
100 %type <list_evsel> event
101 %type <list_evsel> events
102 %type <list_evsel> group_def
103 %type <list_evsel> group
104 %type <list_evsel> groups
105 %destructor { free_list_evsel ($$); } <list_evsel>
106 %type <tracepoint_name> tracepoint_name
107 %type <hardware_term> PE_TERM_HW
108 %destructor { free ($$.str); } <hardware_term>
109
110 %union
111 {
112         char *str;
113         u64 num;
114         struct list_head *list_evsel;
115         struct list_head *list_terms;
116         struct parse_events_term *term;
117         struct tracepoint_name {
118                 char *sys;
119                 char *event;
120         } tracepoint_name;
121         struct hardware_term {
122                 char *str;
123                 u64 num;
124         } hardware_term;
125 }
126 %%
127
128 start:
129 PE_START_EVENTS start_events
130 |
131 PE_START_TERMS  start_terms
132
133 start_events: groups
134 {
135         struct parse_events_state *parse_state = _parse_state;
136
137         /* frees $1 */
138         parse_events_update_lists($1, &parse_state->list);
139 }
140
141 groups:
142 groups ',' group
143 {
144         struct list_head *list  = $1;
145         struct list_head *group = $3;
146
147         /* frees $3 */
148         parse_events_update_lists(group, list);
149         $$ = list;
150 }
151 |
152 groups ',' event
153 {
154         struct list_head *list  = $1;
155         struct list_head *event = $3;
156
157         /* frees $3 */
158         parse_events_update_lists(event, list);
159         $$ = list;
160 }
161 |
162 group
163 |
164 event
165
166 group:
167 group_def ':' PE_MODIFIER_EVENT
168 {
169         struct list_head *list = $1;
170         int err;
171
172         err = parse_events__modifier_group(list, $3);
173         free($3);
174         if (err) {
175                 struct parse_events_state *parse_state = _parse_state;
176                 struct parse_events_error *error = parse_state->error;
177
178                 parse_events_error__handle(error, @3.first_column,
179                                            strdup("Bad modifier"), NULL);
180                 free_list_evsel(list);
181                 YYABORT;
182         }
183         $$ = list;
184 }
185 |
186 group_def
187
188 group_def:
189 PE_NAME '{' events '}'
190 {
191         struct list_head *list = $3;
192
193         /* Takes ownership of $1. */
194         parse_events__set_leader($1, list);
195         $$ = list;
196 }
197 |
198 '{' events '}'
199 {
200         struct list_head *list = $2;
201
202         parse_events__set_leader(NULL, list);
203         $$ = list;
204 }
205
206 events:
207 events ',' event
208 {
209         struct list_head *event = $3;
210         struct list_head *list  = $1;
211
212         /* frees $3 */
213         parse_events_update_lists(event, list);
214         $$ = list;
215 }
216 |
217 event
218
219 event: event_mod
220
221 event_mod:
222 event_name PE_MODIFIER_EVENT
223 {
224         struct list_head *list = $1;
225         int err;
226
227         /*
228          * Apply modifier on all events added by single event definition
229          * (there could be more events added for multiple tracepoint
230          * definitions via '*?'.
231          */
232         err = parse_events__modifier_event(list, $2, false);
233         free($2);
234         if (err) {
235                 struct parse_events_state *parse_state = _parse_state;
236                 struct parse_events_error *error = parse_state->error;
237
238                 parse_events_error__handle(error, @2.first_column,
239                                            strdup("Bad modifier"), NULL);
240                 free_list_evsel(list);
241                 YYABORT;
242         }
243         $$ = list;
244 }
245 |
246 event_name
247
248 event_name:
249 PE_EVENT_NAME event_def
250 {
251         int err;
252
253         err = parse_events_name($2, $1);
254         free($1);
255         if (err) {
256                 free_list_evsel($2);
257                 YYNOMEM;
258         }
259         $$ = $2;
260 }
261 |
262 event_def
263
264 event_def: event_pmu |
265            event_legacy_symbol |
266            event_legacy_cache sep_dc |
267            event_legacy_mem sep_dc |
268            event_legacy_tracepoint sep_dc |
269            event_legacy_numeric sep_dc |
270            event_legacy_raw sep_dc
271
272 event_pmu:
273 PE_NAME opt_pmu_config
274 {
275         struct parse_events_state *parse_state = _parse_state;
276         struct list_head *list = NULL, *orig_terms = NULL, *terms= NULL;
277         char *pattern = NULL;
278
279 #define CLEANUP                                         \
280         do {                                            \
281                 parse_events_terms__delete($2);         \
282                 parse_events_terms__delete(orig_terms); \
283                 free(list);                             \
284                 free($1);                               \
285                 free(pattern);                          \
286         } while(0)
287
288         if (parse_events_copy_term_list($2, &orig_terms)) {
289                 CLEANUP;
290                 YYNOMEM;
291         }
292
293         list = alloc_list();
294         if (!list) {
295                 CLEANUP;
296                 YYNOMEM;
297         }
298         /* Attempt to add to list assuming $1 is a PMU name. */
299         if (parse_events_add_pmu(parse_state, list, $1, $2, /*auto_merge_stats=*/false, &@1)) {
300                 struct perf_pmu *pmu = NULL;
301                 int ok = 0;
302
303                 /* Failure to add, try wildcard expansion of $1 as a PMU name. */
304                 if (asprintf(&pattern, "%s*", $1) < 0) {
305                         CLEANUP;
306                         YYNOMEM;
307                 }
308
309                 while ((pmu = perf_pmus__scan(pmu)) != NULL) {
310                         const char *name = pmu->name;
311
312                         if (parse_events__filter_pmu(parse_state, pmu))
313                                 continue;
314
315                         if (!strncmp(name, "uncore_", 7) &&
316                             strncmp($1, "uncore_", 7))
317                                 name += 7;
318                         if (!perf_pmu__match(pattern, name, $1) ||
319                             !perf_pmu__match(pattern, pmu->alias_name, $1)) {
320                                 bool auto_merge_stats = perf_pmu__auto_merge_stats(pmu);
321
322                                 if (parse_events_copy_term_list(orig_terms, &terms)) {
323                                         CLEANUP;
324                                         YYNOMEM;
325                                 }
326                                 if (!parse_events_add_pmu(parse_state, list, pmu->name, terms,
327                                                           auto_merge_stats, &@1)) {
328                                         ok++;
329                                         parse_state->wild_card_pmus = true;
330                                 }
331                                 parse_events_terms__delete(terms);
332                         }
333                 }
334
335                 if (!ok) {
336                         /* Failure to add, assume $1 is an event name. */
337                         zfree(&list);
338                         ok = !parse_events_multi_pmu_add(parse_state, $1, $2, &list, &@1);
339                         $2 = NULL;
340                 }
341                 if (!ok) {
342                         struct parse_events_error *error = parse_state->error;
343                         char *help;
344
345                         if (asprintf(&help, "Unable to find PMU or event on a PMU of '%s'", $1) < 0)
346                                 help = NULL;
347                         parse_events_error__handle(error, @1.first_column,
348                                                    strdup("Bad event or PMU"),
349                                                    help);
350                         CLEANUP;
351                         YYABORT;
352                 }
353         }
354         $$ = list;
355         list = NULL;
356         CLEANUP;
357 #undef CLEANUP
358 }
359 |
360 PE_NAME sep_dc
361 {
362         struct list_head *list;
363         int err;
364
365         err = parse_events_multi_pmu_add(_parse_state, $1, NULL, &list, &@1);
366         if (err < 0) {
367                 struct parse_events_state *parse_state = _parse_state;
368                 struct parse_events_error *error = parse_state->error;
369                 char *help;
370
371                 if (asprintf(&help, "Unable to find event on a PMU of '%s'", $1) < 0)
372                         help = NULL;
373                 parse_events_error__handle(error, @1.first_column, strdup("Bad event name"), help);
374                 free($1);
375                 PE_ABORT(err);
376         }
377         free($1);
378         $$ = list;
379 }
380
381 value_sym:
382 PE_VALUE_SYM_HW
383 |
384 PE_VALUE_SYM_SW
385
386 event_legacy_symbol:
387 value_sym '/' event_config '/'
388 {
389         struct list_head *list;
390         int type = $1 >> 16;
391         int config = $1 & 255;
392         int err;
393         bool wildcard = (type == PERF_TYPE_HARDWARE || type == PERF_TYPE_HW_CACHE);
394
395         list = alloc_list();
396         if (!list)
397                 YYNOMEM;
398         err = parse_events_add_numeric(_parse_state, list, type, config, $3, wildcard);
399         parse_events_terms__delete($3);
400         if (err) {
401                 free_list_evsel(list);
402                 PE_ABORT(err);
403         }
404         $$ = list;
405 }
406 |
407 value_sym sep_slash_slash_dc
408 {
409         struct list_head *list;
410         int type = $1 >> 16;
411         int config = $1 & 255;
412         bool wildcard = (type == PERF_TYPE_HARDWARE || type == PERF_TYPE_HW_CACHE);
413         int err;
414
415         list = alloc_list();
416         if (!list)
417                 YYNOMEM;
418         err = parse_events_add_numeric(_parse_state, list, type, config, /*head_config=*/NULL, wildcard);
419         if (err)
420                 PE_ABORT(err);
421         $$ = list;
422 }
423 |
424 PE_VALUE_SYM_TOOL sep_slash_slash_dc
425 {
426         struct list_head *list;
427         int err;
428
429         list = alloc_list();
430         if (!list)
431                 YYNOMEM;
432         err = parse_events_add_tool(_parse_state, list, $1);
433         if (err)
434                 YYNOMEM;
435         $$ = list;
436 }
437
438 event_legacy_cache:
439 PE_LEGACY_CACHE opt_event_config
440 {
441         struct parse_events_state *parse_state = _parse_state;
442         struct list_head *list;
443         int err;
444
445         list = alloc_list();
446         if (!list)
447                 YYNOMEM;
448
449         err = parse_events_add_cache(list, &parse_state->idx, $1, parse_state, $2);
450
451         parse_events_terms__delete($2);
452         free($1);
453         if (err) {
454                 free_list_evsel(list);
455                 PE_ABORT(err);
456         }
457         $$ = list;
458 }
459
460 event_legacy_mem:
461 PE_PREFIX_MEM PE_VALUE PE_BP_SLASH PE_VALUE PE_BP_COLON PE_MODIFIER_BP opt_event_config
462 {
463         struct list_head *list;
464         int err;
465
466         list = alloc_list();
467         if (!list)
468                 YYNOMEM;
469
470         err = parse_events_add_breakpoint(_parse_state, list,
471                                           $2, $6, $4, $7);
472         parse_events_terms__delete($7);
473         free($6);
474         if (err) {
475                 free(list);
476                 PE_ABORT(err);
477         }
478         $$ = list;
479 }
480 |
481 PE_PREFIX_MEM PE_VALUE PE_BP_SLASH PE_VALUE opt_event_config
482 {
483         struct list_head *list;
484         int err;
485
486         list = alloc_list();
487         if (!list)
488                 YYNOMEM;
489
490         err = parse_events_add_breakpoint(_parse_state, list,
491                                           $2, NULL, $4, $5);
492         parse_events_terms__delete($5);
493         if (err) {
494                 free(list);
495                 PE_ABORT(err);
496         }
497         $$ = list;
498 }
499 |
500 PE_PREFIX_MEM PE_VALUE PE_BP_COLON PE_MODIFIER_BP opt_event_config
501 {
502         struct list_head *list;
503         int err;
504
505         list = alloc_list();
506         if (!list)
507                 YYNOMEM;
508
509         err = parse_events_add_breakpoint(_parse_state, list,
510                                           $2, $4, 0, $5);
511         parse_events_terms__delete($5);
512         free($4);
513         if (err) {
514                 free(list);
515                 PE_ABORT(err);
516         }
517         $$ = list;
518 }
519 |
520 PE_PREFIX_MEM PE_VALUE opt_event_config
521 {
522         struct list_head *list;
523         int err;
524
525         list = alloc_list();
526         if (!list)
527                 YYNOMEM;
528         err = parse_events_add_breakpoint(_parse_state, list,
529                                           $2, NULL, 0, $3);
530         parse_events_terms__delete($3);
531         if (err) {
532                 free(list);
533                 PE_ABORT(err);
534         }
535         $$ = list;
536 }
537
538 event_legacy_tracepoint:
539 tracepoint_name opt_event_config
540 {
541         struct parse_events_state *parse_state = _parse_state;
542         struct parse_events_error *error = parse_state->error;
543         struct list_head *list;
544         int err;
545
546         list = alloc_list();
547         if (!list)
548                 YYNOMEM;
549         if (error)
550                 error->idx = @1.first_column;
551
552         err = parse_events_add_tracepoint(list, &parse_state->idx, $1.sys, $1.event,
553                                         error, $2, &@1);
554
555         parse_events_terms__delete($2);
556         free($1.sys);
557         free($1.event);
558         if (err) {
559                 free(list);
560                 PE_ABORT(err);
561         }
562         $$ = list;
563 }
564
565 tracepoint_name:
566 PE_NAME ':' PE_NAME
567 {
568         struct tracepoint_name tracepoint = {$1, $3};
569
570         $$ = tracepoint;
571 }
572
573 event_legacy_numeric:
574 PE_VALUE ':' PE_VALUE opt_event_config
575 {
576         struct list_head *list;
577         int err;
578
579         list = alloc_list();
580         if (!list)
581                 YYNOMEM;
582         err = parse_events_add_numeric(_parse_state, list, (u32)$1, $3, $4,
583                                        /*wildcard=*/false);
584         parse_events_terms__delete($4);
585         if (err) {
586                 free(list);
587                 PE_ABORT(err);
588         }
589         $$ = list;
590 }
591
592 event_legacy_raw:
593 PE_RAW opt_event_config
594 {
595         struct list_head *list;
596         int err;
597         u64 num;
598
599         list = alloc_list();
600         if (!list)
601                 YYNOMEM;
602         errno = 0;
603         num = strtoull($1 + 1, NULL, 16);
604         /* Given the lexer will only give [a-fA-F0-9]+ a failure here should be impossible. */
605         if (errno)
606                 YYABORT;
607         free($1);
608         err = parse_events_add_numeric(_parse_state, list, PERF_TYPE_RAW, num, $2,
609                                        /*wildcard=*/false);
610         parse_events_terms__delete($2);
611         if (err) {
612                 free(list);
613                 PE_ABORT(err);
614         }
615         $$ = list;
616 }
617
618 opt_event_config:
619 '/' event_config '/'
620 {
621         $$ = $2;
622 }
623 |
624 '/' '/'
625 {
626         $$ = NULL;
627 }
628 |
629 {
630         $$ = NULL;
631 }
632
633 opt_pmu_config:
634 '/' event_config '/'
635 {
636         $$ = $2;
637 }
638 |
639 '/' '/'
640 {
641         $$ = NULL;
642 }
643
644 start_terms: event_config
645 {
646         struct parse_events_state *parse_state = _parse_state;
647         if (parse_state->terms) {
648                 parse_events_terms__delete ($1);
649                 YYABORT;
650         }
651         parse_state->terms = $1;
652 }
653
654 event_config:
655 event_config ',' event_term
656 {
657         struct list_head *head = $1;
658         struct parse_events_term *term = $3;
659
660         if (!head) {
661                 parse_events_term__delete(term);
662                 YYABORT;
663         }
664         list_add_tail(&term->list, head);
665         $$ = $1;
666 }
667 |
668 event_term
669 {
670         struct list_head *head = malloc(sizeof(*head));
671         struct parse_events_term *term = $1;
672
673         if (!head)
674                 YYNOMEM;
675         INIT_LIST_HEAD(head);
676         list_add_tail(&term->list, head);
677         $$ = head;
678 }
679
680 name_or_raw: PE_RAW | PE_NAME | PE_LEGACY_CACHE
681
682 name_or_legacy: PE_NAME | PE_LEGACY_CACHE
683
684 event_term:
685 PE_RAW
686 {
687         struct parse_events_term *term;
688         int err = parse_events_term__str(&term, PARSE_EVENTS__TERM_TYPE_RAW,
689                                          strdup("raw"), $1, &@1, &@1);
690
691         if (err) {
692                 free($1);
693                 PE_ABORT(err);
694         }
695         $$ = term;
696 }
697 |
698 name_or_raw '=' name_or_legacy
699 {
700         struct parse_events_term *term;
701         int err = parse_events_term__str(&term, PARSE_EVENTS__TERM_TYPE_USER, $1, $3, &@1, &@3);
702
703         if (err) {
704                 free($1);
705                 free($3);
706                 PE_ABORT(err);
707         }
708         $$ = term;
709 }
710 |
711 name_or_raw '=' PE_VALUE
712 {
713         struct parse_events_term *term;
714         int err = parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER,
715                                          $1, $3, false, &@1, &@3);
716
717         if (err) {
718                 free($1);
719                 PE_ABORT(err);
720         }
721         $$ = term;
722 }
723 |
724 name_or_raw '=' PE_TERM_HW
725 {
726         struct parse_events_term *term;
727         int err = parse_events_term__str(&term, PARSE_EVENTS__TERM_TYPE_USER,
728                                          $1, $3.str, &@1, &@3);
729
730         if (err) {
731                 free($1);
732                 free($3.str);
733                 PE_ABORT(err);
734         }
735         $$ = term;
736 }
737 |
738 PE_LEGACY_CACHE
739 {
740         struct parse_events_term *term;
741         int err = parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_LEGACY_CACHE,
742                                          $1, 1, true, &@1, NULL);
743
744         if (err) {
745                 free($1);
746                 PE_ABORT(err);
747         }
748         $$ = term;
749 }
750 |
751 PE_NAME
752 {
753         struct parse_events_term *term;
754         int err = parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER,
755                                          $1, 1, true, &@1, NULL);
756
757         if (err) {
758                 free($1);
759                 PE_ABORT(err);
760         }
761         $$ = term;
762 }
763 |
764 PE_TERM_HW
765 {
766         struct parse_events_term *term;
767         int err = parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_HARDWARE,
768                                          $1.str, $1.num & 255, false, &@1, NULL);
769
770         if (err) {
771                 free($1.str);
772                 PE_ABORT(err);
773         }
774         $$ = term;
775 }
776 |
777 PE_TERM '=' name_or_legacy
778 {
779         struct parse_events_term *term;
780         int err = parse_events_term__str(&term, (enum parse_events__term_type)$1,
781                                         /*config=*/NULL, $3, &@1, &@3);
782
783         if (err) {
784                 free($3);
785                 PE_ABORT(err);
786         }
787         $$ = term;
788 }
789 |
790 PE_TERM '=' PE_TERM_HW
791 {
792         struct parse_events_term *term;
793         int err = parse_events_term__str(&term, (enum parse_events__term_type)$1,
794                                          /*config=*/NULL, $3.str, &@1, &@3);
795
796         if (err) {
797                 free($3.str);
798                 PE_ABORT(err);
799         }
800         $$ = term;
801 }
802 |
803 PE_TERM '=' PE_TERM
804 {
805         struct parse_events_term *term;
806         int err = parse_events_term__term(&term,
807                                           (enum parse_events__term_type)$1,
808                                           (enum parse_events__term_type)$3,
809                                           &@1, &@3);
810
811         if (err)
812                 PE_ABORT(err);
813
814         $$ = term;
815 }
816 |
817 PE_TERM '=' PE_VALUE
818 {
819         struct parse_events_term *term;
820         int err = parse_events_term__num(&term, (enum parse_events__term_type)$1,
821                                          /*config=*/NULL, $3, /*novalue=*/false, &@1, &@3);
822
823         if (err)
824                 PE_ABORT(err);
825
826         $$ = term;
827 }
828 |
829 PE_TERM
830 {
831         struct parse_events_term *term;
832         int err = parse_events_term__num(&term, (enum parse_events__term_type)$1,
833                                         /*config=*/NULL, /*num=*/1, /*novalue=*/true,
834                                         &@1, /*loc_val=*/NULL);
835
836         if (err)
837                 PE_ABORT(err);
838
839         $$ = term;
840 }
841
842 sep_dc: ':' |
843
844 sep_slash_slash_dc: '/' '/' | ':' |
845
846 %%
847
848 void parse_events_error(YYLTYPE *loc, void *parse_state,
849                         void *scanner __maybe_unused,
850                         char const *msg __maybe_unused)
851 {
852         parse_events_evlist_error(parse_state, loc->last_column, "parser error");
853 }