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