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