2 %parse
-param
{void *_parse_state
}
3 %parse
-param
{void *scanner
}
4 %lex
-param
{void* scanner
}
13 #include <linux/compiler.h>
14 #include <linux/types.h>
15 #include <linux/zalloc.h>
18 #include "parse-events.h"
19 #include "parse-events-bison.h"
21 void parse_events_error
(YYLTYPE *loc
, void *parse_state
, void *scanner
, char const *msg
);
23 #define ABORT_ON(val) \
29 static struct list_head
* alloc_list
()
31 struct list_head
*list
;
33 list
= malloc
(sizeof
(*list
));
41 static void free_list_evsel
(struct list_head
* list_evsel
)
43 struct evsel
*evsel
, *tmp
;
45 list_for_each_entry_safe
(evsel
, tmp
, list_evsel
, core.node
) {
46 list_del_init
(&evsel
->core.node
);
47 perf_evsel__delete
(evsel
);
52 static void inc_group_count
(struct list_head
*list
,
53 struct parse_events_state
*parse_state
)
55 /* Count groups only have more than 1 members */
56 if
(!list_is_last
(list
->next
, list
))
57 parse_state
->nr_groups
++;
62 %token PE_START_EVENTS PE_START_TERMS
63 %token PE_VALUE PE_VALUE_SYM_HW PE_VALUE_SYM_SW PE_RAW PE_TERM
64 %token PE_VALUE_SYM_TOOL
67 %token PE_BPF_OBJECT PE_BPF_SOURCE
68 %token PE_MODIFIER_EVENT PE_MODIFIER_BP
69 %token PE_NAME_CACHE_TYPE PE_NAME_CACHE_OP_RESULT
70 %token PE_PREFIX_MEM PE_PREFIX_RAW PE_PREFIX_GROUP
72 %token PE_PMU_EVENT_PRE PE_PMU_EVENT_SUF PE_KERNEL_PMU_EVENT
73 %token PE_ARRAY_ALL PE_ARRAY_RANGE
74 %token PE_DRV_CFG_TERM
76 %type
<num
> PE_VALUE_SYM_HW
77 %type
<num
> PE_VALUE_SYM_SW
78 %type
<num
> PE_VALUE_SYM_TOOL
83 %type
<str
> PE_BPF_OBJECT
84 %type
<str
> PE_BPF_SOURCE
85 %type
<str
> PE_NAME_CACHE_TYPE
86 %type
<str
> PE_NAME_CACHE_OP_RESULT
87 %type
<str
> PE_MODIFIER_EVENT
88 %type
<str
> PE_MODIFIER_BP
89 %type
<str
> PE_EVENT_NAME
90 %type
<str
> PE_PMU_EVENT_PRE PE_PMU_EVENT_SUF PE_KERNEL_PMU_EVENT
91 %type
<str
> PE_DRV_CFG_TERM
92 %destructor
{ free
($$
); } <str
>
93 %type
<term
> event_term
94 %destructor
{ parse_events_term__delete
($$
); } <term
>
95 %type
<list_terms
> event_config
96 %type
<list_terms
> opt_event_config
97 %type
<list_terms
> opt_pmu_config
98 %destructor
{ parse_events_terms__delete
($$
); } <list_terms
>
99 %type
<list_evsel
> event_pmu
100 %type
<list_evsel
> event_legacy_symbol
101 %type
<list_evsel
> event_legacy_cache
102 %type
<list_evsel
> event_legacy_mem
103 %type
<list_evsel
> event_legacy_tracepoint
104 %type
<list_evsel
> event_legacy_numeric
105 %type
<list_evsel
> event_legacy_raw
106 %type
<list_evsel
> event_bpf_file
107 %type
<list_evsel
> event_def
108 %type
<list_evsel
> event_mod
109 %type
<list_evsel
> event_name
110 %type
<list_evsel
> event
111 %type
<list_evsel
> events
112 %type
<list_evsel
> group_def
113 %type
<list_evsel
> group
114 %type
<list_evsel
> groups
115 %destructor
{ free_list_evsel
($$
); } <list_evsel
>
116 %type
<tracepoint_name
> tracepoint_name
117 %destructor
{ free
($$.sys
); free
($$.event
); } <tracepoint_name
>
119 %type
<array
> array_term
120 %type
<array
> array_terms
121 %destructor
{ free
($$.ranges
); } <array
>
127 struct list_head
*list_evsel
;
128 struct list_head
*list_terms
;
129 struct parse_events_term
*term
;
130 struct tracepoint_name
{
134 struct parse_events_array array
;
139 PE_START_EVENTS start_events
141 PE_START_TERMS start_terms
145 struct parse_events_state
*parse_state
= _parse_state
;
148 parse_events_update_lists
($1, &parse_state
->list
);
154 struct list_head
*list
= $1;
155 struct list_head
*group
= $3;
158 parse_events_update_lists
(group
, list
);
164 struct list_head
*list
= $1;
165 struct list_head
*event
= $3;
168 parse_events_update_lists
(event
, list
);
177 group_def
':' PE_MODIFIER_EVENT
179 struct list_head
*list
= $1;
182 err
= parse_events__modifier_group
(list
, $3);
185 free_list_evsel
(list
);
194 PE_NAME
'{' events
'}'
196 struct list_head
*list
= $3;
198 inc_group_count
(list
, _parse_state
);
199 parse_events__set_leader
($1, list
, _parse_state
);
206 struct list_head
*list
= $2;
208 inc_group_count
(list
, _parse_state
);
209 parse_events__set_leader
(NULL
, list
, _parse_state
);
216 struct list_head
*event
= $3;
217 struct list_head
*list
= $1;
220 parse_events_update_lists
(event
, list
);
229 event_name PE_MODIFIER_EVENT
231 struct list_head
*list
= $1;
235 * Apply modifier on all events added by single event definition
236 * (there could be more events added for multiple tracepoint
237 * definitions via '*?'.
239 err
= parse_events__modifier_event
(list
, $2, false
);
242 free_list_evsel
(list
);
251 PE_EVENT_NAME event_def
255 err
= parse_events_name
($2, $1);
266 event_def: event_pmu |
267 event_legacy_symbol |
268 event_legacy_cache sep_dc |
270 event_legacy_tracepoint sep_dc |
271 event_legacy_numeric sep_dc |
272 event_legacy_raw sep_dc |
276 PE_NAME opt_pmu_config
278 struct parse_events_state
*parse_state
= _parse_state
;
279 struct parse_events_error
*error = parse_state
->error;
280 struct list_head
*list
= NULL
, *orig_terms
= NULL
, *terms
= NULL
;
281 char *pattern
= NULL
;
283 #define CLEANUP_YYABORT \
285 parse_events_terms__delete
($2); \
286 parse_events_terms__delete
(orig_terms
); \
293 if
(parse_events_copy_term_list
($2, &orig_terms
))
297 error->idx
= @
1.first_column
;
302 if
(parse_events_add_pmu
(_parse_state
, list
, $1, $2, false
, false
)) {
303 struct perf_pmu
*pmu
= NULL
;
306 if
(asprintf
(&pattern
, "%s*", $1) < 0)
309 while
((pmu
= perf_pmu__scan
(pmu
)) != NULL
) {
310 char *name
= pmu
->name
;
312 if
(!strncmp
(name
, "uncore_", 7) &&
313 strncmp
($1, "uncore_", 7))
315 if
(!fnmatch
(pattern
, name
, 0)) {
316 if
(parse_events_copy_term_list
(orig_terms
, &terms
))
318 if
(!parse_events_add_pmu
(_parse_state
, list
, pmu
->name
, terms
, true
, false
))
320 parse_events_terms__delete
(terms
);
327 parse_events_terms__delete
($2);
328 parse_events_terms__delete
(orig_terms
);
331 #undef CLEANUP_YYABORT
334 PE_KERNEL_PMU_EVENT sep_dc
336 struct list_head
*list
;
339 err
= parse_events_multi_pmu_add
(_parse_state
, $1, &list
);
346 PE_PMU_EVENT_PRE
'-' PE_PMU_EVENT_SUF sep_dc
348 struct list_head
*list
;
351 snprintf
(&pmu_name
, 128, "%s-%s", $1, $3);
354 if
(parse_events_multi_pmu_add
(_parse_state
, pmu_name
, &list
) < 0)
365 value_sym
'/' event_config
'/'
367 struct list_head
*list
;
369 int config
= $1 & 255;
374 err
= parse_events_add_numeric
(_parse_state
, list
, type
, config
, $3);
375 parse_events_terms__delete
($3);
377 free_list_evsel
(list
);
383 value_sym sep_slash_slash_dc
385 struct list_head
*list
;
387 int config
= $1 & 255;
391 ABORT_ON
(parse_events_add_numeric
(_parse_state
, list
, type
, config
, NULL
));
395 PE_VALUE_SYM_TOOL sep_slash_slash_dc
397 struct list_head
*list
;
401 ABORT_ON
(parse_events_add_tool
(_parse_state
, list
, $1));
406 PE_NAME_CACHE_TYPE
'-' PE_NAME_CACHE_OP_RESULT
'-' PE_NAME_CACHE_OP_RESULT opt_event_config
408 struct parse_events_state
*parse_state
= _parse_state
;
409 struct parse_events_error
*error = parse_state
->error;
410 struct list_head
*list
;
415 err
= parse_events_add_cache
(list
, &parse_state
->idx
, $1, $3, $5, error, $6);
416 parse_events_terms__delete
($6);
421 free_list_evsel
(list
);
427 PE_NAME_CACHE_TYPE
'-' PE_NAME_CACHE_OP_RESULT opt_event_config
429 struct parse_events_state
*parse_state
= _parse_state
;
430 struct parse_events_error
*error = parse_state
->error;
431 struct list_head
*list
;
436 err
= parse_events_add_cache
(list
, &parse_state
->idx
, $1, $3, NULL
, error, $4);
437 parse_events_terms__delete
($4);
441 free_list_evsel
(list
);
447 PE_NAME_CACHE_TYPE opt_event_config
449 struct parse_events_state
*parse_state
= _parse_state
;
450 struct parse_events_error
*error = parse_state
->error;
451 struct list_head
*list
;
456 err
= parse_events_add_cache
(list
, &parse_state
->idx
, $1, NULL
, NULL
, error, $2);
457 parse_events_terms__delete
($2);
460 free_list_evsel
(list
);
467 PE_PREFIX_MEM PE_VALUE
'/' PE_VALUE
':' PE_MODIFIER_BP sep_dc
469 struct parse_events_state
*parse_state
= _parse_state
;
470 struct list_head
*list
;
475 err
= parse_events_add_breakpoint
(list
, &parse_state
->idx
,
476 (void *) $2, $6, $4);
485 PE_PREFIX_MEM PE_VALUE
'/' PE_VALUE sep_dc
487 struct parse_events_state
*parse_state
= _parse_state
;
488 struct list_head
*list
;
492 if
(parse_events_add_breakpoint
(list
, &parse_state
->idx
,
493 (void *) $2, NULL
, $4)) {
500 PE_PREFIX_MEM PE_VALUE
':' PE_MODIFIER_BP sep_dc
502 struct parse_events_state
*parse_state
= _parse_state
;
503 struct list_head
*list
;
508 err
= parse_events_add_breakpoint
(list
, &parse_state
->idx
,
518 PE_PREFIX_MEM PE_VALUE sep_dc
520 struct parse_events_state
*parse_state
= _parse_state
;
521 struct list_head
*list
;
525 if
(parse_events_add_breakpoint
(list
, &parse_state
->idx
,
526 (void *) $2, NULL
, 0)) {
533 event_legacy_tracepoint:
534 tracepoint_name opt_event_config
536 struct parse_events_state
*parse_state
= _parse_state
;
537 struct parse_events_error
*error = parse_state
->error;
538 struct list_head
*list
;
544 error->idx
= @
1.first_column
;
546 err
= parse_events_add_tracepoint
(list
, &parse_state
->idx
, $1.sys
, $1.event
,
549 parse_events_terms__delete
($2);
560 PE_NAME
'-' PE_NAME
':' PE_NAME
562 struct tracepoint_name tracepoint
;
564 ABORT_ON
(asprintf
(&tracepoint.sys
, "%s-%s", $1, $3) < 0);
565 tracepoint.event
= $5;
573 struct tracepoint_name tracepoint
= {$1, $3};
578 event_legacy_numeric:
579 PE_VALUE
':' PE_VALUE opt_event_config
581 struct list_head
*list
;
586 err
= parse_events_add_numeric
(_parse_state
, list
, (u32
)$1, $3, $4);
587 parse_events_terms__delete
($4);
596 PE_RAW opt_event_config
598 struct list_head
*list
;
603 err
= parse_events_add_numeric
(_parse_state
, list
, PERF_TYPE_RAW
, $1, $2);
604 parse_events_terms__delete
($2);
613 PE_BPF_OBJECT opt_event_config
615 struct parse_events_state
*parse_state
= _parse_state
;
616 struct list_head
*list
;
621 err
= parse_events_load_bpf
(parse_state
, list
, $1, false
, $2);
622 parse_events_terms__delete
($2);
631 PE_BPF_SOURCE opt_event_config
633 struct list_head
*list
;
638 err
= parse_events_load_bpf
(_parse_state
, list
, $1, true
, $2);
639 parse_events_terms__delete
($2);
673 start_terms: event_config
675 struct parse_events_state
*parse_state
= _parse_state
;
676 if
(parse_state
->terms
) {
677 parse_events_terms__delete
($1);
680 parse_state
->terms
= $1;
684 event_config
',' event_term
686 struct list_head
*head
= $1;
687 struct parse_events_term
*term
= $3;
690 parse_events_term__delete
(term
);
693 list_add_tail
(&term
->list
, head
);
699 struct list_head
*head
= malloc
(sizeof
(*head
));
700 struct parse_events_term
*term
= $1;
703 INIT_LIST_HEAD
(head
);
704 list_add_tail
(&term
->list
, head
);
711 struct parse_events_term
*term
;
713 if
(parse_events_term__str
(&term
, PARSE_EVENTS__TERM_TYPE_USER
,
724 struct parse_events_term
*term
;
726 if
(parse_events_term__num
(&term
, PARSE_EVENTS__TERM_TYPE_USER
,
727 $1, $3, false
, &@
1, &@
3)) {
734 PE_NAME
'=' PE_VALUE_SYM_HW
736 struct parse_events_term
*term
;
737 int config
= $3 & 255;
739 if
(parse_events_term__sym_hw
(&term
, $1, config
)) {
748 struct parse_events_term
*term
;
750 if
(parse_events_term__num
(&term
, PARSE_EVENTS__TERM_TYPE_USER
,
751 $1, 1, true
, &@
1, NULL
)) {
760 struct parse_events_term
*term
;
761 int config
= $1 & 255;
763 ABORT_ON
(parse_events_term__sym_hw
(&term
, NULL
, config
));
769 struct parse_events_term
*term
;
771 if
(parse_events_term__str
(&term
, (int)$1, NULL
, $3, &@
1, &@
3)) {
780 struct parse_events_term
*term
;
782 ABORT_ON
(parse_events_term__num
(&term
, (int)$1, NULL
, $3, false
, &@
1, &@
3));
788 struct parse_events_term
*term
;
790 ABORT_ON
(parse_events_term__num
(&term
, (int)$1, NULL
, 1, true
, &@
1, NULL
));
794 PE_NAME array
'=' PE_NAME
796 struct parse_events_term
*term
;
798 if
(parse_events_term__str
(&term
, PARSE_EVENTS__TERM_TYPE_USER
,
809 PE_NAME array
'=' PE_VALUE
811 struct parse_events_term
*term
;
813 if
(parse_events_term__num
(&term
, PARSE_EVENTS__TERM_TYPE_USER
,
814 $1, $4, false
, &@
1, &@
4)) {
825 struct parse_events_term
*term
;
826 char *config
= strdup
($1);
829 if
(parse_events_term__str
(&term
, PARSE_EVENTS__TERM_TYPE_DRV_CFG
,
830 config
, $1, &@
1, NULL
)) {
851 array_terms
',' array_term
853 struct parse_events_array new_array
;
855 new_array.nr_ranges
= $1.nr_ranges
+ $3.nr_ranges
;
856 new_array.ranges
= realloc
($1.ranges
,
857 sizeof
(new_array.ranges
[0]) *
858 new_array.nr_ranges
);
859 ABORT_ON
(!new_array.ranges
);
860 memcpy
(&new_array.ranges
[$1.nr_ranges
], $3.ranges
,
861 $3.nr_ranges
* sizeof
(new_array.ranges
[0]));
871 struct parse_events_array array
;
874 array.ranges
= malloc
(sizeof
(array.ranges
[0]));
875 ABORT_ON
(!array.ranges
);
876 array.ranges
[0].start
= $1;
877 array.ranges
[0].length
= 1;
881 PE_VALUE PE_ARRAY_RANGE PE_VALUE
883 struct parse_events_array array
;
887 array.ranges
= malloc
(sizeof
(array.ranges
[0]));
888 ABORT_ON
(!array.ranges
);
889 array.ranges
[0].start
= $1;
890 array.ranges
[0].length
= $3 - $1 + 1;
896 sep_slash_slash_dc: '/' '/' |
':' |
900 void parse_events_error
(YYLTYPE *loc
, void *parse_state
,
901 void *scanner __maybe_unused
,
902 char const *msg __maybe_unused
)
904 parse_events_evlist_error
(parse_state
, loc
->last_column
, "parser error");