parse-events.y 7.9 KB

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