^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) %option reentrant
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) %option bison-bridge
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) %option prefix="parse_events_"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) %option stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) %option bison-locations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) %option yylineno
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) %option reject
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) %{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <sys/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <sys/stat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <unistd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include "../perf.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include "parse-events.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include "parse-events-bison.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include "evsel.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) char *parse_events_get_text(yyscan_t yyscanner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) YYSTYPE *parse_events_get_lval(yyscan_t yyscanner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) static int __value(YYSTYPE *yylval, char *str, int base, int token)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) u64 num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) errno = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) num = strtoull(str, NULL, base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) if (errno)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) return PE_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) yylval->num = num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) return token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) static int value(yyscan_t scanner, int base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) YYSTYPE *yylval = parse_events_get_lval(scanner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) char *text = parse_events_get_text(scanner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) return __value(yylval, text, base, PE_VALUE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) static int str(yyscan_t scanner, int token)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) YYSTYPE *yylval = parse_events_get_lval(scanner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) char *text = parse_events_get_text(scanner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) if (text[0] != '\'') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) yylval->str = strdup(text);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * If a text tag specified on the command line
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) * contains opening single quite ' then it is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) * expected that the tag ends with single quote
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) * as well, like this:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) * name=\'CPU_CLK_UNHALTED.THREAD:cmask=1\'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * quotes need to be escaped to bypass shell
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) * processing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) yylval->str = strndup(&text[1], strlen(text) - 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) return token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) static int raw(yyscan_t scanner)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) YYSTYPE *yylval = parse_events_get_lval(scanner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) char *text = parse_events_get_text(scanner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) if (perf_pmu__parse_check(text) == PMU_EVENT_SYMBOL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) return str(scanner, PE_NAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) return __value(yylval, text + 1, 16, PE_RAW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) static bool isbpf_suffix(char *text)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) int len = strlen(text);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) if (len < 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) if ((text[len - 1] == 'c' || text[len - 1] == 'o') &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) text[len - 2] == '.')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) if (len > 4 && !strcmp(text + len - 4, ".obj"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) static bool isbpf(yyscan_t scanner)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) char *text = parse_events_get_text(scanner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) struct stat st;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) if (!isbpf_suffix(text))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) return stat(text, &st) == 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) * This function is called when the parser gets two kind of input:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) * @cfg1 or @cfg2=config
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) * The leading '@' is stripped off before 'cfg1' and 'cfg2=config' are given to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) * bison. In the latter case it is necessary to keep the string intact so that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) * the PMU kernel driver can determine what configurable is associated to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) * 'config'.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) static int drv_str(yyscan_t scanner, int token)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) YYSTYPE *yylval = parse_events_get_lval(scanner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) char *text = parse_events_get_text(scanner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) /* Strip off the '@' */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) yylval->str = strdup(text + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) return token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) #define REWIND(__alloc) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) do { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) YYSTYPE *__yylval = parse_events_get_lval(yyscanner); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) char *text = parse_events_get_text(yyscanner); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) if (__alloc) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) __yylval->str = strdup(text); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) yycolumn -= strlen(text); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) yyless(0); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) static int pmu_str_check(yyscan_t scanner, struct parse_events_state *parse_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) YYSTYPE *yylval = parse_events_get_lval(scanner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) char *text = parse_events_get_text(scanner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) yylval->str = strdup(text);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) if (parse_state->fake_pmu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) return PE_PMU_EVENT_FAKE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) switch (perf_pmu__parse_check(text)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) case PMU_EVENT_SYMBOL_PREFIX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) return PE_PMU_EVENT_PRE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) case PMU_EVENT_SYMBOL_SUFFIX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) return PE_PMU_EVENT_SUF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) case PMU_EVENT_SYMBOL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) return PE_KERNEL_PMU_EVENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) return PE_NAME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) static int sym(yyscan_t scanner, int type, int config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) YYSTYPE *yylval = parse_events_get_lval(scanner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) yylval->num = (type << 16) + config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) return type == PERF_TYPE_HARDWARE ? PE_VALUE_SYM_HW : PE_VALUE_SYM_SW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) static int tool(yyscan_t scanner, enum perf_tool_event event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) YYSTYPE *yylval = parse_events_get_lval(scanner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) yylval->num = event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) return PE_VALUE_SYM_TOOL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) static int term(yyscan_t scanner, int type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) YYSTYPE *yylval = parse_events_get_lval(scanner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) yylval->num = type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) return PE_TERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) #define YY_USER_ACTION \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) do { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) yylloc->last_column = yylloc->first_column; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) yylloc->first_column = yycolumn; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) yycolumn += yyleng; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) } while (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) #define USER_REJECT \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) yycolumn -= yyleng; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) REJECT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) %}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) %x mem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) %s config
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) %x event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) %x array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) group [^,{}/]*[{][^}]*[}][^,{}/]*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) event_pmu [^,{}/]+[/][^/]*[/][^,{}/]*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) event [^,{}/]+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) bpf_object [^,{}]+\.(o|bpf)[a-zA-Z0-9._]*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) bpf_source [^,{}]+\.c[a-zA-Z0-9._]*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) num_dec [0-9]+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) num_hex 0x[a-fA-F0-9]+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) num_raw_hex [a-fA-F0-9]+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) name [a-zA-Z_*?\[\]][a-zA-Z0-9_*?.\[\]]*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) name_tag [\'][a-zA-Z_*?\[\]][a-zA-Z0-9_*?\-,\.\[\]:=]*[\']
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) name_minus [a-zA-Z_*?][a-zA-Z0-9\-_*?.:]*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) drv_cfg_term [a-zA-Z0-9_\.]+(=[a-zA-Z0-9_*?\.:]+)?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) /* If you add a modifier you need to update check_modifier() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) modifier_event [ukhpPGHSDIWe]+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) modifier_bp [rwx]{1,3}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) %%
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) %{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) struct parse_events_state *_parse_state = parse_events_get_extra(yyscanner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) int start_token = _parse_state->stoken;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) if (start_token == PE_START_TERMS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) BEGIN(config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) else if (start_token == PE_START_EVENTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) BEGIN(event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) if (start_token) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) _parse_state->stoken = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) * The flex parser does not init locations variable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) * via the scan_string interface, so we need do the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) * init in here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) yycolumn = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) return start_token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) %}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) <event>{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) {group} {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) BEGIN(INITIAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) REWIND(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) {event_pmu} |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) {bpf_object} |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) {bpf_source} |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) {event} {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) BEGIN(INITIAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) REWIND(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) return PE_EVENT_NAME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) <<EOF>> {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) BEGIN(INITIAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) REWIND(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) , {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) return ',';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) <array>{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) "]" { BEGIN(config); return ']'; }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) {num_dec} { return value(yyscanner, 10); }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) {num_hex} { return value(yyscanner, 16); }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) , { return ','; }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) "\.\.\." { return PE_ARRAY_RANGE; }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) <config>{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) * Please update config_term_names when new static term is added.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) config { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_CONFIG); }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) config1 { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_CONFIG1); }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) config2 { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_CONFIG2); }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) name { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_NAME); }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) period { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD); }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) freq { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_SAMPLE_FREQ); }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) branch_type { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE); }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) time { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_TIME); }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) call-graph { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_CALLGRAPH); }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) stack-size { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_STACKSIZE); }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) max-stack { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_MAX_STACK); }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) nr { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_MAX_EVENTS); }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) inherit { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_INHERIT); }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) no-inherit { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_NOINHERIT); }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) overwrite { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_OVERWRITE); }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) no-overwrite { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_NOOVERWRITE); }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) percore { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_PERCORE); }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) aux-output { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_AUX_OUTPUT); }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) aux-sample-size { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_AUX_SAMPLE_SIZE); }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) r{num_raw_hex} { return raw(yyscanner); }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) r0x{num_raw_hex} { return raw(yyscanner); }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) , { return ','; }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) "/" { BEGIN(INITIAL); return '/'; }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) {name_minus} { return str(yyscanner, PE_NAME); }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) \[all\] { return PE_ARRAY_ALL; }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) "[" { BEGIN(array); return '['; }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) @{drv_cfg_term} { return drv_str(yyscanner, PE_DRV_CFG_TERM); }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) <mem>{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) {modifier_bp} { return str(yyscanner, PE_MODIFIER_BP); }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) : { return ':'; }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) "/" { return '/'; }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) {num_dec} { return value(yyscanner, 10); }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) {num_hex} { return value(yyscanner, 16); }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) * We need to separate 'mem:' scanner part, in order to get specific
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) * modifier bits parsed out. Otherwise we would need to handle PE_NAME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) * and we'd need to parse it manually. During the escape from <mem>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) * state we need to put the escaping char back, so we dont miss it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) . { unput(*yytext); BEGIN(INITIAL); }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) * We destroy the scanner after reaching EOF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) * but anyway just to be sure get back to INIT state.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) <<EOF>> { BEGIN(INITIAL); }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) cpu-cycles|cycles { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_CPU_CYCLES); }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) stalled-cycles-frontend|idle-cycles-frontend { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_STALLED_CYCLES_FRONTEND); }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) stalled-cycles-backend|idle-cycles-backend { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_STALLED_CYCLES_BACKEND); }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) instructions { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_INSTRUCTIONS); }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) cache-references { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_CACHE_REFERENCES); }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) cache-misses { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_CACHE_MISSES); }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) branch-instructions|branches { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_BRANCH_INSTRUCTIONS); }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) branch-misses { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_BRANCH_MISSES); }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) bus-cycles { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_BUS_CYCLES); }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) ref-cycles { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_REF_CPU_CYCLES); }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) cpu-clock { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_CPU_CLOCK); }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) task-clock { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_TASK_CLOCK); }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) page-faults|faults { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_PAGE_FAULTS); }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) minor-faults { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_PAGE_FAULTS_MIN); }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) major-faults { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_PAGE_FAULTS_MAJ); }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) context-switches|cs { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_CONTEXT_SWITCHES); }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) cpu-migrations|migrations { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_CPU_MIGRATIONS); }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) alignment-faults { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_ALIGNMENT_FAULTS); }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) emulation-faults { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_EMULATION_FAULTS); }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) dummy { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_DUMMY); }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) duration_time { return tool(yyscanner, PERF_TOOL_DURATION_TIME); }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) bpf-output { return sym(yyscanner, PERF_TYPE_SOFTWARE, PERF_COUNT_SW_BPF_OUTPUT); }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) * We have to handle the kernel PMU event cycles-ct/cycles-t/mem-loads/mem-stores separately.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) * Because the prefix cycles is mixed up with cpu-cycles.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) * loads and stores are mixed up with cache event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) cycles-ct |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) cycles-t |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) mem-loads |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) mem-stores |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) topdown-[a-z-]+ |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) tx-capacity-[a-z-]+ |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) el-capacity-[a-z-]+ { return str(yyscanner, PE_KERNEL_PMU_EVENT); }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) L1-dcache|l1-d|l1d|L1-data |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) L1-icache|l1-i|l1i|L1-instruction |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) LLC|L2 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) dTLB|d-tlb|Data-TLB |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) iTLB|i-tlb|Instruction-TLB |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) branch|branches|bpu|btb|bpc |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) node { return str(yyscanner, PE_NAME_CACHE_TYPE); }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) load|loads|read |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) store|stores|write |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) prefetch|prefetches |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) speculative-read|speculative-load |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) refs|Reference|ops|access |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) misses|miss { return str(yyscanner, PE_NAME_CACHE_OP_RESULT); }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) mem: { BEGIN(mem); return PE_PREFIX_MEM; }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) r{num_raw_hex} { return raw(yyscanner); }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) {num_dec} { return value(yyscanner, 10); }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) {num_hex} { return value(yyscanner, 16); }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) {modifier_event} { return str(yyscanner, PE_MODIFIER_EVENT); }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) {bpf_object} { if (!isbpf(yyscanner)) { USER_REJECT }; return str(yyscanner, PE_BPF_OBJECT); }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) {bpf_source} { if (!isbpf(yyscanner)) { USER_REJECT }; return str(yyscanner, PE_BPF_SOURCE); }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) {name} { return pmu_str_check(yyscanner, _parse_state); }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) {name_tag} { return str(yyscanner, PE_NAME); }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) "/" { BEGIN(config); return '/'; }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) - { return '-'; }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) , { BEGIN(event); return ','; }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) : { return ':'; }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) "{" { BEGIN(event); return '{'; }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) "}" { return '}'; }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) = { return '='; }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) \n { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) . { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) %%
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) int parse_events_wrap(void *scanner __maybe_unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) }