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