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