xref: /linux/tools/perf/util/probe-event.c (revision 7ca5989dd065cbc48a958666c273794686ea7525)
1 /*
2  * probe-event.c : perf-probe definition to kprobe_events format converter
3  *
4  * Written by Masami Hiramatsu <mhiramat@redhat.com>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19  *
20  */
21 
22 #define _GNU_SOURCE
23 #include <sys/utsname.h>
24 #include <sys/types.h>
25 #include <sys/stat.h>
26 #include <fcntl.h>
27 #include <errno.h>
28 #include <stdio.h>
29 #include <unistd.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <stdarg.h>
33 #include <limits.h>
34 
35 #undef _GNU_SOURCE
36 #include "util.h"
37 #include "event.h"
38 #include "string.h"
39 #include "strlist.h"
40 #include "debug.h"
41 #include "cache.h"
42 #include "color.h"
43 #include "symbol.h"
44 #include "thread.h"
45 #include "debugfs.h"
46 #include "trace-event.h"	/* For __unused */
47 #include "probe-event.h"
48 #include "probe-finder.h"
49 
50 #define MAX_CMDLEN 256
51 #define MAX_PROBE_ARGS 128
52 #define PERFPROBE_GROUP "probe"
53 
54 bool probe_event_dry_run;	/* Dry run flag */
55 
56 #define semantic_error(msg ...) pr_err("Semantic error :" msg)
57 
58 /* If there is no space to write, returns -E2BIG. */
59 static int e_snprintf(char *str, size_t size, const char *format, ...)
60 	__attribute__((format(printf, 3, 4)));
61 
62 static int e_snprintf(char *str, size_t size, const char *format, ...)
63 {
64 	int ret;
65 	va_list ap;
66 	va_start(ap, format);
67 	ret = vsnprintf(str, size, format, ap);
68 	va_end(ap);
69 	if (ret >= (int)size)
70 		ret = -E2BIG;
71 	return ret;
72 }
73 
74 static char *synthesize_perf_probe_point(struct perf_probe_point *pp);
75 static struct map_groups kmap_groups;
76 static struct map *kmaps[MAP__NR_TYPES];
77 
78 /* Initialize symbol maps and path of vmlinux */
79 static int init_vmlinux(void)
80 {
81 	int ret;
82 
83 	symbol_conf.sort_by_name = true;
84 	if (symbol_conf.vmlinux_name == NULL)
85 		symbol_conf.try_vmlinux_path = true;
86 	else
87 		pr_debug("Use vmlinux: %s\n", symbol_conf.vmlinux_name);
88 	ret = symbol__init();
89 	if (ret < 0) {
90 		pr_debug("Failed to init symbol map.\n");
91 		goto out;
92 	}
93 
94 	map_groups__init(&kmap_groups);
95 	ret = map_groups__create_kernel_maps(&kmap_groups, kmaps);
96 	if (ret < 0)
97 		pr_debug("Failed to create kernel maps.\n");
98 
99 out:
100 	if (ret < 0)
101 		pr_warning("Failed to init vmlinux path.\n");
102 	return ret;
103 }
104 
105 #ifdef DWARF_SUPPORT
106 static int open_vmlinux(void)
107 {
108 	if (map__load(kmaps[MAP__FUNCTION], NULL) < 0) {
109 		pr_debug("Failed to load kernel map.\n");
110 		return -EINVAL;
111 	}
112 	pr_debug("Try to open %s\n", kmaps[MAP__FUNCTION]->dso->long_name);
113 	return open(kmaps[MAP__FUNCTION]->dso->long_name, O_RDONLY);
114 }
115 
116 /* Convert trace point to probe point with debuginfo */
117 static int convert_to_perf_probe_point(struct kprobe_trace_point *tp,
118 				       struct perf_probe_point *pp)
119 {
120 	struct symbol *sym;
121 	int fd, ret = -ENOENT;
122 
123 	sym = map__find_symbol_by_name(kmaps[MAP__FUNCTION],
124 				       tp->symbol, NULL);
125 	if (sym) {
126 		fd = open_vmlinux();
127 		if (fd >= 0) {
128 			ret = find_perf_probe_point(fd,
129 						 sym->start + tp->offset, pp);
130 			close(fd);
131 		}
132 	}
133 	if (ret <= 0) {
134 		pr_debug("Failed to find corresponding probes from "
135 			 "debuginfo. Use kprobe event information.\n");
136 		pp->function = strdup(tp->symbol);
137 		if (pp->function == NULL)
138 			return -ENOMEM;
139 		pp->offset = tp->offset;
140 	}
141 	pp->retprobe = tp->retprobe;
142 
143 	return 0;
144 }
145 
146 /* Try to find perf_probe_event with debuginfo */
147 static int try_to_find_kprobe_trace_events(struct perf_probe_event *pev,
148 					   struct kprobe_trace_event **tevs)
149 {
150 	bool need_dwarf = perf_probe_event_need_dwarf(pev);
151 	int fd, ntevs;
152 
153 	fd = open_vmlinux();
154 	if (fd < 0) {
155 		if (need_dwarf) {
156 			pr_warning("Failed to open debuginfo file.\n");
157 			return fd;
158 		}
159 		pr_debug("Could not open vmlinux. Try to use symbols.\n");
160 		return 0;
161 	}
162 
163 	/* Searching trace events corresponding to probe event */
164 	ntevs = find_kprobe_trace_events(fd, pev, tevs);
165 	close(fd);
166 
167 	if (ntevs > 0) {	/* Succeeded to find trace events */
168 		pr_debug("find %d kprobe_trace_events.\n", ntevs);
169 		return ntevs;
170 	}
171 
172 	if (ntevs == 0)	{	/* No error but failed to find probe point. */
173 		pr_warning("Probe point '%s' not found.\n",
174 			   synthesize_perf_probe_point(&pev->point));
175 		return -ENOENT;
176 	}
177 	/* Error path : ntevs < 0 */
178 	if (need_dwarf) {
179 		if (ntevs == -EBADF)
180 			pr_warning("No dwarf info found in the vmlinux - "
181 				"please rebuild with CONFIG_DEBUG_INFO=y.\n");
182 		return ntevs;
183 	}
184 	pr_debug("An error occurred in debuginfo analysis."
185 		 " Try to use symbols.\n");
186 	return 0;
187 }
188 
189 #define LINEBUF_SIZE 256
190 #define NR_ADDITIONAL_LINES 2
191 
192 static int show_one_line(FILE *fp, unsigned int l, bool skip, bool show_num)
193 {
194 	char buf[LINEBUF_SIZE];
195 	const char *color = PERF_COLOR_BLUE;
196 
197 	if (fgets(buf, LINEBUF_SIZE, fp) == NULL)
198 		goto error;
199 	if (!skip) {
200 		if (show_num)
201 			fprintf(stdout, "%7u  %s", l, buf);
202 		else
203 			color_fprintf(stdout, color, "         %s", buf);
204 	}
205 
206 	while (strlen(buf) == LINEBUF_SIZE - 1 &&
207 	       buf[LINEBUF_SIZE - 2] != '\n') {
208 		if (fgets(buf, LINEBUF_SIZE, fp) == NULL)
209 			goto error;
210 		if (!skip) {
211 			if (show_num)
212 				fprintf(stdout, "%s", buf);
213 			else
214 				color_fprintf(stdout, color, "%s", buf);
215 		}
216 	}
217 
218 	return 0;
219 error:
220 	if (feof(fp))
221 		pr_warning("Source file is shorter than expected.\n");
222 	else
223 		pr_warning("File read error: %s\n", strerror(errno));
224 
225 	return -1;
226 }
227 
228 /*
229  * Show line-range always requires debuginfo to find source file and
230  * line number.
231  */
232 int show_line_range(struct line_range *lr)
233 {
234 	unsigned int l = 1;
235 	struct line_node *ln;
236 	FILE *fp;
237 	int fd, ret;
238 
239 	/* Search a line range */
240 	ret = init_vmlinux();
241 	if (ret < 0)
242 		return ret;
243 
244 	fd = open_vmlinux();
245 	if (fd < 0) {
246 		pr_warning("Failed to open debuginfo file.\n");
247 		return fd;
248 	}
249 
250 	ret = find_line_range(fd, lr);
251 	close(fd);
252 	if (ret == 0) {
253 		pr_warning("Specified source line is not found.\n");
254 		return -ENOENT;
255 	} else if (ret < 0) {
256 		pr_warning("Debuginfo analysis failed. (%d)\n", ret);
257 		return ret;
258 	}
259 
260 	setup_pager();
261 
262 	if (lr->function)
263 		fprintf(stdout, "<%s:%d>\n", lr->function,
264 			lr->start - lr->offset);
265 	else
266 		fprintf(stdout, "<%s:%d>\n", lr->file, lr->start);
267 
268 	fp = fopen(lr->path, "r");
269 	if (fp == NULL) {
270 		pr_warning("Failed to open %s: %s\n", lr->path,
271 			   strerror(errno));
272 		return -errno;
273 	}
274 	/* Skip to starting line number */
275 	while (l < lr->start && ret >= 0)
276 		ret = show_one_line(fp, l++, true, false);
277 	if (ret < 0)
278 		goto end;
279 
280 	list_for_each_entry(ln, &lr->line_list, list) {
281 		while (ln->line > l && ret >= 0)
282 			ret = show_one_line(fp, (l++) - lr->offset,
283 					    false, false);
284 		if (ret >= 0)
285 			ret = show_one_line(fp, (l++) - lr->offset,
286 					    false, true);
287 		if (ret < 0)
288 			goto end;
289 	}
290 
291 	if (lr->end == INT_MAX)
292 		lr->end = l + NR_ADDITIONAL_LINES;
293 	while (l < lr->end && !feof(fp) && ret >= 0)
294 		ret = show_one_line(fp, (l++) - lr->offset, false, false);
295 end:
296 	fclose(fp);
297 	return ret;
298 }
299 
300 #else	/* !DWARF_SUPPORT */
301 
302 static int convert_to_perf_probe_point(struct kprobe_trace_point *tp,
303 					struct perf_probe_point *pp)
304 {
305 	pp->function = strdup(tp->symbol);
306 	if (pp->function == NULL)
307 		return -ENOMEM;
308 	pp->offset = tp->offset;
309 	pp->retprobe = tp->retprobe;
310 
311 	return 0;
312 }
313 
314 static int try_to_find_kprobe_trace_events(struct perf_probe_event *pev,
315 				struct kprobe_trace_event **tevs __unused)
316 {
317 	if (perf_probe_event_need_dwarf(pev)) {
318 		pr_warning("Debuginfo-analysis is not supported.\n");
319 		return -ENOSYS;
320 	}
321 	return 0;
322 }
323 
324 int show_line_range(struct line_range *lr __unused)
325 {
326 	pr_warning("Debuginfo-analysis is not supported.\n");
327 	return -ENOSYS;
328 }
329 
330 #endif
331 
332 int parse_line_range_desc(const char *arg, struct line_range *lr)
333 {
334 	const char *ptr;
335 	char *tmp;
336 	/*
337 	 * <Syntax>
338 	 * SRC:SLN[+NUM|-ELN]
339 	 * FUNC[:SLN[+NUM|-ELN]]
340 	 */
341 	ptr = strchr(arg, ':');
342 	if (ptr) {
343 		lr->start = (unsigned int)strtoul(ptr + 1, &tmp, 0);
344 		if (*tmp == '+')
345 			lr->end = lr->start + (unsigned int)strtoul(tmp + 1,
346 								    &tmp, 0);
347 		else if (*tmp == '-')
348 			lr->end = (unsigned int)strtoul(tmp + 1, &tmp, 0);
349 		else
350 			lr->end = 0;
351 		pr_debug("Line range is %u to %u\n", lr->start, lr->end);
352 		if (lr->end && lr->start > lr->end) {
353 			semantic_error("Start line must be smaller"
354 				       " than end line.\n");
355 			return -EINVAL;
356 		}
357 		if (*tmp != '\0') {
358 			semantic_error("Tailing with invalid character '%d'.\n",
359 				       *tmp);
360 			return -EINVAL;
361 		}
362 		tmp = strndup(arg, (ptr - arg));
363 	} else
364 		tmp = strdup(arg);
365 
366 	if (tmp == NULL)
367 		return -ENOMEM;
368 
369 	if (strchr(tmp, '.'))
370 		lr->file = tmp;
371 	else
372 		lr->function = tmp;
373 
374 	return 0;
375 }
376 
377 /* Check the name is good for event/group */
378 static bool check_event_name(const char *name)
379 {
380 	if (!isalpha(*name) && *name != '_')
381 		return false;
382 	while (*++name != '\0') {
383 		if (!isalpha(*name) && !isdigit(*name) && *name != '_')
384 			return false;
385 	}
386 	return true;
387 }
388 
389 /* Parse probepoint definition. */
390 static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
391 {
392 	struct perf_probe_point *pp = &pev->point;
393 	char *ptr, *tmp;
394 	char c, nc = 0;
395 	/*
396 	 * <Syntax>
397 	 * perf probe [EVENT=]SRC[:LN|;PTN]
398 	 * perf probe [EVENT=]FUNC[@SRC][+OFFS|%return|:LN|;PAT]
399 	 *
400 	 * TODO:Group name support
401 	 */
402 
403 	ptr = strpbrk(arg, ";=@+%");
404 	if (ptr && *ptr == '=') {	/* Event name */
405 		*ptr = '\0';
406 		tmp = ptr + 1;
407 		if (strchr(arg, ':')) {
408 			semantic_error("Group name is not supported yet.\n");
409 			return -ENOTSUP;
410 		}
411 		if (!check_event_name(arg)) {
412 			semantic_error("%s is bad for event name -it must "
413 				       "follow C symbol-naming rule.\n", arg);
414 			return -EINVAL;
415 		}
416 		pev->event = strdup(arg);
417 		if (pev->event == NULL)
418 			return -ENOMEM;
419 		pev->group = NULL;
420 		arg = tmp;
421 	}
422 
423 	ptr = strpbrk(arg, ";:+@%");
424 	if (ptr) {
425 		nc = *ptr;
426 		*ptr++ = '\0';
427 	}
428 
429 	tmp = strdup(arg);
430 	if (tmp == NULL)
431 		return -ENOMEM;
432 
433 	/* Check arg is function or file and copy it */
434 	if (strchr(tmp, '.'))	/* File */
435 		pp->file = tmp;
436 	else			/* Function */
437 		pp->function = tmp;
438 
439 	/* Parse other options */
440 	while (ptr) {
441 		arg = ptr;
442 		c = nc;
443 		if (c == ';') {	/* Lazy pattern must be the last part */
444 			pp->lazy_line = strdup(arg);
445 			if (pp->lazy_line == NULL)
446 				return -ENOMEM;
447 			break;
448 		}
449 		ptr = strpbrk(arg, ";:+@%");
450 		if (ptr) {
451 			nc = *ptr;
452 			*ptr++ = '\0';
453 		}
454 		switch (c) {
455 		case ':':	/* Line number */
456 			pp->line = strtoul(arg, &tmp, 0);
457 			if (*tmp != '\0') {
458 				semantic_error("There is non-digit char"
459 					       " in line number.\n");
460 				return -EINVAL;
461 			}
462 			break;
463 		case '+':	/* Byte offset from a symbol */
464 			pp->offset = strtoul(arg, &tmp, 0);
465 			if (*tmp != '\0') {
466 				semantic_error("There is non-digit character"
467 						" in offset.\n");
468 				return -EINVAL;
469 			}
470 			break;
471 		case '@':	/* File name */
472 			if (pp->file) {
473 				semantic_error("SRC@SRC is not allowed.\n");
474 				return -EINVAL;
475 			}
476 			pp->file = strdup(arg);
477 			if (pp->file == NULL)
478 				return -ENOMEM;
479 			break;
480 		case '%':	/* Probe places */
481 			if (strcmp(arg, "return") == 0) {
482 				pp->retprobe = 1;
483 			} else {	/* Others not supported yet */
484 				semantic_error("%%%s is not supported.\n", arg);
485 				return -ENOTSUP;
486 			}
487 			break;
488 		default:	/* Buggy case */
489 			pr_err("This program has a bug at %s:%d.\n",
490 				__FILE__, __LINE__);
491 			return -ENOTSUP;
492 			break;
493 		}
494 	}
495 
496 	/* Exclusion check */
497 	if (pp->lazy_line && pp->line) {
498 		semantic_error("Lazy pattern can't be used with line number.");
499 		return -EINVAL;
500 	}
501 
502 	if (pp->lazy_line && pp->offset) {
503 		semantic_error("Lazy pattern can't be used with offset.");
504 		return -EINVAL;
505 	}
506 
507 	if (pp->line && pp->offset) {
508 		semantic_error("Offset can't be used with line number.");
509 		return -EINVAL;
510 	}
511 
512 	if (!pp->line && !pp->lazy_line && pp->file && !pp->function) {
513 		semantic_error("File always requires line number or "
514 			       "lazy pattern.");
515 		return -EINVAL;
516 	}
517 
518 	if (pp->offset && !pp->function) {
519 		semantic_error("Offset requires an entry function.");
520 		return -EINVAL;
521 	}
522 
523 	if (pp->retprobe && !pp->function) {
524 		semantic_error("Return probe requires an entry function.");
525 		return -EINVAL;
526 	}
527 
528 	if ((pp->offset || pp->line || pp->lazy_line) && pp->retprobe) {
529 		semantic_error("Offset/Line/Lazy pattern can't be used with "
530 			       "return probe.");
531 		return -EINVAL;
532 	}
533 
534 	pr_debug("symbol:%s file:%s line:%d offset:%lu return:%d lazy:%s\n",
535 		 pp->function, pp->file, pp->line, pp->offset, pp->retprobe,
536 		 pp->lazy_line);
537 	return 0;
538 }
539 
540 /* Parse perf-probe event argument */
541 static int parse_perf_probe_arg(char *str, struct perf_probe_arg *arg)
542 {
543 	char *tmp;
544 	struct perf_probe_arg_field **fieldp;
545 
546 	pr_debug("parsing arg: %s into ", str);
547 
548 	tmp = strchr(str, '=');
549 	if (tmp) {
550 		arg->name = strndup(str, tmp - str);
551 		if (arg->name == NULL)
552 			return -ENOMEM;
553 		pr_debug("name:%s ", arg->name);
554 		str = tmp + 1;
555 	}
556 
557 	tmp = strchr(str, ':');
558 	if (tmp) {	/* Type setting */
559 		*tmp = '\0';
560 		arg->type = strdup(tmp + 1);
561 		if (arg->type == NULL)
562 			return -ENOMEM;
563 		pr_debug("type:%s ", arg->type);
564 	}
565 
566 	tmp = strpbrk(str, "-.");
567 	if (!is_c_varname(str) || !tmp) {
568 		/* A variable, register, symbol or special value */
569 		arg->var = strdup(str);
570 		if (arg->var == NULL)
571 			return -ENOMEM;
572 		pr_debug("%s\n", arg->var);
573 		return 0;
574 	}
575 
576 	/* Structure fields */
577 	arg->var = strndup(str, tmp - str);
578 	if (arg->var == NULL)
579 		return -ENOMEM;
580 	pr_debug("%s, ", arg->var);
581 	fieldp = &arg->field;
582 
583 	do {
584 		*fieldp = zalloc(sizeof(struct perf_probe_arg_field));
585 		if (*fieldp == NULL)
586 			return -ENOMEM;
587 		if (*tmp == '.') {
588 			str = tmp + 1;
589 			(*fieldp)->ref = false;
590 		} else if (tmp[1] == '>') {
591 			str = tmp + 2;
592 			(*fieldp)->ref = true;
593 		} else {
594 			semantic_error("Argument parse error: %s\n", str);
595 			return -EINVAL;
596 		}
597 
598 		tmp = strpbrk(str, "-.");
599 		if (tmp) {
600 			(*fieldp)->name = strndup(str, tmp - str);
601 			if ((*fieldp)->name == NULL)
602 				return -ENOMEM;
603 			pr_debug("%s(%d), ", (*fieldp)->name, (*fieldp)->ref);
604 			fieldp = &(*fieldp)->next;
605 		}
606 	} while (tmp);
607 	(*fieldp)->name = strdup(str);
608 	if ((*fieldp)->name == NULL)
609 		return -ENOMEM;
610 	pr_debug("%s(%d)\n", (*fieldp)->name, (*fieldp)->ref);
611 
612 	/* If no name is specified, set the last field name */
613 	if (!arg->name) {
614 		arg->name = strdup((*fieldp)->name);
615 		if (arg->name == NULL)
616 			return -ENOMEM;
617 	}
618 	return 0;
619 }
620 
621 /* Parse perf-probe event command */
622 int parse_perf_probe_command(const char *cmd, struct perf_probe_event *pev)
623 {
624 	char **argv;
625 	int argc, i, ret = 0;
626 
627 	argv = argv_split(cmd, &argc);
628 	if (!argv) {
629 		pr_debug("Failed to split arguments.\n");
630 		return -ENOMEM;
631 	}
632 	if (argc - 1 > MAX_PROBE_ARGS) {
633 		semantic_error("Too many probe arguments (%d).\n", argc - 1);
634 		ret = -ERANGE;
635 		goto out;
636 	}
637 	/* Parse probe point */
638 	ret = parse_perf_probe_point(argv[0], pev);
639 	if (ret < 0)
640 		goto out;
641 
642 	/* Copy arguments and ensure return probe has no C argument */
643 	pev->nargs = argc - 1;
644 	pev->args = zalloc(sizeof(struct perf_probe_arg) * pev->nargs);
645 	if (pev->args == NULL) {
646 		ret = -ENOMEM;
647 		goto out;
648 	}
649 	for (i = 0; i < pev->nargs && ret >= 0; i++) {
650 		ret = parse_perf_probe_arg(argv[i + 1], &pev->args[i]);
651 		if (ret >= 0 &&
652 		    is_c_varname(pev->args[i].var) && pev->point.retprobe) {
653 			semantic_error("You can't specify local variable for"
654 				       " kretprobe.\n");
655 			ret = -EINVAL;
656 		}
657 	}
658 out:
659 	argv_free(argv);
660 
661 	return ret;
662 }
663 
664 /* Return true if this perf_probe_event requires debuginfo */
665 bool perf_probe_event_need_dwarf(struct perf_probe_event *pev)
666 {
667 	int i;
668 
669 	if (pev->point.file || pev->point.line || pev->point.lazy_line)
670 		return true;
671 
672 	for (i = 0; i < pev->nargs; i++)
673 		if (is_c_varname(pev->args[i].var))
674 			return true;
675 
676 	return false;
677 }
678 
679 /* Parse kprobe_events event into struct probe_point */
680 int parse_kprobe_trace_command(const char *cmd, struct kprobe_trace_event *tev)
681 {
682 	struct kprobe_trace_point *tp = &tev->point;
683 	char pr;
684 	char *p;
685 	int ret, i, argc;
686 	char **argv;
687 
688 	pr_debug("Parsing kprobe_events: %s\n", cmd);
689 	argv = argv_split(cmd, &argc);
690 	if (!argv) {
691 		pr_debug("Failed to split arguments.\n");
692 		return -ENOMEM;
693 	}
694 	if (argc < 2) {
695 		semantic_error("Too few probe arguments.\n");
696 		ret = -ERANGE;
697 		goto out;
698 	}
699 
700 	/* Scan event and group name. */
701 	ret = sscanf(argv[0], "%c:%a[^/ \t]/%a[^ \t]",
702 		     &pr, (float *)(void *)&tev->group,
703 		     (float *)(void *)&tev->event);
704 	if (ret != 3) {
705 		semantic_error("Failed to parse event name: %s\n", argv[0]);
706 		ret = -EINVAL;
707 		goto out;
708 	}
709 	pr_debug("Group:%s Event:%s probe:%c\n", tev->group, tev->event, pr);
710 
711 	tp->retprobe = (pr == 'r');
712 
713 	/* Scan function name and offset */
714 	ret = sscanf(argv[1], "%a[^+]+%lu", (float *)(void *)&tp->symbol,
715 		     &tp->offset);
716 	if (ret == 1)
717 		tp->offset = 0;
718 
719 	tev->nargs = argc - 2;
720 	tev->args = zalloc(sizeof(struct kprobe_trace_arg) * tev->nargs);
721 	if (tev->args == NULL) {
722 		ret = -ENOMEM;
723 		goto out;
724 	}
725 	for (i = 0; i < tev->nargs; i++) {
726 		p = strchr(argv[i + 2], '=');
727 		if (p)	/* We don't need which register is assigned. */
728 			*p++ = '\0';
729 		else
730 			p = argv[i + 2];
731 		tev->args[i].name = strdup(argv[i + 2]);
732 		/* TODO: parse regs and offset */
733 		tev->args[i].value = strdup(p);
734 		if (tev->args[i].name == NULL || tev->args[i].value == NULL) {
735 			ret = -ENOMEM;
736 			goto out;
737 		}
738 	}
739 	ret = 0;
740 out:
741 	argv_free(argv);
742 	return ret;
743 }
744 
745 /* Compose only probe arg */
746 int synthesize_perf_probe_arg(struct perf_probe_arg *pa, char *buf, size_t len)
747 {
748 	struct perf_probe_arg_field *field = pa->field;
749 	int ret;
750 	char *tmp = buf;
751 
752 	if (pa->name && pa->var)
753 		ret = e_snprintf(tmp, len, "%s=%s", pa->name, pa->var);
754 	else
755 		ret = e_snprintf(tmp, len, "%s", pa->name ? pa->name : pa->var);
756 	if (ret <= 0)
757 		goto error;
758 	tmp += ret;
759 	len -= ret;
760 
761 	while (field) {
762 		ret = e_snprintf(tmp, len, "%s%s", field->ref ? "->" : ".",
763 				 field->name);
764 		if (ret <= 0)
765 			goto error;
766 		tmp += ret;
767 		len -= ret;
768 		field = field->next;
769 	}
770 
771 	if (pa->type) {
772 		ret = e_snprintf(tmp, len, ":%s", pa->type);
773 		if (ret <= 0)
774 			goto error;
775 		tmp += ret;
776 		len -= ret;
777 	}
778 
779 	return tmp - buf;
780 error:
781 	pr_debug("Failed to synthesize perf probe argument: %s",
782 		 strerror(-ret));
783 	return ret;
784 }
785 
786 /* Compose only probe point (not argument) */
787 static char *synthesize_perf_probe_point(struct perf_probe_point *pp)
788 {
789 	char *buf, *tmp;
790 	char offs[32] = "", line[32] = "", file[32] = "";
791 	int ret, len;
792 
793 	buf = zalloc(MAX_CMDLEN);
794 	if (buf == NULL) {
795 		ret = -ENOMEM;
796 		goto error;
797 	}
798 	if (pp->offset) {
799 		ret = e_snprintf(offs, 32, "+%lu", pp->offset);
800 		if (ret <= 0)
801 			goto error;
802 	}
803 	if (pp->line) {
804 		ret = e_snprintf(line, 32, ":%d", pp->line);
805 		if (ret <= 0)
806 			goto error;
807 	}
808 	if (pp->file) {
809 		len = strlen(pp->file) - 32;
810 		if (len < 0)
811 			len = 0;
812 		tmp = strchr(pp->file + len, '/');
813 		if (!tmp)
814 			tmp = pp->file + len - 1;
815 		ret = e_snprintf(file, 32, "@%s", tmp + 1);
816 		if (ret <= 0)
817 			goto error;
818 	}
819 
820 	if (pp->function)
821 		ret = e_snprintf(buf, MAX_CMDLEN, "%s%s%s%s%s", pp->function,
822 				 offs, pp->retprobe ? "%return" : "", line,
823 				 file);
824 	else
825 		ret = e_snprintf(buf, MAX_CMDLEN, "%s%s", file, line);
826 	if (ret <= 0)
827 		goto error;
828 
829 	return buf;
830 error:
831 	pr_debug("Failed to synthesize perf probe point: %s",
832 		 strerror(-ret));
833 	if (buf)
834 		free(buf);
835 	return NULL;
836 }
837 
838 #if 0
839 char *synthesize_perf_probe_command(struct perf_probe_event *pev)
840 {
841 	char *buf;
842 	int i, len, ret;
843 
844 	buf = synthesize_perf_probe_point(&pev->point);
845 	if (!buf)
846 		return NULL;
847 
848 	len = strlen(buf);
849 	for (i = 0; i < pev->nargs; i++) {
850 		ret = e_snprintf(&buf[len], MAX_CMDLEN - len, " %s",
851 				 pev->args[i].name);
852 		if (ret <= 0) {
853 			free(buf);
854 			return NULL;
855 		}
856 		len += ret;
857 	}
858 
859 	return buf;
860 }
861 #endif
862 
863 static int __synthesize_kprobe_trace_arg_ref(struct kprobe_trace_arg_ref *ref,
864 					     char **buf, size_t *buflen,
865 					     int depth)
866 {
867 	int ret;
868 	if (ref->next) {
869 		depth = __synthesize_kprobe_trace_arg_ref(ref->next, buf,
870 							 buflen, depth + 1);
871 		if (depth < 0)
872 			goto out;
873 	}
874 
875 	ret = e_snprintf(*buf, *buflen, "%+ld(", ref->offset);
876 	if (ret < 0)
877 		depth = ret;
878 	else {
879 		*buf += ret;
880 		*buflen -= ret;
881 	}
882 out:
883 	return depth;
884 
885 }
886 
887 static int synthesize_kprobe_trace_arg(struct kprobe_trace_arg *arg,
888 				       char *buf, size_t buflen)
889 {
890 	int ret, depth = 0;
891 	char *tmp = buf;
892 
893 	/* Argument name or separator */
894 	if (arg->name)
895 		ret = e_snprintf(buf, buflen, " %s=", arg->name);
896 	else
897 		ret = e_snprintf(buf, buflen, " ");
898 	if (ret < 0)
899 		return ret;
900 	buf += ret;
901 	buflen -= ret;
902 
903 	/* Dereferencing arguments */
904 	if (arg->ref) {
905 		depth = __synthesize_kprobe_trace_arg_ref(arg->ref, &buf,
906 							  &buflen, 1);
907 		if (depth < 0)
908 			return depth;
909 	}
910 
911 	/* Print argument value */
912 	ret = e_snprintf(buf, buflen, "%s", arg->value);
913 	if (ret < 0)
914 		return ret;
915 	buf += ret;
916 	buflen -= ret;
917 
918 	/* Closing */
919 	while (depth--) {
920 		ret = e_snprintf(buf, buflen, ")");
921 		if (ret < 0)
922 			return ret;
923 		buf += ret;
924 		buflen -= ret;
925 	}
926 	/* Print argument type */
927 	if (arg->type) {
928 		ret = e_snprintf(buf, buflen, ":%s", arg->type);
929 		if (ret <= 0)
930 			return ret;
931 		buf += ret;
932 	}
933 
934 	return buf - tmp;
935 }
936 
937 char *synthesize_kprobe_trace_command(struct kprobe_trace_event *tev)
938 {
939 	struct kprobe_trace_point *tp = &tev->point;
940 	char *buf;
941 	int i, len, ret;
942 
943 	buf = zalloc(MAX_CMDLEN);
944 	if (buf == NULL)
945 		return NULL;
946 
947 	len = e_snprintf(buf, MAX_CMDLEN, "%c:%s/%s %s+%lu",
948 			 tp->retprobe ? 'r' : 'p',
949 			 tev->group, tev->event,
950 			 tp->symbol, tp->offset);
951 	if (len <= 0)
952 		goto error;
953 
954 	for (i = 0; i < tev->nargs; i++) {
955 		ret = synthesize_kprobe_trace_arg(&tev->args[i], buf + len,
956 						  MAX_CMDLEN - len);
957 		if (ret <= 0)
958 			goto error;
959 		len += ret;
960 	}
961 
962 	return buf;
963 error:
964 	free(buf);
965 	return NULL;
966 }
967 
968 int convert_to_perf_probe_event(struct kprobe_trace_event *tev,
969 				struct perf_probe_event *pev)
970 {
971 	char buf[64] = "";
972 	int i, ret;
973 
974 	/* Convert event/group name */
975 	pev->event = strdup(tev->event);
976 	pev->group = strdup(tev->group);
977 	if (pev->event == NULL || pev->group == NULL)
978 		return -ENOMEM;
979 
980 	/* Convert trace_point to probe_point */
981 	ret = convert_to_perf_probe_point(&tev->point, &pev->point);
982 	if (ret < 0)
983 		return ret;
984 
985 	/* Convert trace_arg to probe_arg */
986 	pev->nargs = tev->nargs;
987 	pev->args = zalloc(sizeof(struct perf_probe_arg) * pev->nargs);
988 	if (pev->args == NULL)
989 		return -ENOMEM;
990 	for (i = 0; i < tev->nargs && ret >= 0; i++) {
991 		if (tev->args[i].name)
992 			pev->args[i].name = strdup(tev->args[i].name);
993 		else {
994 			ret = synthesize_kprobe_trace_arg(&tev->args[i],
995 							  buf, 64);
996 			pev->args[i].name = strdup(buf);
997 		}
998 		if (pev->args[i].name == NULL && ret >= 0)
999 			ret = -ENOMEM;
1000 	}
1001 
1002 	if (ret < 0)
1003 		clear_perf_probe_event(pev);
1004 
1005 	return ret;
1006 }
1007 
1008 void clear_perf_probe_event(struct perf_probe_event *pev)
1009 {
1010 	struct perf_probe_point *pp = &pev->point;
1011 	struct perf_probe_arg_field *field, *next;
1012 	int i;
1013 
1014 	if (pev->event)
1015 		free(pev->event);
1016 	if (pev->group)
1017 		free(pev->group);
1018 	if (pp->file)
1019 		free(pp->file);
1020 	if (pp->function)
1021 		free(pp->function);
1022 	if (pp->lazy_line)
1023 		free(pp->lazy_line);
1024 	for (i = 0; i < pev->nargs; i++) {
1025 		if (pev->args[i].name)
1026 			free(pev->args[i].name);
1027 		if (pev->args[i].var)
1028 			free(pev->args[i].var);
1029 		if (pev->args[i].type)
1030 			free(pev->args[i].type);
1031 		field = pev->args[i].field;
1032 		while (field) {
1033 			next = field->next;
1034 			if (field->name)
1035 				free(field->name);
1036 			free(field);
1037 			field = next;
1038 		}
1039 	}
1040 	if (pev->args)
1041 		free(pev->args);
1042 	memset(pev, 0, sizeof(*pev));
1043 }
1044 
1045 void clear_kprobe_trace_event(struct kprobe_trace_event *tev)
1046 {
1047 	struct kprobe_trace_arg_ref *ref, *next;
1048 	int i;
1049 
1050 	if (tev->event)
1051 		free(tev->event);
1052 	if (tev->group)
1053 		free(tev->group);
1054 	if (tev->point.symbol)
1055 		free(tev->point.symbol);
1056 	for (i = 0; i < tev->nargs; i++) {
1057 		if (tev->args[i].name)
1058 			free(tev->args[i].name);
1059 		if (tev->args[i].value)
1060 			free(tev->args[i].value);
1061 		if (tev->args[i].type)
1062 			free(tev->args[i].type);
1063 		ref = tev->args[i].ref;
1064 		while (ref) {
1065 			next = ref->next;
1066 			free(ref);
1067 			ref = next;
1068 		}
1069 	}
1070 	if (tev->args)
1071 		free(tev->args);
1072 	memset(tev, 0, sizeof(*tev));
1073 }
1074 
1075 static int open_kprobe_events(bool readwrite)
1076 {
1077 	char buf[PATH_MAX];
1078 	const char *__debugfs;
1079 	int ret;
1080 
1081 	__debugfs = debugfs_find_mountpoint();
1082 	if (__debugfs == NULL) {
1083 		pr_warning("Debugfs is not mounted.\n");
1084 		return -ENOENT;
1085 	}
1086 
1087 	ret = e_snprintf(buf, PATH_MAX, "%stracing/kprobe_events", __debugfs);
1088 	if (ret >= 0) {
1089 		pr_debug("Opening %s write=%d\n", buf, readwrite);
1090 		if (readwrite && !probe_event_dry_run)
1091 			ret = open(buf, O_RDWR, O_APPEND);
1092 		else
1093 			ret = open(buf, O_RDONLY, 0);
1094 	}
1095 
1096 	if (ret < 0) {
1097 		if (errno == ENOENT)
1098 			pr_warning("kprobe_events file does not exist - please"
1099 				 " rebuild kernel with CONFIG_KPROBE_EVENT.\n");
1100 		else
1101 			pr_warning("Failed to open kprobe_events file: %s\n",
1102 				   strerror(errno));
1103 	}
1104 	return ret;
1105 }
1106 
1107 /* Get raw string list of current kprobe_events */
1108 static struct strlist *get_kprobe_trace_command_rawlist(int fd)
1109 {
1110 	int ret, idx;
1111 	FILE *fp;
1112 	char buf[MAX_CMDLEN];
1113 	char *p;
1114 	struct strlist *sl;
1115 
1116 	sl = strlist__new(true, NULL);
1117 
1118 	fp = fdopen(dup(fd), "r");
1119 	while (!feof(fp)) {
1120 		p = fgets(buf, MAX_CMDLEN, fp);
1121 		if (!p)
1122 			break;
1123 
1124 		idx = strlen(p) - 1;
1125 		if (p[idx] == '\n')
1126 			p[idx] = '\0';
1127 		ret = strlist__add(sl, buf);
1128 		if (ret < 0) {
1129 			pr_debug("strlist__add failed: %s\n", strerror(-ret));
1130 			strlist__delete(sl);
1131 			return NULL;
1132 		}
1133 	}
1134 	fclose(fp);
1135 
1136 	return sl;
1137 }
1138 
1139 /* Show an event */
1140 static int show_perf_probe_event(struct perf_probe_event *pev)
1141 {
1142 	int i, ret;
1143 	char buf[128];
1144 	char *place;
1145 
1146 	/* Synthesize only event probe point */
1147 	place = synthesize_perf_probe_point(&pev->point);
1148 	if (!place)
1149 		return -EINVAL;
1150 
1151 	ret = e_snprintf(buf, 128, "%s:%s", pev->group, pev->event);
1152 	if (ret < 0)
1153 		return ret;
1154 
1155 	printf("  %-20s (on %s", buf, place);
1156 
1157 	if (pev->nargs > 0) {
1158 		printf(" with");
1159 		for (i = 0; i < pev->nargs; i++) {
1160 			ret = synthesize_perf_probe_arg(&pev->args[i],
1161 							buf, 128);
1162 			if (ret < 0)
1163 				break;
1164 			printf(" %s", buf);
1165 		}
1166 	}
1167 	printf(")\n");
1168 	free(place);
1169 	return ret;
1170 }
1171 
1172 /* List up current perf-probe events */
1173 int show_perf_probe_events(void)
1174 {
1175 	int fd, ret;
1176 	struct kprobe_trace_event tev;
1177 	struct perf_probe_event pev;
1178 	struct strlist *rawlist;
1179 	struct str_node *ent;
1180 
1181 	setup_pager();
1182 	ret = init_vmlinux();
1183 	if (ret < 0)
1184 		return ret;
1185 
1186 	memset(&tev, 0, sizeof(tev));
1187 	memset(&pev, 0, sizeof(pev));
1188 
1189 	fd = open_kprobe_events(false);
1190 	if (fd < 0)
1191 		return fd;
1192 
1193 	rawlist = get_kprobe_trace_command_rawlist(fd);
1194 	close(fd);
1195 	if (!rawlist)
1196 		return -ENOENT;
1197 
1198 	strlist__for_each(ent, rawlist) {
1199 		ret = parse_kprobe_trace_command(ent->s, &tev);
1200 		if (ret >= 0) {
1201 			ret = convert_to_perf_probe_event(&tev, &pev);
1202 			if (ret >= 0)
1203 				ret = show_perf_probe_event(&pev);
1204 		}
1205 		clear_perf_probe_event(&pev);
1206 		clear_kprobe_trace_event(&tev);
1207 		if (ret < 0)
1208 			break;
1209 	}
1210 	strlist__delete(rawlist);
1211 
1212 	return ret;
1213 }
1214 
1215 /* Get current perf-probe event names */
1216 static struct strlist *get_kprobe_trace_event_names(int fd, bool include_group)
1217 {
1218 	char buf[128];
1219 	struct strlist *sl, *rawlist;
1220 	struct str_node *ent;
1221 	struct kprobe_trace_event tev;
1222 	int ret = 0;
1223 
1224 	memset(&tev, 0, sizeof(tev));
1225 
1226 	rawlist = get_kprobe_trace_command_rawlist(fd);
1227 	sl = strlist__new(true, NULL);
1228 	strlist__for_each(ent, rawlist) {
1229 		ret = parse_kprobe_trace_command(ent->s, &tev);
1230 		if (ret < 0)
1231 			break;
1232 		if (include_group) {
1233 			ret = e_snprintf(buf, 128, "%s:%s", tev.group,
1234 					tev.event);
1235 			if (ret >= 0)
1236 				ret = strlist__add(sl, buf);
1237 		} else
1238 			ret = strlist__add(sl, tev.event);
1239 		clear_kprobe_trace_event(&tev);
1240 		if (ret < 0)
1241 			break;
1242 	}
1243 	strlist__delete(rawlist);
1244 
1245 	if (ret < 0) {
1246 		strlist__delete(sl);
1247 		return NULL;
1248 	}
1249 	return sl;
1250 }
1251 
1252 static int write_kprobe_trace_event(int fd, struct kprobe_trace_event *tev)
1253 {
1254 	int ret;
1255 	char *buf = synthesize_kprobe_trace_command(tev);
1256 
1257 	if (!buf) {
1258 		pr_debug("Failed to synthesize kprobe trace event.\n");
1259 		return -EINVAL;
1260 	}
1261 
1262 	pr_debug("Writing event: %s\n", buf);
1263 	if (!probe_event_dry_run) {
1264 		ret = write(fd, buf, strlen(buf));
1265 		if (ret <= 0)
1266 			pr_warning("Failed to write event: %s\n",
1267 				   strerror(errno));
1268 	}
1269 	free(buf);
1270 	return ret;
1271 }
1272 
1273 static int get_new_event_name(char *buf, size_t len, const char *base,
1274 			      struct strlist *namelist, bool allow_suffix)
1275 {
1276 	int i, ret;
1277 
1278 	/* Try no suffix */
1279 	ret = e_snprintf(buf, len, "%s", base);
1280 	if (ret < 0) {
1281 		pr_debug("snprintf() failed: %s\n", strerror(-ret));
1282 		return ret;
1283 	}
1284 	if (!strlist__has_entry(namelist, buf))
1285 		return 0;
1286 
1287 	if (!allow_suffix) {
1288 		pr_warning("Error: event \"%s\" already exists. "
1289 			   "(Use -f to force duplicates.)\n", base);
1290 		return -EEXIST;
1291 	}
1292 
1293 	/* Try to add suffix */
1294 	for (i = 1; i < MAX_EVENT_INDEX; i++) {
1295 		ret = e_snprintf(buf, len, "%s_%d", base, i);
1296 		if (ret < 0) {
1297 			pr_debug("snprintf() failed: %s\n", strerror(-ret));
1298 			return ret;
1299 		}
1300 		if (!strlist__has_entry(namelist, buf))
1301 			break;
1302 	}
1303 	if (i == MAX_EVENT_INDEX) {
1304 		pr_warning("Too many events are on the same function.\n");
1305 		ret = -ERANGE;
1306 	}
1307 
1308 	return ret;
1309 }
1310 
1311 static int __add_kprobe_trace_events(struct perf_probe_event *pev,
1312 				     struct kprobe_trace_event *tevs,
1313 				     int ntevs, bool allow_suffix)
1314 {
1315 	int i, fd, ret;
1316 	struct kprobe_trace_event *tev = NULL;
1317 	char buf[64];
1318 	const char *event, *group;
1319 	struct strlist *namelist;
1320 
1321 	fd = open_kprobe_events(true);
1322 	if (fd < 0)
1323 		return fd;
1324 	/* Get current event names */
1325 	namelist = get_kprobe_trace_event_names(fd, false);
1326 	if (!namelist) {
1327 		pr_debug("Failed to get current event list.\n");
1328 		return -EIO;
1329 	}
1330 
1331 	ret = 0;
1332 	printf("Add new event%s\n", (ntevs > 1) ? "s:" : ":");
1333 	for (i = 0; i < ntevs; i++) {
1334 		tev = &tevs[i];
1335 		if (pev->event)
1336 			event = pev->event;
1337 		else
1338 			if (pev->point.function)
1339 				event = pev->point.function;
1340 			else
1341 				event = tev->point.symbol;
1342 		if (pev->group)
1343 			group = pev->group;
1344 		else
1345 			group = PERFPROBE_GROUP;
1346 
1347 		/* Get an unused new event name */
1348 		ret = get_new_event_name(buf, 64, event,
1349 					 namelist, allow_suffix);
1350 		if (ret < 0)
1351 			break;
1352 		event = buf;
1353 
1354 		tev->event = strdup(event);
1355 		tev->group = strdup(group);
1356 		if (tev->event == NULL || tev->group == NULL) {
1357 			ret = -ENOMEM;
1358 			break;
1359 		}
1360 		ret = write_kprobe_trace_event(fd, tev);
1361 		if (ret < 0)
1362 			break;
1363 		/* Add added event name to namelist */
1364 		strlist__add(namelist, event);
1365 
1366 		/* Trick here - save current event/group */
1367 		event = pev->event;
1368 		group = pev->group;
1369 		pev->event = tev->event;
1370 		pev->group = tev->group;
1371 		show_perf_probe_event(pev);
1372 		/* Trick here - restore current event/group */
1373 		pev->event = (char *)event;
1374 		pev->group = (char *)group;
1375 
1376 		/*
1377 		 * Probes after the first probe which comes from same
1378 		 * user input are always allowed to add suffix, because
1379 		 * there might be several addresses corresponding to
1380 		 * one code line.
1381 		 */
1382 		allow_suffix = true;
1383 	}
1384 
1385 	if (ret >= 0) {
1386 		/* Show how to use the event. */
1387 		printf("\nYou can now use it on all perf tools, such as:\n\n");
1388 		printf("\tperf record -e %s:%s -aR sleep 1\n\n", tev->group,
1389 			 tev->event);
1390 	}
1391 
1392 	strlist__delete(namelist);
1393 	close(fd);
1394 	return ret;
1395 }
1396 
1397 static int convert_to_kprobe_trace_events(struct perf_probe_event *pev,
1398 					  struct kprobe_trace_event **tevs)
1399 {
1400 	struct symbol *sym;
1401 	int ret = 0, i;
1402 	struct kprobe_trace_event *tev;
1403 
1404 	/* Convert perf_probe_event with debuginfo */
1405 	ret = try_to_find_kprobe_trace_events(pev, tevs);
1406 	if (ret != 0)
1407 		return ret;
1408 
1409 	/* Allocate trace event buffer */
1410 	tev = *tevs = zalloc(sizeof(struct kprobe_trace_event));
1411 	if (tev == NULL)
1412 		return -ENOMEM;
1413 
1414 	/* Copy parameters */
1415 	tev->point.symbol = strdup(pev->point.function);
1416 	if (tev->point.symbol == NULL) {
1417 		ret = -ENOMEM;
1418 		goto error;
1419 	}
1420 	tev->point.offset = pev->point.offset;
1421 	tev->nargs = pev->nargs;
1422 	if (tev->nargs) {
1423 		tev->args = zalloc(sizeof(struct kprobe_trace_arg)
1424 				   * tev->nargs);
1425 		if (tev->args == NULL) {
1426 			ret = -ENOMEM;
1427 			goto error;
1428 		}
1429 		for (i = 0; i < tev->nargs; i++) {
1430 			if (pev->args[i].name) {
1431 				tev->args[i].name = strdup(pev->args[i].name);
1432 				if (tev->args[i].name == NULL) {
1433 					ret = -ENOMEM;
1434 					goto error;
1435 				}
1436 			}
1437 			tev->args[i].value = strdup(pev->args[i].var);
1438 			if (tev->args[i].value == NULL) {
1439 				ret = -ENOMEM;
1440 				goto error;
1441 			}
1442 			if (pev->args[i].type) {
1443 				tev->args[i].type = strdup(pev->args[i].type);
1444 				if (tev->args[i].type == NULL) {
1445 					ret = -ENOMEM;
1446 					goto error;
1447 				}
1448 			}
1449 		}
1450 	}
1451 
1452 	/* Currently just checking function name from symbol map */
1453 	sym = map__find_symbol_by_name(kmaps[MAP__FUNCTION],
1454 				       tev->point.symbol, NULL);
1455 	if (!sym) {
1456 		pr_warning("Kernel symbol \'%s\' not found.\n",
1457 			   tev->point.symbol);
1458 		ret = -ENOENT;
1459 		goto error;
1460 	}
1461 
1462 	return 1;
1463 error:
1464 	clear_kprobe_trace_event(tev);
1465 	free(tev);
1466 	*tevs = NULL;
1467 	return ret;
1468 }
1469 
1470 struct __event_package {
1471 	struct perf_probe_event		*pev;
1472 	struct kprobe_trace_event	*tevs;
1473 	int				ntevs;
1474 };
1475 
1476 int add_perf_probe_events(struct perf_probe_event *pevs, int npevs,
1477 			  bool force_add)
1478 {
1479 	int i, j, ret;
1480 	struct __event_package *pkgs;
1481 
1482 	pkgs = zalloc(sizeof(struct __event_package) * npevs);
1483 	if (pkgs == NULL)
1484 		return -ENOMEM;
1485 
1486 	/* Init vmlinux path */
1487 	ret = init_vmlinux();
1488 	if (ret < 0)
1489 		return ret;
1490 
1491 	/* Loop 1: convert all events */
1492 	for (i = 0; i < npevs; i++) {
1493 		pkgs[i].pev = &pevs[i];
1494 		/* Convert with or without debuginfo */
1495 		ret  = convert_to_kprobe_trace_events(pkgs[i].pev,
1496 						      &pkgs[i].tevs);
1497 		if (ret < 0)
1498 			goto end;
1499 		pkgs[i].ntevs = ret;
1500 	}
1501 
1502 	/* Loop 2: add all events */
1503 	for (i = 0; i < npevs && ret >= 0; i++)
1504 		ret = __add_kprobe_trace_events(pkgs[i].pev, pkgs[i].tevs,
1505 						pkgs[i].ntevs, force_add);
1506 end:
1507 	/* Loop 3: cleanup trace events  */
1508 	for (i = 0; i < npevs; i++)
1509 		for (j = 0; j < pkgs[i].ntevs; j++)
1510 			clear_kprobe_trace_event(&pkgs[i].tevs[j]);
1511 
1512 	return ret;
1513 }
1514 
1515 static int __del_trace_kprobe_event(int fd, struct str_node *ent)
1516 {
1517 	char *p;
1518 	char buf[128];
1519 	int ret;
1520 
1521 	/* Convert from perf-probe event to trace-kprobe event */
1522 	ret = e_snprintf(buf, 128, "-:%s", ent->s);
1523 	if (ret < 0)
1524 		goto error;
1525 
1526 	p = strchr(buf + 2, ':');
1527 	if (!p) {
1528 		pr_debug("Internal error: %s should have ':' but not.\n",
1529 			 ent->s);
1530 		ret = -ENOTSUP;
1531 		goto error;
1532 	}
1533 	*p = '/';
1534 
1535 	pr_debug("Writing event: %s\n", buf);
1536 	ret = write(fd, buf, strlen(buf));
1537 	if (ret < 0)
1538 		goto error;
1539 
1540 	printf("Remove event: %s\n", ent->s);
1541 	return 0;
1542 error:
1543 	pr_warning("Failed to delete event: %s\n", strerror(-ret));
1544 	return ret;
1545 }
1546 
1547 static int del_trace_kprobe_event(int fd, const char *group,
1548 				  const char *event, struct strlist *namelist)
1549 {
1550 	char buf[128];
1551 	struct str_node *ent, *n;
1552 	int found = 0, ret = 0;
1553 
1554 	ret = e_snprintf(buf, 128, "%s:%s", group, event);
1555 	if (ret < 0) {
1556 		pr_err("Failed to copy event.");
1557 		return ret;
1558 	}
1559 
1560 	if (strpbrk(buf, "*?")) { /* Glob-exp */
1561 		strlist__for_each_safe(ent, n, namelist)
1562 			if (strglobmatch(ent->s, buf)) {
1563 				found++;
1564 				ret = __del_trace_kprobe_event(fd, ent);
1565 				if (ret < 0)
1566 					break;
1567 				strlist__remove(namelist, ent);
1568 			}
1569 	} else {
1570 		ent = strlist__find(namelist, buf);
1571 		if (ent) {
1572 			found++;
1573 			ret = __del_trace_kprobe_event(fd, ent);
1574 			if (ret >= 0)
1575 				strlist__remove(namelist, ent);
1576 		}
1577 	}
1578 	if (found == 0 && ret >= 0)
1579 		pr_info("Info: Event \"%s\" does not exist.\n", buf);
1580 
1581 	return ret;
1582 }
1583 
1584 int del_perf_probe_events(struct strlist *dellist)
1585 {
1586 	int fd, ret = 0;
1587 	const char *group, *event;
1588 	char *p, *str;
1589 	struct str_node *ent;
1590 	struct strlist *namelist;
1591 
1592 	fd = open_kprobe_events(true);
1593 	if (fd < 0)
1594 		return fd;
1595 
1596 	/* Get current event names */
1597 	namelist = get_kprobe_trace_event_names(fd, true);
1598 	if (namelist == NULL)
1599 		return -EINVAL;
1600 
1601 	strlist__for_each(ent, dellist) {
1602 		str = strdup(ent->s);
1603 		if (str == NULL) {
1604 			ret = -ENOMEM;
1605 			break;
1606 		}
1607 		pr_debug("Parsing: %s\n", str);
1608 		p = strchr(str, ':');
1609 		if (p) {
1610 			group = str;
1611 			*p = '\0';
1612 			event = p + 1;
1613 		} else {
1614 			group = "*";
1615 			event = str;
1616 		}
1617 		pr_debug("Group: %s, Event: %s\n", group, event);
1618 		ret = del_trace_kprobe_event(fd, group, event, namelist);
1619 		free(str);
1620 		if (ret < 0)
1621 			break;
1622 	}
1623 	strlist__delete(namelist);
1624 	close(fd);
1625 
1626 	return ret;
1627 }
1628 
1629