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