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