1 %pure-parser 2 %parse-param {void *_data} 3 %parse-param {void *scanner} 4 %lex-param {void* scanner} 5 6 %{ 7 8 #define YYDEBUG 1 9 10 #include <linux/compiler.h> 11 #include <linux/list.h> 12 #include <linux/types.h> 13 #include "util.h" 14 #include "parse-events.h" 15 #include "parse-events-bison.h" 16 17 extern int parse_events_lex (YYSTYPE* lvalp, void* scanner); 18 19 #define ABORT_ON(val) \ 20 do { \ 21 if (val) \ 22 YYABORT; \ 23 } while (0) 24 25 #define ALLOC_LIST(list) \ 26 do { \ 27 list = malloc(sizeof(*list)); \ 28 ABORT_ON(!list); \ 29 INIT_LIST_HEAD(list); \ 30 } while (0) 31 32 static inc_group_count(struct list_head *list, 33 struct parse_events_evlist *data) 34 { 35 /* Count groups only have more than 1 members */ 36 if (!list_is_last(list->next, list)) 37 data->nr_groups++; 38 } 39 40 %} 41 42 %token PE_START_EVENTS PE_START_TERMS 43 %token PE_VALUE PE_VALUE_SYM_HW PE_VALUE_SYM_SW PE_RAW PE_TERM 44 %token PE_EVENT_NAME 45 %token PE_NAME 46 %token PE_MODIFIER_EVENT PE_MODIFIER_BP 47 %token PE_NAME_CACHE_TYPE PE_NAME_CACHE_OP_RESULT 48 %token PE_PREFIX_MEM PE_PREFIX_RAW PE_PREFIX_GROUP 49 %token PE_ERROR 50 %type <num> PE_VALUE 51 %type <num> PE_VALUE_SYM_HW 52 %type <num> PE_VALUE_SYM_SW 53 %type <num> PE_RAW 54 %type <num> PE_TERM 55 %type <str> PE_NAME 56 %type <str> PE_NAME_CACHE_TYPE 57 %type <str> PE_NAME_CACHE_OP_RESULT 58 %type <str> PE_MODIFIER_EVENT 59 %type <str> PE_MODIFIER_BP 60 %type <str> PE_EVENT_NAME 61 %type <num> value_sym 62 %type <head> event_config 63 %type <term> event_term 64 %type <head> event_pmu 65 %type <head> event_legacy_symbol 66 %type <head> event_legacy_cache 67 %type <head> event_legacy_mem 68 %type <head> event_legacy_tracepoint 69 %type <head> event_legacy_numeric 70 %type <head> event_legacy_raw 71 %type <head> event_def 72 %type <head> event_mod 73 %type <head> event_name 74 %type <head> event 75 %type <head> events 76 %type <head> group_def 77 %type <head> group 78 %type <head> groups 79 80 %union 81 { 82 char *str; 83 u64 num; 84 struct list_head *head; 85 struct parse_events_term *term; 86 } 87 %% 88 89 start: 90 PE_START_EVENTS start_events 91 | 92 PE_START_TERMS start_terms 93 94 start_events: groups 95 { 96 struct parse_events_evlist *data = _data; 97 98 parse_events_update_lists($1, &data->list); 99 } 100 101 groups: 102 groups ',' group 103 { 104 struct list_head *list = $1; 105 struct list_head *group = $3; 106 107 parse_events_update_lists(group, list); 108 $$ = list; 109 } 110 | 111 groups ',' event 112 { 113 struct list_head *list = $1; 114 struct list_head *event = $3; 115 116 parse_events_update_lists(event, list); 117 $$ = list; 118 } 119 | 120 group 121 | 122 event 123 124 group: 125 group_def ':' PE_MODIFIER_EVENT 126 { 127 struct list_head *list = $1; 128 129 ABORT_ON(parse_events__modifier_group(list, $3)); 130 $$ = list; 131 } 132 | 133 group_def 134 135 group_def: 136 PE_NAME '{' events '}' 137 { 138 struct list_head *list = $3; 139 140 inc_group_count(list, _data); 141 parse_events__set_leader($1, list); 142 $$ = list; 143 } 144 | 145 '{' events '}' 146 { 147 struct list_head *list = $2; 148 149 inc_group_count(list, _data); 150 parse_events__set_leader(NULL, list); 151 $$ = list; 152 } 153 154 events: 155 events ',' event 156 { 157 struct list_head *event = $3; 158 struct list_head *list = $1; 159 160 parse_events_update_lists(event, list); 161 $$ = list; 162 } 163 | 164 event 165 166 event: event_mod 167 168 event_mod: 169 event_name PE_MODIFIER_EVENT 170 { 171 struct list_head *list = $1; 172 173 /* 174 * Apply modifier on all events added by single event definition 175 * (there could be more events added for multiple tracepoint 176 * definitions via '*?'. 177 */ 178 ABORT_ON(parse_events__modifier_event(list, $2, false)); 179 $$ = list; 180 } 181 | 182 event_name 183 184 event_name: 185 PE_EVENT_NAME event_def 186 { 187 ABORT_ON(parse_events_name($2, $1)); 188 free($1); 189 $$ = $2; 190 } 191 | 192 event_def 193 194 event_def: event_pmu | 195 event_legacy_symbol | 196 event_legacy_cache sep_dc | 197 event_legacy_mem | 198 event_legacy_tracepoint sep_dc | 199 event_legacy_numeric sep_dc | 200 event_legacy_raw sep_dc 201 202 event_pmu: 203 PE_NAME '/' event_config '/' 204 { 205 struct parse_events_evlist *data = _data; 206 struct list_head *list; 207 208 ALLOC_LIST(list); 209 ABORT_ON(parse_events_add_pmu(list, &data->idx, $1, $3)); 210 parse_events__free_terms($3); 211 $$ = list; 212 } 213 214 value_sym: 215 PE_VALUE_SYM_HW 216 | 217 PE_VALUE_SYM_SW 218 219 event_legacy_symbol: 220 value_sym '/' event_config '/' 221 { 222 struct parse_events_evlist *data = _data; 223 struct list_head *list; 224 int type = $1 >> 16; 225 int config = $1 & 255; 226 227 ALLOC_LIST(list); 228 ABORT_ON(parse_events_add_numeric(list, &data->idx, 229 type, config, $3)); 230 parse_events__free_terms($3); 231 $$ = list; 232 } 233 | 234 value_sym sep_slash_dc 235 { 236 struct parse_events_evlist *data = _data; 237 struct list_head *list; 238 int type = $1 >> 16; 239 int config = $1 & 255; 240 241 ALLOC_LIST(list); 242 ABORT_ON(parse_events_add_numeric(list, &data->idx, 243 type, config, NULL)); 244 $$ = list; 245 } 246 247 event_legacy_cache: 248 PE_NAME_CACHE_TYPE '-' PE_NAME_CACHE_OP_RESULT '-' PE_NAME_CACHE_OP_RESULT 249 { 250 struct parse_events_evlist *data = _data; 251 struct list_head *list; 252 253 ALLOC_LIST(list); 254 ABORT_ON(parse_events_add_cache(list, &data->idx, $1, $3, $5)); 255 $$ = list; 256 } 257 | 258 PE_NAME_CACHE_TYPE '-' PE_NAME_CACHE_OP_RESULT 259 { 260 struct parse_events_evlist *data = _data; 261 struct list_head *list; 262 263 ALLOC_LIST(list); 264 ABORT_ON(parse_events_add_cache(list, &data->idx, $1, $3, NULL)); 265 $$ = list; 266 } 267 | 268 PE_NAME_CACHE_TYPE 269 { 270 struct parse_events_evlist *data = _data; 271 struct list_head *list; 272 273 ALLOC_LIST(list); 274 ABORT_ON(parse_events_add_cache(list, &data->idx, $1, NULL, NULL)); 275 $$ = list; 276 } 277 278 event_legacy_mem: 279 PE_PREFIX_MEM PE_VALUE ':' PE_MODIFIER_BP sep_dc 280 { 281 struct parse_events_evlist *data = _data; 282 struct list_head *list; 283 284 ALLOC_LIST(list); 285 ABORT_ON(parse_events_add_breakpoint(list, &data->idx, 286 (void *) $2, $4)); 287 $$ = list; 288 } 289 | 290 PE_PREFIX_MEM PE_VALUE sep_dc 291 { 292 struct parse_events_evlist *data = _data; 293 struct list_head *list; 294 295 ALLOC_LIST(list); 296 ABORT_ON(parse_events_add_breakpoint(list, &data->idx, 297 (void *) $2, NULL)); 298 $$ = list; 299 } 300 301 event_legacy_tracepoint: 302 PE_NAME '-' PE_NAME ':' PE_NAME 303 { 304 struct parse_events_evlist *data = _data; 305 struct list_head *list; 306 char sys_name[128]; 307 snprintf(&sys_name, 128, "%s-%s", $1, $3); 308 309 ALLOC_LIST(list); 310 ABORT_ON(parse_events_add_tracepoint(list, &data->idx, &sys_name, $5)); 311 $$ = list; 312 } 313 | 314 PE_NAME ':' PE_NAME 315 { 316 struct parse_events_evlist *data = _data; 317 struct list_head *list; 318 319 ALLOC_LIST(list); 320 ABORT_ON(parse_events_add_tracepoint(list, &data->idx, $1, $3)); 321 $$ = list; 322 } 323 324 event_legacy_numeric: 325 PE_VALUE ':' PE_VALUE 326 { 327 struct parse_events_evlist *data = _data; 328 struct list_head *list; 329 330 ALLOC_LIST(list); 331 ABORT_ON(parse_events_add_numeric(list, &data->idx, (u32)$1, $3, NULL)); 332 $$ = list; 333 } 334 335 event_legacy_raw: 336 PE_RAW 337 { 338 struct parse_events_evlist *data = _data; 339 struct list_head *list; 340 341 ALLOC_LIST(list); 342 ABORT_ON(parse_events_add_numeric(list, &data->idx, 343 PERF_TYPE_RAW, $1, NULL)); 344 $$ = list; 345 } 346 347 start_terms: event_config 348 { 349 struct parse_events_terms *data = _data; 350 data->terms = $1; 351 } 352 353 event_config: 354 event_config ',' event_term 355 { 356 struct list_head *head = $1; 357 struct parse_events_term *term = $3; 358 359 ABORT_ON(!head); 360 list_add_tail(&term->list, head); 361 $$ = $1; 362 } 363 | 364 event_term 365 { 366 struct list_head *head = malloc(sizeof(*head)); 367 struct parse_events_term *term = $1; 368 369 ABORT_ON(!head); 370 INIT_LIST_HEAD(head); 371 list_add_tail(&term->list, head); 372 $$ = head; 373 } 374 375 event_term: 376 PE_NAME '=' PE_NAME 377 { 378 struct parse_events_term *term; 379 380 ABORT_ON(parse_events_term__str(&term, PARSE_EVENTS__TERM_TYPE_USER, 381 $1, $3)); 382 $$ = term; 383 } 384 | 385 PE_NAME '=' PE_VALUE 386 { 387 struct parse_events_term *term; 388 389 ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER, 390 $1, $3)); 391 $$ = term; 392 } 393 | 394 PE_NAME '=' PE_VALUE_SYM_HW 395 { 396 struct parse_events_term *term; 397 int config = $3 & 255; 398 399 ABORT_ON(parse_events_term__sym_hw(&term, $1, config)); 400 $$ = term; 401 } 402 | 403 PE_NAME 404 { 405 struct parse_events_term *term; 406 407 ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER, 408 $1, 1)); 409 $$ = term; 410 } 411 | 412 PE_VALUE_SYM_HW 413 { 414 struct parse_events_term *term; 415 int config = $1 & 255; 416 417 ABORT_ON(parse_events_term__sym_hw(&term, NULL, config)); 418 $$ = term; 419 } 420 | 421 PE_TERM '=' PE_NAME 422 { 423 struct parse_events_term *term; 424 425 ABORT_ON(parse_events_term__str(&term, (int)$1, NULL, $3)); 426 $$ = term; 427 } 428 | 429 PE_TERM '=' PE_VALUE 430 { 431 struct parse_events_term *term; 432 433 ABORT_ON(parse_events_term__num(&term, (int)$1, NULL, $3)); 434 $$ = term; 435 } 436 | 437 PE_TERM 438 { 439 struct parse_events_term *term; 440 441 ABORT_ON(parse_events_term__num(&term, (int)$1, NULL, 1)); 442 $$ = term; 443 } 444 445 sep_dc: ':' | 446 447 sep_slash_dc: '/' | ':' | 448 449 %% 450 451 void parse_events_error(void *data __maybe_unused, void *scanner __maybe_unused, 452 char const *msg __maybe_unused) 453 { 454 } 455