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 | ||
ffaecd7d | 29 | static struct list_head* alloc_list(void) |
a26e4716 IR |
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 |
387ad33f | 72 | %token PE_PMU_EVENT_PRE PE_PMU_EVENT_SUF PE_KERNEL_PMU_EVENT PE_PMU_EVENT_FAKE |
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 |
387ad33f | 90 | %type <str> PE_PMU_EVENT_PRE PE_PMU_EVENT_SUF PE_KERNEL_PMU_EVENT PE_PMU_EVENT_FAKE |
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 | |
c2412fae | 352 | snprintf(pmu_name, sizeof(pmu_name), "%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 | } | |
387ad33f JO |
359 | | |
360 | PE_PMU_EVENT_FAKE sep_dc | |
361 | { | |
362 | struct list_head *list; | |
363 | int err; | |
364 | ||
365 | list = alloc_list(); | |
366 | if (!list) | |
367 | YYABORT; | |
368 | ||
369 | err = parse_events_add_pmu(_parse_state, list, $1, NULL, false, false); | |
370 | free($1); | |
371 | if (err < 0) { | |
372 | free(list); | |
373 | YYABORT; | |
374 | } | |
375 | $$ = list; | |
376 | } | |
377 | | | |
378 | PE_PMU_EVENT_FAKE opt_pmu_config | |
379 | { | |
380 | struct list_head *list; | |
381 | int err; | |
382 | ||
383 | list = alloc_list(); | |
384 | if (!list) | |
385 | YYABORT; | |
386 | ||
387 | err = parse_events_add_pmu(_parse_state, list, $1, $2, false, false); | |
388 | free($1); | |
389 | parse_events_terms__delete($2); | |
390 | if (err < 0) { | |
391 | free(list); | |
392 | YYABORT; | |
393 | } | |
394 | $$ = list; | |
395 | } | |
5f537a26 | 396 | |
cf3506dc JO |
397 | value_sym: |
398 | PE_VALUE_SYM_HW | |
399 | | | |
400 | PE_VALUE_SYM_SW | |
401 | ||
89812fc8 | 402 | event_legacy_symbol: |
cf3506dc | 403 | value_sym '/' event_config '/' |
89812fc8 | 404 | { |
c5cd8ac0 | 405 | struct list_head *list; |
89812fc8 JO |
406 | int type = $1 >> 16; |
407 | int config = $1 & 255; | |
cabbf268 | 408 | int err; |
89812fc8 | 409 | |
a26e4716 IR |
410 | list = alloc_list(); |
411 | ABORT_ON(!list); | |
cabbf268 | 412 | err = parse_events_add_numeric(_parse_state, list, type, config, $3); |
2146afc6 | 413 | parse_events_terms__delete($3); |
cabbf268 IR |
414 | if (err) { |
415 | free_list_evsel(list); | |
416 | YYABORT; | |
417 | } | |
b847cbdc | 418 | $$ = list; |
8f707d84 JO |
419 | } |
420 | | | |
714a92d8 | 421 | value_sym sep_slash_slash_dc |
8f707d84 | 422 | { |
c5cd8ac0 | 423 | struct list_head *list; |
8f707d84 JO |
424 | int type = $1 >> 16; |
425 | int config = $1 & 255; | |
426 | ||
a26e4716 IR |
427 | list = alloc_list(); |
428 | ABORT_ON(!list); | |
5d9cdc11 | 429 | ABORT_ON(parse_events_add_numeric(_parse_state, list, type, config, NULL)); |
b847cbdc | 430 | $$ = list; |
89812fc8 | 431 | } |
f0fbb114 AK |
432 | | |
433 | PE_VALUE_SYM_TOOL sep_slash_slash_dc | |
434 | { | |
435 | struct list_head *list; | |
436 | ||
a26e4716 IR |
437 | list = alloc_list(); |
438 | ABORT_ON(!list); | |
f0fbb114 AK |
439 | ABORT_ON(parse_events_add_tool(_parse_state, list, $1)); |
440 | $$ = list; | |
441 | } | |
89812fc8 JO |
442 | |
443 | event_legacy_cache: | |
43d0b978 | 444 | PE_NAME_CACHE_TYPE '-' PE_NAME_CACHE_OP_RESULT '-' PE_NAME_CACHE_OP_RESULT opt_event_config |
89812fc8 | 445 | { |
5d9cdc11 ACM |
446 | struct parse_events_state *parse_state = _parse_state; |
447 | struct parse_events_error *error = parse_state->error; | |
c5cd8ac0 | 448 | struct list_head *list; |
cabbf268 | 449 | int err; |
b847cbdc | 450 | |
a26e4716 IR |
451 | list = alloc_list(); |
452 | ABORT_ON(!list); | |
cabbf268 | 453 | err = parse_events_add_cache(list, &parse_state->idx, $1, $3, $5, error, $6); |
43d0b978 | 454 | parse_events_terms__delete($6); |
cabbf268 IR |
455 | free($1); |
456 | free($3); | |
457 | free($5); | |
458 | if (err) { | |
459 | free_list_evsel(list); | |
460 | YYABORT; | |
461 | } | |
b847cbdc | 462 | $$ = list; |
89812fc8 JO |
463 | } |
464 | | | |
43d0b978 | 465 | PE_NAME_CACHE_TYPE '-' PE_NAME_CACHE_OP_RESULT opt_event_config |
89812fc8 | 466 | { |
5d9cdc11 ACM |
467 | struct parse_events_state *parse_state = _parse_state; |
468 | struct parse_events_error *error = parse_state->error; | |
c5cd8ac0 | 469 | struct list_head *list; |
cabbf268 | 470 | int err; |
b847cbdc | 471 | |
a26e4716 IR |
472 | list = alloc_list(); |
473 | ABORT_ON(!list); | |
cabbf268 | 474 | err = parse_events_add_cache(list, &parse_state->idx, $1, $3, NULL, error, $4); |
43d0b978 | 475 | parse_events_terms__delete($4); |
cabbf268 IR |
476 | free($1); |
477 | free($3); | |
478 | if (err) { | |
479 | free_list_evsel(list); | |
480 | YYABORT; | |
481 | } | |
b847cbdc | 482 | $$ = list; |
89812fc8 JO |
483 | } |
484 | | | |
43d0b978 | 485 | PE_NAME_CACHE_TYPE opt_event_config |
89812fc8 | 486 | { |
5d9cdc11 ACM |
487 | struct parse_events_state *parse_state = _parse_state; |
488 | struct parse_events_error *error = parse_state->error; | |
c5cd8ac0 | 489 | struct list_head *list; |
cabbf268 | 490 | int err; |
b847cbdc | 491 | |
a26e4716 IR |
492 | list = alloc_list(); |
493 | ABORT_ON(!list); | |
cabbf268 | 494 | err = parse_events_add_cache(list, &parse_state->idx, $1, NULL, NULL, error, $2); |
43d0b978 | 495 | parse_events_terms__delete($2); |
cabbf268 IR |
496 | free($1); |
497 | if (err) { | |
498 | free_list_evsel(list); | |
499 | YYABORT; | |
500 | } | |
b847cbdc | 501 | $$ = list; |
89812fc8 JO |
502 | } |
503 | ||
504 | event_legacy_mem: | |
3741eb9f JS |
505 | PE_PREFIX_MEM PE_VALUE '/' PE_VALUE ':' PE_MODIFIER_BP sep_dc |
506 | { | |
5d9cdc11 | 507 | struct parse_events_state *parse_state = _parse_state; |
3741eb9f | 508 | struct list_head *list; |
cabbf268 | 509 | int err; |
3741eb9f | 510 | |
a26e4716 IR |
511 | list = alloc_list(); |
512 | ABORT_ON(!list); | |
cabbf268 | 513 | err = parse_events_add_breakpoint(list, &parse_state->idx, |
0823f768 | 514 | (void *)(uintptr_t) $2, $6, $4); |
cabbf268 IR |
515 | free($6); |
516 | if (err) { | |
517 | free(list); | |
518 | YYABORT; | |
519 | } | |
3741eb9f JS |
520 | $$ = list; |
521 | } | |
522 | | | |
523 | PE_PREFIX_MEM PE_VALUE '/' PE_VALUE sep_dc | |
524 | { | |
5d9cdc11 | 525 | struct parse_events_state *parse_state = _parse_state; |
3741eb9f JS |
526 | struct list_head *list; |
527 | ||
a26e4716 IR |
528 | list = alloc_list(); |
529 | ABORT_ON(!list); | |
cabbf268 | 530 | if (parse_events_add_breakpoint(list, &parse_state->idx, |
0823f768 | 531 | (void *)(uintptr_t) $2, NULL, $4)) { |
cabbf268 IR |
532 | free(list); |
533 | YYABORT; | |
534 | } | |
3741eb9f JS |
535 | $$ = list; |
536 | } | |
537 | | | |
89812fc8 JO |
538 | PE_PREFIX_MEM PE_VALUE ':' PE_MODIFIER_BP sep_dc |
539 | { | |
5d9cdc11 | 540 | struct parse_events_state *parse_state = _parse_state; |
c5cd8ac0 | 541 | struct list_head *list; |
cabbf268 | 542 | int err; |
b847cbdc | 543 | |
a26e4716 IR |
544 | list = alloc_list(); |
545 | ABORT_ON(!list); | |
cabbf268 | 546 | err = parse_events_add_breakpoint(list, &parse_state->idx, |
0823f768 | 547 | (void *)(uintptr_t) $2, $4, 0); |
cabbf268 IR |
548 | free($4); |
549 | if (err) { | |
550 | free(list); | |
551 | YYABORT; | |
552 | } | |
b847cbdc | 553 | $$ = list; |
89812fc8 JO |
554 | } |
555 | | | |
556 | PE_PREFIX_MEM PE_VALUE sep_dc | |
557 | { | |
5d9cdc11 | 558 | struct parse_events_state *parse_state = _parse_state; |
c5cd8ac0 | 559 | struct list_head *list; |
b847cbdc | 560 | |
a26e4716 IR |
561 | list = alloc_list(); |
562 | ABORT_ON(!list); | |
cabbf268 | 563 | if (parse_events_add_breakpoint(list, &parse_state->idx, |
0823f768 | 564 | (void *)(uintptr_t) $2, NULL, 0)) { |
cabbf268 IR |
565 | free(list); |
566 | YYABORT; | |
567 | } | |
b847cbdc | 568 | $$ = list; |
89812fc8 JO |
569 | } |
570 | ||
571 | event_legacy_tracepoint: | |
1d55e8ef | 572 | tracepoint_name opt_event_config |
2b9032e0 | 573 | { |
5d9cdc11 ACM |
574 | struct parse_events_state *parse_state = _parse_state; |
575 | struct parse_events_error *error = parse_state->error; | |
2b9032e0 | 576 | struct list_head *list; |
cabbf268 | 577 | int err; |
2b9032e0 | 578 | |
a26e4716 IR |
579 | list = alloc_list(); |
580 | ABORT_ON(!list); | |
e637d177 HK |
581 | if (error) |
582 | error->idx = @1.first_column; | |
583 | ||
cabbf268 IR |
584 | err = parse_events_add_tracepoint(list, &parse_state->idx, $1.sys, $1.event, |
585 | error, $2); | |
e637d177 | 586 | |
cabbf268 IR |
587 | parse_events_terms__delete($2); |
588 | free($1.sys); | |
589 | free($1.event); | |
590 | if (err) { | |
591 | free(list); | |
e1e9b78d | 592 | YYABORT; |
cabbf268 | 593 | } |
2b9032e0 AY |
594 | $$ = list; |
595 | } | |
865582c3 HK |
596 | |
597 | tracepoint_name: | |
598 | PE_NAME '-' PE_NAME ':' PE_NAME | |
599 | { | |
865582c3 HK |
600 | struct tracepoint_name tracepoint; |
601 | ||
cabbf268 | 602 | ABORT_ON(asprintf(&tracepoint.sys, "%s-%s", $1, $3) < 0); |
865582c3 | 603 | tracepoint.event = $5; |
cabbf268 IR |
604 | free($1); |
605 | free($3); | |
865582c3 HK |
606 | $$ = tracepoint; |
607 | } | |
2b9032e0 | 608 | | |
89812fc8 JO |
609 | PE_NAME ':' PE_NAME |
610 | { | |
865582c3 | 611 | struct tracepoint_name tracepoint = {$1, $3}; |
b847cbdc | 612 | |
865582c3 | 613 | $$ = tracepoint; |
89812fc8 JO |
614 | } |
615 | ||
616 | event_legacy_numeric: | |
10bf358a | 617 | PE_VALUE ':' PE_VALUE opt_event_config |
89812fc8 | 618 | { |
c5cd8ac0 | 619 | struct list_head *list; |
cabbf268 | 620 | int err; |
b847cbdc | 621 | |
a26e4716 IR |
622 | list = alloc_list(); |
623 | ABORT_ON(!list); | |
cabbf268 | 624 | err = parse_events_add_numeric(_parse_state, list, (u32)$1, $3, $4); |
10bf358a | 625 | parse_events_terms__delete($4); |
cabbf268 IR |
626 | if (err) { |
627 | free(list); | |
628 | YYABORT; | |
629 | } | |
b847cbdc | 630 | $$ = list; |
89812fc8 JO |
631 | } |
632 | ||
633 | event_legacy_raw: | |
10bf358a | 634 | PE_RAW opt_event_config |
89812fc8 | 635 | { |
c5cd8ac0 | 636 | struct list_head *list; |
cabbf268 | 637 | int err; |
b847cbdc | 638 | |
a26e4716 IR |
639 | list = alloc_list(); |
640 | ABORT_ON(!list); | |
cabbf268 | 641 | err = parse_events_add_numeric(_parse_state, list, PERF_TYPE_RAW, $1, $2); |
10bf358a | 642 | parse_events_terms__delete($2); |
cabbf268 IR |
643 | if (err) { |
644 | free(list); | |
645 | YYABORT; | |
646 | } | |
b847cbdc | 647 | $$ = list; |
8f707d84 JO |
648 | } |
649 | ||
84c86ca1 | 650 | event_bpf_file: |
a34f3be7 | 651 | PE_BPF_OBJECT opt_event_config |
84c86ca1 | 652 | { |
5d9cdc11 | 653 | struct parse_events_state *parse_state = _parse_state; |
84c86ca1 | 654 | struct list_head *list; |
cabbf268 | 655 | int err; |
84c86ca1 | 656 | |
a26e4716 IR |
657 | list = alloc_list(); |
658 | ABORT_ON(!list); | |
cabbf268 | 659 | err = parse_events_load_bpf(parse_state, list, $1, false, $2); |
a34f3be7 | 660 | parse_events_terms__delete($2); |
cabbf268 IR |
661 | free($1); |
662 | if (err) { | |
663 | free(list); | |
664 | YYABORT; | |
665 | } | |
d509db04 WN |
666 | $$ = list; |
667 | } | |
668 | | | |
a34f3be7 | 669 | PE_BPF_SOURCE opt_event_config |
d509db04 | 670 | { |
d509db04 | 671 | struct list_head *list; |
cabbf268 | 672 | int err; |
d509db04 | 673 | |
a26e4716 IR |
674 | list = alloc_list(); |
675 | ABORT_ON(!list); | |
cabbf268 | 676 | err = parse_events_load_bpf(_parse_state, list, $1, true, $2); |
a34f3be7 | 677 | parse_events_terms__delete($2); |
cabbf268 IR |
678 | if (err) { |
679 | free(list); | |
680 | YYABORT; | |
681 | } | |
84c86ca1 WN |
682 | $$ = list; |
683 | } | |
684 | ||
1d55e8ef ACM |
685 | opt_event_config: |
686 | '/' event_config '/' | |
687 | { | |
688 | $$ = $2; | |
689 | } | |
690 | | | |
691 | '/' '/' | |
692 | { | |
693 | $$ = NULL; | |
694 | } | |
695 | | | |
696 | { | |
697 | $$ = NULL; | |
698 | } | |
699 | ||
ceac7b79 JO |
700 | opt_pmu_config: |
701 | '/' event_config '/' | |
702 | { | |
703 | $$ = $2; | |
704 | } | |
705 | | | |
706 | '/' '/' | |
707 | { | |
708 | $$ = NULL; | |
709 | } | |
710 | ||
89efb029 | 711 | start_terms: event_config |
90e2b22d | 712 | { |
5d9cdc11 | 713 | struct parse_events_state *parse_state = _parse_state; |
cabbf268 IR |
714 | if (parse_state->terms) { |
715 | parse_events_terms__delete ($1); | |
716 | YYABORT; | |
717 | } | |
5d9cdc11 | 718 | parse_state->terms = $1; |
90e2b22d JO |
719 | } |
720 | ||
8f707d84 JO |
721 | event_config: |
722 | event_config ',' event_term | |
723 | { | |
724 | struct list_head *head = $1; | |
6cee6cd3 | 725 | struct parse_events_term *term = $3; |
8f707d84 | 726 | |
cabbf268 | 727 | if (!head) { |
1dc92556 | 728 | parse_events_term__delete(term); |
cabbf268 IR |
729 | YYABORT; |
730 | } | |
8f707d84 JO |
731 | list_add_tail(&term->list, head); |
732 | $$ = $1; | |
733 | } | |
734 | | | |
735 | event_term | |
736 | { | |
737 | struct list_head *head = malloc(sizeof(*head)); | |
6cee6cd3 | 738 | struct parse_events_term *term = $1; |
8f707d84 JO |
739 | |
740 | ABORT_ON(!head); | |
741 | INIT_LIST_HEAD(head); | |
742 | list_add_tail(&term->list, head); | |
743 | $$ = head; | |
744 | } | |
745 | ||
746 | event_term: | |
3a6c51e4 JO |
747 | PE_RAW |
748 | { | |
749 | struct parse_events_term *term; | |
750 | ||
751 | ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_CONFIG, | |
752 | NULL, $1, false, &@1, NULL)); | |
753 | $$ = term; | |
754 | } | |
755 | | | |
8f707d84 JO |
756 | PE_NAME '=' PE_NAME |
757 | { | |
6cee6cd3 | 758 | struct parse_events_term *term; |
8f707d84 | 759 | |
cabbf268 IR |
760 | if (parse_events_term__str(&term, PARSE_EVENTS__TERM_TYPE_USER, |
761 | $1, $3, &@1, &@3)) { | |
762 | free($1); | |
763 | free($3); | |
764 | YYABORT; | |
765 | } | |
8f707d84 JO |
766 | $$ = term; |
767 | } | |
768 | | | |
769 | PE_NAME '=' PE_VALUE | |
770 | { | |
6cee6cd3 | 771 | struct parse_events_term *term; |
8f707d84 | 772 | |
cabbf268 IR |
773 | if (parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER, |
774 | $1, $3, false, &@1, &@3)) { | |
775 | free($1); | |
776 | YYABORT; | |
777 | } | |
8f707d84 JO |
778 | $$ = term; |
779 | } | |
780 | | | |
1d33d6dc JO |
781 | PE_NAME '=' PE_VALUE_SYM_HW |
782 | { | |
6cee6cd3 | 783 | struct parse_events_term *term; |
1d33d6dc JO |
784 | int config = $3 & 255; |
785 | ||
cabbf268 IR |
786 | if (parse_events_term__sym_hw(&term, $1, config)) { |
787 | free($1); | |
788 | YYABORT; | |
789 | } | |
1d33d6dc JO |
790 | $$ = term; |
791 | } | |
792 | | | |
8f707d84 JO |
793 | PE_NAME |
794 | { | |
6cee6cd3 | 795 | struct parse_events_term *term; |
8f707d84 | 796 | |
cabbf268 IR |
797 | if (parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER, |
798 | $1, 1, true, &@1, NULL)) { | |
799 | free($1); | |
800 | YYABORT; | |
801 | } | |
8f707d84 JO |
802 | $$ = term; |
803 | } | |
804 | | | |
1d33d6dc JO |
805 | PE_VALUE_SYM_HW |
806 | { | |
6cee6cd3 | 807 | struct parse_events_term *term; |
1d33d6dc JO |
808 | int config = $1 & 255; |
809 | ||
6cee6cd3 | 810 | ABORT_ON(parse_events_term__sym_hw(&term, NULL, config)); |
1d33d6dc JO |
811 | $$ = term; |
812 | } | |
813 | | | |
6b5fc39b JO |
814 | PE_TERM '=' PE_NAME |
815 | { | |
6cee6cd3 | 816 | struct parse_events_term *term; |
6b5fc39b | 817 | |
cabbf268 IR |
818 | if (parse_events_term__str(&term, (int)$1, NULL, $3, &@1, &@3)) { |
819 | free($3); | |
820 | YYABORT; | |
821 | } | |
6b5fc39b JO |
822 | $$ = term; |
823 | } | |
824 | | | |
8f707d84 JO |
825 | PE_TERM '=' PE_VALUE |
826 | { | |
6cee6cd3 | 827 | struct parse_events_term *term; |
8f707d84 | 828 | |
99e7138e | 829 | ABORT_ON(parse_events_term__num(&term, (int)$1, NULL, $3, false, &@1, &@3)); |
8f707d84 JO |
830 | $$ = term; |
831 | } | |
832 | | | |
833 | PE_TERM | |
834 | { | |
6cee6cd3 | 835 | struct parse_events_term *term; |
8f707d84 | 836 | |
99e7138e | 837 | ABORT_ON(parse_events_term__num(&term, (int)$1, NULL, 1, true, &@1, NULL)); |
8f707d84 | 838 | $$ = term; |
89812fc8 | 839 | } |
e571e029 WN |
840 | | |
841 | PE_NAME array '=' PE_NAME | |
842 | { | |
843 | struct parse_events_term *term; | |
e571e029 | 844 | |
cabbf268 IR |
845 | if (parse_events_term__str(&term, PARSE_EVENTS__TERM_TYPE_USER, |
846 | $1, $4, &@1, &@4)) { | |
847 | free($1); | |
848 | free($4); | |
849 | free($2.ranges); | |
850 | YYABORT; | |
851 | } | |
e571e029 WN |
852 | term->array = $2; |
853 | $$ = term; | |
854 | } | |
855 | | | |
856 | PE_NAME array '=' PE_VALUE | |
857 | { | |
858 | struct parse_events_term *term; | |
859 | ||
cabbf268 IR |
860 | if (parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER, |
861 | $1, $4, false, &@1, &@4)) { | |
862 | free($1); | |
863 | free($2.ranges); | |
864 | YYABORT; | |
865 | } | |
e571e029 WN |
866 | term->array = $2; |
867 | $$ = term; | |
868 | } | |
dd60fba7 MP |
869 | | |
870 | PE_DRV_CFG_TERM | |
871 | { | |
872 | struct parse_events_term *term; | |
b6645a72 | 873 | char *config = strdup($1); |
dd60fba7 | 874 | |
b6645a72 | 875 | ABORT_ON(!config); |
cabbf268 IR |
876 | if (parse_events_term__str(&term, PARSE_EVENTS__TERM_TYPE_DRV_CFG, |
877 | config, $1, &@1, NULL)) { | |
878 | free($1); | |
879 | free(config); | |
880 | YYABORT; | |
881 | } | |
dd60fba7 MP |
882 | $$ = term; |
883 | } | |
e571e029 WN |
884 | |
885 | array: | |
886 | '[' array_terms ']' | |
887 | { | |
888 | $$ = $2; | |
889 | } | |
890 | | | |
891 | PE_ARRAY_ALL | |
892 | { | |
893 | $$.nr_ranges = 0; | |
894 | $$.ranges = NULL; | |
895 | } | |
896 | ||
897 | array_terms: | |
898 | array_terms ',' array_term | |
899 | { | |
900 | struct parse_events_array new_array; | |
901 | ||
902 | new_array.nr_ranges = $1.nr_ranges + $3.nr_ranges; | |
826100a7 IR |
903 | new_array.ranges = realloc($1.ranges, |
904 | sizeof(new_array.ranges[0]) * | |
905 | new_array.nr_ranges); | |
e571e029 | 906 | ABORT_ON(!new_array.ranges); |
e571e029 WN |
907 | memcpy(&new_array.ranges[$1.nr_ranges], $3.ranges, |
908 | $3.nr_ranges * sizeof(new_array.ranges[0])); | |
e571e029 WN |
909 | free($3.ranges); |
910 | $$ = new_array; | |
911 | } | |
912 | | | |
913 | array_term | |
914 | ||
915 | array_term: | |
916 | PE_VALUE | |
917 | { | |
918 | struct parse_events_array array; | |
919 | ||
920 | array.nr_ranges = 1; | |
921 | array.ranges = malloc(sizeof(array.ranges[0])); | |
922 | ABORT_ON(!array.ranges); | |
923 | array.ranges[0].start = $1; | |
924 | array.ranges[0].length = 1; | |
925 | $$ = array; | |
926 | } | |
927 | | | |
928 | PE_VALUE PE_ARRAY_RANGE PE_VALUE | |
929 | { | |
930 | struct parse_events_array array; | |
931 | ||
932 | ABORT_ON($3 < $1); | |
933 | array.nr_ranges = 1; | |
934 | array.ranges = malloc(sizeof(array.ranges[0])); | |
935 | ABORT_ON(!array.ranges); | |
936 | array.ranges[0].start = $1; | |
937 | array.ranges[0].length = $3 - $1 + 1; | |
938 | $$ = array; | |
939 | } | |
89812fc8 JO |
940 | |
941 | sep_dc: ':' | | |
942 | ||
714a92d8 | 943 | sep_slash_slash_dc: '/' '/' | ':' | |
8f707d84 | 944 | |
89812fc8 JO |
945 | %% |
946 | ||
5d9cdc11 | 947 | void parse_events_error(YYLTYPE *loc, void *parse_state, |
6297d423 | 948 | void *scanner __maybe_unused, |
1d037ca1 | 949 | char const *msg __maybe_unused) |
89812fc8 | 950 | { |
5d9cdc11 | 951 | parse_events_evlist_error(parse_state, loc->last_column, "parser error"); |
89812fc8 | 952 | } |