]>
Commit | Line | Data |
---|---|---|
fc8c0a99 | 1 | %define api.pure full |
5d9cdc11 | 2 | %parse-param {void *_parse_state} |
ac20de6f ZY |
3 | %parse-param {void *scanner} |
4 | %lex-param {void* scanner} | |
6297d423 | 5 | %locations |
89812fc8 JO |
6 | |
7 | %{ | |
8 | ||
9 | #define YYDEBUG 1 | |
10 | ||
b2b9d3a3 | 11 | #include <fnmatch.h> |
bd704620 | 12 | #include <stdio.h> |
89812fc8 | 13 | #include <linux/compiler.h> |
d944c4ee | 14 | #include <linux/types.h> |
f2a8ecd8 | 15 | #include <linux/zalloc.h> |
231bb2aa | 16 | #include "pmu.h" |
f0fbb114 | 17 | #include "evsel.h" |
89812fc8 | 18 | #include "parse-events.h" |
ac20de6f | 19 | #include "parse-events-bison.h" |
89812fc8 | 20 | |
5d9cdc11 | 21 | void parse_events_error(YYLTYPE *loc, void *parse_state, void *scanner, char const *msg); |
34a0548f | 22 | |
89812fc8 JO |
23 | #define ABORT_ON(val) \ |
24 | do { \ | |
25 | if (val) \ | |
26 | YYABORT; \ | |
27 | } while (0) | |
28 | ||
a26e4716 IR |
29 | static struct list_head* alloc_list() |
30 | { | |
31 | struct list_head *list; | |
32 | ||
33 | list = malloc(sizeof(*list)); | |
34 | if (!list) | |
35 | return NULL; | |
36 | ||
37 | INIT_LIST_HEAD(list); | |
38 | return list; | |
39 | } | |
c5cd8ac0 | 40 | |
f2a8ecd8 IR |
41 | static void free_list_evsel(struct list_head* list_evsel) |
42 | { | |
43 | struct evsel *evsel, *tmp; | |
44 | ||
45 | list_for_each_entry_safe(evsel, tmp, list_evsel, core.node) { | |
46 | list_del_init(&evsel->core.node); | |
672f707e | 47 | evsel__delete(evsel); |
f2a8ecd8 IR |
48 | } |
49 | free(list_evsel); | |
50 | } | |
51 | ||
07ef7574 | 52 | static void inc_group_count(struct list_head *list, |
5d9cdc11 | 53 | struct parse_events_state *parse_state) |
97f63e4a NK |
54 | { |
55 | /* Count groups only have more than 1 members */ | |
56 | if (!list_is_last(list->next, list)) | |
5d9cdc11 | 57 | parse_state->nr_groups++; |
97f63e4a NK |
58 | } |
59 | ||
89812fc8 JO |
60 | %} |
61 | ||
90e2b22d | 62 | %token PE_START_EVENTS PE_START_TERMS |
cf3506dc | 63 | %token PE_VALUE PE_VALUE_SYM_HW PE_VALUE_SYM_SW PE_RAW PE_TERM |
f0fbb114 | 64 | %token PE_VALUE_SYM_TOOL |
ac2ba9f3 | 65 | %token PE_EVENT_NAME |
89812fc8 | 66 | %token PE_NAME |
d509db04 | 67 | %token PE_BPF_OBJECT PE_BPF_SOURCE |
89812fc8 JO |
68 | %token PE_MODIFIER_EVENT PE_MODIFIER_BP |
69 | %token PE_NAME_CACHE_TYPE PE_NAME_CACHE_OP_RESULT | |
89efb029 | 70 | %token PE_PREFIX_MEM PE_PREFIX_RAW PE_PREFIX_GROUP |
89812fc8 | 71 | %token PE_ERROR |
ba32a451 | 72 | %token PE_PMU_EVENT_PRE PE_PMU_EVENT_SUF PE_KERNEL_PMU_EVENT |
e571e029 | 73 | %token PE_ARRAY_ALL PE_ARRAY_RANGE |
dd60fba7 | 74 | %token PE_DRV_CFG_TERM |
89812fc8 | 75 | %type <num> PE_VALUE |
cf3506dc JO |
76 | %type <num> PE_VALUE_SYM_HW |
77 | %type <num> PE_VALUE_SYM_SW | |
f0fbb114 | 78 | %type <num> PE_VALUE_SYM_TOOL |
89812fc8 | 79 | %type <num> PE_RAW |
8f707d84 | 80 | %type <num> PE_TERM |
f2a8ecd8 | 81 | %type <num> value_sym |
89812fc8 | 82 | %type <str> PE_NAME |
84c86ca1 | 83 | %type <str> PE_BPF_OBJECT |
d509db04 | 84 | %type <str> PE_BPF_SOURCE |
89812fc8 JO |
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 | |
ac2ba9f3 | 89 | %type <str> PE_EVENT_NAME |
ba32a451 | 90 | %type <str> PE_PMU_EVENT_PRE PE_PMU_EVENT_SUF PE_KERNEL_PMU_EVENT |
dd60fba7 | 91 | %type <str> PE_DRV_CFG_TERM |
f2a8ecd8 | 92 | %destructor { free ($$); } <str> |
8f707d84 | 93 | %type <term> event_term |
1dc92556 | 94 | %destructor { parse_events_term__delete ($$); } <term> |
f2a8ecd8 IR |
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> | |
865582c3 | 116 | %type <tracepoint_name> tracepoint_name |
f2a8ecd8 | 117 | %destructor { free ($$.sys); free ($$.event); } <tracepoint_name> |
e571e029 WN |
118 | %type <array> array |
119 | %type <array> array_term | |
120 | %type <array> array_terms | |
f2a8ecd8 | 121 | %destructor { free ($$.ranges); } <array> |
89812fc8 JO |
122 | |
123 | %union | |
124 | { | |
125 | char *str; | |
b527bab5 | 126 | u64 num; |
f2a8ecd8 IR |
127 | struct list_head *list_evsel; |
128 | struct list_head *list_terms; | |
6cee6cd3 | 129 | struct parse_events_term *term; |
865582c3 HK |
130 | struct tracepoint_name { |
131 | char *sys; | |
132 | char *event; | |
133 | } tracepoint_name; | |
e571e029 | 134 | struct parse_events_array array; |
89812fc8 JO |
135 | } |
136 | %% | |
137 | ||
90e2b22d | 138 | start: |
89efb029 | 139 | PE_START_EVENTS start_events |
90e2b22d | 140 | | |
89efb029 JO |
141 | PE_START_TERMS start_terms |
142 | ||
143 | start_events: groups | |
144 | { | |
5d9cdc11 | 145 | struct parse_events_state *parse_state = _parse_state; |
89efb029 | 146 | |
cabbf268 | 147 | /* frees $1 */ |
5d9cdc11 | 148 | parse_events_update_lists($1, &parse_state->list); |
89efb029 JO |
149 | } |
150 | ||
151 | groups: | |
152 | groups ',' group | |
153 | { | |
154 | struct list_head *list = $1; | |
155 | struct list_head *group = $3; | |
156 | ||
cabbf268 | 157 | /* frees $3 */ |
89efb029 JO |
158 | parse_events_update_lists(group, list); |
159 | $$ = list; | |
160 | } | |
161 | | | |
162 | groups ',' event | |
163 | { | |
164 | struct list_head *list = $1; | |
165 | struct list_head *event = $3; | |
166 | ||
cabbf268 | 167 | /* frees $3 */ |
89efb029 JO |
168 | parse_events_update_lists(event, list); |
169 | $$ = list; | |
170 | } | |
171 | | | |
172 | group | |
173 | | | |
174 | event | |
175 | ||
176 | group: | |
177 | group_def ':' PE_MODIFIER_EVENT | |
178 | { | |
179 | struct list_head *list = $1; | |
cabbf268 | 180 | int err; |
89efb029 | 181 | |
cabbf268 IR |
182 | err = parse_events__modifier_group(list, $3); |
183 | free($3); | |
184 | if (err) { | |
185 | free_list_evsel(list); | |
186 | YYABORT; | |
187 | } | |
89efb029 JO |
188 | $$ = list; |
189 | } | |
190 | | | |
191 | group_def | |
192 | ||
193 | group_def: | |
194 | PE_NAME '{' events '}' | |
195 | { | |
196 | struct list_head *list = $3; | |
197 | ||
5d9cdc11 | 198 | inc_group_count(list, _parse_state); |
3cdc5c2c | 199 | parse_events__set_leader($1, list, _parse_state); |
cabbf268 | 200 | free($1); |
89efb029 JO |
201 | $$ = list; |
202 | } | |
203 | | | |
204 | '{' events '}' | |
205 | { | |
206 | struct list_head *list = $2; | |
207 | ||
5d9cdc11 | 208 | inc_group_count(list, _parse_state); |
3cdc5c2c | 209 | parse_events__set_leader(NULL, list, _parse_state); |
89efb029 JO |
210 | $$ = list; |
211 | } | |
90e2b22d | 212 | |
89812fc8 | 213 | events: |
89efb029 JO |
214 | events ',' event |
215 | { | |
216 | struct list_head *event = $3; | |
217 | struct list_head *list = $1; | |
218 | ||
cabbf268 | 219 | /* frees $3 */ |
89efb029 JO |
220 | parse_events_update_lists(event, list); |
221 | $$ = list; | |
222 | } | |
223 | | | |
224 | event | |
89812fc8 | 225 | |
ac2ba9f3 RR |
226 | event: event_mod |
227 | ||
228 | event_mod: | |
229 | event_name PE_MODIFIER_EVENT | |
89812fc8 | 230 | { |
89efb029 | 231 | struct list_head *list = $1; |
cabbf268 | 232 | int err; |
46010ab2 | 233 | |
5d7be90e JO |
234 | /* |
235 | * Apply modifier on all events added by single event definition | |
236 | * (there could be more events added for multiple tracepoint | |
237 | * definitions via '*?'. | |
238 | */ | |
cabbf268 IR |
239 | err = parse_events__modifier_event(list, $2, false); |
240 | free($2); | |
241 | if (err) { | |
242 | free_list_evsel(list); | |
243 | YYABORT; | |
244 | } | |
89efb029 | 245 | $$ = list; |
89812fc8 JO |
246 | } |
247 | | | |
ac2ba9f3 RR |
248 | event_name |
249 | ||
250 | event_name: | |
251 | PE_EVENT_NAME event_def | |
252 | { | |
cabbf268 IR |
253 | int err; |
254 | ||
255 | err = parse_events_name($2, $1); | |
ac2ba9f3 | 256 | free($1); |
cabbf268 IR |
257 | if (err) { |
258 | free_list_evsel($2); | |
259 | YYABORT; | |
260 | } | |
ac2ba9f3 RR |
261 | $$ = $2; |
262 | } | |
263 | | | |
89812fc8 JO |
264 | event_def |
265 | ||
5f537a26 JO |
266 | event_def: event_pmu | |
267 | event_legacy_symbol | | |
89812fc8 JO |
268 | event_legacy_cache sep_dc | |
269 | event_legacy_mem | | |
270 | event_legacy_tracepoint sep_dc | | |
271 | event_legacy_numeric sep_dc | | |
84c86ca1 WN |
272 | event_legacy_raw sep_dc | |
273 | event_bpf_file | |
89812fc8 | 274 | |
5f537a26 | 275 | event_pmu: |
ceac7b79 | 276 | PE_NAME opt_pmu_config |
5f537a26 | 277 | { |
f7fa827f JO |
278 | struct parse_events_state *parse_state = _parse_state; |
279 | struct parse_events_error *error = parse_state->error; | |
cabbf268 IR |
280 | struct list_head *list = NULL, *orig_terms = NULL, *terms= NULL; |
281 | char *pattern = NULL; | |
282 | ||
283 | #define CLEANUP_YYABORT \ | |
284 | do { \ | |
285 | parse_events_terms__delete($2); \ | |
286 | parse_events_terms__delete(orig_terms); \ | |
e1e9b78d | 287 | free(list); \ |
cabbf268 IR |
288 | free($1); \ |
289 | free(pattern); \ | |
290 | YYABORT; \ | |
291 | } while(0) | |
8255718f | 292 | |
4a35a902 | 293 | if (parse_events_copy_term_list($2, &orig_terms)) |
cabbf268 | 294 | CLEANUP_YYABORT; |
b847cbdc | 295 | |
f7fa827f JO |
296 | if (error) |
297 | error->idx = @1.first_column; | |
298 | ||
a26e4716 | 299 | list = alloc_list(); |
cabbf268 IR |
300 | if (!list) |
301 | CLEANUP_YYABORT; | |
3cdc5c2c | 302 | if (parse_events_add_pmu(_parse_state, list, $1, $2, false, false)) { |
8255718f AK |
303 | struct perf_pmu *pmu = NULL; |
304 | int ok = 0; | |
b2b9d3a3 AVF |
305 | |
306 | if (asprintf(&pattern, "%s*", $1) < 0) | |
cabbf268 | 307 | CLEANUP_YYABORT; |
8255718f AK |
308 | |
309 | while ((pmu = perf_pmu__scan(pmu)) != NULL) { | |
310 | char *name = pmu->name; | |
311 | ||
a820e335 AK |
312 | if (!strncmp(name, "uncore_", 7) && |
313 | strncmp($1, "uncore_", 7)) | |
314 | name += 7; | |
b2b9d3a3 | 315 | if (!fnmatch(pattern, name, 0)) { |
cabbf268 IR |
316 | if (parse_events_copy_term_list(orig_terms, &terms)) |
317 | CLEANUP_YYABORT; | |
3cdc5c2c | 318 | if (!parse_events_add_pmu(_parse_state, list, pmu->name, terms, true, false)) |
8255718f AK |
319 | ok++; |
320 | parse_events_terms__delete(terms); | |
321 | } | |
322 | } | |
b2b9d3a3 | 323 | |
8255718f | 324 | if (!ok) |
cabbf268 | 325 | CLEANUP_YYABORT; |
8255718f | 326 | } |
4a35a902 | 327 | parse_events_terms__delete($2); |
8255718f | 328 | parse_events_terms__delete(orig_terms); |
ba08829a | 329 | free(pattern); |
cabbf268 | 330 | free($1); |
b847cbdc | 331 | $$ = list; |
cabbf268 | 332 | #undef CLEANUP_YYABORT |
5f537a26 | 333 | } |
ad962273 | 334 | | |
ba32a451 KL |
335 | PE_KERNEL_PMU_EVENT sep_dc |
336 | { | |
ba32a451 | 337 | struct list_head *list; |
cabbf268 | 338 | int err; |
ba32a451 | 339 | |
cabbf268 IR |
340 | err = parse_events_multi_pmu_add(_parse_state, $1, &list); |
341 | free($1); | |
342 | if (err < 0) | |
231bb2aa | 343 | YYABORT; |
ba32a451 KL |
344 | $$ = list; |
345 | } | |
346 | | | |
347 | PE_PMU_EVENT_PRE '-' PE_PMU_EVENT_SUF sep_dc | |
348 | { | |
ba32a451 KL |
349 | struct list_head *list; |
350 | char pmu_name[128]; | |
ba32a451 | 351 | |
8255718f | 352 | snprintf(&pmu_name, 128, "%s-%s", $1, $3); |
cabbf268 IR |
353 | free($1); |
354 | free($3); | |
5d9cdc11 | 355 | if (parse_events_multi_pmu_add(_parse_state, pmu_name, &list) < 0) |
8255718f | 356 | YYABORT; |
ba32a451 KL |
357 | $$ = list; |
358 | } | |
5f537a26 | 359 | |
cf3506dc JO |
360 | value_sym: |
361 | PE_VALUE_SYM_HW | |
362 | | | |
363 | PE_VALUE_SYM_SW | |
364 | ||
89812fc8 | 365 | event_legacy_symbol: |
cf3506dc | 366 | value_sym '/' event_config '/' |
89812fc8 | 367 | { |
c5cd8ac0 | 368 | struct list_head *list; |
89812fc8 JO |
369 | int type = $1 >> 16; |
370 | int config = $1 & 255; | |
cabbf268 | 371 | int err; |
89812fc8 | 372 | |
a26e4716 IR |
373 | list = alloc_list(); |
374 | ABORT_ON(!list); | |
cabbf268 | 375 | err = parse_events_add_numeric(_parse_state, list, type, config, $3); |
2146afc6 | 376 | parse_events_terms__delete($3); |
cabbf268 IR |
377 | if (err) { |
378 | free_list_evsel(list); | |
379 | YYABORT; | |
380 | } | |
b847cbdc | 381 | $$ = list; |
8f707d84 JO |
382 | } |
383 | | | |
714a92d8 | 384 | value_sym sep_slash_slash_dc |
8f707d84 | 385 | { |
c5cd8ac0 | 386 | struct list_head *list; |
8f707d84 JO |
387 | int type = $1 >> 16; |
388 | int config = $1 & 255; | |
389 | ||
a26e4716 IR |
390 | list = alloc_list(); |
391 | ABORT_ON(!list); | |
5d9cdc11 | 392 | ABORT_ON(parse_events_add_numeric(_parse_state, list, type, config, NULL)); |
b847cbdc | 393 | $$ = list; |
89812fc8 | 394 | } |
f0fbb114 AK |
395 | | |
396 | PE_VALUE_SYM_TOOL sep_slash_slash_dc | |
397 | { | |
398 | struct list_head *list; | |
399 | ||
a26e4716 IR |
400 | list = alloc_list(); |
401 | ABORT_ON(!list); | |
f0fbb114 AK |
402 | ABORT_ON(parse_events_add_tool(_parse_state, list, $1)); |
403 | $$ = list; | |
404 | } | |
89812fc8 JO |
405 | |
406 | event_legacy_cache: | |
43d0b978 | 407 | PE_NAME_CACHE_TYPE '-' PE_NAME_CACHE_OP_RESULT '-' PE_NAME_CACHE_OP_RESULT opt_event_config |
89812fc8 | 408 | { |
5d9cdc11 ACM |
409 | struct parse_events_state *parse_state = _parse_state; |
410 | struct parse_events_error *error = parse_state->error; | |
c5cd8ac0 | 411 | struct list_head *list; |
cabbf268 | 412 | int err; |
b847cbdc | 413 | |
a26e4716 IR |
414 | list = alloc_list(); |
415 | ABORT_ON(!list); | |
cabbf268 | 416 | err = parse_events_add_cache(list, &parse_state->idx, $1, $3, $5, error, $6); |
43d0b978 | 417 | parse_events_terms__delete($6); |
cabbf268 IR |
418 | free($1); |
419 | free($3); | |
420 | free($5); | |
421 | if (err) { | |
422 | free_list_evsel(list); | |
423 | YYABORT; | |
424 | } | |
b847cbdc | 425 | $$ = list; |
89812fc8 JO |
426 | } |
427 | | | |
43d0b978 | 428 | PE_NAME_CACHE_TYPE '-' PE_NAME_CACHE_OP_RESULT opt_event_config |
89812fc8 | 429 | { |
5d9cdc11 ACM |
430 | struct parse_events_state *parse_state = _parse_state; |
431 | struct parse_events_error *error = parse_state->error; | |
c5cd8ac0 | 432 | struct list_head *list; |
cabbf268 | 433 | int err; |
b847cbdc | 434 | |
a26e4716 IR |
435 | list = alloc_list(); |
436 | ABORT_ON(!list); | |
cabbf268 | 437 | err = parse_events_add_cache(list, &parse_state->idx, $1, $3, NULL, error, $4); |
43d0b978 | 438 | parse_events_terms__delete($4); |
cabbf268 IR |
439 | free($1); |
440 | free($3); | |
441 | if (err) { | |
442 | free_list_evsel(list); | |
443 | YYABORT; | |
444 | } | |
b847cbdc | 445 | $$ = list; |
89812fc8 JO |
446 | } |
447 | | | |
43d0b978 | 448 | PE_NAME_CACHE_TYPE opt_event_config |
89812fc8 | 449 | { |
5d9cdc11 ACM |
450 | struct parse_events_state *parse_state = _parse_state; |
451 | struct parse_events_error *error = parse_state->error; | |
c5cd8ac0 | 452 | struct list_head *list; |
cabbf268 | 453 | int err; |
b847cbdc | 454 | |
a26e4716 IR |
455 | list = alloc_list(); |
456 | ABORT_ON(!list); | |
cabbf268 | 457 | err = parse_events_add_cache(list, &parse_state->idx, $1, NULL, NULL, error, $2); |
43d0b978 | 458 | parse_events_terms__delete($2); |
cabbf268 IR |
459 | free($1); |
460 | if (err) { | |
461 | free_list_evsel(list); | |
462 | YYABORT; | |
463 | } | |
b847cbdc | 464 | $$ = list; |
89812fc8 JO |
465 | } |
466 | ||
467 | event_legacy_mem: | |
3741eb9f JS |
468 | PE_PREFIX_MEM PE_VALUE '/' PE_VALUE ':' PE_MODIFIER_BP sep_dc |
469 | { | |
5d9cdc11 | 470 | struct parse_events_state *parse_state = _parse_state; |
3741eb9f | 471 | struct list_head *list; |
cabbf268 | 472 | int err; |
3741eb9f | 473 | |
a26e4716 IR |
474 | list = alloc_list(); |
475 | ABORT_ON(!list); | |
cabbf268 IR |
476 | err = parse_events_add_breakpoint(list, &parse_state->idx, |
477 | (void *) $2, $6, $4); | |
478 | free($6); | |
479 | if (err) { | |
480 | free(list); | |
481 | YYABORT; | |
482 | } | |
3741eb9f JS |
483 | $$ = list; |
484 | } | |
485 | | | |
486 | PE_PREFIX_MEM PE_VALUE '/' PE_VALUE sep_dc | |
487 | { | |
5d9cdc11 | 488 | struct parse_events_state *parse_state = _parse_state; |
3741eb9f JS |
489 | struct list_head *list; |
490 | ||
a26e4716 IR |
491 | list = alloc_list(); |
492 | ABORT_ON(!list); | |
cabbf268 IR |
493 | if (parse_events_add_breakpoint(list, &parse_state->idx, |
494 | (void *) $2, NULL, $4)) { | |
495 | free(list); | |
496 | YYABORT; | |
497 | } | |
3741eb9f JS |
498 | $$ = list; |
499 | } | |
500 | | | |
89812fc8 JO |
501 | PE_PREFIX_MEM PE_VALUE ':' PE_MODIFIER_BP sep_dc |
502 | { | |
5d9cdc11 | 503 | struct parse_events_state *parse_state = _parse_state; |
c5cd8ac0 | 504 | struct list_head *list; |
cabbf268 | 505 | int err; |
b847cbdc | 506 | |
a26e4716 IR |
507 | list = alloc_list(); |
508 | ABORT_ON(!list); | |
cabbf268 IR |
509 | err = parse_events_add_breakpoint(list, &parse_state->idx, |
510 | (void *) $2, $4, 0); | |
511 | free($4); | |
512 | if (err) { | |
513 | free(list); | |
514 | YYABORT; | |
515 | } | |
b847cbdc | 516 | $$ = list; |
89812fc8 JO |
517 | } |
518 | | | |
519 | PE_PREFIX_MEM PE_VALUE sep_dc | |
520 | { | |
5d9cdc11 | 521 | struct parse_events_state *parse_state = _parse_state; |
c5cd8ac0 | 522 | struct list_head *list; |
b847cbdc | 523 | |
a26e4716 IR |
524 | list = alloc_list(); |
525 | ABORT_ON(!list); | |
cabbf268 IR |
526 | if (parse_events_add_breakpoint(list, &parse_state->idx, |
527 | (void *) $2, NULL, 0)) { | |
528 | free(list); | |
529 | YYABORT; | |
530 | } | |
b847cbdc | 531 | $$ = list; |
89812fc8 JO |
532 | } |
533 | ||
534 | event_legacy_tracepoint: | |
1d55e8ef | 535 | tracepoint_name opt_event_config |
2b9032e0 | 536 | { |
5d9cdc11 ACM |
537 | struct parse_events_state *parse_state = _parse_state; |
538 | struct parse_events_error *error = parse_state->error; | |
2b9032e0 | 539 | struct list_head *list; |
cabbf268 | 540 | int err; |
2b9032e0 | 541 | |
a26e4716 IR |
542 | list = alloc_list(); |
543 | ABORT_ON(!list); | |
e637d177 HK |
544 | if (error) |
545 | error->idx = @1.first_column; | |
546 | ||
cabbf268 IR |
547 | err = parse_events_add_tracepoint(list, &parse_state->idx, $1.sys, $1.event, |
548 | error, $2); | |
e637d177 | 549 | |
cabbf268 IR |
550 | parse_events_terms__delete($2); |
551 | free($1.sys); | |
552 | free($1.event); | |
553 | if (err) { | |
554 | free(list); | |
e1e9b78d | 555 | YYABORT; |
cabbf268 | 556 | } |
2b9032e0 AY |
557 | $$ = list; |
558 | } | |
865582c3 HK |
559 | |
560 | tracepoint_name: | |
561 | PE_NAME '-' PE_NAME ':' PE_NAME | |
562 | { | |
865582c3 HK |
563 | struct tracepoint_name tracepoint; |
564 | ||
cabbf268 | 565 | ABORT_ON(asprintf(&tracepoint.sys, "%s-%s", $1, $3) < 0); |
865582c3 | 566 | tracepoint.event = $5; |
cabbf268 IR |
567 | free($1); |
568 | free($3); | |
865582c3 HK |
569 | $$ = tracepoint; |
570 | } | |
2b9032e0 | 571 | | |
89812fc8 JO |
572 | PE_NAME ':' PE_NAME |
573 | { | |
865582c3 | 574 | struct tracepoint_name tracepoint = {$1, $3}; |
b847cbdc | 575 | |
865582c3 | 576 | $$ = tracepoint; |
89812fc8 JO |
577 | } |
578 | ||
579 | event_legacy_numeric: | |
10bf358a | 580 | PE_VALUE ':' PE_VALUE opt_event_config |
89812fc8 | 581 | { |
c5cd8ac0 | 582 | struct list_head *list; |
cabbf268 | 583 | int err; |
b847cbdc | 584 | |
a26e4716 IR |
585 | list = alloc_list(); |
586 | ABORT_ON(!list); | |
cabbf268 | 587 | err = parse_events_add_numeric(_parse_state, list, (u32)$1, $3, $4); |
10bf358a | 588 | parse_events_terms__delete($4); |
cabbf268 IR |
589 | if (err) { |
590 | free(list); | |
591 | YYABORT; | |
592 | } | |
b847cbdc | 593 | $$ = list; |
89812fc8 JO |
594 | } |
595 | ||
596 | event_legacy_raw: | |
10bf358a | 597 | PE_RAW opt_event_config |
89812fc8 | 598 | { |
c5cd8ac0 | 599 | struct list_head *list; |
cabbf268 | 600 | int err; |
b847cbdc | 601 | |
a26e4716 IR |
602 | list = alloc_list(); |
603 | ABORT_ON(!list); | |
cabbf268 | 604 | err = parse_events_add_numeric(_parse_state, list, PERF_TYPE_RAW, $1, $2); |
10bf358a | 605 | parse_events_terms__delete($2); |
cabbf268 IR |
606 | if (err) { |
607 | free(list); | |
608 | YYABORT; | |
609 | } | |
b847cbdc | 610 | $$ = list; |
8f707d84 JO |
611 | } |
612 | ||
84c86ca1 | 613 | event_bpf_file: |
a34f3be7 | 614 | PE_BPF_OBJECT opt_event_config |
84c86ca1 | 615 | { |
5d9cdc11 | 616 | struct parse_events_state *parse_state = _parse_state; |
84c86ca1 | 617 | struct list_head *list; |
cabbf268 | 618 | int err; |
84c86ca1 | 619 | |
a26e4716 IR |
620 | list = alloc_list(); |
621 | ABORT_ON(!list); | |
cabbf268 | 622 | err = parse_events_load_bpf(parse_state, list, $1, false, $2); |
a34f3be7 | 623 | parse_events_terms__delete($2); |
cabbf268 IR |
624 | free($1); |
625 | if (err) { | |
626 | free(list); | |
627 | YYABORT; | |
628 | } | |
d509db04 WN |
629 | $$ = list; |
630 | } | |
631 | | | |
a34f3be7 | 632 | PE_BPF_SOURCE opt_event_config |
d509db04 | 633 | { |
d509db04 | 634 | struct list_head *list; |
cabbf268 | 635 | int err; |
d509db04 | 636 | |
a26e4716 IR |
637 | list = alloc_list(); |
638 | ABORT_ON(!list); | |
cabbf268 | 639 | err = parse_events_load_bpf(_parse_state, list, $1, true, $2); |
a34f3be7 | 640 | parse_events_terms__delete($2); |
cabbf268 IR |
641 | if (err) { |
642 | free(list); | |
643 | YYABORT; | |
644 | } | |
84c86ca1 WN |
645 | $$ = list; |
646 | } | |
647 | ||
1d55e8ef ACM |
648 | opt_event_config: |
649 | '/' event_config '/' | |
650 | { | |
651 | $$ = $2; | |
652 | } | |
653 | | | |
654 | '/' '/' | |
655 | { | |
656 | $$ = NULL; | |
657 | } | |
658 | | | |
659 | { | |
660 | $$ = NULL; | |
661 | } | |
662 | ||
ceac7b79 JO |
663 | opt_pmu_config: |
664 | '/' event_config '/' | |
665 | { | |
666 | $$ = $2; | |
667 | } | |
668 | | | |
669 | '/' '/' | |
670 | { | |
671 | $$ = NULL; | |
672 | } | |
673 | ||
89efb029 | 674 | start_terms: event_config |
90e2b22d | 675 | { |
5d9cdc11 | 676 | struct parse_events_state *parse_state = _parse_state; |
cabbf268 IR |
677 | if (parse_state->terms) { |
678 | parse_events_terms__delete ($1); | |
679 | YYABORT; | |
680 | } | |
5d9cdc11 | 681 | parse_state->terms = $1; |
90e2b22d JO |
682 | } |
683 | ||
8f707d84 JO |
684 | event_config: |
685 | event_config ',' event_term | |
686 | { | |
687 | struct list_head *head = $1; | |
6cee6cd3 | 688 | struct parse_events_term *term = $3; |
8f707d84 | 689 | |
cabbf268 | 690 | if (!head) { |
1dc92556 | 691 | parse_events_term__delete(term); |
cabbf268 IR |
692 | YYABORT; |
693 | } | |
8f707d84 JO |
694 | list_add_tail(&term->list, head); |
695 | $$ = $1; | |
696 | } | |
697 | | | |
698 | event_term | |
699 | { | |
700 | struct list_head *head = malloc(sizeof(*head)); | |
6cee6cd3 | 701 | struct parse_events_term *term = $1; |
8f707d84 JO |
702 | |
703 | ABORT_ON(!head); | |
704 | INIT_LIST_HEAD(head); | |
705 | list_add_tail(&term->list, head); | |
706 | $$ = head; | |
707 | } | |
708 | ||
709 | event_term: | |
3a6c51e4 JO |
710 | PE_RAW |
711 | { | |
712 | struct parse_events_term *term; | |
713 | ||
714 | ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_CONFIG, | |
715 | NULL, $1, false, &@1, NULL)); | |
716 | $$ = term; | |
717 | } | |
718 | | | |
8f707d84 JO |
719 | PE_NAME '=' PE_NAME |
720 | { | |
6cee6cd3 | 721 | struct parse_events_term *term; |
8f707d84 | 722 | |
cabbf268 IR |
723 | if (parse_events_term__str(&term, PARSE_EVENTS__TERM_TYPE_USER, |
724 | $1, $3, &@1, &@3)) { | |
725 | free($1); | |
726 | free($3); | |
727 | YYABORT; | |
728 | } | |
8f707d84 JO |
729 | $$ = term; |
730 | } | |
731 | | | |
732 | PE_NAME '=' PE_VALUE | |
733 | { | |
6cee6cd3 | 734 | struct parse_events_term *term; |
8f707d84 | 735 | |
cabbf268 IR |
736 | if (parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER, |
737 | $1, $3, false, &@1, &@3)) { | |
738 | free($1); | |
739 | YYABORT; | |
740 | } | |
8f707d84 JO |
741 | $$ = term; |
742 | } | |
743 | | | |
1d33d6dc JO |
744 | PE_NAME '=' PE_VALUE_SYM_HW |
745 | { | |
6cee6cd3 | 746 | struct parse_events_term *term; |
1d33d6dc JO |
747 | int config = $3 & 255; |
748 | ||
cabbf268 IR |
749 | if (parse_events_term__sym_hw(&term, $1, config)) { |
750 | free($1); | |
751 | YYABORT; | |
752 | } | |
1d33d6dc JO |
753 | $$ = term; |
754 | } | |
755 | | | |
8f707d84 JO |
756 | PE_NAME |
757 | { | |
6cee6cd3 | 758 | struct parse_events_term *term; |
8f707d84 | 759 | |
cabbf268 IR |
760 | if (parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER, |
761 | $1, 1, true, &@1, NULL)) { | |
762 | free($1); | |
763 | YYABORT; | |
764 | } | |
8f707d84 JO |
765 | $$ = term; |
766 | } | |
767 | | | |
1d33d6dc JO |
768 | PE_VALUE_SYM_HW |
769 | { | |
6cee6cd3 | 770 | struct parse_events_term *term; |
1d33d6dc JO |
771 | int config = $1 & 255; |
772 | ||
6cee6cd3 | 773 | ABORT_ON(parse_events_term__sym_hw(&term, NULL, config)); |
1d33d6dc JO |
774 | $$ = term; |
775 | } | |
776 | | | |
6b5fc39b JO |
777 | PE_TERM '=' PE_NAME |
778 | { | |
6cee6cd3 | 779 | struct parse_events_term *term; |
6b5fc39b | 780 | |
cabbf268 IR |
781 | if (parse_events_term__str(&term, (int)$1, NULL, $3, &@1, &@3)) { |
782 | free($3); | |
783 | YYABORT; | |
784 | } | |
6b5fc39b JO |
785 | $$ = term; |
786 | } | |
787 | | | |
8f707d84 JO |
788 | PE_TERM '=' PE_VALUE |
789 | { | |
6cee6cd3 | 790 | struct parse_events_term *term; |
8f707d84 | 791 | |
99e7138e | 792 | ABORT_ON(parse_events_term__num(&term, (int)$1, NULL, $3, false, &@1, &@3)); |
8f707d84 JO |
793 | $$ = term; |
794 | } | |
795 | | | |
796 | PE_TERM | |
797 | { | |
6cee6cd3 | 798 | struct parse_events_term *term; |
8f707d84 | 799 | |
99e7138e | 800 | ABORT_ON(parse_events_term__num(&term, (int)$1, NULL, 1, true, &@1, NULL)); |
8f707d84 | 801 | $$ = term; |
89812fc8 | 802 | } |
e571e029 WN |
803 | | |
804 | PE_NAME array '=' PE_NAME | |
805 | { | |
806 | struct parse_events_term *term; | |
e571e029 | 807 | |
cabbf268 IR |
808 | if (parse_events_term__str(&term, PARSE_EVENTS__TERM_TYPE_USER, |
809 | $1, $4, &@1, &@4)) { | |
810 | free($1); | |
811 | free($4); | |
812 | free($2.ranges); | |
813 | YYABORT; | |
814 | } | |
e571e029 WN |
815 | term->array = $2; |
816 | $$ = term; | |
817 | } | |
818 | | | |
819 | PE_NAME array '=' PE_VALUE | |
820 | { | |
821 | struct parse_events_term *term; | |
822 | ||
cabbf268 IR |
823 | if (parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER, |
824 | $1, $4, false, &@1, &@4)) { | |
825 | free($1); | |
826 | free($2.ranges); | |
827 | YYABORT; | |
828 | } | |
e571e029 WN |
829 | term->array = $2; |
830 | $$ = term; | |
831 | } | |
dd60fba7 MP |
832 | | |
833 | PE_DRV_CFG_TERM | |
834 | { | |
835 | struct parse_events_term *term; | |
b6645a72 | 836 | char *config = strdup($1); |
dd60fba7 | 837 | |
b6645a72 | 838 | ABORT_ON(!config); |
cabbf268 IR |
839 | if (parse_events_term__str(&term, PARSE_EVENTS__TERM_TYPE_DRV_CFG, |
840 | config, $1, &@1, NULL)) { | |
841 | free($1); | |
842 | free(config); | |
843 | YYABORT; | |
844 | } | |
dd60fba7 MP |
845 | $$ = term; |
846 | } | |
e571e029 WN |
847 | |
848 | array: | |
849 | '[' array_terms ']' | |
850 | { | |
851 | $$ = $2; | |
852 | } | |
853 | | | |
854 | PE_ARRAY_ALL | |
855 | { | |
856 | $$.nr_ranges = 0; | |
857 | $$.ranges = NULL; | |
858 | } | |
859 | ||
860 | array_terms: | |
861 | array_terms ',' array_term | |
862 | { | |
863 | struct parse_events_array new_array; | |
864 | ||
865 | new_array.nr_ranges = $1.nr_ranges + $3.nr_ranges; | |
826100a7 IR |
866 | new_array.ranges = realloc($1.ranges, |
867 | sizeof(new_array.ranges[0]) * | |
868 | new_array.nr_ranges); | |
e571e029 | 869 | ABORT_ON(!new_array.ranges); |
e571e029 WN |
870 | memcpy(&new_array.ranges[$1.nr_ranges], $3.ranges, |
871 | $3.nr_ranges * sizeof(new_array.ranges[0])); | |
e571e029 WN |
872 | free($3.ranges); |
873 | $$ = new_array; | |
874 | } | |
875 | | | |
876 | array_term | |
877 | ||
878 | array_term: | |
879 | PE_VALUE | |
880 | { | |
881 | struct parse_events_array array; | |
882 | ||
883 | array.nr_ranges = 1; | |
884 | array.ranges = malloc(sizeof(array.ranges[0])); | |
885 | ABORT_ON(!array.ranges); | |
886 | array.ranges[0].start = $1; | |
887 | array.ranges[0].length = 1; | |
888 | $$ = array; | |
889 | } | |
890 | | | |
891 | PE_VALUE PE_ARRAY_RANGE PE_VALUE | |
892 | { | |
893 | struct parse_events_array array; | |
894 | ||
895 | ABORT_ON($3 < $1); | |
896 | array.nr_ranges = 1; | |
897 | array.ranges = malloc(sizeof(array.ranges[0])); | |
898 | ABORT_ON(!array.ranges); | |
899 | array.ranges[0].start = $1; | |
900 | array.ranges[0].length = $3 - $1 + 1; | |
901 | $$ = array; | |
902 | } | |
89812fc8 JO |
903 | |
904 | sep_dc: ':' | | |
905 | ||
714a92d8 | 906 | sep_slash_slash_dc: '/' '/' | ':' | |
8f707d84 | 907 | |
89812fc8 JO |
908 | %% |
909 | ||
5d9cdc11 | 910 | void parse_events_error(YYLTYPE *loc, void *parse_state, |
6297d423 | 911 | void *scanner __maybe_unused, |
1d037ca1 | 912 | char const *msg __maybe_unused) |
89812fc8 | 913 | { |
5d9cdc11 | 914 | parse_events_evlist_error(parse_state, loc->last_column, "parser error"); |
89812fc8 | 915 | } |