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