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