parse-events.y 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647
  1. %define api.pure full
  2. %parse-param {void *_parse_state}
  3. %parse-param {void *scanner}
  4. %lex-param {void* scanner}
  5. %locations
  6. %{
  7. #ifndef NDEBUG
  8. #define YYDEBUG 1
  9. #endif
  10. #include <errno.h>
  11. #include <linux/compiler.h>
  12. #include <linux/types.h>
  13. #include "pmu.h"
  14. #include "pmus.h"
  15. #include "evsel.h"
  16. #include "parse-events.h"
  17. #include "parse-events-bison.h"
  18. int parse_events_lex(YYSTYPE * yylval_param, YYLTYPE * yylloc_param , void *yyscanner);
  19. void parse_events_error(YYLTYPE *loc, void *parse_state, void *scanner, char const *msg);
  20. #define PE_ABORT(val) \
  21. do { \
  22. if (val == -ENOMEM) \
  23. YYNOMEM; \
  24. YYABORT; \
  25. } while (0)
  26. static struct list_head* alloc_list(void)
  27. {
  28. struct list_head *list;
  29. list = malloc(sizeof(*list));
  30. if (!list)
  31. return NULL;
  32. INIT_LIST_HEAD(list);
  33. return list;
  34. }
  35. static void free_list_evsel(struct list_head* list_evsel)
  36. {
  37. struct evsel *evsel, *tmp;
  38. list_for_each_entry_safe(evsel, tmp, list_evsel, core.node) {
  39. list_del_init(&evsel->core.node);
  40. evsel__delete(evsel);
  41. }
  42. free(list_evsel);
  43. }
  44. %}
  45. %token PE_START_EVENTS PE_START_TERMS
  46. %token PE_VALUE PE_TERM
  47. %token PE_EVENT_NAME
  48. %token PE_RAW PE_NAME
  49. %token PE_MODIFIER_EVENT PE_MODIFIER_BP PE_BP_COLON PE_BP_SLASH
  50. %token PE_PREFIX_MEM
  51. %token PE_ERROR
  52. %token PE_DRV_CFG_TERM
  53. %type <num> PE_VALUE
  54. %type <mod> PE_MODIFIER_EVENT
  55. %type <term_type> PE_TERM
  56. %type <str> PE_RAW
  57. %type <str> PE_NAME
  58. %type <str> PE_MODIFIER_BP
  59. %type <str> PE_EVENT_NAME
  60. %type <str> PE_DRV_CFG_TERM
  61. %type <str> name_or_raw
  62. %destructor { free ($$); } <str>
  63. %type <term> event_term
  64. %destructor { parse_events_term__delete ($$); } <term>
  65. %type <list_terms> event_config
  66. %type <list_terms> opt_event_config
  67. %type <list_terms> opt_pmu_config
  68. %destructor { parse_events_terms__delete ($$); } <list_terms>
  69. %type <list_evsel> event_pmu
  70. %type <list_evsel> event_legacy_mem
  71. %type <list_evsel> event_legacy_tracepoint
  72. %type <list_evsel> event_legacy_numeric
  73. %type <list_evsel> event_legacy_raw
  74. %type <list_evsel> event_def
  75. %type <list_evsel> event_mod
  76. %type <list_evsel> event_name
  77. %type <list_evsel> event
  78. %type <list_evsel> events
  79. %type <list_evsel> group_def
  80. %type <list_evsel> group
  81. %type <list_evsel> groups
  82. %destructor { free_list_evsel ($$); } <list_evsel>
  83. %type <tracepoint_name> tracepoint_name
  84. %destructor { free ($$.sys); free ($$.event); } <tracepoint_name>
  85. %union
  86. {
  87. char *str;
  88. u64 num;
  89. struct parse_events_modifier mod;
  90. enum parse_events__term_type term_type;
  91. struct list_head *list_evsel;
  92. struct parse_events_terms *list_terms;
  93. struct parse_events_term *term;
  94. struct tracepoint_name {
  95. char *sys;
  96. char *event;
  97. } tracepoint_name;
  98. }
  99. %%
  100. /*
  101. * Entry points. We are either parsing events or terminals. Just terminal
  102. * parsing is used for parsing events in sysfs.
  103. */
  104. start:
  105. PE_START_EVENTS start_events
  106. |
  107. PE_START_TERMS start_terms
  108. start_events: groups
  109. {
  110. /* Take the parsed events, groups.. and place into parse_state. */
  111. struct list_head *groups = $1;
  112. struct parse_events_state *parse_state = _parse_state;
  113. list_splice_tail(groups, &parse_state->list);
  114. free(groups);
  115. }
  116. groups: /* A list of groups or events. */
  117. groups ',' group
  118. {
  119. /* Merge group into the list of events/groups. */
  120. struct list_head *groups = $1;
  121. struct list_head *group = $3;
  122. list_splice_tail(group, groups);
  123. free(group);
  124. $$ = groups;
  125. }
  126. |
  127. groups ',' event
  128. {
  129. /* Merge event into the list of events/groups. */
  130. struct list_head *groups = $1;
  131. struct list_head *event = $3;
  132. list_splice_tail(event, groups);
  133. free(event);
  134. $$ = groups;
  135. }
  136. |
  137. group
  138. |
  139. event
  140. group:
  141. group_def ':' PE_MODIFIER_EVENT
  142. {
  143. /* Apply the modifier to the events in the group_def. */
  144. struct list_head *list = $1;
  145. int err;
  146. err = parse_events__modifier_group(_parse_state, &@3, list, $3);
  147. if (err)
  148. YYABORT;
  149. $$ = list;
  150. }
  151. |
  152. group_def
  153. group_def:
  154. PE_NAME '{' events '}'
  155. {
  156. struct list_head *list = $3;
  157. /*
  158. * Set the first entry of list to be the leader. Set the group name on
  159. * the leader to $1 taking ownership.
  160. */
  161. parse_events__set_leader($1, list);
  162. $$ = list;
  163. }
  164. |
  165. '{' events '}'
  166. {
  167. struct list_head *list = $2;
  168. /* Set the first entry of list to be the leader clearing the group name. */
  169. parse_events__set_leader(NULL, list);
  170. $$ = list;
  171. }
  172. events:
  173. events ',' event
  174. {
  175. struct list_head *events = $1;
  176. struct list_head *event = $3;
  177. list_splice_tail(event, events);
  178. free(event);
  179. $$ = events;
  180. }
  181. |
  182. event
  183. event: event_mod
  184. event_mod:
  185. event_name PE_MODIFIER_EVENT
  186. {
  187. struct list_head *list = $1;
  188. int err;
  189. /*
  190. * Apply modifier on all events added by single event definition
  191. * (there could be more events added for multiple tracepoint
  192. * definitions via '*?'.
  193. */
  194. err = parse_events__modifier_event(_parse_state, &@2, list, $2);
  195. if (err)
  196. YYABORT;
  197. $$ = list;
  198. }
  199. |
  200. event_name
  201. event_name:
  202. PE_EVENT_NAME event_def
  203. {
  204. /*
  205. * When an event is parsed the text is rewound and the entire text of
  206. * the event is set to the str of PE_EVENT_NAME token matched here. If
  207. * no name was on an event via a term, set the name to the entire text
  208. * taking ownership of the allocation.
  209. */
  210. int err = parse_events__set_default_name($2, $1);
  211. if (err) {
  212. free_list_evsel($2);
  213. YYNOMEM;
  214. }
  215. $$ = $2;
  216. }
  217. |
  218. event_def
  219. event_def: event_pmu |
  220. event_legacy_mem sep_dc |
  221. event_legacy_tracepoint sep_dc |
  222. event_legacy_numeric sep_dc |
  223. event_legacy_raw sep_dc
  224. event_pmu:
  225. PE_NAME opt_pmu_config
  226. {
  227. /* List of created evsels. */
  228. struct list_head *list = NULL;
  229. int err = parse_events_multi_pmu_add_or_add_pmu(_parse_state, $1, $2, &list, &@1);
  230. parse_events_terms__delete($2);
  231. free($1);
  232. if (err)
  233. PE_ABORT(err);
  234. $$ = list;
  235. }
  236. |
  237. PE_NAME sep_dc
  238. {
  239. struct list_head *list;
  240. int err;
  241. err = parse_events_multi_pmu_add(_parse_state, $1, /*const_parsed_terms*/NULL, &list, &@1);
  242. if (err < 0) {
  243. struct parse_events_state *parse_state = _parse_state;
  244. struct parse_events_error *error = parse_state->error;
  245. char *help;
  246. if (asprintf(&help, "Unable to find event on a PMU of '%s'", $1) < 0)
  247. help = NULL;
  248. parse_events_error__handle(error, @1.first_column, strdup("Bad event name"), help);
  249. free($1);
  250. PE_ABORT(err);
  251. }
  252. free($1);
  253. $$ = list;
  254. }
  255. event_legacy_mem:
  256. PE_PREFIX_MEM PE_VALUE PE_BP_SLASH PE_VALUE PE_BP_COLON PE_MODIFIER_BP opt_event_config
  257. {
  258. struct list_head *list;
  259. int err;
  260. list = alloc_list();
  261. if (!list)
  262. YYNOMEM;
  263. err = parse_events_add_breakpoint(_parse_state, list,
  264. $2, $6, $4, $7);
  265. parse_events_terms__delete($7);
  266. free($6);
  267. if (err) {
  268. free(list);
  269. PE_ABORT(err);
  270. }
  271. $$ = list;
  272. }
  273. |
  274. PE_PREFIX_MEM PE_VALUE PE_BP_SLASH PE_VALUE opt_event_config
  275. {
  276. struct list_head *list;
  277. int err;
  278. list = alloc_list();
  279. if (!list)
  280. YYNOMEM;
  281. err = parse_events_add_breakpoint(_parse_state, list,
  282. $2, NULL, $4, $5);
  283. parse_events_terms__delete($5);
  284. if (err) {
  285. free(list);
  286. PE_ABORT(err);
  287. }
  288. $$ = list;
  289. }
  290. |
  291. PE_PREFIX_MEM PE_VALUE PE_BP_COLON PE_MODIFIER_BP opt_event_config
  292. {
  293. struct list_head *list;
  294. int err;
  295. list = alloc_list();
  296. if (!list)
  297. YYNOMEM;
  298. err = parse_events_add_breakpoint(_parse_state, list,
  299. $2, $4, 0, $5);
  300. parse_events_terms__delete($5);
  301. free($4);
  302. if (err) {
  303. free(list);
  304. PE_ABORT(err);
  305. }
  306. $$ = list;
  307. }
  308. |
  309. PE_PREFIX_MEM PE_VALUE opt_event_config
  310. {
  311. struct list_head *list;
  312. int err;
  313. list = alloc_list();
  314. if (!list)
  315. YYNOMEM;
  316. err = parse_events_add_breakpoint(_parse_state, list,
  317. $2, NULL, 0, $3);
  318. parse_events_terms__delete($3);
  319. if (err) {
  320. free(list);
  321. PE_ABORT(err);
  322. }
  323. $$ = list;
  324. }
  325. event_legacy_tracepoint:
  326. tracepoint_name opt_event_config
  327. {
  328. struct parse_events_state *parse_state = _parse_state;
  329. struct parse_events_error *error = parse_state->error;
  330. struct list_head *list;
  331. int err;
  332. list = alloc_list();
  333. if (!list)
  334. YYNOMEM;
  335. err = parse_events_add_tracepoint(parse_state, list, $1.sys, $1.event,
  336. error, $2, &@1);
  337. parse_events_terms__delete($2);
  338. free($1.sys);
  339. free($1.event);
  340. if (err) {
  341. free(list);
  342. PE_ABORT(err);
  343. }
  344. $$ = list;
  345. }
  346. tracepoint_name:
  347. PE_NAME ':' PE_NAME
  348. {
  349. struct tracepoint_name tracepoint = {$1, $3};
  350. $$ = tracepoint;
  351. }
  352. event_legacy_numeric:
  353. PE_VALUE ':' PE_VALUE opt_event_config
  354. {
  355. struct list_head *list;
  356. int err;
  357. list = alloc_list();
  358. if (!list)
  359. YYNOMEM;
  360. err = parse_events_add_numeric(_parse_state, list, (u32)$1, $3, $4,
  361. /*wildcard=*/false);
  362. parse_events_terms__delete($4);
  363. if (err) {
  364. free(list);
  365. PE_ABORT(err);
  366. }
  367. $$ = list;
  368. }
  369. event_legacy_raw:
  370. PE_RAW opt_event_config
  371. {
  372. struct list_head *list;
  373. int err;
  374. u64 num;
  375. list = alloc_list();
  376. if (!list)
  377. YYNOMEM;
  378. errno = 0;
  379. num = strtoull($1 + 1, NULL, 16);
  380. /* Given the lexer will only give [a-fA-F0-9]+ a failure here should be impossible. */
  381. if (errno)
  382. YYABORT;
  383. free($1);
  384. err = parse_events_add_numeric(_parse_state, list, PERF_TYPE_RAW, num, $2,
  385. /*wildcard=*/false);
  386. parse_events_terms__delete($2);
  387. if (err) {
  388. free(list);
  389. PE_ABORT(err);
  390. }
  391. $$ = list;
  392. }
  393. opt_event_config:
  394. '/' event_config '/'
  395. {
  396. $$ = $2;
  397. }
  398. |
  399. '/' '/'
  400. {
  401. $$ = NULL;
  402. }
  403. |
  404. {
  405. $$ = NULL;
  406. }
  407. opt_pmu_config:
  408. '/' event_config '/'
  409. {
  410. $$ = $2;
  411. }
  412. |
  413. '/' '/'
  414. {
  415. $$ = NULL;
  416. }
  417. start_terms: event_config
  418. {
  419. struct parse_events_state *parse_state = _parse_state;
  420. if (parse_state->terms) {
  421. parse_events_terms__delete ($1);
  422. YYABORT;
  423. }
  424. parse_state->terms = $1;
  425. }
  426. event_config:
  427. event_config ',' event_term
  428. {
  429. struct parse_events_terms *head = $1;
  430. struct parse_events_term *term = $3;
  431. if (!head) {
  432. parse_events_term__delete(term);
  433. YYABORT;
  434. }
  435. list_add_tail(&term->list, &head->terms);
  436. $$ = $1;
  437. }
  438. |
  439. event_term
  440. {
  441. struct parse_events_terms *head = malloc(sizeof(*head));
  442. struct parse_events_term *term = $1;
  443. if (!head)
  444. YYNOMEM;
  445. parse_events_terms__init(head);
  446. list_add_tail(&term->list, &head->terms);
  447. $$ = head;
  448. }
  449. name_or_raw: PE_RAW | PE_NAME
  450. event_term:
  451. PE_RAW
  452. {
  453. struct parse_events_term *term;
  454. int err = parse_events_term__str(&term, PARSE_EVENTS__TERM_TYPE_RAW,
  455. strdup("raw"), $1, &@1, &@1);
  456. if (err) {
  457. free($1);
  458. PE_ABORT(err);
  459. }
  460. $$ = term;
  461. }
  462. |
  463. name_or_raw '=' name_or_raw
  464. {
  465. struct parse_events_term *term;
  466. int err = parse_events_term__str(&term, PARSE_EVENTS__TERM_TYPE_USER, $1, $3, &@1, &@3);
  467. if (err) {
  468. free($1);
  469. free($3);
  470. PE_ABORT(err);
  471. }
  472. $$ = term;
  473. }
  474. |
  475. name_or_raw '=' PE_VALUE
  476. {
  477. struct parse_events_term *term;
  478. int err = parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER,
  479. $1, $3, /*novalue=*/false, &@1, &@3);
  480. if (err) {
  481. free($1);
  482. PE_ABORT(err);
  483. }
  484. $$ = term;
  485. }
  486. |
  487. PE_NAME
  488. {
  489. struct parse_events_term *term;
  490. int err = parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER,
  491. $1, /*num=*/1, /*novalue=*/true, &@1, /*loc_val=*/NULL);
  492. if (err) {
  493. free($1);
  494. PE_ABORT(err);
  495. }
  496. $$ = term;
  497. }
  498. |
  499. PE_TERM '=' name_or_raw
  500. {
  501. struct parse_events_term *term;
  502. int err = parse_events_term__str(&term, $1, /*config=*/NULL, $3, &@1, &@3);
  503. if (err) {
  504. free($3);
  505. PE_ABORT(err);
  506. }
  507. $$ = term;
  508. }
  509. |
  510. PE_TERM '=' PE_TERM
  511. {
  512. struct parse_events_term *term;
  513. int err = parse_events_term__term(&term, $1, $3, &@1, &@3);
  514. if (err)
  515. PE_ABORT(err);
  516. $$ = term;
  517. }
  518. |
  519. PE_TERM '=' PE_VALUE
  520. {
  521. struct parse_events_term *term;
  522. int err = parse_events_term__num(&term, $1,
  523. /*config=*/NULL, $3, /*novalue=*/false,
  524. &@1, &@3);
  525. if (err)
  526. PE_ABORT(err);
  527. $$ = term;
  528. }
  529. |
  530. PE_TERM
  531. {
  532. struct parse_events_term *term;
  533. int err = parse_events_term__num(&term, $1,
  534. /*config=*/NULL, /*num=*/1, /*novalue=*/true,
  535. &@1, /*loc_val=*/NULL);
  536. if (err)
  537. PE_ABORT(err);
  538. $$ = term;
  539. }
  540. |
  541. PE_DRV_CFG_TERM
  542. {
  543. struct parse_events_term *term;
  544. char *config = strdup($1);
  545. int err;
  546. if (!config)
  547. YYNOMEM;
  548. err = parse_events_term__str(&term, PARSE_EVENTS__TERM_TYPE_DRV_CFG, config, $1, &@1, NULL);
  549. if (err) {
  550. free($1);
  551. free(config);
  552. PE_ABORT(err);
  553. }
  554. $$ = term;
  555. }
  556. sep_dc: ':' |
  557. %%
  558. void parse_events_error(YYLTYPE *loc, void *_parse_state,
  559. void *scanner __maybe_unused,
  560. char const *msg __maybe_unused)
  561. {
  562. struct parse_events_state *parse_state = _parse_state;
  563. if (!parse_state->error || !list_empty(&parse_state->error->list))
  564. return;
  565. parse_events_error__handle(parse_state->error, loc->last_column,
  566. strdup("Unrecognized input"), NULL);
  567. }