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