• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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