Home | History | Annotate | Download | only in util
      1 /* ANDROID_CHANGE_BEGIN */
      2 #if 0
      3 #include "../../../include/linux/hw_breakpoint.h"
      4 #else
      5 #include "include/linux/added/hw_breakpoint.h"
      6 #endif
      7 /* ANDROID_CHANGE_END */
      8 #include "util.h"
      9 #include "../perf.h"
     10 #include "evlist.h"
     11 #include "evsel.h"
     12 #include "parse-options.h"
     13 #include "parse-events.h"
     14 #include "exec_cmd.h"
     15 #include "string.h"
     16 #include "symbol.h"
     17 #include "cache.h"
     18 #include "header.h"
     19 #include "debugfs.h"
     20 
     21 struct event_symbol {
     22 	u8		type;
     23 	u64		config;
     24 	const char	*symbol;
     25 	const char	*alias;
     26 };
     27 
     28 enum event_result {
     29 	EVT_FAILED,
     30 	EVT_HANDLED,
     31 	EVT_HANDLED_ALL
     32 };
     33 
     34 char debugfs_path[MAXPATHLEN];
     35 
     36 #define CHW(x) .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_##x
     37 #define CSW(x) .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_##x
     38 
     39 static struct event_symbol event_symbols[] = {
     40   { CHW(CPU_CYCLES),			"cpu-cycles",			"cycles"		},
     41   { CHW(STALLED_CYCLES_FRONTEND),	"stalled-cycles-frontend",	"idle-cycles-frontend"	},
     42   { CHW(STALLED_CYCLES_BACKEND),	"stalled-cycles-backend",	"idle-cycles-backend"	},
     43   { CHW(INSTRUCTIONS),			"instructions",			""			},
     44   { CHW(CACHE_REFERENCES),		"cache-references",		""			},
     45   { CHW(CACHE_MISSES),			"cache-misses",			""			},
     46   { CHW(BRANCH_INSTRUCTIONS),		"branch-instructions",		"branches"		},
     47   { CHW(BRANCH_MISSES),			"branch-misses",		""			},
     48   { CHW(BUS_CYCLES),			"bus-cycles",			""			},
     49 
     50   { CSW(CPU_CLOCK),			"cpu-clock",			""			},
     51   { CSW(TASK_CLOCK),			"task-clock",			""			},
     52   { CSW(PAGE_FAULTS),			"page-faults",			"faults"		},
     53   { CSW(PAGE_FAULTS_MIN),		"minor-faults",			""			},
     54   { CSW(PAGE_FAULTS_MAJ),		"major-faults",			""			},
     55   { CSW(CONTEXT_SWITCHES),		"context-switches",		"cs"			},
     56   { CSW(CPU_MIGRATIONS),		"cpu-migrations",		"migrations"		},
     57   { CSW(ALIGNMENT_FAULTS),		"alignment-faults",		""			},
     58   { CSW(EMULATION_FAULTS),		"emulation-faults",		""			},
     59 };
     60 
     61 #define __PERF_EVENT_FIELD(config, name) \
     62 	((config & PERF_EVENT_##name##_MASK) >> PERF_EVENT_##name##_SHIFT)
     63 
     64 #define PERF_EVENT_RAW(config)		__PERF_EVENT_FIELD(config, RAW)
     65 #define PERF_EVENT_CONFIG(config)	__PERF_EVENT_FIELD(config, CONFIG)
     66 #define PERF_EVENT_TYPE(config)		__PERF_EVENT_FIELD(config, TYPE)
     67 #define PERF_EVENT_ID(config)		__PERF_EVENT_FIELD(config, EVENT)
     68 
     69 static const char *hw_event_names[PERF_COUNT_HW_MAX] = {
     70 	"cycles",
     71 	"instructions",
     72 	"cache-references",
     73 	"cache-misses",
     74 	"branches",
     75 	"branch-misses",
     76 	"bus-cycles",
     77 	"stalled-cycles-frontend",
     78 	"stalled-cycles-backend",
     79 };
     80 
     81 static const char *sw_event_names[PERF_COUNT_SW_MAX] = {
     82 	"cpu-clock",
     83 	"task-clock",
     84 	"page-faults",
     85 	"context-switches",
     86 	"CPU-migrations",
     87 	"minor-faults",
     88 	"major-faults",
     89 	"alignment-faults",
     90 	"emulation-faults",
     91 };
     92 
     93 #define MAX_ALIASES 8
     94 
     95 static const char *hw_cache[][MAX_ALIASES] = {
     96  { "L1-dcache",	"l1-d",		"l1d",		"L1-data",		},
     97  { "L1-icache",	"l1-i",		"l1i",		"L1-instruction",	},
     98  { "LLC",	"L2"							},
     99  { "dTLB",	"d-tlb",	"Data-TLB",				},
    100  { "iTLB",	"i-tlb",	"Instruction-TLB",			},
    101  { "branch",	"branches",	"bpu",		"btb",		"bpc",	},
    102 };
    103 
    104 static const char *hw_cache_op[][MAX_ALIASES] = {
    105  { "load",	"loads",	"read",					},
    106  { "store",	"stores",	"write",				},
    107  { "prefetch",	"prefetches",	"speculative-read", "speculative-load",	},
    108 };
    109 
    110 static const char *hw_cache_result[][MAX_ALIASES] = {
    111  { "refs",	"Reference",	"ops",		"access",		},
    112  { "misses",	"miss",							},
    113 };
    114 
    115 #define C(x)		PERF_COUNT_HW_CACHE_##x
    116 #define CACHE_READ	(1 << C(OP_READ))
    117 #define CACHE_WRITE	(1 << C(OP_WRITE))
    118 #define CACHE_PREFETCH	(1 << C(OP_PREFETCH))
    119 #define COP(x)		(1 << x)
    120 
    121 /*
    122  * cache operartion stat
    123  * L1I : Read and prefetch only
    124  * ITLB and BPU : Read-only
    125  */
    126 static unsigned long hw_cache_stat[C(MAX)] = {
    127  [C(L1D)]	= (CACHE_READ | CACHE_WRITE | CACHE_PREFETCH),
    128  [C(L1I)]	= (CACHE_READ | CACHE_PREFETCH),
    129  [C(LL)]	= (CACHE_READ | CACHE_WRITE | CACHE_PREFETCH),
    130  [C(DTLB)]	= (CACHE_READ | CACHE_WRITE | CACHE_PREFETCH),
    131  [C(ITLB)]	= (CACHE_READ),
    132  [C(BPU)]	= (CACHE_READ),
    133 };
    134 
    135 #define for_each_subsystem(sys_dir, sys_dirent, sys_next)	       \
    136 	while (!readdir_r(sys_dir, &sys_dirent, &sys_next) && sys_next)	       \
    137 	if (sys_dirent.d_type == DT_DIR &&				       \
    138 	   (strcmp(sys_dirent.d_name, ".")) &&				       \
    139 	   (strcmp(sys_dirent.d_name, "..")))
    140 
    141 static int tp_event_has_id(struct dirent *sys_dir, struct dirent *evt_dir)
    142 {
    143 	char evt_path[MAXPATHLEN];
    144 	int fd;
    145 
    146 	snprintf(evt_path, MAXPATHLEN, "%s/%s/%s/id", debugfs_path,
    147 			sys_dir->d_name, evt_dir->d_name);
    148 	fd = open(evt_path, O_RDONLY);
    149 	if (fd < 0)
    150 		return -EINVAL;
    151 	close(fd);
    152 
    153 	return 0;
    154 }
    155 
    156 #define for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next)	       \
    157 	while (!readdir_r(evt_dir, &evt_dirent, &evt_next) && evt_next)        \
    158 	if (evt_dirent.d_type == DT_DIR &&				       \
    159 	   (strcmp(evt_dirent.d_name, ".")) &&				       \
    160 	   (strcmp(evt_dirent.d_name, "..")) &&				       \
    161 	   (!tp_event_has_id(&sys_dirent, &evt_dirent)))
    162 
    163 #define MAX_EVENT_LENGTH 512
    164 
    165 
    166 struct tracepoint_path *tracepoint_id_to_path(u64 config)
    167 {
    168 	struct tracepoint_path *path = NULL;
    169 	DIR *sys_dir, *evt_dir;
    170 	struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent;
    171 	char id_buf[4];
    172 	int fd;
    173 	u64 id;
    174 	char evt_path[MAXPATHLEN];
    175 	char dir_path[MAXPATHLEN];
    176 
    177 	if (debugfs_valid_mountpoint(debugfs_path))
    178 		return NULL;
    179 
    180 	sys_dir = opendir(debugfs_path);
    181 	if (!sys_dir)
    182 		return NULL;
    183 
    184 	for_each_subsystem(sys_dir, sys_dirent, sys_next) {
    185 
    186 		snprintf(dir_path, MAXPATHLEN, "%s/%s", debugfs_path,
    187 			 sys_dirent.d_name);
    188 		evt_dir = opendir(dir_path);
    189 		if (!evt_dir)
    190 			continue;
    191 
    192 		for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) {
    193 
    194 			snprintf(evt_path, MAXPATHLEN, "%s/%s/id", dir_path,
    195 				 evt_dirent.d_name);
    196 			fd = open(evt_path, O_RDONLY);
    197 			if (fd < 0)
    198 				continue;
    199 			if (read(fd, id_buf, sizeof(id_buf)) < 0) {
    200 				close(fd);
    201 				continue;
    202 			}
    203 			close(fd);
    204 			id = atoll(id_buf);
    205 			if (id == config) {
    206 				closedir(evt_dir);
    207 				closedir(sys_dir);
    208 				path = zalloc(sizeof(*path));
    209 				path->system = malloc(MAX_EVENT_LENGTH);
    210 				if (!path->system) {
    211 					free(path);
    212 					return NULL;
    213 				}
    214 				path->name = malloc(MAX_EVENT_LENGTH);
    215 				if (!path->name) {
    216 					free(path->system);
    217 					free(path);
    218 					return NULL;
    219 				}
    220 				strncpy(path->system, sys_dirent.d_name,
    221 					MAX_EVENT_LENGTH);
    222 				strncpy(path->name, evt_dirent.d_name,
    223 					MAX_EVENT_LENGTH);
    224 				return path;
    225 			}
    226 		}
    227 		closedir(evt_dir);
    228 	}
    229 
    230 	closedir(sys_dir);
    231 	return NULL;
    232 }
    233 
    234 #define TP_PATH_LEN (MAX_EVENT_LENGTH * 2 + 1)
    235 static const char *tracepoint_id_to_name(u64 config)
    236 {
    237 	static char buf[TP_PATH_LEN];
    238 	struct tracepoint_path *path;
    239 
    240 	path = tracepoint_id_to_path(config);
    241 	if (path) {
    242 		snprintf(buf, TP_PATH_LEN, "%s:%s", path->system, path->name);
    243 		free(path->name);
    244 		free(path->system);
    245 		free(path);
    246 	} else
    247 		snprintf(buf, TP_PATH_LEN, "%s:%s", "unknown", "unknown");
    248 
    249 	return buf;
    250 }
    251 
    252 static int is_cache_op_valid(u8 cache_type, u8 cache_op)
    253 {
    254 	if (hw_cache_stat[cache_type] & COP(cache_op))
    255 		return 1;	/* valid */
    256 	else
    257 		return 0;	/* invalid */
    258 }
    259 
    260 static char *event_cache_name(u8 cache_type, u8 cache_op, u8 cache_result)
    261 {
    262 	static char name[50];
    263 
    264 	if (cache_result) {
    265 		sprintf(name, "%s-%s-%s", hw_cache[cache_type][0],
    266 			hw_cache_op[cache_op][0],
    267 			hw_cache_result[cache_result][0]);
    268 	} else {
    269 		sprintf(name, "%s-%s", hw_cache[cache_type][0],
    270 			hw_cache_op[cache_op][1]);
    271 	}
    272 
    273 	return name;
    274 }
    275 
    276 const char *event_type(int type)
    277 {
    278 	switch (type) {
    279 	case PERF_TYPE_HARDWARE:
    280 		return "hardware";
    281 
    282 	case PERF_TYPE_SOFTWARE:
    283 		return "software";
    284 
    285 	case PERF_TYPE_TRACEPOINT:
    286 		return "tracepoint";
    287 
    288 	case PERF_TYPE_HW_CACHE:
    289 		return "hardware-cache";
    290 
    291 	default:
    292 		break;
    293 	}
    294 
    295 	return "unknown";
    296 }
    297 
    298 const char *event_name(struct perf_evsel *evsel)
    299 {
    300 	u64 config = evsel->attr.config;
    301 	int type = evsel->attr.type;
    302 
    303 	if (evsel->name)
    304 		return evsel->name;
    305 
    306 	return __event_name(type, config);
    307 }
    308 
    309 const char *__event_name(int type, u64 config)
    310 {
    311 	static char buf[32];
    312 
    313 	if (type == PERF_TYPE_RAW) {
    314 		sprintf(buf, "raw 0x%" PRIx64, config);
    315 		return buf;
    316 	}
    317 
    318 	switch (type) {
    319 	case PERF_TYPE_HARDWARE:
    320 		if (config < PERF_COUNT_HW_MAX && hw_event_names[config])
    321 			return hw_event_names[config];
    322 		return "unknown-hardware";
    323 
    324 	case PERF_TYPE_HW_CACHE: {
    325 		u8 cache_type, cache_op, cache_result;
    326 
    327 		cache_type   = (config >>  0) & 0xff;
    328 		if (cache_type > PERF_COUNT_HW_CACHE_MAX)
    329 			return "unknown-ext-hardware-cache-type";
    330 
    331 		cache_op     = (config >>  8) & 0xff;
    332 		if (cache_op > PERF_COUNT_HW_CACHE_OP_MAX)
    333 			return "unknown-ext-hardware-cache-op";
    334 
    335 		cache_result = (config >> 16) & 0xff;
    336 		if (cache_result > PERF_COUNT_HW_CACHE_RESULT_MAX)
    337 			return "unknown-ext-hardware-cache-result";
    338 
    339 		if (!is_cache_op_valid(cache_type, cache_op))
    340 			return "invalid-cache";
    341 
    342 		return event_cache_name(cache_type, cache_op, cache_result);
    343 	}
    344 
    345 	case PERF_TYPE_SOFTWARE:
    346 		if (config < PERF_COUNT_SW_MAX && sw_event_names[config])
    347 			return sw_event_names[config];
    348 		return "unknown-software";
    349 
    350 	case PERF_TYPE_TRACEPOINT:
    351 		return tracepoint_id_to_name(config);
    352 
    353 	default:
    354 		break;
    355 	}
    356 
    357 	return "unknown";
    358 }
    359 
    360 static int parse_aliases(const char **str, const char *names[][MAX_ALIASES], int size)
    361 {
    362 	int i, j;
    363 	int n, longest = -1;
    364 
    365 	for (i = 0; i < size; i++) {
    366 		for (j = 0; j < MAX_ALIASES && names[i][j]; j++) {
    367 			n = strlen(names[i][j]);
    368 			if (n > longest && !strncasecmp(*str, names[i][j], n))
    369 				longest = n;
    370 		}
    371 		if (longest > 0) {
    372 			*str += longest;
    373 			return i;
    374 		}
    375 	}
    376 
    377 	return -1;
    378 }
    379 
    380 static enum event_result
    381 parse_generic_hw_event(const char **str, struct perf_event_attr *attr)
    382 {
    383 	const char *s = *str;
    384 	int cache_type = -1, cache_op = -1, cache_result = -1;
    385 
    386 	cache_type = parse_aliases(&s, hw_cache, PERF_COUNT_HW_CACHE_MAX);
    387 	/*
    388 	 * No fallback - if we cannot get a clear cache type
    389 	 * then bail out:
    390 	 */
    391 	if (cache_type == -1)
    392 		return EVT_FAILED;
    393 
    394 	while ((cache_op == -1 || cache_result == -1) && *s == '-') {
    395 		++s;
    396 
    397 		if (cache_op == -1) {
    398 			cache_op = parse_aliases(&s, hw_cache_op,
    399 						PERF_COUNT_HW_CACHE_OP_MAX);
    400 			if (cache_op >= 0) {
    401 				if (!is_cache_op_valid(cache_type, cache_op))
    402 					return 0;
    403 				continue;
    404 			}
    405 		}
    406 
    407 		if (cache_result == -1) {
    408 			cache_result = parse_aliases(&s, hw_cache_result,
    409 						PERF_COUNT_HW_CACHE_RESULT_MAX);
    410 			if (cache_result >= 0)
    411 				continue;
    412 		}
    413 
    414 		/*
    415 		 * Can't parse this as a cache op or result, so back up
    416 		 * to the '-'.
    417 		 */
    418 		--s;
    419 		break;
    420 	}
    421 
    422 	/*
    423 	 * Fall back to reads:
    424 	 */
    425 	if (cache_op == -1)
    426 		cache_op = PERF_COUNT_HW_CACHE_OP_READ;
    427 
    428 	/*
    429 	 * Fall back to accesses:
    430 	 */
    431 	if (cache_result == -1)
    432 		cache_result = PERF_COUNT_HW_CACHE_RESULT_ACCESS;
    433 
    434 	attr->config = cache_type | (cache_op << 8) | (cache_result << 16);
    435 	attr->type = PERF_TYPE_HW_CACHE;
    436 
    437 	*str = s;
    438 	return EVT_HANDLED;
    439 }
    440 
    441 static enum event_result
    442 parse_single_tracepoint_event(char *sys_name,
    443 			      const char *evt_name,
    444 			      unsigned int evt_length,
    445 			      struct perf_event_attr *attr,
    446 			      const char **strp)
    447 {
    448 	char evt_path[MAXPATHLEN];
    449 	char id_buf[4];
    450 	u64 id;
    451 	int fd;
    452 
    453 	snprintf(evt_path, MAXPATHLEN, "%s/%s/%s/id", debugfs_path,
    454 		 sys_name, evt_name);
    455 
    456 	fd = open(evt_path, O_RDONLY);
    457 	if (fd < 0)
    458 		return EVT_FAILED;
    459 
    460 	if (read(fd, id_buf, sizeof(id_buf)) < 0) {
    461 		close(fd);
    462 		return EVT_FAILED;
    463 	}
    464 
    465 	close(fd);
    466 	id = atoll(id_buf);
    467 	attr->config = id;
    468 	attr->type = PERF_TYPE_TRACEPOINT;
    469 	*strp += strlen(sys_name) + evt_length + 1; /* + 1 for the ':' */
    470 
    471 	attr->sample_type |= PERF_SAMPLE_RAW;
    472 	attr->sample_type |= PERF_SAMPLE_TIME;
    473 	attr->sample_type |= PERF_SAMPLE_CPU;
    474 
    475 	attr->sample_period = 1;
    476 
    477 
    478 	return EVT_HANDLED;
    479 }
    480 
    481 /* sys + ':' + event + ':' + flags*/
    482 #define MAX_EVOPT_LEN	(MAX_EVENT_LENGTH * 2 + 2 + 128)
    483 static enum event_result
    484 parse_multiple_tracepoint_event(const struct option *opt, char *sys_name,
    485 				const char *evt_exp, char *flags)
    486 {
    487 	char evt_path[MAXPATHLEN];
    488 	struct dirent *evt_ent;
    489 	DIR *evt_dir;
    490 
    491 	snprintf(evt_path, MAXPATHLEN, "%s/%s", debugfs_path, sys_name);
    492 	evt_dir = opendir(evt_path);
    493 
    494 	if (!evt_dir) {
    495 		perror("Can't open event dir");
    496 		return EVT_FAILED;
    497 	}
    498 
    499 	while ((evt_ent = readdir(evt_dir))) {
    500 		char event_opt[MAX_EVOPT_LEN + 1];
    501 		int len;
    502 
    503 		if (!strcmp(evt_ent->d_name, ".")
    504 		    || !strcmp(evt_ent->d_name, "..")
    505 		    || !strcmp(evt_ent->d_name, "enable")
    506 		    || !strcmp(evt_ent->d_name, "filter"))
    507 			continue;
    508 
    509 		if (!strglobmatch(evt_ent->d_name, evt_exp))
    510 			continue;
    511 
    512 		len = snprintf(event_opt, MAX_EVOPT_LEN, "%s:%s%s%s", sys_name,
    513 			       evt_ent->d_name, flags ? ":" : "",
    514 			       flags ?: "");
    515 		if (len < 0)
    516 			return EVT_FAILED;
    517 
    518 		if (parse_events(opt, event_opt, 0))
    519 			return EVT_FAILED;
    520 	}
    521 
    522 	return EVT_HANDLED_ALL;
    523 }
    524 
    525 static enum event_result
    526 parse_tracepoint_event(const struct option *opt, const char **strp,
    527 		       struct perf_event_attr *attr)
    528 {
    529 	const char *evt_name;
    530 	char *flags = NULL, *comma_loc;
    531 	char sys_name[MAX_EVENT_LENGTH];
    532 	unsigned int sys_length, evt_length;
    533 
    534 	if (debugfs_valid_mountpoint(debugfs_path))
    535 		return 0;
    536 
    537 	evt_name = strchr(*strp, ':');
    538 	if (!evt_name)
    539 		return EVT_FAILED;
    540 
    541 	sys_length = evt_name - *strp;
    542 	if (sys_length >= MAX_EVENT_LENGTH)
    543 		return 0;
    544 
    545 	strncpy(sys_name, *strp, sys_length);
    546 	sys_name[sys_length] = '\0';
    547 	evt_name = evt_name + 1;
    548 
    549 	comma_loc = strchr(evt_name, ',');
    550 	if (comma_loc) {
    551 		/* take the event name up to the comma */
    552 		evt_name = strndup(evt_name, comma_loc - evt_name);
    553 	}
    554 	flags = strchr(evt_name, ':');
    555 	if (flags) {
    556 		/* split it out: */
    557 		evt_name = strndup(evt_name, flags - evt_name);
    558 		flags++;
    559 	}
    560 
    561 	evt_length = strlen(evt_name);
    562 	if (evt_length >= MAX_EVENT_LENGTH)
    563 		return EVT_FAILED;
    564 	if (strpbrk(evt_name, "*?")) {
    565 		*strp += strlen(sys_name) + evt_length + 1; /* 1 == the ':' */
    566 		return parse_multiple_tracepoint_event(opt, sys_name, evt_name,
    567 						       flags);
    568 	} else {
    569 		return parse_single_tracepoint_event(sys_name, evt_name,
    570 						     evt_length, attr, strp);
    571 	}
    572 }
    573 
    574 static enum event_result
    575 parse_breakpoint_type(const char *type, const char **strp,
    576 		      struct perf_event_attr *attr)
    577 {
    578 	int i;
    579 
    580 	for (i = 0; i < 3; i++) {
    581 		if (!type[i])
    582 			break;
    583 
    584 		switch (type[i]) {
    585 		case 'r':
    586 			attr->bp_type |= HW_BREAKPOINT_R;
    587 			break;
    588 		case 'w':
    589 			attr->bp_type |= HW_BREAKPOINT_W;
    590 			break;
    591 		case 'x':
    592 			attr->bp_type |= HW_BREAKPOINT_X;
    593 			break;
    594 		default:
    595 			return EVT_FAILED;
    596 		}
    597 	}
    598 	if (!attr->bp_type) /* Default */
    599 		attr->bp_type = HW_BREAKPOINT_R | HW_BREAKPOINT_W;
    600 
    601 	*strp = type + i;
    602 
    603 	return EVT_HANDLED;
    604 }
    605 
    606 static enum event_result
    607 parse_breakpoint_event(const char **strp, struct perf_event_attr *attr)
    608 {
    609 	const char *target;
    610 	const char *type;
    611 	char *endaddr;
    612 	u64 addr;
    613 	enum event_result err;
    614 
    615 	target = strchr(*strp, ':');
    616 	if (!target)
    617 		return EVT_FAILED;
    618 
    619 	if (strncmp(*strp, "mem", target - *strp) != 0)
    620 		return EVT_FAILED;
    621 
    622 	target++;
    623 
    624 	addr = strtoull(target, &endaddr, 0);
    625 	if (target == endaddr)
    626 		return EVT_FAILED;
    627 
    628 	attr->bp_addr = addr;
    629 	*strp = endaddr;
    630 
    631 	type = strchr(target, ':');
    632 
    633 	/* If no type is defined, just rw as default */
    634 	if (!type) {
    635 		attr->bp_type = HW_BREAKPOINT_R | HW_BREAKPOINT_W;
    636 	} else {
    637 		err = parse_breakpoint_type(++type, strp, attr);
    638 		if (err == EVT_FAILED)
    639 			return EVT_FAILED;
    640 	}
    641 
    642 	/*
    643 	 * We should find a nice way to override the access length
    644 	 * Provide some defaults for now
    645 	 */
    646 	if (attr->bp_type == HW_BREAKPOINT_X)
    647 		attr->bp_len = sizeof(long);
    648 	else
    649 		attr->bp_len = HW_BREAKPOINT_LEN_4;
    650 
    651 	attr->type = PERF_TYPE_BREAKPOINT;
    652 
    653 	return EVT_HANDLED;
    654 }
    655 
    656 static int check_events(const char *str, unsigned int i)
    657 {
    658 	int n;
    659 
    660 	n = strlen(event_symbols[i].symbol);
    661 	if (!strncasecmp(str, event_symbols[i].symbol, n))
    662 		return n;
    663 
    664 	n = strlen(event_symbols[i].alias);
    665 	if (n) {
    666 		if (!strncasecmp(str, event_symbols[i].alias, n))
    667 			return n;
    668 	}
    669 
    670 	return 0;
    671 }
    672 
    673 static enum event_result
    674 parse_symbolic_event(const char **strp, struct perf_event_attr *attr)
    675 {
    676 	const char *str = *strp;
    677 	unsigned int i;
    678 	int n;
    679 
    680 	for (i = 0; i < ARRAY_SIZE(event_symbols); i++) {
    681 		n = check_events(str, i);
    682 		if (n > 0) {
    683 			attr->type = event_symbols[i].type;
    684 			attr->config = event_symbols[i].config;
    685 			*strp = str + n;
    686 			return EVT_HANDLED;
    687 		}
    688 	}
    689 	return EVT_FAILED;
    690 }
    691 
    692 static enum event_result
    693 parse_raw_event(const char **strp, struct perf_event_attr *attr)
    694 {
    695 	const char *str = *strp;
    696 	u64 config;
    697 	int n;
    698 
    699 	if (*str != 'r')
    700 		return EVT_FAILED;
    701 	n = hex2u64(str + 1, &config);
    702 	if (n > 0) {
    703 		*strp = str + n + 1;
    704 		attr->type = PERF_TYPE_RAW;
    705 		attr->config = config;
    706 		return EVT_HANDLED;
    707 	}
    708 	return EVT_FAILED;
    709 }
    710 
    711 static enum event_result
    712 parse_numeric_event(const char **strp, struct perf_event_attr *attr)
    713 {
    714 	const char *str = *strp;
    715 	char *endp;
    716 	unsigned long type;
    717 	u64 config;
    718 
    719 	type = strtoul(str, &endp, 0);
    720 	if (endp > str && type < PERF_TYPE_MAX && *endp == ':') {
    721 		str = endp + 1;
    722 		config = strtoul(str, &endp, 0);
    723 		if (endp > str) {
    724 			attr->type = type;
    725 			attr->config = config;
    726 			*strp = endp;
    727 			return EVT_HANDLED;
    728 		}
    729 	}
    730 	return EVT_FAILED;
    731 }
    732 
    733 static int
    734 parse_event_modifier(const char **strp, struct perf_event_attr *attr)
    735 {
    736 	const char *str = *strp;
    737 	int exclude = 0;
    738 	int eu = 0, ek = 0, eh = 0, precise = 0;
    739 
    740 	if (!*str)
    741 		return 0;
    742 
    743 	if (*str == ',')
    744 		return 0;
    745 
    746 	if (*str++ != ':')
    747 		return -1;
    748 
    749 	while (*str) {
    750 		if (*str == 'u') {
    751 			if (!exclude)
    752 				exclude = eu = ek = eh = 1;
    753 			eu = 0;
    754 		} else if (*str == 'k') {
    755 			if (!exclude)
    756 				exclude = eu = ek = eh = 1;
    757 			ek = 0;
    758 		} else if (*str == 'h') {
    759 			if (!exclude)
    760 				exclude = eu = ek = eh = 1;
    761 			eh = 0;
    762 		} else if (*str == 'p') {
    763 			precise++;
    764 		} else
    765 			break;
    766 
    767 		++str;
    768 	}
    769 	if (str < *strp + 2)
    770 		return -1;
    771 
    772 	*strp = str;
    773 
    774 	attr->exclude_user   = eu;
    775 	attr->exclude_kernel = ek;
    776 	attr->exclude_hv     = eh;
    777 	attr->precise_ip     = precise;
    778 
    779 	return 0;
    780 }
    781 
    782 /*
    783  * Each event can have multiple symbolic names.
    784  * Symbolic names are (almost) exactly matched.
    785  */
    786 static enum event_result
    787 parse_event_symbols(const struct option *opt, const char **str,
    788 		    struct perf_event_attr *attr)
    789 {
    790 	enum event_result ret;
    791 
    792 	ret = parse_tracepoint_event(opt, str, attr);
    793 	if (ret != EVT_FAILED)
    794 		goto modifier;
    795 
    796 	ret = parse_raw_event(str, attr);
    797 	if (ret != EVT_FAILED)
    798 		goto modifier;
    799 
    800 	ret = parse_numeric_event(str, attr);
    801 	if (ret != EVT_FAILED)
    802 		goto modifier;
    803 
    804 	ret = parse_symbolic_event(str, attr);
    805 	if (ret != EVT_FAILED)
    806 		goto modifier;
    807 
    808 	ret = parse_generic_hw_event(str, attr);
    809 	if (ret != EVT_FAILED)
    810 		goto modifier;
    811 
    812 	ret = parse_breakpoint_event(str, attr);
    813 	if (ret != EVT_FAILED)
    814 		goto modifier;
    815 
    816 	fprintf(stderr, "invalid or unsupported event: '%s'\n", *str);
    817 	fprintf(stderr, "Run 'perf list' for a list of valid events\n");
    818 	return EVT_FAILED;
    819 
    820 modifier:
    821 	if (parse_event_modifier(str, attr) < 0) {
    822 		fprintf(stderr, "invalid event modifier: '%s'\n", *str);
    823 		fprintf(stderr, "Run 'perf list' for a list of valid events and modifiers\n");
    824 
    825 		return EVT_FAILED;
    826 	}
    827 
    828 	return ret;
    829 }
    830 
    831 int parse_events(const struct option *opt, const char *str, int unset __used)
    832 {
    833 	struct perf_evlist *evlist = *(struct perf_evlist **)opt->value;
    834 	struct perf_event_attr attr;
    835 	enum event_result ret;
    836 	const char *ostr;
    837 
    838 	for (;;) {
    839 		ostr = str;
    840 		memset(&attr, 0, sizeof(attr));
    841 		ret = parse_event_symbols(opt, &str, &attr);
    842 		if (ret == EVT_FAILED)
    843 			return -1;
    844 
    845 		if (!(*str == 0 || *str == ',' || isspace(*str)))
    846 			return -1;
    847 
    848 		if (ret != EVT_HANDLED_ALL) {
    849 			struct perf_evsel *evsel;
    850 			evsel = perf_evsel__new(&attr, evlist->nr_entries);
    851 			if (evsel == NULL)
    852 				return -1;
    853 			perf_evlist__add(evlist, evsel);
    854 
    855 			evsel->name = calloc(str - ostr + 1, 1);
    856 			if (!evsel->name)
    857 				return -1;
    858 			strncpy(evsel->name, ostr, str - ostr);
    859 		}
    860 
    861 		if (*str == 0)
    862 			break;
    863 		if (*str == ',')
    864 			++str;
    865 		while (isspace(*str))
    866 			++str;
    867 	}
    868 
    869 	return 0;
    870 }
    871 
    872 int parse_filter(const struct option *opt, const char *str,
    873 		 int unset __used)
    874 {
    875 	struct perf_evlist *evlist = *(struct perf_evlist **)opt->value;
    876 	struct perf_evsel *last = NULL;
    877 
    878 	if (evlist->nr_entries > 0)
    879 		last = list_entry(evlist->entries.prev, struct perf_evsel, node);
    880 
    881 	if (last == NULL || last->attr.type != PERF_TYPE_TRACEPOINT) {
    882 		fprintf(stderr,
    883 			"-F option should follow a -e tracepoint option\n");
    884 		return -1;
    885 	}
    886 
    887 	last->filter = strdup(str);
    888 	if (last->filter == NULL) {
    889 		fprintf(stderr, "not enough memory to hold filter string\n");
    890 		return -1;
    891 	}
    892 
    893 	return 0;
    894 }
    895 
    896 static const char * const event_type_descriptors[] = {
    897 	"Hardware event",
    898 	"Software event",
    899 	"Tracepoint event",
    900 	"Hardware cache event",
    901 	"Raw hardware event descriptor",
    902 	"Hardware breakpoint",
    903 };
    904 
    905 /*
    906  * Print the events from <debugfs_mount_point>/tracing/events
    907  */
    908 
    909 void print_tracepoint_events(const char *subsys_glob, const char *event_glob)
    910 {
    911 	DIR *sys_dir, *evt_dir;
    912 	struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent;
    913 	char evt_path[MAXPATHLEN];
    914 	char dir_path[MAXPATHLEN];
    915 
    916 	if (debugfs_valid_mountpoint(debugfs_path))
    917 		return;
    918 
    919 	sys_dir = opendir(debugfs_path);
    920 	if (!sys_dir)
    921 		return;
    922 
    923 	for_each_subsystem(sys_dir, sys_dirent, sys_next) {
    924 		if (subsys_glob != NULL &&
    925 		    !strglobmatch(sys_dirent.d_name, subsys_glob))
    926 			continue;
    927 
    928 		snprintf(dir_path, MAXPATHLEN, "%s/%s", debugfs_path,
    929 			 sys_dirent.d_name);
    930 		evt_dir = opendir(dir_path);
    931 		if (!evt_dir)
    932 			continue;
    933 
    934 		for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) {
    935 			if (event_glob != NULL &&
    936 			    !strglobmatch(evt_dirent.d_name, event_glob))
    937 				continue;
    938 
    939 			snprintf(evt_path, MAXPATHLEN, "%s:%s",
    940 				 sys_dirent.d_name, evt_dirent.d_name);
    941 			printf("  %-50s [%s]\n", evt_path,
    942 				event_type_descriptors[PERF_TYPE_TRACEPOINT]);
    943 		}
    944 		closedir(evt_dir);
    945 	}
    946 	closedir(sys_dir);
    947 }
    948 
    949 /*
    950  * Check whether event is in <debugfs_mount_point>/tracing/events
    951  */
    952 
    953 int is_valid_tracepoint(const char *event_string)
    954 {
    955 	DIR *sys_dir, *evt_dir;
    956 	struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent;
    957 	char evt_path[MAXPATHLEN];
    958 	char dir_path[MAXPATHLEN];
    959 
    960 	if (debugfs_valid_mountpoint(debugfs_path))
    961 		return 0;
    962 
    963 	sys_dir = opendir(debugfs_path);
    964 	if (!sys_dir)
    965 		return 0;
    966 
    967 	for_each_subsystem(sys_dir, sys_dirent, sys_next) {
    968 
    969 		snprintf(dir_path, MAXPATHLEN, "%s/%s", debugfs_path,
    970 			 sys_dirent.d_name);
    971 		evt_dir = opendir(dir_path);
    972 		if (!evt_dir)
    973 			continue;
    974 
    975 		for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) {
    976 			snprintf(evt_path, MAXPATHLEN, "%s:%s",
    977 				 sys_dirent.d_name, evt_dirent.d_name);
    978 			if (!strcmp(evt_path, event_string)) {
    979 				closedir(evt_dir);
    980 				closedir(sys_dir);
    981 				return 1;
    982 			}
    983 		}
    984 		closedir(evt_dir);
    985 	}
    986 	closedir(sys_dir);
    987 	return 0;
    988 }
    989 
    990 void print_events_type(u8 type)
    991 {
    992 	struct event_symbol *syms = event_symbols;
    993 	unsigned int i;
    994 	char name[64];
    995 
    996 	for (i = 0; i < ARRAY_SIZE(event_symbols); i++, syms++) {
    997 		if (type != syms->type)
    998 			continue;
    999 
   1000 		if (strlen(syms->alias))
   1001 			snprintf(name, sizeof(name),  "%s OR %s",
   1002 				 syms->symbol, syms->alias);
   1003 		else
   1004 			snprintf(name, sizeof(name), "%s", syms->symbol);
   1005 
   1006 		printf("  %-50s [%s]\n", name,
   1007 			event_type_descriptors[type]);
   1008 	}
   1009 }
   1010 
   1011 int print_hwcache_events(const char *event_glob)
   1012 {
   1013 	unsigned int type, op, i, printed = 0;
   1014 
   1015 	for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) {
   1016 		for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) {
   1017 			/* skip invalid cache type */
   1018 			if (!is_cache_op_valid(type, op))
   1019 				continue;
   1020 
   1021 			for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) {
   1022 				char *name = event_cache_name(type, op, i);
   1023 
   1024 				if (event_glob != NULL && !strglobmatch(name, event_glob))
   1025 					continue;
   1026 
   1027 				printf("  %-50s [%s]\n", name,
   1028 					event_type_descriptors[PERF_TYPE_HW_CACHE]);
   1029 				++printed;
   1030 			}
   1031 		}
   1032 	}
   1033 
   1034 	return printed;
   1035 }
   1036 
   1037 #define MAX_NAME_LEN 100
   1038 
   1039 /*
   1040  * Print the help text for the event symbols:
   1041  */
   1042 void print_events(const char *event_glob)
   1043 {
   1044 	unsigned int i, type, prev_type = -1, printed = 0, ntypes_printed = 0;
   1045 	struct event_symbol *syms = event_symbols;
   1046 	char name[MAX_NAME_LEN];
   1047 
   1048 	printf("\n");
   1049 	printf("List of pre-defined events (to be used in -e):\n");
   1050 
   1051 	for (i = 0; i < ARRAY_SIZE(event_symbols); i++, syms++) {
   1052 		type = syms->type;
   1053 
   1054 		if (type != prev_type && printed) {
   1055 			printf("\n");
   1056 			printed = 0;
   1057 			ntypes_printed++;
   1058 		}
   1059 
   1060 		if (event_glob != NULL &&
   1061 		    !(strglobmatch(syms->symbol, event_glob) ||
   1062 		      (syms->alias && strglobmatch(syms->alias, event_glob))))
   1063 			continue;
   1064 
   1065 		if (strlen(syms->alias))
   1066 			snprintf(name, MAX_NAME_LEN, "%s OR %s", syms->symbol, syms->alias);
   1067 		else
   1068 			strncpy(name, syms->symbol, MAX_NAME_LEN);
   1069 		printf("  %-50s [%s]\n", name,
   1070 			event_type_descriptors[type]);
   1071 
   1072 		prev_type = type;
   1073 		++printed;
   1074 	}
   1075 
   1076 	if (ntypes_printed) {
   1077 		printed = 0;
   1078 		printf("\n");
   1079 	}
   1080 	print_hwcache_events(event_glob);
   1081 
   1082 	if (event_glob != NULL)
   1083 		return;
   1084 
   1085 	printf("\n");
   1086 	printf("  %-50s [%s]\n",
   1087 		"rNNN (see 'perf list --help' on how to encode it)",
   1088 	       event_type_descriptors[PERF_TYPE_RAW]);
   1089 	printf("\n");
   1090 
   1091 	printf("  %-50s [%s]\n",
   1092 			"mem:<addr>[:access]",
   1093 			event_type_descriptors[PERF_TYPE_BREAKPOINT]);
   1094 	printf("\n");
   1095 
   1096 	print_tracepoint_events(NULL, NULL);
   1097 
   1098 	exit(129);
   1099 }
   1100