parse-events.y 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454
  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 <linux/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 ':' PE_NAME
  261. {
  262. struct parse_events_evlist *data = _data;
  263. struct list_head *list;
  264. char sys_name[128];
  265. snprintf(&sys_name, 128, "%s-%s", $1, $3);
  266. ALLOC_LIST(list);
  267. ABORT_ON(parse_events_add_tracepoint(list, &data->idx, &sys_name, $5));
  268. $$ = list;
  269. }
  270. |
  271. PE_NAME ':' PE_NAME
  272. {
  273. struct parse_events_evlist *data = _data;
  274. struct list_head *list;
  275. ALLOC_LIST(list);
  276. ABORT_ON(parse_events_add_tracepoint(list, &data->idx, $1, $3));
  277. $$ = list;
  278. }
  279. event_legacy_numeric:
  280. PE_VALUE ':' PE_VALUE
  281. {
  282. struct parse_events_evlist *data = _data;
  283. struct list_head *list;
  284. ALLOC_LIST(list);
  285. ABORT_ON(parse_events_add_numeric(list, &data->idx, (u32)$1, $3, NULL));
  286. $$ = list;
  287. }
  288. event_legacy_raw:
  289. PE_RAW
  290. {
  291. struct parse_events_evlist *data = _data;
  292. struct list_head *list;
  293. ALLOC_LIST(list);
  294. ABORT_ON(parse_events_add_numeric(list, &data->idx,
  295. PERF_TYPE_RAW, $1, NULL));
  296. $$ = list;
  297. }
  298. start_terms: event_config
  299. {
  300. struct parse_events_terms *data = _data;
  301. data->terms = $1;
  302. }
  303. event_config:
  304. event_config ',' event_term
  305. {
  306. struct list_head *head = $1;
  307. struct parse_events_term *term = $3;
  308. ABORT_ON(!head);
  309. list_add_tail(&term->list, head);
  310. $$ = $1;
  311. }
  312. |
  313. event_term
  314. {
  315. struct list_head *head = malloc(sizeof(*head));
  316. struct parse_events_term *term = $1;
  317. ABORT_ON(!head);
  318. INIT_LIST_HEAD(head);
  319. list_add_tail(&term->list, head);
  320. $$ = head;
  321. }
  322. event_term:
  323. PE_NAME '=' PE_NAME
  324. {
  325. struct parse_events_term *term;
  326. ABORT_ON(parse_events_term__str(&term, PARSE_EVENTS__TERM_TYPE_USER,
  327. $1, $3));
  328. $$ = term;
  329. }
  330. |
  331. PE_NAME '=' PE_VALUE
  332. {
  333. struct parse_events_term *term;
  334. ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER,
  335. $1, $3));
  336. $$ = term;
  337. }
  338. |
  339. PE_NAME '=' PE_VALUE_SYM_HW
  340. {
  341. struct parse_events_term *term;
  342. int config = $3 & 255;
  343. ABORT_ON(parse_events_term__sym_hw(&term, $1, config));
  344. $$ = term;
  345. }
  346. |
  347. PE_NAME
  348. {
  349. struct parse_events_term *term;
  350. ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER,
  351. $1, 1));
  352. $$ = term;
  353. }
  354. |
  355. PE_VALUE_SYM_HW
  356. {
  357. struct parse_events_term *term;
  358. int config = $1 & 255;
  359. ABORT_ON(parse_events_term__sym_hw(&term, NULL, config));
  360. $$ = term;
  361. }
  362. |
  363. PE_TERM '=' PE_NAME
  364. {
  365. struct parse_events_term *term;
  366. ABORT_ON(parse_events_term__str(&term, (int)$1, NULL, $3));
  367. $$ = term;
  368. }
  369. |
  370. PE_TERM '=' PE_VALUE
  371. {
  372. struct parse_events_term *term;
  373. ABORT_ON(parse_events_term__num(&term, (int)$1, NULL, $3));
  374. $$ = term;
  375. }
  376. |
  377. PE_TERM
  378. {
  379. struct parse_events_term *term;
  380. ABORT_ON(parse_events_term__num(&term, (int)$1, NULL, 1));
  381. $$ = term;
  382. }
  383. sep_dc: ':' |
  384. sep_slash_dc: '/' | ':' |
  385. %%
  386. void parse_events_error(void *data __maybe_unused, void *scanner __maybe_unused,
  387. char const *msg __maybe_unused)
  388. {
  389. }