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