root/tools/perf/util/parse-events.y

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. inc_group_count
  2. parse_events_error

   1 %pure-parser
   2 %parse-param {void *_parse_state}
   3 %parse-param {void *scanner}
   4 %lex-param {void* scanner}
   5 %locations
   6 
   7 %{
   8 
   9 #define YYDEBUG 1
  10 
  11 #include <fnmatch.h>
  12 #include <stdio.h>
  13 #include <linux/compiler.h>
  14 #include <linux/types.h>
  15 #include "pmu.h"
  16 #include "evsel.h"
  17 #include "parse-events.h"
  18 #include "parse-events-bison.h"
  19 
  20 void parse_events_error(YYLTYPE *loc, void *parse_state, void *scanner, char const *msg);
  21 
  22 #define ABORT_ON(val) \
  23 do { \
  24         if (val) \
  25                 YYABORT; \
  26 } while (0)
  27 
  28 #define ALLOC_LIST(list) \
  29 do { \
  30         list = malloc(sizeof(*list)); \
  31         ABORT_ON(!list);              \
  32         INIT_LIST_HEAD(list);         \
  33 } while (0)
  34 
  35 static void inc_group_count(struct list_head *list,
  36                        struct parse_events_state *parse_state)
  37 {
  38         /* Count groups only have more than 1 members */
  39         if (!list_is_last(list->next, list))
  40                 parse_state->nr_groups++;
  41 }
  42 
  43 %}
  44 
  45 %token PE_START_EVENTS PE_START_TERMS
  46 %token PE_VALUE PE_VALUE_SYM_HW PE_VALUE_SYM_SW PE_RAW PE_TERM
  47 %token PE_VALUE_SYM_TOOL
  48 %token PE_EVENT_NAME
  49 %token PE_NAME
  50 %token PE_BPF_OBJECT PE_BPF_SOURCE
  51 %token PE_MODIFIER_EVENT PE_MODIFIER_BP
  52 %token PE_NAME_CACHE_TYPE PE_NAME_CACHE_OP_RESULT
  53 %token PE_PREFIX_MEM PE_PREFIX_RAW PE_PREFIX_GROUP
  54 %token PE_ERROR
  55 %token PE_PMU_EVENT_PRE PE_PMU_EVENT_SUF PE_KERNEL_PMU_EVENT
  56 %token PE_ARRAY_ALL PE_ARRAY_RANGE
  57 %token PE_DRV_CFG_TERM
  58 %type <num> PE_VALUE
  59 %type <num> PE_VALUE_SYM_HW
  60 %type <num> PE_VALUE_SYM_SW
  61 %type <num> PE_VALUE_SYM_TOOL
  62 %type <num> PE_RAW
  63 %type <num> PE_TERM
  64 %type <str> PE_NAME
  65 %type <str> PE_BPF_OBJECT
  66 %type <str> PE_BPF_SOURCE
  67 %type <str> PE_NAME_CACHE_TYPE
  68 %type <str> PE_NAME_CACHE_OP_RESULT
  69 %type <str> PE_MODIFIER_EVENT
  70 %type <str> PE_MODIFIER_BP
  71 %type <str> PE_EVENT_NAME
  72 %type <str> PE_PMU_EVENT_PRE PE_PMU_EVENT_SUF PE_KERNEL_PMU_EVENT
  73 %type <str> PE_DRV_CFG_TERM
  74 %type <num> value_sym
  75 %type <head> event_config
  76 %type <head> opt_event_config
  77 %type <head> opt_pmu_config
  78 %type <term> event_term
  79 %type <head> event_pmu
  80 %type <head> event_legacy_symbol
  81 %type <head> event_legacy_cache
  82 %type <head> event_legacy_mem
  83 %type <head> event_legacy_tracepoint
  84 %type <tracepoint_name> tracepoint_name
  85 %type <head> event_legacy_numeric
  86 %type <head> event_legacy_raw
  87 %type <head> event_bpf_file
  88 %type <head> event_def
  89 %type <head> event_mod
  90 %type <head> event_name
  91 %type <head> event
  92 %type <head> events
  93 %type <head> group_def
  94 %type <head> group
  95 %type <head> groups
  96 %type <array> array
  97 %type <array> array_term
  98 %type <array> array_terms
  99 
 100 %union
 101 {
 102         char *str;
 103         u64 num;
 104         struct list_head *head;
 105         struct parse_events_term *term;
 106         struct tracepoint_name {
 107                 char *sys;
 108                 char *event;
 109         } tracepoint_name;
 110         struct parse_events_array array;
 111 }
 112 %%
 113 
 114 start:
 115 PE_START_EVENTS start_events
 116 |
 117 PE_START_TERMS  start_terms
 118 
 119 start_events: groups
 120 {
 121         struct parse_events_state *parse_state = _parse_state;
 122 
 123         parse_events_update_lists($1, &parse_state->list);
 124 }
 125 
 126 groups:
 127 groups ',' group
 128 {
 129         struct list_head *list  = $1;
 130         struct list_head *group = $3;
 131 
 132         parse_events_update_lists(group, list);
 133         $$ = list;
 134 }
 135 |
 136 groups ',' event
 137 {
 138         struct list_head *list  = $1;
 139         struct list_head *event = $3;
 140 
 141         parse_events_update_lists(event, list);
 142         $$ = list;
 143 }
 144 |
 145 group
 146 |
 147 event
 148 
 149 group:
 150 group_def ':' PE_MODIFIER_EVENT
 151 {
 152         struct list_head *list = $1;
 153 
 154         ABORT_ON(parse_events__modifier_group(list, $3));
 155         $$ = list;
 156 }
 157 |
 158 group_def
 159 
 160 group_def:
 161 PE_NAME '{' events '}'
 162 {
 163         struct list_head *list = $3;
 164 
 165         inc_group_count(list, _parse_state);
 166         parse_events__set_leader($1, list, _parse_state);
 167         $$ = list;
 168 }
 169 |
 170 '{' events '}'
 171 {
 172         struct list_head *list = $2;
 173 
 174         inc_group_count(list, _parse_state);
 175         parse_events__set_leader(NULL, list, _parse_state);
 176         $$ = list;
 177 }
 178 
 179 events:
 180 events ',' event
 181 {
 182         struct list_head *event = $3;
 183         struct list_head *list  = $1;
 184 
 185         parse_events_update_lists(event, list);
 186         $$ = list;
 187 }
 188 |
 189 event
 190 
 191 event: event_mod
 192 
 193 event_mod:
 194 event_name PE_MODIFIER_EVENT
 195 {
 196         struct list_head *list = $1;
 197 
 198         /*
 199          * Apply modifier on all events added by single event definition
 200          * (there could be more events added for multiple tracepoint
 201          * definitions via '*?'.
 202          */
 203         ABORT_ON(parse_events__modifier_event(list, $2, false));
 204         $$ = list;
 205 }
 206 |
 207 event_name
 208 
 209 event_name:
 210 PE_EVENT_NAME event_def
 211 {
 212         ABORT_ON(parse_events_name($2, $1));
 213         free($1);
 214         $$ = $2;
 215 }
 216 |
 217 event_def
 218 
 219 event_def: event_pmu |
 220            event_legacy_symbol |
 221            event_legacy_cache sep_dc |
 222            event_legacy_mem |
 223            event_legacy_tracepoint sep_dc |
 224            event_legacy_numeric sep_dc |
 225            event_legacy_raw sep_dc |
 226            event_bpf_file
 227 
 228 event_pmu:
 229 PE_NAME opt_pmu_config
 230 {
 231         struct parse_events_state *parse_state = _parse_state;
 232         struct parse_events_error *error = parse_state->error;
 233         struct list_head *list, *orig_terms, *terms;
 234 
 235         if (parse_events_copy_term_list($2, &orig_terms))
 236                 YYABORT;
 237 
 238         if (error)
 239                 error->idx = @1.first_column;
 240 
 241         ALLOC_LIST(list);
 242         if (parse_events_add_pmu(_parse_state, list, $1, $2, false, false)) {
 243                 struct perf_pmu *pmu = NULL;
 244                 int ok = 0;
 245                 char *pattern;
 246 
 247                 if (asprintf(&pattern, "%s*", $1) < 0)
 248                         YYABORT;
 249 
 250                 while ((pmu = perf_pmu__scan(pmu)) != NULL) {
 251                         char *name = pmu->name;
 252 
 253                         if (!strncmp(name, "uncore_", 7) &&
 254                             strncmp($1, "uncore_", 7))
 255                                 name += 7;
 256                         if (!fnmatch(pattern, name, 0)) {
 257                                 if (parse_events_copy_term_list(orig_terms, &terms)) {
 258                                         free(pattern);
 259                                         YYABORT;
 260                                 }
 261                                 if (!parse_events_add_pmu(_parse_state, list, pmu->name, terms, true, false))
 262                                         ok++;
 263                                 parse_events_terms__delete(terms);
 264                         }
 265                 }
 266 
 267                 free(pattern);
 268 
 269                 if (!ok)
 270                         YYABORT;
 271         }
 272         parse_events_terms__delete($2);
 273         parse_events_terms__delete(orig_terms);
 274         $$ = list;
 275 }
 276 |
 277 PE_KERNEL_PMU_EVENT sep_dc
 278 {
 279         struct list_head *list;
 280 
 281         if (parse_events_multi_pmu_add(_parse_state, $1, &list) < 0)
 282                 YYABORT;
 283         $$ = list;
 284 }
 285 |
 286 PE_PMU_EVENT_PRE '-' PE_PMU_EVENT_SUF sep_dc
 287 {
 288         struct list_head *list;
 289         char pmu_name[128];
 290 
 291         snprintf(&pmu_name, 128, "%s-%s", $1, $3);
 292         if (parse_events_multi_pmu_add(_parse_state, pmu_name, &list) < 0)
 293                 YYABORT;
 294         $$ = list;
 295 }
 296 
 297 value_sym:
 298 PE_VALUE_SYM_HW
 299 |
 300 PE_VALUE_SYM_SW
 301 
 302 event_legacy_symbol:
 303 value_sym '/' event_config '/'
 304 {
 305         struct list_head *list;
 306         int type = $1 >> 16;
 307         int config = $1 & 255;
 308 
 309         ALLOC_LIST(list);
 310         ABORT_ON(parse_events_add_numeric(_parse_state, list, type, config, $3));
 311         parse_events_terms__delete($3);
 312         $$ = list;
 313 }
 314 |
 315 value_sym sep_slash_slash_dc
 316 {
 317         struct list_head *list;
 318         int type = $1 >> 16;
 319         int config = $1 & 255;
 320 
 321         ALLOC_LIST(list);
 322         ABORT_ON(parse_events_add_numeric(_parse_state, list, type, config, NULL));
 323         $$ = list;
 324 }
 325 |
 326 PE_VALUE_SYM_TOOL sep_slash_slash_dc
 327 {
 328         struct list_head *list;
 329 
 330         ALLOC_LIST(list);
 331         ABORT_ON(parse_events_add_tool(_parse_state, list, $1));
 332         $$ = list;
 333 }
 334 
 335 event_legacy_cache:
 336 PE_NAME_CACHE_TYPE '-' PE_NAME_CACHE_OP_RESULT '-' PE_NAME_CACHE_OP_RESULT opt_event_config
 337 {
 338         struct parse_events_state *parse_state = _parse_state;
 339         struct parse_events_error *error = parse_state->error;
 340         struct list_head *list;
 341 
 342         ALLOC_LIST(list);
 343         ABORT_ON(parse_events_add_cache(list, &parse_state->idx, $1, $3, $5, error, $6));
 344         parse_events_terms__delete($6);
 345         $$ = list;
 346 }
 347 |
 348 PE_NAME_CACHE_TYPE '-' PE_NAME_CACHE_OP_RESULT opt_event_config
 349 {
 350         struct parse_events_state *parse_state = _parse_state;
 351         struct parse_events_error *error = parse_state->error;
 352         struct list_head *list;
 353 
 354         ALLOC_LIST(list);
 355         ABORT_ON(parse_events_add_cache(list, &parse_state->idx, $1, $3, NULL, error, $4));
 356         parse_events_terms__delete($4);
 357         $$ = list;
 358 }
 359 |
 360 PE_NAME_CACHE_TYPE opt_event_config
 361 {
 362         struct parse_events_state *parse_state = _parse_state;
 363         struct parse_events_error *error = parse_state->error;
 364         struct list_head *list;
 365 
 366         ALLOC_LIST(list);
 367         ABORT_ON(parse_events_add_cache(list, &parse_state->idx, $1, NULL, NULL, error, $2));
 368         parse_events_terms__delete($2);
 369         $$ = list;
 370 }
 371 
 372 event_legacy_mem:
 373 PE_PREFIX_MEM PE_VALUE '/' PE_VALUE ':' PE_MODIFIER_BP sep_dc
 374 {
 375         struct parse_events_state *parse_state = _parse_state;
 376         struct list_head *list;
 377 
 378         ALLOC_LIST(list);
 379         ABORT_ON(parse_events_add_breakpoint(list, &parse_state->idx,
 380                                              (void *) $2, $6, $4));
 381         $$ = list;
 382 }
 383 |
 384 PE_PREFIX_MEM PE_VALUE '/' PE_VALUE sep_dc
 385 {
 386         struct parse_events_state *parse_state = _parse_state;
 387         struct list_head *list;
 388 
 389         ALLOC_LIST(list);
 390         ABORT_ON(parse_events_add_breakpoint(list, &parse_state->idx,
 391                                              (void *) $2, NULL, $4));
 392         $$ = list;
 393 }
 394 |
 395 PE_PREFIX_MEM PE_VALUE ':' PE_MODIFIER_BP sep_dc
 396 {
 397         struct parse_events_state *parse_state = _parse_state;
 398         struct list_head *list;
 399 
 400         ALLOC_LIST(list);
 401         ABORT_ON(parse_events_add_breakpoint(list, &parse_state->idx,
 402                                              (void *) $2, $4, 0));
 403         $$ = list;
 404 }
 405 |
 406 PE_PREFIX_MEM PE_VALUE sep_dc
 407 {
 408         struct parse_events_state *parse_state = _parse_state;
 409         struct list_head *list;
 410 
 411         ALLOC_LIST(list);
 412         ABORT_ON(parse_events_add_breakpoint(list, &parse_state->idx,
 413                                              (void *) $2, NULL, 0));
 414         $$ = list;
 415 }
 416 
 417 event_legacy_tracepoint:
 418 tracepoint_name opt_event_config
 419 {
 420         struct parse_events_state *parse_state = _parse_state;
 421         struct parse_events_error *error = parse_state->error;
 422         struct list_head *list;
 423 
 424         ALLOC_LIST(list);
 425         if (error)
 426                 error->idx = @1.first_column;
 427 
 428         if (parse_events_add_tracepoint(list, &parse_state->idx, $1.sys, $1.event,
 429                                         error, $2))
 430                 return -1;
 431 
 432         $$ = list;
 433 }
 434 
 435 tracepoint_name:
 436 PE_NAME '-' PE_NAME ':' PE_NAME
 437 {
 438         char sys_name[128];
 439         struct tracepoint_name tracepoint;
 440 
 441         snprintf(&sys_name, 128, "%s-%s", $1, $3);
 442         tracepoint.sys = &sys_name;
 443         tracepoint.event = $5;
 444 
 445         $$ = tracepoint;
 446 }
 447 |
 448 PE_NAME ':' PE_NAME
 449 {
 450         struct tracepoint_name tracepoint = {$1, $3};
 451 
 452         $$ = tracepoint;
 453 }
 454 
 455 event_legacy_numeric:
 456 PE_VALUE ':' PE_VALUE opt_event_config
 457 {
 458         struct list_head *list;
 459 
 460         ALLOC_LIST(list);
 461         ABORT_ON(parse_events_add_numeric(_parse_state, list, (u32)$1, $3, $4));
 462         parse_events_terms__delete($4);
 463         $$ = list;
 464 }
 465 
 466 event_legacy_raw:
 467 PE_RAW opt_event_config
 468 {
 469         struct list_head *list;
 470 
 471         ALLOC_LIST(list);
 472         ABORT_ON(parse_events_add_numeric(_parse_state, list, PERF_TYPE_RAW, $1, $2));
 473         parse_events_terms__delete($2);
 474         $$ = list;
 475 }
 476 
 477 event_bpf_file:
 478 PE_BPF_OBJECT opt_event_config
 479 {
 480         struct parse_events_state *parse_state = _parse_state;
 481         struct list_head *list;
 482 
 483         ALLOC_LIST(list);
 484         ABORT_ON(parse_events_load_bpf(parse_state, list, $1, false, $2));
 485         parse_events_terms__delete($2);
 486         $$ = list;
 487 }
 488 |
 489 PE_BPF_SOURCE opt_event_config
 490 {
 491         struct list_head *list;
 492 
 493         ALLOC_LIST(list);
 494         ABORT_ON(parse_events_load_bpf(_parse_state, list, $1, true, $2));
 495         parse_events_terms__delete($2);
 496         $$ = list;
 497 }
 498 
 499 opt_event_config:
 500 '/' event_config '/'
 501 {
 502         $$ = $2;
 503 }
 504 |
 505 '/' '/'
 506 {
 507         $$ = NULL;
 508 }
 509 |
 510 {
 511         $$ = NULL;
 512 }
 513 
 514 opt_pmu_config:
 515 '/' event_config '/'
 516 {
 517         $$ = $2;
 518 }
 519 |
 520 '/' '/'
 521 {
 522         $$ = NULL;
 523 }
 524 
 525 start_terms: event_config
 526 {
 527         struct parse_events_state *parse_state = _parse_state;
 528         parse_state->terms = $1;
 529 }
 530 
 531 event_config:
 532 event_config ',' event_term
 533 {
 534         struct list_head *head = $1;
 535         struct parse_events_term *term = $3;
 536 
 537         ABORT_ON(!head);
 538         list_add_tail(&term->list, head);
 539         $$ = $1;
 540 }
 541 |
 542 event_term
 543 {
 544         struct list_head *head = malloc(sizeof(*head));
 545         struct parse_events_term *term = $1;
 546 
 547         ABORT_ON(!head);
 548         INIT_LIST_HEAD(head);
 549         list_add_tail(&term->list, head);
 550         $$ = head;
 551 }
 552 
 553 event_term:
 554 PE_NAME '=' PE_NAME
 555 {
 556         struct parse_events_term *term;
 557 
 558         ABORT_ON(parse_events_term__str(&term, PARSE_EVENTS__TERM_TYPE_USER,
 559                                         $1, $3, &@1, &@3));
 560         $$ = term;
 561 }
 562 |
 563 PE_NAME '=' PE_VALUE
 564 {
 565         struct parse_events_term *term;
 566 
 567         ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER,
 568                                         $1, $3, false, &@1, &@3));
 569         $$ = term;
 570 }
 571 |
 572 PE_NAME '=' PE_VALUE_SYM_HW
 573 {
 574         struct parse_events_term *term;
 575         int config = $3 & 255;
 576 
 577         ABORT_ON(parse_events_term__sym_hw(&term, $1, config));
 578         $$ = term;
 579 }
 580 |
 581 PE_NAME
 582 {
 583         struct parse_events_term *term;
 584 
 585         ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER,
 586                                         $1, 1, true, &@1, NULL));
 587         $$ = term;
 588 }
 589 |
 590 PE_VALUE_SYM_HW
 591 {
 592         struct parse_events_term *term;
 593         int config = $1 & 255;
 594 
 595         ABORT_ON(parse_events_term__sym_hw(&term, NULL, config));
 596         $$ = term;
 597 }
 598 |
 599 PE_TERM '=' PE_NAME
 600 {
 601         struct parse_events_term *term;
 602 
 603         ABORT_ON(parse_events_term__str(&term, (int)$1, NULL, $3, &@1, &@3));
 604         $$ = term;
 605 }
 606 |
 607 PE_TERM '=' PE_VALUE
 608 {
 609         struct parse_events_term *term;
 610 
 611         ABORT_ON(parse_events_term__num(&term, (int)$1, NULL, $3, false, &@1, &@3));
 612         $$ = term;
 613 }
 614 |
 615 PE_TERM
 616 {
 617         struct parse_events_term *term;
 618 
 619         ABORT_ON(parse_events_term__num(&term, (int)$1, NULL, 1, true, &@1, NULL));
 620         $$ = term;
 621 }
 622 |
 623 PE_NAME array '=' PE_NAME
 624 {
 625         struct parse_events_term *term;
 626 
 627         ABORT_ON(parse_events_term__str(&term, PARSE_EVENTS__TERM_TYPE_USER,
 628                                         $1, $4, &@1, &@4));
 629 
 630         term->array = $2;
 631         $$ = term;
 632 }
 633 |
 634 PE_NAME array '=' PE_VALUE
 635 {
 636         struct parse_events_term *term;
 637 
 638         ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER,
 639                                         $1, $4, false, &@1, &@4));
 640         term->array = $2;
 641         $$ = term;
 642 }
 643 |
 644 PE_DRV_CFG_TERM
 645 {
 646         struct parse_events_term *term;
 647 
 648         ABORT_ON(parse_events_term__str(&term, PARSE_EVENTS__TERM_TYPE_DRV_CFG,
 649                                         $1, $1, &@1, NULL));
 650         $$ = term;
 651 }
 652 
 653 array:
 654 '[' array_terms ']'
 655 {
 656         $$ = $2;
 657 }
 658 |
 659 PE_ARRAY_ALL
 660 {
 661         $$.nr_ranges = 0;
 662         $$.ranges = NULL;
 663 }
 664 
 665 array_terms:
 666 array_terms ',' array_term
 667 {
 668         struct parse_events_array new_array;
 669 
 670         new_array.nr_ranges = $1.nr_ranges + $3.nr_ranges;
 671         new_array.ranges = malloc(sizeof(new_array.ranges[0]) *
 672                                   new_array.nr_ranges);
 673         ABORT_ON(!new_array.ranges);
 674         memcpy(&new_array.ranges[0], $1.ranges,
 675                $1.nr_ranges * sizeof(new_array.ranges[0]));
 676         memcpy(&new_array.ranges[$1.nr_ranges], $3.ranges,
 677                $3.nr_ranges * sizeof(new_array.ranges[0]));
 678         free($1.ranges);
 679         free($3.ranges);
 680         $$ = new_array;
 681 }
 682 |
 683 array_term
 684 
 685 array_term:
 686 PE_VALUE
 687 {
 688         struct parse_events_array array;
 689 
 690         array.nr_ranges = 1;
 691         array.ranges = malloc(sizeof(array.ranges[0]));
 692         ABORT_ON(!array.ranges);
 693         array.ranges[0].start = $1;
 694         array.ranges[0].length = 1;
 695         $$ = array;
 696 }
 697 |
 698 PE_VALUE PE_ARRAY_RANGE PE_VALUE
 699 {
 700         struct parse_events_array array;
 701 
 702         ABORT_ON($3 < $1);
 703         array.nr_ranges = 1;
 704         array.ranges = malloc(sizeof(array.ranges[0]));
 705         ABORT_ON(!array.ranges);
 706         array.ranges[0].start = $1;
 707         array.ranges[0].length = $3 - $1 + 1;
 708         $$ = array;
 709 }
 710 
 711 sep_dc: ':' |
 712 
 713 sep_slash_slash_dc: '/' '/' | ':' |
 714 
 715 %%
 716 
 717 void parse_events_error(YYLTYPE *loc, void *parse_state,
 718                         void *scanner __maybe_unused,
 719                         char const *msg __maybe_unused)
 720 {
 721         parse_events_evlist_error(parse_state, loc->last_column, "parser error");
 722 }

/* [<][>][^][v][top][bottom][index][help] */