Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
at v3.17 454 lines 8.4 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%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 89start: 90PE_START_EVENTS start_events 91| 92PE_START_TERMS start_terms 93 94start_events: groups 95{ 96 struct parse_events_evlist *data = _data; 97 98 parse_events_update_lists($1, &data->list); 99} 100 101groups: 102groups ',' 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| 111groups ',' 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| 120group 121| 122event 123 124group: 125group_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| 133group_def 134 135group_def: 136PE_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 154events: 155events ',' 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| 164event 165 166event: event_mod 167 168event_mod: 169event_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| 182event_name 183 184event_name: 185PE_EVENT_NAME event_def 186{ 187 ABORT_ON(parse_events_name($2, $1)); 188 free($1); 189 $$ = $2; 190} 191| 192event_def 193 194event_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 202event_pmu: 203PE_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 214value_sym: 215PE_VALUE_SYM_HW 216| 217PE_VALUE_SYM_SW 218 219event_legacy_symbol: 220value_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| 234value_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 247event_legacy_cache: 248PE_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| 258PE_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| 268PE_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 278event_legacy_mem: 279PE_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| 290PE_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 301event_legacy_tracepoint: 302PE_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| 314PE_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 324event_legacy_numeric: 325PE_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 335event_legacy_raw: 336PE_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 347start_terms: event_config 348{ 349 struct parse_events_terms *data = _data; 350 data->terms = $1; 351} 352 353event_config: 354event_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| 364event_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 375event_term: 376PE_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| 385PE_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| 394PE_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| 403PE_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| 412PE_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| 421PE_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| 429PE_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| 437PE_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 445sep_dc: ':' | 446 447sep_slash_dc: '/' | ':' | 448 449%% 450 451void parse_events_error(void *data __maybe_unused, void *scanner __maybe_unused, 452 char const *msg __maybe_unused) 453{ 454}