PageRenderTime 53ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 0ms

/tools/perf/util/parse-events.y

https://gitlab.com/felipe_artur/linux-stable
Happy | 672 lines | 584 code | 88 blank | 0 comment | 0 complexity | dca5a40bbc1a30c650e60188bcd0f0b1 MD5 | raw file
  1. %pure-parser
  2. %parse-param {void *_data}
  3. %parse-param {void *scanner}
  4. %lex-param {void* scanner}
  5. %locations
  6. %{
  7. #define YYDEBUG 1
  8. #include <linux/compiler.h>
  9. #include <linux/list.h>
  10. #include <linux/types.h>
  11. #include "util.h"
  12. #include "parse-events.h"
  13. #include "parse-events-bison.h"
  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 void 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_BPF_OBJECT PE_BPF_SOURCE
  38. %token PE_MODIFIER_EVENT PE_MODIFIER_BP
  39. %token PE_NAME_CACHE_TYPE PE_NAME_CACHE_OP_RESULT
  40. %token PE_PREFIX_MEM PE_PREFIX_RAW PE_PREFIX_GROUP
  41. %token PE_ERROR
  42. %token PE_PMU_EVENT_PRE PE_PMU_EVENT_SUF PE_KERNEL_PMU_EVENT
  43. %token PE_ARRAY_ALL PE_ARRAY_RANGE
  44. %type <num> PE_VALUE
  45. %type <num> PE_VALUE_SYM_HW
  46. %type <num> PE_VALUE_SYM_SW
  47. %type <num> PE_RAW
  48. %type <num> PE_TERM
  49. %type <str> PE_NAME
  50. %type <str> PE_BPF_OBJECT
  51. %type <str> PE_BPF_SOURCE
  52. %type <str> PE_NAME_CACHE_TYPE
  53. %type <str> PE_NAME_CACHE_OP_RESULT
  54. %type <str> PE_MODIFIER_EVENT
  55. %type <str> PE_MODIFIER_BP
  56. %type <str> PE_EVENT_NAME
  57. %type <str> PE_PMU_EVENT_PRE PE_PMU_EVENT_SUF PE_KERNEL_PMU_EVENT
  58. %type <num> value_sym
  59. %type <head> event_config
  60. %type <head> opt_event_config
  61. %type <term> event_term
  62. %type <head> event_pmu
  63. %type <head> event_legacy_symbol
  64. %type <head> event_legacy_cache
  65. %type <head> event_legacy_mem
  66. %type <head> event_legacy_tracepoint
  67. %type <tracepoint_name> tracepoint_name
  68. %type <head> event_legacy_numeric
  69. %type <head> event_legacy_raw
  70. %type <head> event_bpf_file
  71. %type <head> event_def
  72. %type <head> event_mod
  73. %type <head> event_name
  74. %type <head> event
  75. %type <head> events
  76. %type <head> group_def
  77. %type <head> group
  78. %type <head> groups
  79. %type <array> array
  80. %type <array> array_term
  81. %type <array> array_terms
  82. %union
  83. {
  84. char *str;
  85. u64 num;
  86. struct list_head *head;
  87. struct parse_events_term *term;
  88. struct tracepoint_name {
  89. char *sys;
  90. char *event;
  91. } tracepoint_name;
  92. struct parse_events_array array;
  93. }
  94. %%
  95. start:
  96. PE_START_EVENTS start_events
  97. |
  98. PE_START_TERMS start_terms
  99. start_events: groups
  100. {
  101. struct parse_events_evlist *data = _data;
  102. parse_events_update_lists($1, &data->list);
  103. }
  104. groups:
  105. groups ',' group
  106. {
  107. struct list_head *list = $1;
  108. struct list_head *group = $3;
  109. parse_events_update_lists(group, list);
  110. $$ = list;
  111. }
  112. |
  113. groups ',' event
  114. {
  115. struct list_head *list = $1;
  116. struct list_head *event = $3;
  117. parse_events_update_lists(event, list);
  118. $$ = list;
  119. }
  120. |
  121. group
  122. |
  123. event
  124. group:
  125. group_def ':' PE_MODIFIER_EVENT
  126. {
  127. struct list_head *list = $1;
  128. ABORT_ON(parse_events__modifier_group(list, $3));
  129. $$ = list;
  130. }
  131. |
  132. group_def
  133. group_def:
  134. PE_NAME '{' events '}'
  135. {
  136. struct list_head *list = $3;
  137. inc_group_count(list, _data);
  138. parse_events__set_leader($1, list);
  139. $$ = list;
  140. }
  141. |
  142. '{' events '}'
  143. {
  144. struct list_head *list = $2;
  145. inc_group_count(list, _data);
  146. parse_events__set_leader(NULL, list);
  147. $$ = list;
  148. }
  149. events:
  150. events ',' event
  151. {
  152. struct list_head *event = $3;
  153. struct list_head *list = $1;
  154. parse_events_update_lists(event, list);
  155. $$ = list;
  156. }
  157. |
  158. event
  159. event: event_mod
  160. event_mod:
  161. event_name PE_MODIFIER_EVENT
  162. {
  163. struct list_head *list = $1;
  164. /*
  165. * Apply modifier on all events added by single event definition
  166. * (there could be more events added for multiple tracepoint
  167. * definitions via '*?'.
  168. */
  169. ABORT_ON(parse_events__modifier_event(list, $2, false));
  170. $$ = list;
  171. }
  172. |
  173. event_name
  174. event_name:
  175. PE_EVENT_NAME event_def
  176. {
  177. ABORT_ON(parse_events_name($2, $1));
  178. free($1);
  179. $$ = $2;
  180. }
  181. |
  182. event_def
  183. event_def: event_pmu |
  184. event_legacy_symbol |
  185. event_legacy_cache sep_dc |
  186. event_legacy_mem |
  187. event_legacy_tracepoint sep_dc |
  188. event_legacy_numeric sep_dc |
  189. event_legacy_raw sep_dc |
  190. event_bpf_file
  191. event_pmu:
  192. PE_NAME opt_event_config
  193. {
  194. struct parse_events_evlist *data = _data;
  195. struct list_head *list;
  196. ALLOC_LIST(list);
  197. ABORT_ON(parse_events_add_pmu(data, list, $1, $2));
  198. parse_events_terms__delete($2);
  199. $$ = list;
  200. }
  201. |
  202. PE_KERNEL_PMU_EVENT sep_dc
  203. {
  204. struct parse_events_evlist *data = _data;
  205. struct list_head *head;
  206. struct parse_events_term *term;
  207. struct list_head *list;
  208. ALLOC_LIST(head);
  209. ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER,
  210. $1, 1, &@1, NULL));
  211. list_add_tail(&term->list, head);
  212. ALLOC_LIST(list);
  213. ABORT_ON(parse_events_add_pmu(data, list, "cpu", head));
  214. parse_events_terms__delete(head);
  215. $$ = list;
  216. }
  217. |
  218. PE_PMU_EVENT_PRE '-' PE_PMU_EVENT_SUF sep_dc
  219. {
  220. struct parse_events_evlist *data = _data;
  221. struct list_head *head;
  222. struct parse_events_term *term;
  223. struct list_head *list;
  224. char pmu_name[128];
  225. snprintf(&pmu_name, 128, "%s-%s", $1, $3);
  226. ALLOC_LIST(head);
  227. ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER,
  228. &pmu_name, 1, &@1, NULL));
  229. list_add_tail(&term->list, head);
  230. ALLOC_LIST(list);
  231. ABORT_ON(parse_events_add_pmu(data, list, "cpu", head));
  232. parse_events_terms__delete(head);
  233. $$ = list;
  234. }
  235. value_sym:
  236. PE_VALUE_SYM_HW
  237. |
  238. PE_VALUE_SYM_SW
  239. event_legacy_symbol:
  240. value_sym '/' event_config '/'
  241. {
  242. struct parse_events_evlist *data = _data;
  243. struct list_head *list;
  244. int type = $1 >> 16;
  245. int config = $1 & 255;
  246. ALLOC_LIST(list);
  247. ABORT_ON(parse_events_add_numeric(data, list, type, config, $3));
  248. parse_events_terms__delete($3);
  249. $$ = list;
  250. }
  251. |
  252. value_sym sep_slash_dc
  253. {
  254. struct parse_events_evlist *data = _data;
  255. struct list_head *list;
  256. int type = $1 >> 16;
  257. int config = $1 & 255;
  258. ALLOC_LIST(list);
  259. ABORT_ON(parse_events_add_numeric(data, list, type, config, NULL));
  260. $$ = list;
  261. }
  262. event_legacy_cache:
  263. PE_NAME_CACHE_TYPE '-' PE_NAME_CACHE_OP_RESULT '-' PE_NAME_CACHE_OP_RESULT opt_event_config
  264. {
  265. struct parse_events_evlist *data = _data;
  266. struct parse_events_error *error = data->error;
  267. struct list_head *list;
  268. ALLOC_LIST(list);
  269. ABORT_ON(parse_events_add_cache(list, &data->idx, $1, $3, $5, error, $6));
  270. parse_events_terms__delete($6);
  271. $$ = list;
  272. }
  273. |
  274. PE_NAME_CACHE_TYPE '-' PE_NAME_CACHE_OP_RESULT opt_event_config
  275. {
  276. struct parse_events_evlist *data = _data;
  277. struct parse_events_error *error = data->error;
  278. struct list_head *list;
  279. ALLOC_LIST(list);
  280. ABORT_ON(parse_events_add_cache(list, &data->idx, $1, $3, NULL, error, $4));
  281. parse_events_terms__delete($4);
  282. $$ = list;
  283. }
  284. |
  285. PE_NAME_CACHE_TYPE opt_event_config
  286. {
  287. struct parse_events_evlist *data = _data;
  288. struct parse_events_error *error = data->error;
  289. struct list_head *list;
  290. ALLOC_LIST(list);
  291. ABORT_ON(parse_events_add_cache(list, &data->idx, $1, NULL, NULL, error, $2));
  292. parse_events_terms__delete($2);
  293. $$ = list;
  294. }
  295. event_legacy_mem:
  296. PE_PREFIX_MEM PE_VALUE '/' PE_VALUE ':' PE_MODIFIER_BP sep_dc
  297. {
  298. struct parse_events_evlist *data = _data;
  299. struct list_head *list;
  300. ALLOC_LIST(list);
  301. ABORT_ON(parse_events_add_breakpoint(list, &data->idx,
  302. (void *) $2, $6, $4));
  303. $$ = list;
  304. }
  305. |
  306. PE_PREFIX_MEM PE_VALUE '/' PE_VALUE sep_dc
  307. {
  308. struct parse_events_evlist *data = _data;
  309. struct list_head *list;
  310. ALLOC_LIST(list);
  311. ABORT_ON(parse_events_add_breakpoint(list, &data->idx,
  312. (void *) $2, NULL, $4));
  313. $$ = list;
  314. }
  315. |
  316. PE_PREFIX_MEM PE_VALUE ':' PE_MODIFIER_BP sep_dc
  317. {
  318. struct parse_events_evlist *data = _data;
  319. struct list_head *list;
  320. ALLOC_LIST(list);
  321. ABORT_ON(parse_events_add_breakpoint(list, &data->idx,
  322. (void *) $2, $4, 0));
  323. $$ = list;
  324. }
  325. |
  326. PE_PREFIX_MEM PE_VALUE sep_dc
  327. {
  328. struct parse_events_evlist *data = _data;
  329. struct list_head *list;
  330. ALLOC_LIST(list);
  331. ABORT_ON(parse_events_add_breakpoint(list, &data->idx,
  332. (void *) $2, NULL, 0));
  333. $$ = list;
  334. }
  335. event_legacy_tracepoint:
  336. tracepoint_name opt_event_config
  337. {
  338. struct parse_events_evlist *data = _data;
  339. struct parse_events_error *error = data->error;
  340. struct list_head *list;
  341. ALLOC_LIST(list);
  342. if (error)
  343. error->idx = @1.first_column;
  344. if (parse_events_add_tracepoint(list, &data->idx, $1.sys, $1.event,
  345. error, $2))
  346. return -1;
  347. $$ = list;
  348. }
  349. tracepoint_name:
  350. PE_NAME '-' PE_NAME ':' PE_NAME
  351. {
  352. char sys_name[128];
  353. struct tracepoint_name tracepoint;
  354. snprintf(&sys_name, 128, "%s-%s", $1, $3);
  355. tracepoint.sys = &sys_name;
  356. tracepoint.event = $5;
  357. $$ = tracepoint;
  358. }
  359. |
  360. PE_NAME ':' PE_NAME
  361. {
  362. struct tracepoint_name tracepoint = {$1, $3};
  363. $$ = tracepoint;
  364. }
  365. event_legacy_numeric:
  366. PE_VALUE ':' PE_VALUE opt_event_config
  367. {
  368. struct parse_events_evlist *data = _data;
  369. struct list_head *list;
  370. ALLOC_LIST(list);
  371. ABORT_ON(parse_events_add_numeric(data, list, (u32)$1, $3, $4));
  372. parse_events_terms__delete($4);
  373. $$ = list;
  374. }
  375. event_legacy_raw:
  376. PE_RAW opt_event_config
  377. {
  378. struct parse_events_evlist *data = _data;
  379. struct list_head *list;
  380. ALLOC_LIST(list);
  381. ABORT_ON(parse_events_add_numeric(data, list, PERF_TYPE_RAW, $1, $2));
  382. parse_events_terms__delete($2);
  383. $$ = list;
  384. }
  385. event_bpf_file:
  386. PE_BPF_OBJECT opt_event_config
  387. {
  388. struct parse_events_evlist *data = _data;
  389. struct parse_events_error *error = data->error;
  390. struct list_head *list;
  391. ALLOC_LIST(list);
  392. ABORT_ON(parse_events_load_bpf(data, list, $1, false, $2));
  393. parse_events_terms__delete($2);
  394. $$ = list;
  395. }
  396. |
  397. PE_BPF_SOURCE opt_event_config
  398. {
  399. struct parse_events_evlist *data = _data;
  400. struct list_head *list;
  401. ALLOC_LIST(list);
  402. ABORT_ON(parse_events_load_bpf(data, list, $1, true, $2));
  403. parse_events_terms__delete($2);
  404. $$ = list;
  405. }
  406. opt_event_config:
  407. '/' event_config '/'
  408. {
  409. $$ = $2;
  410. }
  411. |
  412. '/' '/'
  413. {
  414. $$ = NULL;
  415. }
  416. |
  417. {
  418. $$ = NULL;
  419. }
  420. start_terms: event_config
  421. {
  422. struct parse_events_terms *data = _data;
  423. data->terms = $1;
  424. }
  425. event_config:
  426. event_config ',' event_term
  427. {
  428. struct list_head *head = $1;
  429. struct parse_events_term *term = $3;
  430. ABORT_ON(!head);
  431. list_add_tail(&term->list, head);
  432. $$ = $1;
  433. }
  434. |
  435. event_term
  436. {
  437. struct list_head *head = malloc(sizeof(*head));
  438. struct parse_events_term *term = $1;
  439. ABORT_ON(!head);
  440. INIT_LIST_HEAD(head);
  441. list_add_tail(&term->list, head);
  442. $$ = head;
  443. }
  444. event_term:
  445. PE_NAME '=' PE_NAME
  446. {
  447. struct parse_events_term *term;
  448. ABORT_ON(parse_events_term__str(&term, PARSE_EVENTS__TERM_TYPE_USER,
  449. $1, $3, &@1, &@3));
  450. $$ = term;
  451. }
  452. |
  453. PE_NAME '=' PE_VALUE
  454. {
  455. struct parse_events_term *term;
  456. ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER,
  457. $1, $3, &@1, &@3));
  458. $$ = term;
  459. }
  460. |
  461. PE_NAME '=' PE_VALUE_SYM_HW
  462. {
  463. struct parse_events_term *term;
  464. int config = $3 & 255;
  465. ABORT_ON(parse_events_term__sym_hw(&term, $1, config));
  466. $$ = term;
  467. }
  468. |
  469. PE_NAME
  470. {
  471. struct parse_events_term *term;
  472. ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER,
  473. $1, 1, &@1, NULL));
  474. $$ = term;
  475. }
  476. |
  477. PE_VALUE_SYM_HW
  478. {
  479. struct parse_events_term *term;
  480. int config = $1 & 255;
  481. ABORT_ON(parse_events_term__sym_hw(&term, NULL, config));
  482. $$ = term;
  483. }
  484. |
  485. PE_TERM '=' PE_NAME
  486. {
  487. struct parse_events_term *term;
  488. ABORT_ON(parse_events_term__str(&term, (int)$1, NULL, $3, &@1, &@3));
  489. $$ = term;
  490. }
  491. |
  492. PE_TERM '=' PE_VALUE
  493. {
  494. struct parse_events_term *term;
  495. ABORT_ON(parse_events_term__num(&term, (int)$1, NULL, $3, &@1, &@3));
  496. $$ = term;
  497. }
  498. |
  499. PE_TERM
  500. {
  501. struct parse_events_term *term;
  502. ABORT_ON(parse_events_term__num(&term, (int)$1, NULL, 1, &@1, NULL));
  503. $$ = term;
  504. }
  505. |
  506. PE_NAME array '=' PE_NAME
  507. {
  508. struct parse_events_term *term;
  509. int i;
  510. ABORT_ON(parse_events_term__str(&term, PARSE_EVENTS__TERM_TYPE_USER,
  511. $1, $4, &@1, &@4));
  512. term->array = $2;
  513. $$ = term;
  514. }
  515. |
  516. PE_NAME array '=' PE_VALUE
  517. {
  518. struct parse_events_term *term;
  519. ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER,
  520. $1, $4, &@1, &@4));
  521. term->array = $2;
  522. $$ = term;
  523. }
  524. array:
  525. '[' array_terms ']'
  526. {
  527. $$ = $2;
  528. }
  529. |
  530. PE_ARRAY_ALL
  531. {
  532. $$.nr_ranges = 0;
  533. $$.ranges = NULL;
  534. }
  535. array_terms:
  536. array_terms ',' array_term
  537. {
  538. struct parse_events_array new_array;
  539. new_array.nr_ranges = $1.nr_ranges + $3.nr_ranges;
  540. new_array.ranges = malloc(sizeof(new_array.ranges[0]) *
  541. new_array.nr_ranges);
  542. ABORT_ON(!new_array.ranges);
  543. memcpy(&new_array.ranges[0], $1.ranges,
  544. $1.nr_ranges * sizeof(new_array.ranges[0]));
  545. memcpy(&new_array.ranges[$1.nr_ranges], $3.ranges,
  546. $3.nr_ranges * sizeof(new_array.ranges[0]));
  547. free($1.ranges);
  548. free($3.ranges);
  549. $$ = new_array;
  550. }
  551. |
  552. array_term
  553. array_term:
  554. PE_VALUE
  555. {
  556. struct parse_events_array array;
  557. array.nr_ranges = 1;
  558. array.ranges = malloc(sizeof(array.ranges[0]));
  559. ABORT_ON(!array.ranges);
  560. array.ranges[0].start = $1;
  561. array.ranges[0].length = 1;
  562. $$ = array;
  563. }
  564. |
  565. PE_VALUE PE_ARRAY_RANGE PE_VALUE
  566. {
  567. struct parse_events_array array;
  568. ABORT_ON($3 < $1);
  569. array.nr_ranges = 1;
  570. array.ranges = malloc(sizeof(array.ranges[0]));
  571. ABORT_ON(!array.ranges);
  572. array.ranges[0].start = $1;
  573. array.ranges[0].length = $3 - $1 + 1;
  574. $$ = array;
  575. }
  576. sep_dc: ':' |
  577. sep_slash_dc: '/' | ':' |
  578. %%
  579. void parse_events_error(YYLTYPE *loc, void *data,
  580. void *scanner __maybe_unused,
  581. char const *msg __maybe_unused)
  582. {
  583. parse_events_evlist_error(data, loc->last_column, "parser error");
  584. }