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