1 %define api.pure full 1 %define api.pure full 2 %parse-param {void *_parse_state} 2 %parse-param {void *_parse_state} 3 %parse-param {void *scanner} 3 %parse-param {void *scanner} 4 %lex-param {void* scanner} 4 %lex-param {void* scanner} 5 %locations 5 %locations 6 6 7 %{ 7 %{ 8 8 9 #ifndef NDEBUG 9 #ifndef NDEBUG 10 #define YYDEBUG 1 10 #define YYDEBUG 1 11 #endif 11 #endif 12 12 13 #include <errno.h> 13 #include <errno.h> 14 #include <linux/compiler.h> 14 #include <linux/compiler.h> 15 #include <linux/types.h> 15 #include <linux/types.h> 16 #include "pmu.h" 16 #include "pmu.h" 17 #include "pmus.h" 17 #include "pmus.h" 18 #include "evsel.h" 18 #include "evsel.h" 19 #include "parse-events.h" 19 #include "parse-events.h" 20 #include "parse-events-bison.h" 20 #include "parse-events-bison.h" 21 21 22 int parse_events_lex(YYSTYPE * yylval_param, Y 22 int parse_events_lex(YYSTYPE * yylval_param, YYLTYPE * yylloc_param , void *yyscanner); 23 void parse_events_error(YYLTYPE *loc, void *pa 23 void parse_events_error(YYLTYPE *loc, void *parse_state, void *scanner, char const *msg); 24 24 25 #define PE_ABORT(val) \ 25 #define PE_ABORT(val) \ 26 do { \ 26 do { \ 27 if (val == -ENOMEM) \ 27 if (val == -ENOMEM) \ 28 YYNOMEM; \ 28 YYNOMEM; \ 29 YYABORT; \ 29 YYABORT; \ 30 } while (0) 30 } while (0) 31 31 32 static struct list_head* alloc_list(void) 32 static struct list_head* alloc_list(void) 33 { 33 { 34 struct list_head *list; 34 struct list_head *list; 35 35 36 list = malloc(sizeof(*list)); 36 list = malloc(sizeof(*list)); 37 if (!list) 37 if (!list) 38 return NULL; 38 return NULL; 39 39 40 INIT_LIST_HEAD(list); 40 INIT_LIST_HEAD(list); 41 return list; 41 return list; 42 } 42 } 43 43 44 static void free_list_evsel(struct list_head* 44 static void free_list_evsel(struct list_head* list_evsel) 45 { 45 { 46 struct evsel *evsel, *tmp; 46 struct evsel *evsel, *tmp; 47 47 48 list_for_each_entry_safe(evsel, tmp, l 48 list_for_each_entry_safe(evsel, tmp, list_evsel, core.node) { 49 list_del_init(&evsel->core.nod 49 list_del_init(&evsel->core.node); 50 evsel__delete(evsel); 50 evsel__delete(evsel); 51 } 51 } 52 free(list_evsel); 52 free(list_evsel); 53 } 53 } 54 54 55 %} 55 %} 56 56 57 %token PE_START_EVENTS PE_START_TERMS 57 %token PE_START_EVENTS PE_START_TERMS 58 %token PE_VALUE PE_VALUE_SYM_HW PE_VALUE_SYM_S 58 %token PE_VALUE PE_VALUE_SYM_HW PE_VALUE_SYM_SW PE_TERM 59 %token PE_VALUE_SYM_TOOL 59 %token PE_VALUE_SYM_TOOL 60 %token PE_EVENT_NAME 60 %token PE_EVENT_NAME 61 %token PE_RAW PE_NAME 61 %token PE_RAW PE_NAME 62 %token PE_MODIFIER_EVENT PE_MODIFIER_BP PE_BP_ 62 %token PE_MODIFIER_EVENT PE_MODIFIER_BP PE_BP_COLON PE_BP_SLASH 63 %token PE_LEGACY_CACHE 63 %token PE_LEGACY_CACHE 64 %token PE_PREFIX_MEM 64 %token PE_PREFIX_MEM 65 %token PE_ERROR 65 %token PE_ERROR 66 %token PE_DRV_CFG_TERM 66 %token PE_DRV_CFG_TERM 67 %token PE_TERM_HW 67 %token PE_TERM_HW 68 %type <num> PE_VALUE 68 %type <num> PE_VALUE 69 %type <num> PE_VALUE_SYM_HW 69 %type <num> PE_VALUE_SYM_HW 70 %type <num> PE_VALUE_SYM_SW 70 %type <num> PE_VALUE_SYM_SW 71 %type <num> PE_VALUE_SYM_TOOL 71 %type <num> PE_VALUE_SYM_TOOL 72 %type <mod> PE_MODIFIER_EVENT << 73 %type <term_type> PE_TERM 72 %type <term_type> PE_TERM 74 %type <num> value_sym 73 %type <num> value_sym 75 %type <str> PE_RAW 74 %type <str> PE_RAW 76 %type <str> PE_NAME 75 %type <str> PE_NAME 77 %type <str> PE_LEGACY_CACHE 76 %type <str> PE_LEGACY_CACHE >> 77 %type <str> PE_MODIFIER_EVENT 78 %type <str> PE_MODIFIER_BP 78 %type <str> PE_MODIFIER_BP 79 %type <str> PE_EVENT_NAME 79 %type <str> PE_EVENT_NAME 80 %type <str> PE_DRV_CFG_TERM 80 %type <str> PE_DRV_CFG_TERM 81 %type <str> name_or_raw 81 %type <str> name_or_raw 82 %destructor { free ($$); } <str> 82 %destructor { free ($$); } <str> 83 %type <term> event_term 83 %type <term> event_term 84 %destructor { parse_events_term__delete ($$); 84 %destructor { parse_events_term__delete ($$); } <term> 85 %type <list_terms> event_config 85 %type <list_terms> event_config 86 %type <list_terms> opt_event_config 86 %type <list_terms> opt_event_config 87 %type <list_terms> opt_pmu_config 87 %type <list_terms> opt_pmu_config 88 %destructor { parse_events_terms__delete ($$); 88 %destructor { parse_events_terms__delete ($$); } <list_terms> 89 %type <list_evsel> event_pmu 89 %type <list_evsel> event_pmu 90 %type <list_evsel> event_legacy_symbol 90 %type <list_evsel> event_legacy_symbol 91 %type <list_evsel> event_legacy_cache 91 %type <list_evsel> event_legacy_cache 92 %type <list_evsel> event_legacy_mem 92 %type <list_evsel> event_legacy_mem 93 %type <list_evsel> event_legacy_tracepoint 93 %type <list_evsel> event_legacy_tracepoint 94 %type <list_evsel> event_legacy_numeric 94 %type <list_evsel> event_legacy_numeric 95 %type <list_evsel> event_legacy_raw 95 %type <list_evsel> event_legacy_raw 96 %type <list_evsel> event_def 96 %type <list_evsel> event_def 97 %type <list_evsel> event_mod 97 %type <list_evsel> event_mod 98 %type <list_evsel> event_name 98 %type <list_evsel> event_name 99 %type <list_evsel> event 99 %type <list_evsel> event 100 %type <list_evsel> events 100 %type <list_evsel> events 101 %type <list_evsel> group_def 101 %type <list_evsel> group_def 102 %type <list_evsel> group 102 %type <list_evsel> group 103 %type <list_evsel> groups 103 %type <list_evsel> groups 104 %destructor { free_list_evsel ($$); } <list_ev 104 %destructor { free_list_evsel ($$); } <list_evsel> 105 %type <tracepoint_name> tracepoint_name 105 %type <tracepoint_name> tracepoint_name 106 %destructor { free ($$.sys); free ($$.event); 106 %destructor { free ($$.sys); free ($$.event); } <tracepoint_name> 107 %type <hardware_term> PE_TERM_HW 107 %type <hardware_term> PE_TERM_HW 108 %destructor { free ($$.str); } <hardware_term> 108 %destructor { free ($$.str); } <hardware_term> 109 109 110 %union 110 %union 111 { 111 { 112 char *str; 112 char *str; 113 u64 num; 113 u64 num; 114 struct parse_events_modifier mod; << 115 enum parse_events__term_type term_type 114 enum parse_events__term_type term_type; 116 struct list_head *list_evsel; 115 struct list_head *list_evsel; 117 struct parse_events_terms *list_terms; 116 struct parse_events_terms *list_terms; 118 struct parse_events_term *term; 117 struct parse_events_term *term; 119 struct tracepoint_name { 118 struct tracepoint_name { 120 char *sys; 119 char *sys; 121 char *event; 120 char *event; 122 } tracepoint_name; 121 } tracepoint_name; 123 struct hardware_term { 122 struct hardware_term { 124 char *str; 123 char *str; 125 u64 num; 124 u64 num; 126 } hardware_term; 125 } hardware_term; 127 } 126 } 128 %% 127 %% 129 128 130 /* << 131 * Entry points. We are either parsing events << 132 * parsing is used for parsing events in sysf << 133 */ << 134 start: 129 start: 135 PE_START_EVENTS start_events 130 PE_START_EVENTS start_events 136 | 131 | 137 PE_START_TERMS start_terms 132 PE_START_TERMS start_terms 138 133 139 start_events: groups 134 start_events: groups 140 { 135 { 141 /* Take the parsed events, groups.. an << 142 struct list_head *groups = $1; << 143 struct parse_events_state *parse_state 136 struct parse_events_state *parse_state = _parse_state; 144 137 145 list_splice_tail(groups, &parse_state- !! 138 /* frees $1 */ 146 free(groups); !! 139 parse_events_update_lists($1, &parse_state->list); 147 } 140 } 148 141 149 groups: /* A list of groups or events. */ !! 142 groups: 150 groups ',' group 143 groups ',' group 151 { 144 { 152 /* Merge group into the list of events !! 145 struct list_head *list = $1; 153 struct list_head *groups = $1; !! 146 struct list_head *group = $3; 154 struct list_head *group = $3; !! 147 155 !! 148 /* frees $3 */ 156 list_splice_tail(group, groups); !! 149 parse_events_update_lists(group, list); 157 free(group); !! 150 $$ = list; 158 $$ = groups; << 159 } 151 } 160 | 152 | 161 groups ',' event 153 groups ',' event 162 { 154 { 163 /* Merge event into the list of events !! 155 struct list_head *list = $1; 164 struct list_head *groups = $1; << 165 struct list_head *event = $3; 156 struct list_head *event = $3; 166 157 167 !! 158 /* frees $3 */ 168 list_splice_tail(event, groups); !! 159 parse_events_update_lists(event, list); 169 free(event); !! 160 $$ = list; 170 $$ = groups; << 171 } 161 } 172 | 162 | 173 group 163 group 174 | 164 | 175 event 165 event 176 166 177 group: 167 group: 178 group_def ':' PE_MODIFIER_EVENT 168 group_def ':' PE_MODIFIER_EVENT 179 { 169 { 180 /* Apply the modifier to the events in << 181 struct list_head *list = $1; 170 struct list_head *list = $1; 182 int err; 171 int err; 183 172 184 err = parse_events__modifier_group(_pa !! 173 err = parse_events__modifier_group(list, $3); 185 if (err) !! 174 free($3); >> 175 if (err) { >> 176 struct parse_events_state *parse_state = _parse_state; >> 177 struct parse_events_error *error = parse_state->error; >> 178 >> 179 parse_events_error__handle(error, @3.first_column, >> 180 strdup("Bad modifier"), NULL); >> 181 free_list_evsel(list); 186 YYABORT; 182 YYABORT; >> 183 } 187 $$ = list; 184 $$ = list; 188 } 185 } 189 | 186 | 190 group_def 187 group_def 191 188 192 group_def: 189 group_def: 193 PE_NAME '{' events '}' 190 PE_NAME '{' events '}' 194 { 191 { 195 struct list_head *list = $3; 192 struct list_head *list = $3; 196 193 197 /* !! 194 /* Takes ownership of $1. */ 198 * Set the first entry of list to be t << 199 * the leader to $1 taking ownership. << 200 */ << 201 parse_events__set_leader($1, list); 195 parse_events__set_leader($1, list); 202 $$ = list; 196 $$ = list; 203 } 197 } 204 | 198 | 205 '{' events '}' 199 '{' events '}' 206 { 200 { 207 struct list_head *list = $2; 201 struct list_head *list = $2; 208 202 209 /* Set the first entry of list to be t << 210 parse_events__set_leader(NULL, list); 203 parse_events__set_leader(NULL, list); 211 $$ = list; 204 $$ = list; 212 } 205 } 213 206 214 events: 207 events: 215 events ',' event 208 events ',' event 216 { 209 { 217 struct list_head *events = $1; << 218 struct list_head *event = $3; 210 struct list_head *event = $3; >> 211 struct list_head *list = $1; 219 212 220 list_splice_tail(event, events); !! 213 /* frees $3 */ 221 free(event); !! 214 parse_events_update_lists(event, list); 222 $$ = events; !! 215 $$ = list; 223 } 216 } 224 | 217 | 225 event 218 event 226 219 227 event: event_mod 220 event: event_mod 228 221 229 event_mod: 222 event_mod: 230 event_name PE_MODIFIER_EVENT 223 event_name PE_MODIFIER_EVENT 231 { 224 { 232 struct list_head *list = $1; 225 struct list_head *list = $1; 233 int err; 226 int err; 234 227 235 /* 228 /* 236 * Apply modifier on all events added 229 * Apply modifier on all events added by single event definition 237 * (there could be more events added f 230 * (there could be more events added for multiple tracepoint 238 * definitions via '*?'. 231 * definitions via '*?'. 239 */ 232 */ 240 err = parse_events__modifier_event(_pa !! 233 err = parse_events__modifier_event(list, $2, false); 241 if (err) !! 234 free($2); >> 235 if (err) { >> 236 struct parse_events_state *parse_state = _parse_state; >> 237 struct parse_events_error *error = parse_state->error; >> 238 >> 239 parse_events_error__handle(error, @2.first_column, >> 240 strdup("Bad modifier"), NULL); >> 241 free_list_evsel(list); 242 YYABORT; 242 YYABORT; >> 243 } 243 $$ = list; 244 $$ = list; 244 } 245 } 245 | 246 | 246 event_name 247 event_name 247 248 248 event_name: 249 event_name: 249 PE_EVENT_NAME event_def 250 PE_EVENT_NAME event_def 250 { 251 { 251 /* !! 252 int err; 252 * When an event is parsed the text is << 253 * the event is set to the str of PE_E << 254 * no name was on an event via a term, << 255 * taking ownership of the allocation. << 256 */ << 257 int err = parse_events__set_default_na << 258 253 >> 254 err = parse_events_name($2, $1); >> 255 free($1); 259 if (err) { 256 if (err) { 260 free_list_evsel($2); 257 free_list_evsel($2); 261 YYNOMEM; 258 YYNOMEM; 262 } 259 } 263 $$ = $2; 260 $$ = $2; 264 } 261 } 265 | 262 | 266 event_def 263 event_def 267 264 268 event_def: event_pmu | 265 event_def: event_pmu | 269 event_legacy_symbol | 266 event_legacy_symbol | 270 event_legacy_cache sep_dc | 267 event_legacy_cache sep_dc | 271 event_legacy_mem sep_dc | 268 event_legacy_mem sep_dc | 272 event_legacy_tracepoint sep_dc | 269 event_legacy_tracepoint sep_dc | 273 event_legacy_numeric sep_dc | 270 event_legacy_numeric sep_dc | 274 event_legacy_raw sep_dc 271 event_legacy_raw sep_dc 275 272 276 event_pmu: 273 event_pmu: 277 PE_NAME opt_pmu_config 274 PE_NAME opt_pmu_config 278 { 275 { >> 276 struct parse_events_state *parse_state = _parse_state; 279 /* List of created evsels. */ 277 /* List of created evsels. */ 280 struct list_head *list = NULL; 278 struct list_head *list = NULL; 281 int err = parse_events_multi_pmu_add_o !! 279 char *pattern = NULL; 282 280 283 parse_events_terms__delete($2); !! 281 #define CLEANUP \ 284 free($1); !! 282 do { \ 285 if (err) !! 283 parse_events_terms__delete($2); \ 286 PE_ABORT(err); !! 284 free(list); \ 287 $$ = list; !! 285 free($1); \ >> 286 free(pattern); \ >> 287 } while(0) >> 288 >> 289 list = alloc_list(); >> 290 if (!list) { >> 291 CLEANUP; >> 292 YYNOMEM; >> 293 } >> 294 /* Attempt to add to list assuming $1 is a PMU name. */ >> 295 if (parse_events_add_pmu(parse_state, list, $1, $2, /*auto_merge_stats=*/false, &@1)) { >> 296 struct perf_pmu *pmu = NULL; >> 297 int ok = 0; >> 298 >> 299 /* Failure to add, try wildcard expansion of $1 as a PMU name. */ >> 300 if (asprintf(&pattern, "%s*", $1) < 0) { >> 301 CLEANUP; >> 302 YYNOMEM; >> 303 } >> 304 >> 305 while ((pmu = perf_pmus__scan(pmu)) != NULL) { >> 306 const char *name = pmu->name; >> 307 >> 308 if (parse_events__filter_pmu(parse_state, pmu)) >> 309 continue; >> 310 >> 311 if (!strncmp(name, "uncore_", 7) && >> 312 strncmp($1, "uncore_", 7)) >> 313 name += 7; >> 314 if (!perf_pmu__match(pattern, name, $1) || >> 315 !perf_pmu__match(pattern, pmu->alias_name, $1)) { >> 316 bool auto_merge_stats = perf_pmu__auto_merge_stats(pmu); >> 317 >> 318 if (!parse_events_add_pmu(parse_state, list, pmu->name, $2, >> 319 auto_merge_stats, &@1)) { >> 320 ok++; >> 321 parse_state->wild_card_pmus = true; >> 322 } >> 323 } >> 324 } >> 325 >> 326 if (!ok) { >> 327 /* Failure to add, assume $1 is an event name. */ >> 328 zfree(&list); >> 329 ok = !parse_events_multi_pmu_add(parse_state, $1, $2, &list, &@1); >> 330 } >> 331 if (!ok) { >> 332 struct parse_events_error *error = parse_state->error; >> 333 char *help; >> 334 >> 335 if (asprintf(&help, "Unable to find PMU or event on a PMU of '%s'", $1) < 0) >> 336 help = NULL; >> 337 parse_events_error__handle(error, @1.first_column, >> 338 strdup("Bad event or PMU"), >> 339 help); >> 340 CLEANUP; >> 341 YYABORT; >> 342 } >> 343 } >> 344 $$ = list; >> 345 list = NULL; >> 346 CLEANUP; >> 347 #undef CLEANUP 288 } 348 } 289 | 349 | 290 PE_NAME sep_dc 350 PE_NAME sep_dc 291 { 351 { 292 struct list_head *list; 352 struct list_head *list; 293 int err; 353 int err; 294 354 295 err = parse_events_multi_pmu_add(_pars 355 err = parse_events_multi_pmu_add(_parse_state, $1, NULL, &list, &@1); 296 if (err < 0) { 356 if (err < 0) { 297 struct parse_events_state *par 357 struct parse_events_state *parse_state = _parse_state; 298 struct parse_events_error *err 358 struct parse_events_error *error = parse_state->error; 299 char *help; 359 char *help; 300 360 301 if (asprintf(&help, "Unable to 361 if (asprintf(&help, "Unable to find event on a PMU of '%s'", $1) < 0) 302 help = NULL; 362 help = NULL; 303 parse_events_error__handle(err 363 parse_events_error__handle(error, @1.first_column, strdup("Bad event name"), help); 304 free($1); 364 free($1); 305 PE_ABORT(err); 365 PE_ABORT(err); 306 } 366 } 307 free($1); 367 free($1); 308 $$ = list; 368 $$ = list; 309 } 369 } 310 370 311 value_sym: 371 value_sym: 312 PE_VALUE_SYM_HW 372 PE_VALUE_SYM_HW 313 | 373 | 314 PE_VALUE_SYM_SW 374 PE_VALUE_SYM_SW 315 375 316 event_legacy_symbol: 376 event_legacy_symbol: 317 value_sym '/' event_config '/' 377 value_sym '/' event_config '/' 318 { 378 { 319 struct list_head *list; 379 struct list_head *list; 320 int type = $1 >> 16; 380 int type = $1 >> 16; 321 int config = $1 & 255; 381 int config = $1 & 255; 322 int err; 382 int err; 323 bool wildcard = (type == PERF_TYPE_HAR 383 bool wildcard = (type == PERF_TYPE_HARDWARE || type == PERF_TYPE_HW_CACHE); 324 384 325 list = alloc_list(); 385 list = alloc_list(); 326 if (!list) 386 if (!list) 327 YYNOMEM; 387 YYNOMEM; 328 err = parse_events_add_numeric(_parse_ 388 err = parse_events_add_numeric(_parse_state, list, type, config, $3, wildcard); 329 parse_events_terms__delete($3); 389 parse_events_terms__delete($3); 330 if (err) { 390 if (err) { 331 free_list_evsel(list); 391 free_list_evsel(list); 332 PE_ABORT(err); 392 PE_ABORT(err); 333 } 393 } 334 $$ = list; 394 $$ = list; 335 } 395 } 336 | 396 | 337 value_sym sep_slash_slash_dc 397 value_sym sep_slash_slash_dc 338 { 398 { 339 struct list_head *list; 399 struct list_head *list; 340 int type = $1 >> 16; 400 int type = $1 >> 16; 341 int config = $1 & 255; 401 int config = $1 & 255; 342 bool wildcard = (type == PERF_TYPE_HAR 402 bool wildcard = (type == PERF_TYPE_HARDWARE || type == PERF_TYPE_HW_CACHE); 343 int err; 403 int err; 344 404 345 list = alloc_list(); 405 list = alloc_list(); 346 if (!list) 406 if (!list) 347 YYNOMEM; 407 YYNOMEM; 348 err = parse_events_add_numeric(_parse_ 408 err = parse_events_add_numeric(_parse_state, list, type, config, /*head_config=*/NULL, wildcard); 349 if (err) 409 if (err) 350 PE_ABORT(err); 410 PE_ABORT(err); 351 $$ = list; 411 $$ = list; 352 } 412 } 353 | 413 | 354 PE_VALUE_SYM_TOOL sep_slash_slash_dc 414 PE_VALUE_SYM_TOOL sep_slash_slash_dc 355 { 415 { 356 struct list_head *list; 416 struct list_head *list; 357 int err; 417 int err; 358 418 359 list = alloc_list(); 419 list = alloc_list(); 360 if (!list) 420 if (!list) 361 YYNOMEM; 421 YYNOMEM; 362 err = parse_events_add_tool(_parse_sta 422 err = parse_events_add_tool(_parse_state, list, $1); 363 if (err) 423 if (err) 364 YYNOMEM; 424 YYNOMEM; 365 $$ = list; 425 $$ = list; 366 } 426 } 367 427 368 event_legacy_cache: 428 event_legacy_cache: 369 PE_LEGACY_CACHE opt_event_config 429 PE_LEGACY_CACHE opt_event_config 370 { 430 { 371 struct parse_events_state *parse_state 431 struct parse_events_state *parse_state = _parse_state; 372 struct list_head *list; 432 struct list_head *list; 373 int err; 433 int err; 374 434 375 list = alloc_list(); 435 list = alloc_list(); 376 if (!list) 436 if (!list) 377 YYNOMEM; 437 YYNOMEM; 378 438 379 err = parse_events_add_cache(list, &pa 439 err = parse_events_add_cache(list, &parse_state->idx, $1, parse_state, $2); 380 440 381 parse_events_terms__delete($2); 441 parse_events_terms__delete($2); 382 free($1); 442 free($1); 383 if (err) { 443 if (err) { 384 free_list_evsel(list); 444 free_list_evsel(list); 385 PE_ABORT(err); 445 PE_ABORT(err); 386 } 446 } 387 $$ = list; 447 $$ = list; 388 } 448 } 389 449 390 event_legacy_mem: 450 event_legacy_mem: 391 PE_PREFIX_MEM PE_VALUE PE_BP_SLASH PE_VALUE PE 451 PE_PREFIX_MEM PE_VALUE PE_BP_SLASH PE_VALUE PE_BP_COLON PE_MODIFIER_BP opt_event_config 392 { 452 { 393 struct list_head *list; 453 struct list_head *list; 394 int err; 454 int err; 395 455 396 list = alloc_list(); 456 list = alloc_list(); 397 if (!list) 457 if (!list) 398 YYNOMEM; 458 YYNOMEM; 399 459 400 err = parse_events_add_breakpoint(_par 460 err = parse_events_add_breakpoint(_parse_state, list, 401 $2, 461 $2, $6, $4, $7); 402 parse_events_terms__delete($7); 462 parse_events_terms__delete($7); 403 free($6); 463 free($6); 404 if (err) { 464 if (err) { 405 free(list); 465 free(list); 406 PE_ABORT(err); 466 PE_ABORT(err); 407 } 467 } 408 $$ = list; 468 $$ = list; 409 } 469 } 410 | 470 | 411 PE_PREFIX_MEM PE_VALUE PE_BP_SLASH PE_VALUE op 471 PE_PREFIX_MEM PE_VALUE PE_BP_SLASH PE_VALUE opt_event_config 412 { 472 { 413 struct list_head *list; 473 struct list_head *list; 414 int err; 474 int err; 415 475 416 list = alloc_list(); 476 list = alloc_list(); 417 if (!list) 477 if (!list) 418 YYNOMEM; 478 YYNOMEM; 419 479 420 err = parse_events_add_breakpoint(_par 480 err = parse_events_add_breakpoint(_parse_state, list, 421 $2, 481 $2, NULL, $4, $5); 422 parse_events_terms__delete($5); 482 parse_events_terms__delete($5); 423 if (err) { 483 if (err) { 424 free(list); 484 free(list); 425 PE_ABORT(err); 485 PE_ABORT(err); 426 } 486 } 427 $$ = list; 487 $$ = list; 428 } 488 } 429 | 489 | 430 PE_PREFIX_MEM PE_VALUE PE_BP_COLON PE_MODIFIER 490 PE_PREFIX_MEM PE_VALUE PE_BP_COLON PE_MODIFIER_BP opt_event_config 431 { 491 { 432 struct list_head *list; 492 struct list_head *list; 433 int err; 493 int err; 434 494 435 list = alloc_list(); 495 list = alloc_list(); 436 if (!list) 496 if (!list) 437 YYNOMEM; 497 YYNOMEM; 438 498 439 err = parse_events_add_breakpoint(_par 499 err = parse_events_add_breakpoint(_parse_state, list, 440 $2, 500 $2, $4, 0, $5); 441 parse_events_terms__delete($5); 501 parse_events_terms__delete($5); 442 free($4); 502 free($4); 443 if (err) { 503 if (err) { 444 free(list); 504 free(list); 445 PE_ABORT(err); 505 PE_ABORT(err); 446 } 506 } 447 $$ = list; 507 $$ = list; 448 } 508 } 449 | 509 | 450 PE_PREFIX_MEM PE_VALUE opt_event_config 510 PE_PREFIX_MEM PE_VALUE opt_event_config 451 { 511 { 452 struct list_head *list; 512 struct list_head *list; 453 int err; 513 int err; 454 514 455 list = alloc_list(); 515 list = alloc_list(); 456 if (!list) 516 if (!list) 457 YYNOMEM; 517 YYNOMEM; 458 err = parse_events_add_breakpoint(_par 518 err = parse_events_add_breakpoint(_parse_state, list, 459 $2, 519 $2, NULL, 0, $3); 460 parse_events_terms__delete($3); 520 parse_events_terms__delete($3); 461 if (err) { 521 if (err) { 462 free(list); 522 free(list); 463 PE_ABORT(err); 523 PE_ABORT(err); 464 } 524 } 465 $$ = list; 525 $$ = list; 466 } 526 } 467 527 468 event_legacy_tracepoint: 528 event_legacy_tracepoint: 469 tracepoint_name opt_event_config 529 tracepoint_name opt_event_config 470 { 530 { 471 struct parse_events_state *parse_state 531 struct parse_events_state *parse_state = _parse_state; 472 struct parse_events_error *error = par 532 struct parse_events_error *error = parse_state->error; 473 struct list_head *list; 533 struct list_head *list; 474 int err; 534 int err; 475 535 476 list = alloc_list(); 536 list = alloc_list(); 477 if (!list) 537 if (!list) 478 YYNOMEM; 538 YYNOMEM; >> 539 if (error) >> 540 error->idx = @1.first_column; 479 541 480 err = parse_events_add_tracepoint(pars !! 542 err = parse_events_add_tracepoint(list, &parse_state->idx, $1.sys, $1.event, 481 error, 543 error, $2, &@1); 482 544 483 parse_events_terms__delete($2); 545 parse_events_terms__delete($2); 484 free($1.sys); 546 free($1.sys); 485 free($1.event); 547 free($1.event); 486 if (err) { 548 if (err) { 487 free(list); 549 free(list); 488 PE_ABORT(err); 550 PE_ABORT(err); 489 } 551 } 490 $$ = list; 552 $$ = list; 491 } 553 } 492 554 493 tracepoint_name: 555 tracepoint_name: 494 PE_NAME ':' PE_NAME 556 PE_NAME ':' PE_NAME 495 { 557 { 496 struct tracepoint_name tracepoint = {$ 558 struct tracepoint_name tracepoint = {$1, $3}; 497 559 498 $$ = tracepoint; 560 $$ = tracepoint; 499 } 561 } 500 562 501 event_legacy_numeric: 563 event_legacy_numeric: 502 PE_VALUE ':' PE_VALUE opt_event_config 564 PE_VALUE ':' PE_VALUE opt_event_config 503 { 565 { 504 struct list_head *list; 566 struct list_head *list; 505 int err; 567 int err; 506 568 507 list = alloc_list(); 569 list = alloc_list(); 508 if (!list) 570 if (!list) 509 YYNOMEM; 571 YYNOMEM; 510 err = parse_events_add_numeric(_parse_ 572 err = parse_events_add_numeric(_parse_state, list, (u32)$1, $3, $4, 511 /*wildc 573 /*wildcard=*/false); 512 parse_events_terms__delete($4); 574 parse_events_terms__delete($4); 513 if (err) { 575 if (err) { 514 free(list); 576 free(list); 515 PE_ABORT(err); 577 PE_ABORT(err); 516 } 578 } 517 $$ = list; 579 $$ = list; 518 } 580 } 519 581 520 event_legacy_raw: 582 event_legacy_raw: 521 PE_RAW opt_event_config 583 PE_RAW opt_event_config 522 { 584 { 523 struct list_head *list; 585 struct list_head *list; 524 int err; 586 int err; 525 u64 num; 587 u64 num; 526 588 527 list = alloc_list(); 589 list = alloc_list(); 528 if (!list) 590 if (!list) 529 YYNOMEM; 591 YYNOMEM; 530 errno = 0; 592 errno = 0; 531 num = strtoull($1 + 1, NULL, 16); 593 num = strtoull($1 + 1, NULL, 16); 532 /* Given the lexer will only give [a-f 594 /* Given the lexer will only give [a-fA-F0-9]+ a failure here should be impossible. */ 533 if (errno) 595 if (errno) 534 YYABORT; 596 YYABORT; 535 free($1); 597 free($1); 536 err = parse_events_add_numeric(_parse_ 598 err = parse_events_add_numeric(_parse_state, list, PERF_TYPE_RAW, num, $2, 537 /*wildc 599 /*wildcard=*/false); 538 parse_events_terms__delete($2); 600 parse_events_terms__delete($2); 539 if (err) { 601 if (err) { 540 free(list); 602 free(list); 541 PE_ABORT(err); 603 PE_ABORT(err); 542 } 604 } 543 $$ = list; 605 $$ = list; 544 } 606 } 545 607 546 opt_event_config: 608 opt_event_config: 547 '/' event_config '/' 609 '/' event_config '/' 548 { 610 { 549 $$ = $2; 611 $$ = $2; 550 } 612 } 551 | 613 | 552 '/' '/' 614 '/' '/' 553 { 615 { 554 $$ = NULL; 616 $$ = NULL; 555 } 617 } 556 | 618 | 557 { 619 { 558 $$ = NULL; 620 $$ = NULL; 559 } 621 } 560 622 561 opt_pmu_config: 623 opt_pmu_config: 562 '/' event_config '/' 624 '/' event_config '/' 563 { 625 { 564 $$ = $2; 626 $$ = $2; 565 } 627 } 566 | 628 | 567 '/' '/' 629 '/' '/' 568 { 630 { 569 $$ = NULL; 631 $$ = NULL; 570 } 632 } 571 633 572 start_terms: event_config 634 start_terms: event_config 573 { 635 { 574 struct parse_events_state *parse_state 636 struct parse_events_state *parse_state = _parse_state; 575 if (parse_state->terms) { 637 if (parse_state->terms) { 576 parse_events_terms__delete ($1 638 parse_events_terms__delete ($1); 577 YYABORT; 639 YYABORT; 578 } 640 } 579 parse_state->terms = $1; 641 parse_state->terms = $1; 580 } 642 } 581 643 582 event_config: 644 event_config: 583 event_config ',' event_term 645 event_config ',' event_term 584 { 646 { 585 struct parse_events_terms *head = $1; 647 struct parse_events_terms *head = $1; 586 struct parse_events_term *term = $3; 648 struct parse_events_term *term = $3; 587 649 588 if (!head) { 650 if (!head) { 589 parse_events_term__delete(term 651 parse_events_term__delete(term); 590 YYABORT; 652 YYABORT; 591 } 653 } 592 list_add_tail(&term->list, &head->term 654 list_add_tail(&term->list, &head->terms); 593 $$ = $1; 655 $$ = $1; 594 } 656 } 595 | 657 | 596 event_term 658 event_term 597 { 659 { 598 struct parse_events_terms *head = mall 660 struct parse_events_terms *head = malloc(sizeof(*head)); 599 struct parse_events_term *term = $1; 661 struct parse_events_term *term = $1; 600 662 601 if (!head) 663 if (!head) 602 YYNOMEM; 664 YYNOMEM; 603 parse_events_terms__init(head); 665 parse_events_terms__init(head); 604 list_add_tail(&term->list, &head->term 666 list_add_tail(&term->list, &head->terms); 605 $$ = head; 667 $$ = head; 606 } 668 } 607 669 608 name_or_raw: PE_RAW | PE_NAME | PE_LEGACY_CACH 670 name_or_raw: PE_RAW | PE_NAME | PE_LEGACY_CACHE 609 | << 610 PE_TERM_HW << 611 { << 612 $$ = $1.str; << 613 } << 614 671 615 event_term: 672 event_term: 616 PE_RAW 673 PE_RAW 617 { 674 { 618 struct parse_events_term *term; 675 struct parse_events_term *term; 619 int err = parse_events_term__str(&term 676 int err = parse_events_term__str(&term, PARSE_EVENTS__TERM_TYPE_RAW, 620 strdu 677 strdup("raw"), $1, &@1, &@1); 621 678 622 if (err) { 679 if (err) { 623 free($1); 680 free($1); 624 PE_ABORT(err); 681 PE_ABORT(err); 625 } 682 } 626 $$ = term; 683 $$ = term; 627 } 684 } 628 | 685 | 629 name_or_raw '=' name_or_raw 686 name_or_raw '=' name_or_raw 630 { 687 { 631 struct parse_events_term *term; 688 struct parse_events_term *term; 632 int err = parse_events_term__str(&term 689 int err = parse_events_term__str(&term, PARSE_EVENTS__TERM_TYPE_USER, $1, $3, &@1, &@3); 633 690 634 if (err) { 691 if (err) { 635 free($1); 692 free($1); 636 free($3); 693 free($3); 637 PE_ABORT(err); 694 PE_ABORT(err); 638 } 695 } 639 $$ = term; 696 $$ = term; 640 } 697 } 641 | 698 | 642 name_or_raw '=' PE_VALUE 699 name_or_raw '=' PE_VALUE 643 { 700 { 644 struct parse_events_term *term; 701 struct parse_events_term *term; 645 int err = parse_events_term__num(&term 702 int err = parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER, 646 $1, $ 703 $1, $3, /*novalue=*/false, &@1, &@3); 647 704 648 if (err) { 705 if (err) { 649 free($1); 706 free($1); 650 PE_ABORT(err); 707 PE_ABORT(err); 651 } 708 } 652 $$ = term; 709 $$ = term; 653 } 710 } 654 | 711 | >> 712 name_or_raw '=' PE_TERM_HW >> 713 { >> 714 struct parse_events_term *term; >> 715 int err = parse_events_term__str(&term, PARSE_EVENTS__TERM_TYPE_USER, >> 716 $1, $3.str, &@1, &@3); >> 717 >> 718 if (err) { >> 719 free($1); >> 720 free($3.str); >> 721 PE_ABORT(err); >> 722 } >> 723 $$ = term; >> 724 } >> 725 | 655 PE_LEGACY_CACHE 726 PE_LEGACY_CACHE 656 { 727 { 657 struct parse_events_term *term; 728 struct parse_events_term *term; 658 int err = parse_events_term__num(&term 729 int err = parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_LEGACY_CACHE, 659 $1, / 730 $1, /*num=*/1, /*novalue=*/true, &@1, /*loc_val=*/NULL); 660 731 661 if (err) { 732 if (err) { 662 free($1); 733 free($1); 663 PE_ABORT(err); 734 PE_ABORT(err); 664 } 735 } 665 $$ = term; 736 $$ = term; 666 } 737 } 667 | 738 | 668 PE_NAME 739 PE_NAME 669 { 740 { 670 struct parse_events_term *term; 741 struct parse_events_term *term; 671 int err = parse_events_term__num(&term 742 int err = parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER, 672 $1, / 743 $1, /*num=*/1, /*novalue=*/true, &@1, /*loc_val=*/NULL); 673 744 674 if (err) { 745 if (err) { 675 free($1); 746 free($1); 676 PE_ABORT(err); 747 PE_ABORT(err); 677 } 748 } 678 $$ = term; 749 $$ = term; 679 } 750 } 680 | 751 | 681 PE_TERM_HW 752 PE_TERM_HW 682 { 753 { 683 struct parse_events_term *term; 754 struct parse_events_term *term; 684 int err = parse_events_term__num(&term 755 int err = parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_HARDWARE, 685 $1.st 756 $1.str, $1.num & 255, /*novalue=*/false, 686 &@1, 757 &@1, /*loc_val=*/NULL); 687 758 688 if (err) { 759 if (err) { 689 free($1.str); 760 free($1.str); 690 PE_ABORT(err); 761 PE_ABORT(err); 691 } 762 } 692 $$ = term; 763 $$ = term; 693 } 764 } 694 | 765 | 695 PE_TERM '=' name_or_raw 766 PE_TERM '=' name_or_raw 696 { 767 { 697 struct parse_events_term *term; 768 struct parse_events_term *term; 698 int err = parse_events_term__str(&term 769 int err = parse_events_term__str(&term, $1, /*config=*/NULL, $3, &@1, &@3); 699 770 700 if (err) { 771 if (err) { 701 free($3); 772 free($3); 702 PE_ABORT(err); 773 PE_ABORT(err); 703 } 774 } 704 $$ = term; 775 $$ = term; 705 } 776 } 706 | 777 | >> 778 PE_TERM '=' PE_TERM_HW >> 779 { >> 780 struct parse_events_term *term; >> 781 int err = parse_events_term__str(&term, $1, /*config=*/NULL, $3.str, &@1, &@3); >> 782 >> 783 if (err) { >> 784 free($3.str); >> 785 PE_ABORT(err); >> 786 } >> 787 $$ = term; >> 788 } >> 789 | 707 PE_TERM '=' PE_TERM 790 PE_TERM '=' PE_TERM 708 { 791 { 709 struct parse_events_term *term; 792 struct parse_events_term *term; 710 int err = parse_events_term__term(&ter 793 int err = parse_events_term__term(&term, $1, $3, &@1, &@3); 711 794 712 if (err) 795 if (err) 713 PE_ABORT(err); 796 PE_ABORT(err); 714 797 715 $$ = term; 798 $$ = term; 716 } 799 } 717 | 800 | 718 PE_TERM '=' PE_VALUE 801 PE_TERM '=' PE_VALUE 719 { 802 { 720 struct parse_events_term *term; 803 struct parse_events_term *term; 721 int err = parse_events_term__num(&term 804 int err = parse_events_term__num(&term, $1, 722 /*con 805 /*config=*/NULL, $3, /*novalue=*/false, 723 &@1, 806 &@1, &@3); 724 807 725 if (err) 808 if (err) 726 PE_ABORT(err); 809 PE_ABORT(err); 727 810 728 $$ = term; 811 $$ = term; 729 } 812 } 730 | 813 | 731 PE_TERM 814 PE_TERM 732 { 815 { 733 struct parse_events_term *term; 816 struct parse_events_term *term; 734 int err = parse_events_term__num(&term 817 int err = parse_events_term__num(&term, $1, 735 /*con 818 /*config=*/NULL, /*num=*/1, /*novalue=*/true, 736 &@1, 819 &@1, /*loc_val=*/NULL); 737 820 738 if (err) 821 if (err) 739 PE_ABORT(err); 822 PE_ABORT(err); 740 823 741 $$ = term; 824 $$ = term; 742 } 825 } 743 | 826 | 744 PE_DRV_CFG_TERM 827 PE_DRV_CFG_TERM 745 { 828 { 746 struct parse_events_term *term; 829 struct parse_events_term *term; 747 char *config = strdup($1); 830 char *config = strdup($1); 748 int err; 831 int err; 749 832 750 if (!config) 833 if (!config) 751 YYNOMEM; 834 YYNOMEM; 752 err = parse_events_term__str(&term, PA 835 err = parse_events_term__str(&term, PARSE_EVENTS__TERM_TYPE_DRV_CFG, config, $1, &@1, NULL); 753 if (err) { 836 if (err) { 754 free($1); 837 free($1); 755 free(config); 838 free(config); 756 PE_ABORT(err); 839 PE_ABORT(err); 757 } 840 } 758 $$ = term; 841 $$ = term; 759 } 842 } 760 843 761 sep_dc: ':' | 844 sep_dc: ':' | 762 845 763 sep_slash_slash_dc: '/' '/' | ':' | 846 sep_slash_slash_dc: '/' '/' | ':' | 764 847 765 %% 848 %% 766 849 767 void parse_events_error(YYLTYPE *loc, void *_p !! 850 void parse_events_error(YYLTYPE *loc, void *parse_state, 768 void *scanner __maybe_ 851 void *scanner __maybe_unused, 769 char const *msg __mayb 852 char const *msg __maybe_unused) 770 { 853 { 771 struct parse_events_state *parse_state !! 854 parse_events_evlist_error(parse_state, loc->last_column, "parser error"); 772 << 773 if (!parse_state->error || !list_empty << 774 return; << 775 << 776 parse_events_error__handle(parse_state << 777 strdup("Unr << 778 } 855 }
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.