probe-event.c 35.8 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
/*
 * probe-event.c : perf-probe definition to kprobe_events format converter
 *
 * Written by Masami Hiramatsu <mhiramat@redhat.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 *
 */

#define _GNU_SOURCE
#include <sys/utsname.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
32 33
#include <stdarg.h>
#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 44
#include "symbol.h"
#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 51 52 53

#define MAX_CMDLEN 256
#define MAX_PROBE_ARGS 128
#define PERFPROBE_GROUP "probe"

54 55
bool probe_event_dry_run;	/* Dry run flag */

56
#define semantic_error(msg ...) pr_err("Semantic error :" msg)
57

58
/* If there is no space to write, returns -E2BIG. */
59 60 61
static int e_snprintf(char *str, size_t size, const char *format, ...)
	__attribute__((format(printf, 3, 4)));

62 63 64 65 66 67 68 69 70 71 72 73
static int e_snprintf(char *str, size_t size, const char *format, ...)
{
	int ret;
	va_list ap;
	va_start(ap, format);
	ret = vsnprintf(str, size, format, ap);
	va_end(ap);
	if (ret >= (int)size)
		ret = -E2BIG;
	return ret;
}

74
static char *synthesize_perf_probe_point(struct perf_probe_point *pp);
75 76 77
static struct map_groups kmap_groups;
static struct map *kmaps[MAP__NR_TYPES];

78
/* Initialize symbol maps and path of vmlinux */
79
static int init_vmlinux(void)
80
{
81
	struct dso *kernel;
82 83
	int ret;

84 85 86 87 88
	symbol_conf.sort_by_name = true;
	if (symbol_conf.vmlinux_name == NULL)
		symbol_conf.try_vmlinux_path = true;
	else
		pr_debug("Use vmlinux: %s\n", symbol_conf.vmlinux_name);
89 90 91 92 93
	ret = symbol__init();
	if (ret < 0) {
		pr_debug("Failed to init symbol map.\n");
		goto out;
	}
94

95 96 97 98
	kernel = dso__new_kernel(symbol_conf.vmlinux_name);
	if (kernel == NULL)
		die("Failed to create kernel dso.");

99
	map_groups__init(&kmap_groups);
100
	ret = __map_groups__create_kernel_maps(&kmap_groups, kmaps, kernel);
101 102 103 104 105 106 107
	if (ret < 0)
		pr_debug("Failed to create kernel maps.\n");

out:
	if (ret < 0)
		pr_warning("Failed to init vmlinux path.\n");
	return ret;
108 109
}

110
#ifdef DWARF_SUPPORT
111 112 113 114 115 116 117 118 119
static int open_vmlinux(void)
{
	if (map__load(kmaps[MAP__FUNCTION], NULL) < 0) {
		pr_debug("Failed to load kernel map.\n");
		return -EINVAL;
	}
	pr_debug("Try to open %s\n", kmaps[MAP__FUNCTION]->dso->long_name);
	return open(kmaps[MAP__FUNCTION]->dso->long_name, O_RDONLY);
}
120

121 122 123
/* Convert trace point to probe point with debuginfo */
static int convert_to_perf_probe_point(struct kprobe_trace_point *tp,
				       struct perf_probe_point *pp)
124 125
{
	struct symbol *sym;
126
	int fd, ret = -ENOENT;
127 128 129 130 131

	sym = map__find_symbol_by_name(kmaps[MAP__FUNCTION],
				       tp->symbol, NULL);
	if (sym) {
		fd = open_vmlinux();
132 133 134 135 136
		if (fd >= 0) {
			ret = find_perf_probe_point(fd,
						 sym->start + tp->offset, pp);
			close(fd);
		}
137 138
	}
	if (ret <= 0) {
139 140
		pr_debug("Failed to find corresponding probes from "
			 "debuginfo. Use kprobe event information.\n");
141 142 143
		pp->function = strdup(tp->symbol);
		if (pp->function == NULL)
			return -ENOMEM;
144 145 146
		pp->offset = tp->offset;
	}
	pp->retprobe = tp->retprobe;
147 148

	return 0;
149 150 151 152 153 154 155 156 157 158 159
}

/* Try to find perf_probe_event with debuginfo */
static int try_to_find_kprobe_trace_events(struct perf_probe_event *pev,
					   struct kprobe_trace_event **tevs)
{
	bool need_dwarf = perf_probe_event_need_dwarf(pev);
	int fd, ntevs;

	fd = open_vmlinux();
	if (fd < 0) {
160 161 162 163
		if (need_dwarf) {
			pr_warning("Failed to open debuginfo file.\n");
			return fd;
		}
164 165 166 167 168 169 170 171
		pr_debug("Could not open vmlinux. Try to use symbols.\n");
		return 0;
	}

	/* Searching trace events corresponding to probe event */
	ntevs = find_kprobe_trace_events(fd, pev, tevs);
	close(fd);

172 173
	if (ntevs > 0) {	/* Succeeded to find trace events */
		pr_debug("find %d kprobe_trace_events.\n", ntevs);
174
		return ntevs;
175
	}
176

177 178 179 180 181 182
	if (ntevs == 0)	{	/* No error but failed to find probe point. */
		pr_warning("Probe point '%s' not found.\n",
			   synthesize_perf_probe_point(&pev->point));
		return -ENOENT;
	}
	/* Error path : ntevs < 0 */
183 184 185 186 187 188 189 190
	pr_debug("An error occurred in debuginfo analysis (%d).\n", ntevs);
	if (ntevs == -EBADF) {
		pr_warning("Warning: No dwarf info found in the vmlinux - "
			"please rebuild kernel with CONFIG_DEBUG_INFO=y.\n");
		if (!need_dwarf) {
			pr_debug("Trying to use symbols.\nn");
			return 0;
		}
191
	}
192
	return ntevs;
193 194 195 196 197
}

#define LINEBUF_SIZE 256
#define NR_ADDITIONAL_LINES 2

198
static int show_one_line(FILE *fp, int l, bool skip, bool show_num)
199 200 201 202 203 204 205 206
{
	char buf[LINEBUF_SIZE];
	const char *color = PERF_COLOR_BLUE;

	if (fgets(buf, LINEBUF_SIZE, fp) == NULL)
		goto error;
	if (!skip) {
		if (show_num)
207
			fprintf(stdout, "%7d  %s", l, buf);
208 209 210 211 212 213 214 215 216 217 218 219 220 221 222
		else
			color_fprintf(stdout, color, "         %s", buf);
	}

	while (strlen(buf) == LINEBUF_SIZE - 1 &&
	       buf[LINEBUF_SIZE - 2] != '\n') {
		if (fgets(buf, LINEBUF_SIZE, fp) == NULL)
			goto error;
		if (!skip) {
			if (show_num)
				fprintf(stdout, "%s", buf);
			else
				color_fprintf(stdout, color, "%s", buf);
		}
	}
223 224

	return 0;
225 226
error:
	if (feof(fp))
227
		pr_warning("Source file is shorter than expected.\n");
228
	else
229 230 231
		pr_warning("File read error: %s\n", strerror(errno));

	return -1;
232 233 234 235 236 237
}

/*
 * Show line-range always requires debuginfo to find source file and
 * line number.
 */
238
int show_line_range(struct line_range *lr)
239
{
240
	int l = 1;
241 242 243 244 245
	struct line_node *ln;
	FILE *fp;
	int fd, ret;

	/* Search a line range */
246 247 248 249
	ret = init_vmlinux();
	if (ret < 0)
		return ret;

250
	fd = open_vmlinux();
251 252 253 254 255
	if (fd < 0) {
		pr_warning("Failed to open debuginfo file.\n");
		return fd;
	}

256 257
	ret = find_line_range(fd, lr);
	close(fd);
258 259 260 261 262 263 264
	if (ret == 0) {
		pr_warning("Specified source line is not found.\n");
		return -ENOENT;
	} else if (ret < 0) {
		pr_warning("Debuginfo analysis failed. (%d)\n", ret);
		return ret;
	}
265 266 267 268 269 270 271 272 273 274

	setup_pager();

	if (lr->function)
		fprintf(stdout, "<%s:%d>\n", lr->function,
			lr->start - lr->offset);
	else
		fprintf(stdout, "<%s:%d>\n", lr->file, lr->start);

	fp = fopen(lr->path, "r");
275 276 277 278 279
	if (fp == NULL) {
		pr_warning("Failed to open %s: %s\n", lr->path,
			   strerror(errno));
		return -errno;
	}
280
	/* Skip to starting line number */
281 282 283 284
	while (l < lr->start && ret >= 0)
		ret = show_one_line(fp, l++, true, false);
	if (ret < 0)
		goto end;
285 286

	list_for_each_entry(ln, &lr->line_list, list) {
287 288 289 290 291 292 293 294
		while (ln->line > l && ret >= 0)
			ret = show_one_line(fp, (l++) - lr->offset,
					    false, false);
		if (ret >= 0)
			ret = show_one_line(fp, (l++) - lr->offset,
					    false, true);
		if (ret < 0)
			goto end;
295 296 297 298
	}

	if (lr->end == INT_MAX)
		lr->end = l + NR_ADDITIONAL_LINES;
299
	while (l <= lr->end && !feof(fp) && ret >= 0)
300 301
		ret = show_one_line(fp, (l++) - lr->offset, false, false);
end:
302
	fclose(fp);
303
	return ret;
304 305 306 307
}

#else	/* !DWARF_SUPPORT */

308
static int convert_to_perf_probe_point(struct kprobe_trace_point *tp,
309 310
					struct perf_probe_point *pp)
{
311 312 313
	pp->function = strdup(tp->symbol);
	if (pp->function == NULL)
		return -ENOMEM;
314 315
	pp->offset = tp->offset;
	pp->retprobe = tp->retprobe;
316 317

	return 0;
318 319 320 321 322
}

static int try_to_find_kprobe_trace_events(struct perf_probe_event *pev,
				struct kprobe_trace_event **tevs __unused)
{
323 324 325 326
	if (perf_probe_event_need_dwarf(pev)) {
		pr_warning("Debuginfo-analysis is not supported.\n");
		return -ENOSYS;
	}
327 328 329
	return 0;
}

330
int show_line_range(struct line_range *lr __unused)
331
{
332 333
	pr_warning("Debuginfo-analysis is not supported.\n");
	return -ENOSYS;
334 335
}

336 337
#endif

338
int parse_line_range_desc(const char *arg, struct line_range *lr)
339 340 341 342 343 344 345 346 347 348
{
	const char *ptr;
	char *tmp;
	/*
	 * <Syntax>
	 * SRC:SLN[+NUM|-ELN]
	 * FUNC[:SLN[+NUM|-ELN]]
	 */
	ptr = strchr(arg, ':');
	if (ptr) {
349
		lr->start = (int)strtoul(ptr + 1, &tmp, 0);
350
		if (*tmp == '+') {
351
			lr->end = lr->start + (int)strtoul(tmp + 1, &tmp, 0);
352 353 354 355 356 357 358
			lr->end--;	/*
					 * Adjust the number of lines here.
					 * If the number of lines == 1, the
					 * the end of line should be equal to
					 * the start of line.
					 */
		} else if (*tmp == '-')
359
			lr->end = (int)strtoul(tmp + 1, &tmp, 0);
360
		else
361 362 363
			lr->end = INT_MAX;
		pr_debug("Line range is %d to %d\n", lr->start, lr->end);
		if (lr->start > lr->end) {
364
			semantic_error("Start line must be smaller"
365 366 367 368 369
				       " than end line.\n");
			return -EINVAL;
		}
		if (*tmp != '\0') {
			semantic_error("Tailing with invalid character '%d'.\n",
370
				       *tmp);
371 372
			return -EINVAL;
		}
373
		tmp = strndup(arg, (ptr - arg));
374
	} else {
375
		tmp = strdup(arg);
376 377
		lr->end = INT_MAX;
	}
378 379 380

	if (tmp == NULL)
		return -ENOMEM;
381 382 383 384 385

	if (strchr(tmp, '.'))
		lr->file = tmp;
	else
		lr->function = tmp;
386 387

	return 0;
388 389
}

390 391 392 393 394 395 396 397 398 399 400 401
/* Check the name is good for event/group */
static bool check_event_name(const char *name)
{
	if (!isalpha(*name) && *name != '_')
		return false;
	while (*++name != '\0') {
		if (!isalpha(*name) && !isdigit(*name) && *name != '_')
			return false;
	}
	return true;
}

402
/* Parse probepoint definition. */
403
static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
404
{
405
	struct perf_probe_point *pp = &pev->point;
406 407 408 409
	char *ptr, *tmp;
	char c, nc = 0;
	/*
	 * <Syntax>
410 411
	 * perf probe [EVENT=]SRC[:LN|;PTN]
	 * perf probe [EVENT=]FUNC[@SRC][+OFFS|%return|:LN|;PAT]
412 413
	 *
	 * TODO:Group name support
414 415
	 */

416 417
	ptr = strpbrk(arg, ";=@+%");
	if (ptr && *ptr == '=') {	/* Event name */
418 419
		*ptr = '\0';
		tmp = ptr + 1;
420 421 422 423 424
		if (strchr(arg, ':')) {
			semantic_error("Group name is not supported yet.\n");
			return -ENOTSUP;
		}
		if (!check_event_name(arg)) {
425
			semantic_error("%s is bad for event name -it must "
426 427 428
				       "follow C symbol-naming rule.\n", arg);
			return -EINVAL;
		}
429 430 431
		pev->event = strdup(arg);
		if (pev->event == NULL)
			return -ENOMEM;
432
		pev->group = NULL;
433 434 435
		arg = tmp;
	}

436
	ptr = strpbrk(arg, ";:+@%");
437 438 439 440 441
	if (ptr) {
		nc = *ptr;
		*ptr++ = '\0';
	}

442 443 444 445
	tmp = strdup(arg);
	if (tmp == NULL)
		return -ENOMEM;

446
	/* Check arg is function or file and copy it */
447 448
	if (strchr(tmp, '.'))	/* File */
		pp->file = tmp;
449
	else			/* Function */
450
		pp->function = tmp;
451 452 453 454 455

	/* Parse other options */
	while (ptr) {
		arg = ptr;
		c = nc;
456
		if (c == ';') {	/* Lazy pattern must be the last part */
457 458 459
			pp->lazy_line = strdup(arg);
			if (pp->lazy_line == NULL)
				return -ENOMEM;
460 461 462
			break;
		}
		ptr = strpbrk(arg, ";:+@%");
463 464 465 466 467 468 469
		if (ptr) {
			nc = *ptr;
			*ptr++ = '\0';
		}
		switch (c) {
		case ':':	/* Line number */
			pp->line = strtoul(arg, &tmp, 0);
470
			if (*tmp != '\0') {
471
				semantic_error("There is non-digit char"
472 473 474
					       " in line number.\n");
				return -EINVAL;
			}
475 476 477
			break;
		case '+':	/* Byte offset from a symbol */
			pp->offset = strtoul(arg, &tmp, 0);
478
			if (*tmp != '\0') {
479
				semantic_error("There is non-digit character"
480 481 482
						" in offset.\n");
				return -EINVAL;
			}
483 484
			break;
		case '@':	/* File name */
485 486 487 488
			if (pp->file) {
				semantic_error("SRC@SRC is not allowed.\n");
				return -EINVAL;
			}
489 490 491
			pp->file = strdup(arg);
			if (pp->file == NULL)
				return -ENOMEM;
492 493 494 495
			break;
		case '%':	/* Probe places */
			if (strcmp(arg, "return") == 0) {
				pp->retprobe = 1;
496 497 498 499
			} else {	/* Others not supported yet */
				semantic_error("%%%s is not supported.\n", arg);
				return -ENOTSUP;
			}
500
			break;
501 502 503 504
		default:	/* Buggy case */
			pr_err("This program has a bug at %s:%d.\n",
				__FILE__, __LINE__);
			return -ENOTSUP;
505 506 507 508 509
			break;
		}
	}

	/* Exclusion check */
510
	if (pp->lazy_line && pp->line) {
511
		semantic_error("Lazy pattern can't be used with line number.");
512 513
		return -EINVAL;
	}
514

515
	if (pp->lazy_line && pp->offset) {
516
		semantic_error("Lazy pattern can't be used with offset.");
517 518
		return -EINVAL;
	}
519

520
	if (pp->line && pp->offset) {
521
		semantic_error("Offset can't be used with line number.");
522 523
		return -EINVAL;
	}
524

525
	if (!pp->line && !pp->lazy_line && pp->file && !pp->function) {
526 527
		semantic_error("File always requires line number or "
			       "lazy pattern.");
528 529
		return -EINVAL;
	}
530

531
	if (pp->offset && !pp->function) {
532
		semantic_error("Offset requires an entry function.");
533 534
		return -EINVAL;
	}
535

536
	if (pp->retprobe && !pp->function) {
537
		semantic_error("Return probe requires an entry function.");
538 539
		return -EINVAL;
	}
540

541
	if ((pp->offset || pp->line || pp->lazy_line) && pp->retprobe) {
542 543
		semantic_error("Offset/Line/Lazy pattern can't be used with "
			       "return probe.");
544 545
		return -EINVAL;
	}
546

547
	pr_debug("symbol:%s file:%s line:%d offset:%lu return:%d lazy:%s\n",
548 549
		 pp->function, pp->file, pp->line, pp->offset, pp->retprobe,
		 pp->lazy_line);
550
	return 0;
551 552
}

553
/* Parse perf-probe event argument */
554
static int parse_perf_probe_arg(char *str, struct perf_probe_arg *arg)
555
{
556
	char *tmp;
557 558 559 560
	struct perf_probe_arg_field **fieldp;

	pr_debug("parsing arg: %s into ", str);

561 562
	tmp = strchr(str, '=');
	if (tmp) {
563 564 565
		arg->name = strndup(str, tmp - str);
		if (arg->name == NULL)
			return -ENOMEM;
566
		pr_debug("name:%s ", arg->name);
567 568 569
		str = tmp + 1;
	}

570 571 572
	tmp = strchr(str, ':');
	if (tmp) {	/* Type setting */
		*tmp = '\0';
573 574 575
		arg->type = strdup(tmp + 1);
		if (arg->type == NULL)
			return -ENOMEM;
576 577 578
		pr_debug("type:%s ", arg->type);
	}

579 580 581
	tmp = strpbrk(str, "-.");
	if (!is_c_varname(str) || !tmp) {
		/* A variable, register, symbol or special value */
582 583 584
		arg->var = strdup(str);
		if (arg->var == NULL)
			return -ENOMEM;
585
		pr_debug("%s\n", arg->var);
586
		return 0;
587 588 589
	}

	/* Structure fields */
590 591 592
	arg->var = strndup(str, tmp - str);
	if (arg->var == NULL)
		return -ENOMEM;
593
	pr_debug("%s, ", arg->var);
594 595 596
	fieldp = &arg->field;

	do {
597 598 599
		*fieldp = zalloc(sizeof(struct perf_probe_arg_field));
		if (*fieldp == NULL)
			return -ENOMEM;
600 601 602 603 604 605
		if (*tmp == '.') {
			str = tmp + 1;
			(*fieldp)->ref = false;
		} else if (tmp[1] == '>') {
			str = tmp + 2;
			(*fieldp)->ref = true;
606 607 608 609
		} else {
			semantic_error("Argument parse error: %s\n", str);
			return -EINVAL;
		}
610 611 612

		tmp = strpbrk(str, "-.");
		if (tmp) {
613 614 615
			(*fieldp)->name = strndup(str, tmp - str);
			if ((*fieldp)->name == NULL)
				return -ENOMEM;
616 617 618 619
			pr_debug("%s(%d), ", (*fieldp)->name, (*fieldp)->ref);
			fieldp = &(*fieldp)->next;
		}
	} while (tmp);
620 621 622
	(*fieldp)->name = strdup(str);
	if ((*fieldp)->name == NULL)
		return -ENOMEM;
623
	pr_debug("%s(%d)\n", (*fieldp)->name, (*fieldp)->ref);
624 625

	/* If no name is specified, set the last field name */
626 627 628 629 630
	if (!arg->name) {
		arg->name = strdup((*fieldp)->name);
		if (arg->name == NULL)
			return -ENOMEM;
	}
631
	return 0;
632 633
}

634
/* Parse perf-probe event command */
635
int parse_perf_probe_command(const char *cmd, struct perf_probe_event *pev)
636
{
637
	char **argv;
638
	int argc, i, ret = 0;
639

640
	argv = argv_split(cmd, &argc);
641 642 643 644 645 646 647 648 649
	if (!argv) {
		pr_debug("Failed to split arguments.\n");
		return -ENOMEM;
	}
	if (argc - 1 > MAX_PROBE_ARGS) {
		semantic_error("Too many probe arguments (%d).\n", argc - 1);
		ret = -ERANGE;
		goto out;
	}
650
	/* Parse probe point */
651 652 653
	ret = parse_perf_probe_point(argv[0], pev);
	if (ret < 0)
		goto out;
654

655
	/* Copy arguments and ensure return probe has no C argument */
656
	pev->nargs = argc - 1;
657 658 659 660 661
	pev->args = zalloc(sizeof(struct perf_probe_arg) * pev->nargs);
	if (pev->args == NULL) {
		ret = -ENOMEM;
		goto out;
	}
662 663 664 665
	for (i = 0; i < pev->nargs && ret >= 0; i++) {
		ret = parse_perf_probe_arg(argv[i + 1], &pev->args[i]);
		if (ret >= 0 &&
		    is_c_varname(pev->args[i].var) && pev->point.retprobe) {
666
			semantic_error("You can't specify local variable for"
667 668 669
				       " kretprobe.\n");
			ret = -EINVAL;
		}
670
	}
671
out:
672
	argv_free(argv);
673 674

	return ret;
675 676
}

677 678 679 680 681 682 683 684 685
/* Return true if this perf_probe_event requires debuginfo */
bool perf_probe_event_need_dwarf(struct perf_probe_event *pev)
{
	int i;

	if (pev->point.file || pev->point.line || pev->point.lazy_line)
		return true;

	for (i = 0; i < pev->nargs; i++)
686
		if (is_c_varname(pev->args[i].var))
687 688 689 690 691
			return true;

	return false;
}

692
/* Parse kprobe_events event into struct probe_point */
693
int parse_kprobe_trace_command(const char *cmd, struct kprobe_trace_event *tev)
694
{
695
	struct kprobe_trace_point *tp = &tev->point;
696 697 698 699 700
	char pr;
	char *p;
	int ret, i, argc;
	char **argv;

701 702
	pr_debug("Parsing kprobe_events: %s\n", cmd);
	argv = argv_split(cmd, &argc);
703 704 705 706 707 708 709 710 711
	if (!argv) {
		pr_debug("Failed to split arguments.\n");
		return -ENOMEM;
	}
	if (argc < 2) {
		semantic_error("Too few probe arguments.\n");
		ret = -ERANGE;
		goto out;
	}
712 713

	/* Scan event and group name. */
714
	ret = sscanf(argv[0], "%c:%a[^/ \t]/%a[^ \t]",
715 716
		     &pr, (float *)(void *)&tev->group,
		     (float *)(void *)&tev->event);
717 718 719 720 721
	if (ret != 3) {
		semantic_error("Failed to parse event name: %s\n", argv[0]);
		ret = -EINVAL;
		goto out;
	}
722
	pr_debug("Group:%s Event:%s probe:%c\n", tev->group, tev->event, pr);
723

724
	tp->retprobe = (pr == 'r');
725 726

	/* Scan function name and offset */
727 728
	ret = sscanf(argv[1], "%a[^+]+%lu", (float *)(void *)&tp->symbol,
		     &tp->offset);
729
	if (ret == 1)
730
		tp->offset = 0;
731

732
	tev->nargs = argc - 2;
733 734 735 736 737
	tev->args = zalloc(sizeof(struct kprobe_trace_arg) * tev->nargs);
	if (tev->args == NULL) {
		ret = -ENOMEM;
		goto out;
	}
738
	for (i = 0; i < tev->nargs; i++) {
739 740
		p = strchr(argv[i + 2], '=');
		if (p)	/* We don't need which register is assigned. */
741 742 743
			*p++ = '\0';
		else
			p = argv[i + 2];
744
		tev->args[i].name = strdup(argv[i + 2]);
745
		/* TODO: parse regs and offset */
746 747 748 749 750
		tev->args[i].value = strdup(p);
		if (tev->args[i].name == NULL || tev->args[i].value == NULL) {
			ret = -ENOMEM;
			goto out;
		}
751
	}
752 753
	ret = 0;
out:
754
	argv_free(argv);
755
	return ret;
756 757
}

758 759 760 761 762 763 764
/* Compose only probe arg */
int synthesize_perf_probe_arg(struct perf_probe_arg *pa, char *buf, size_t len)
{
	struct perf_probe_arg_field *field = pa->field;
	int ret;
	char *tmp = buf;

765 766 767 768
	if (pa->name && pa->var)
		ret = e_snprintf(tmp, len, "%s=%s", pa->name, pa->var);
	else
		ret = e_snprintf(tmp, len, "%s", pa->name ? pa->name : pa->var);
769 770 771 772 773 774 775 776 777 778 779 780 781 782
	if (ret <= 0)
		goto error;
	tmp += ret;
	len -= ret;

	while (field) {
		ret = e_snprintf(tmp, len, "%s%s", field->ref ? "->" : ".",
				 field->name);
		if (ret <= 0)
			goto error;
		tmp += ret;
		len -= ret;
		field = field->next;
	}
783 784 785 786 787 788 789 790 791

	if (pa->type) {
		ret = e_snprintf(tmp, len, ":%s", pa->type);
		if (ret <= 0)
			goto error;
		tmp += ret;
		len -= ret;
	}

792 793
	return tmp - buf;
error:
794 795 796
	pr_debug("Failed to synthesize perf probe argument: %s",
		 strerror(-ret));
	return ret;
797 798
}

799 800
/* Compose only probe point (not argument) */
static char *synthesize_perf_probe_point(struct perf_probe_point *pp)
801
{
802 803 804
	char *buf, *tmp;
	char offs[32] = "", line[32] = "", file[32] = "";
	int ret, len;
805

806 807 808 809 810
	buf = zalloc(MAX_CMDLEN);
	if (buf == NULL) {
		ret = -ENOMEM;
		goto error;
	}
811
	if (pp->offset) {
812
		ret = e_snprintf(offs, 32, "+%lu", pp->offset);
813 814 815 816
		if (ret <= 0)
			goto error;
	}
	if (pp->line) {
817 818 819 820 821
		ret = e_snprintf(line, 32, ":%d", pp->line);
		if (ret <= 0)
			goto error;
	}
	if (pp->file) {
822
		len = strlen(pp->file) - 31;
823 824 825 826
		if (len < 0)
			len = 0;
		tmp = strchr(pp->file + len, '/');
		if (!tmp)
827
			tmp = pp->file + len;
828
		ret = e_snprintf(file, 32, "@%s", tmp + 1);
829 830 831 832 833
		if (ret <= 0)
			goto error;
	}

	if (pp->function)
834 835 836
		ret = e_snprintf(buf, MAX_CMDLEN, "%s%s%s%s%s", pp->function,
				 offs, pp->retprobe ? "%return" : "", line,
				 file);
837
	else
838
		ret = e_snprintf(buf, MAX_CMDLEN, "%s%s", file, line);
839 840 841 842
	if (ret <= 0)
		goto error;

	return buf;
843
error:
844 845
	pr_debug("Failed to synthesize perf probe point: %s",
		 strerror(-ret));
846 847
	if (buf)
		free(buf);
848
	return NULL;
849 850
}

851 852
#if 0
char *synthesize_perf_probe_command(struct perf_probe_event *pev)
853 854 855 856
{
	char *buf;
	int i, len, ret;

857 858 859
	buf = synthesize_perf_probe_point(&pev->point);
	if (!buf)
		return NULL;
860

861 862
	len = strlen(buf);
	for (i = 0; i < pev->nargs; i++) {
863
		ret = e_snprintf(&buf[len], MAX_CMDLEN - len, " %s",
864 865 866 867 868
				 pev->args[i].name);
		if (ret <= 0) {
			free(buf);
			return NULL;
		}
869 870 871
		len += ret;
	}

872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896
	return buf;
}
#endif

static int __synthesize_kprobe_trace_arg_ref(struct kprobe_trace_arg_ref *ref,
					     char **buf, size_t *buflen,
					     int depth)
{
	int ret;
	if (ref->next) {
		depth = __synthesize_kprobe_trace_arg_ref(ref->next, buf,
							 buflen, depth + 1);
		if (depth < 0)
			goto out;
	}

	ret = e_snprintf(*buf, *buflen, "%+ld(", ref->offset);
	if (ret < 0)
		depth = ret;
	else {
		*buf += ret;
		*buflen -= ret;
	}
out:
	return depth;
897 898 899

}

900 901
static int synthesize_kprobe_trace_arg(struct kprobe_trace_arg *arg,
				       char *buf, size_t buflen)
902
{
903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938
	int ret, depth = 0;
	char *tmp = buf;

	/* Argument name or separator */
	if (arg->name)
		ret = e_snprintf(buf, buflen, " %s=", arg->name);
	else
		ret = e_snprintf(buf, buflen, " ");
	if (ret < 0)
		return ret;
	buf += ret;
	buflen -= ret;

	/* Dereferencing arguments */
	if (arg->ref) {
		depth = __synthesize_kprobe_trace_arg_ref(arg->ref, &buf,
							  &buflen, 1);
		if (depth < 0)
			return depth;
	}

	/* Print argument value */
	ret = e_snprintf(buf, buflen, "%s", arg->value);
	if (ret < 0)
		return ret;
	buf += ret;
	buflen -= ret;

	/* Closing */
	while (depth--) {
		ret = e_snprintf(buf, buflen, ")");
		if (ret < 0)
			return ret;
		buf += ret;
		buflen -= ret;
	}
939 940 941 942 943 944 945
	/* Print argument type */
	if (arg->type) {
		ret = e_snprintf(buf, buflen, ":%s", arg->type);
		if (ret <= 0)
			return ret;
		buf += ret;
	}
946 947 948 949 950 951 952

	return buf - tmp;
}

char *synthesize_kprobe_trace_command(struct kprobe_trace_event *tev)
{
	struct kprobe_trace_point *tp = &tev->point;
953 954 955
	char *buf;
	int i, len, ret;

956 957 958 959
	buf = zalloc(MAX_CMDLEN);
	if (buf == NULL)
		return NULL;

960 961 962 963 964
	len = e_snprintf(buf, MAX_CMDLEN, "%c:%s/%s %s+%lu",
			 tp->retprobe ? 'r' : 'p',
			 tev->group, tev->event,
			 tp->symbol, tp->offset);
	if (len <= 0)
965 966
		goto error;

967 968 969
	for (i = 0; i < tev->nargs; i++) {
		ret = synthesize_kprobe_trace_arg(&tev->args[i], buf + len,
						  MAX_CMDLEN - len);
970
		if (ret <= 0)
971 972 973 974
			goto error;
		len += ret;
	}

975
	return buf;
976
error:
977 978 979
	free(buf);
	return NULL;
}
980

981 982
int convert_to_perf_probe_event(struct kprobe_trace_event *tev,
				struct perf_probe_event *pev)
983
{
984
	char buf[64] = "";
985
	int i, ret;
986

987
	/* Convert event/group name */
988 989 990 991
	pev->event = strdup(tev->event);
	pev->group = strdup(tev->group);
	if (pev->event == NULL || pev->group == NULL)
		return -ENOMEM;
992

993
	/* Convert trace_point to probe_point */
994 995 996
	ret = convert_to_perf_probe_point(&tev->point, &pev->point);
	if (ret < 0)
		return ret;
997

998 999
	/* Convert trace_arg to probe_arg */
	pev->nargs = tev->nargs;
1000 1001 1002
	pev->args = zalloc(sizeof(struct perf_probe_arg) * pev->nargs);
	if (pev->args == NULL)
		return -ENOMEM;
1003
	for (i = 0; i < tev->nargs && ret >= 0; i++) {
1004
		if (tev->args[i].name)
1005
			pev->args[i].name = strdup(tev->args[i].name);
1006
		else {
1007 1008
			ret = synthesize_kprobe_trace_arg(&tev->args[i],
							  buf, 64);
1009
			pev->args[i].name = strdup(buf);
1010
		}
1011 1012 1013
		if (pev->args[i].name == NULL && ret >= 0)
			ret = -ENOMEM;
	}
1014 1015 1016 1017 1018

	if (ret < 0)
		clear_perf_probe_event(pev);

	return ret;
1019 1020 1021 1022 1023
}

void clear_perf_probe_event(struct perf_probe_event *pev)
{
	struct perf_probe_point *pp = &pev->point;
1024
	struct perf_probe_arg_field *field, *next;
1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036
	int i;

	if (pev->event)
		free(pev->event);
	if (pev->group)
		free(pev->group);
	if (pp->file)
		free(pp->file);
	if (pp->function)
		free(pp->function);
	if (pp->lazy_line)
		free(pp->lazy_line);
1037
	for (i = 0; i < pev->nargs; i++) {
1038 1039
		if (pev->args[i].name)
			free(pev->args[i].name);
1040 1041
		if (pev->args[i].var)
			free(pev->args[i].var);
1042 1043
		if (pev->args[i].type)
			free(pev->args[i].type);
1044 1045 1046 1047 1048 1049 1050 1051 1052
		field = pev->args[i].field;
		while (field) {
			next = field->next;
			if (field->name)
				free(field->name);
			free(field);
			field = next;
		}
	}
1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073
	if (pev->args)
		free(pev->args);
	memset(pev, 0, sizeof(*pev));
}

void clear_kprobe_trace_event(struct kprobe_trace_event *tev)
{
	struct kprobe_trace_arg_ref *ref, *next;
	int i;

	if (tev->event)
		free(tev->event);
	if (tev->group)
		free(tev->group);
	if (tev->point.symbol)
		free(tev->point.symbol);
	for (i = 0; i < tev->nargs; i++) {
		if (tev->args[i].name)
			free(tev->args[i].name);
		if (tev->args[i].value)
			free(tev->args[i].value);
1074 1075
		if (tev->args[i].type)
			free(tev->args[i].type);
1076 1077 1078 1079 1080 1081 1082 1083 1084 1085
		ref = tev->args[i].ref;
		while (ref) {
			next = ref->next;
			free(ref);
			ref = next;
		}
	}
	if (tev->args)
		free(tev->args);
	memset(tev, 0, sizeof(*tev));
1086 1087
}

1088
static int open_kprobe_events(bool readwrite)
1089 1090
{
	char buf[PATH_MAX];
1091
	const char *__debugfs;
1092 1093
	int ret;

1094 1095 1096 1097 1098 1099 1100
	__debugfs = debugfs_find_mountpoint();
	if (__debugfs == NULL) {
		pr_warning("Debugfs is not mounted.\n");
		return -ENOENT;
	}

	ret = e_snprintf(buf, PATH_MAX, "%stracing/kprobe_events", __debugfs);
1101
	if (ret >= 0) {
1102
		pr_debug("Opening %s write=%d\n", buf, readwrite);
1103 1104 1105 1106 1107
		if (readwrite && !probe_event_dry_run)
			ret = open(buf, O_RDWR, O_APPEND);
		else
			ret = open(buf, O_RDONLY, 0);
	}
1108

1109 1110
	if (ret < 0) {
		if (errno == ENOENT)
1111 1112
			pr_warning("kprobe_events file does not exist - please"
				 " rebuild kernel with CONFIG_KPROBE_EVENT.\n");
1113
		else
1114 1115
			pr_warning("Failed to open kprobe_events file: %s\n",
				   strerror(errno));
1116 1117 1118 1119 1120
	}
	return ret;
}

/* Get raw string list of current kprobe_events */
1121
static struct strlist *get_kprobe_trace_command_rawlist(int fd)
1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140
{
	int ret, idx;
	FILE *fp;
	char buf[MAX_CMDLEN];
	char *p;
	struct strlist *sl;

	sl = strlist__new(true, NULL);

	fp = fdopen(dup(fd), "r");
	while (!feof(fp)) {
		p = fgets(buf, MAX_CMDLEN, fp);
		if (!p)
			break;

		idx = strlen(p) - 1;
		if (p[idx] == '\n')
			p[idx] = '\0';
		ret = strlist__add(sl, buf);
1141 1142 1143 1144 1145
		if (ret < 0) {
			pr_debug("strlist__add failed: %s\n", strerror(-ret));
			strlist__delete(sl);
			return NULL;
		}
1146 1147 1148 1149 1150 1151
	}
	fclose(fp);

	return sl;
}

1152
/* Show an event */
1153
static int show_perf_probe_event(struct perf_probe_event *pev)
1154
{
1155
	int i, ret;
1156
	char buf[128];
1157
	char *place;
1158

1159 1160
	/* Synthesize only event probe point */
	place = synthesize_perf_probe_point(&pev->point);
1161 1162
	if (!place)
		return -EINVAL;
1163 1164

	ret = e_snprintf(buf, 128, "%s:%s", pev->group, pev->event);
1165
	if (ret < 0)
1166 1167
		return ret;

1168
	printf("  %-20s (on %s", buf, place);
1169

1170
	if (pev->nargs > 0) {
1171
		printf(" with");
1172
		for (i = 0; i < pev->nargs; i++) {
1173 1174 1175 1176
			ret = synthesize_perf_probe_arg(&pev->args[i],
							buf, 128);
			if (ret < 0)
				break;
1177 1178
			printf(" %s", buf);
		}
1179 1180
	}
	printf(")\n");
1181
	free(place);
1182
	return ret;
1183 1184
}

1185
/* List up current perf-probe events */
1186
int show_perf_probe_events(void)
1187
{
1188
	int fd, ret;
1189 1190
	struct kprobe_trace_event tev;
	struct perf_probe_event pev;
1191 1192 1193
	struct strlist *rawlist;
	struct str_node *ent;

1194
	setup_pager();
1195 1196 1197
	ret = init_vmlinux();
	if (ret < 0)
		return ret;
1198 1199 1200

	memset(&tev, 0, sizeof(tev));
	memset(&pev, 0, sizeof(pev));
1201

1202
	fd = open_kprobe_events(false);
1203 1204 1205
	if (fd < 0)
		return fd;

1206
	rawlist = get_kprobe_trace_command_rawlist(fd);
1207
	close(fd);
1208 1209
	if (!rawlist)
		return -ENOENT;
1210

1211
	strlist__for_each(ent, rawlist) {
1212 1213 1214 1215 1216 1217
		ret = parse_kprobe_trace_command(ent->s, &tev);
		if (ret >= 0) {
			ret = convert_to_perf_probe_event(&tev, &pev);
			if (ret >= 0)
				ret = show_perf_probe_event(&pev);
		}
1218 1219
		clear_perf_probe_event(&pev);
		clear_kprobe_trace_event(&tev);
1220 1221
		if (ret < 0)
			break;
1222 1223
	}
	strlist__delete(rawlist);
1224 1225

	return ret;
1226 1227
}

1228
/* Get current perf-probe event names */
1229
static struct strlist *get_kprobe_trace_event_names(int fd, bool include_group)
1230
{
1231
	char buf[128];
1232 1233
	struct strlist *sl, *rawlist;
	struct str_node *ent;
1234
	struct kprobe_trace_event tev;
1235
	int ret = 0;
1236

1237
	memset(&tev, 0, sizeof(tev));
1238

1239
	rawlist = get_kprobe_trace_command_rawlist(fd);
1240
	sl = strlist__new(true, NULL);
1241
	strlist__for_each(ent, rawlist) {
1242 1243 1244
		ret = parse_kprobe_trace_command(ent->s, &tev);
		if (ret < 0)
			break;
1245
		if (include_group) {
1246 1247 1248 1249
			ret = e_snprintf(buf, 128, "%s:%s", tev.group,
					tev.event);
			if (ret >= 0)
				ret = strlist__add(sl, buf);
1250
		} else
1251
			ret = strlist__add(sl, tev.event);
1252
		clear_kprobe_trace_event(&tev);
1253 1254
		if (ret < 0)
			break;
1255 1256 1257
	}
	strlist__delete(rawlist);

1258 1259 1260 1261
	if (ret < 0) {
		strlist__delete(sl);
		return NULL;
	}
1262 1263 1264
	return sl;
}

1265
static int write_kprobe_trace_event(int fd, struct kprobe_trace_event *tev)
1266
{
1267
	int ret = 0;
1268
	char *buf = synthesize_kprobe_trace_command(tev);
1269

1270 1271 1272 1273 1274
	if (!buf) {
		pr_debug("Failed to synthesize kprobe trace event.\n");
		return -EINVAL;
	}

1275
	pr_debug("Writing event: %s\n", buf);
1276 1277 1278
	if (!probe_event_dry_run) {
		ret = write(fd, buf, strlen(buf));
		if (ret <= 0)
1279 1280
			pr_warning("Failed to write event: %s\n",
				   strerror(errno));
1281
	}
1282
	free(buf);
1283
	return ret;
1284 1285
}

1286 1287
static int get_new_event_name(char *buf, size_t len, const char *base,
			      struct strlist *namelist, bool allow_suffix)
1288 1289
{
	int i, ret;
1290 1291 1292

	/* Try no suffix */
	ret = e_snprintf(buf, len, "%s", base);
1293 1294 1295 1296
	if (ret < 0) {
		pr_debug("snprintf() failed: %s\n", strerror(-ret));
		return ret;
	}
1297
	if (!strlist__has_entry(namelist, buf))
1298
		return 0;
1299

1300 1301 1302
	if (!allow_suffix) {
		pr_warning("Error: event \"%s\" already exists. "
			   "(Use -f to force duplicates.)\n", base);
1303
		return -EEXIST;
1304 1305
	}

1306 1307
	/* Try to add suffix */
	for (i = 1; i < MAX_EVENT_INDEX; i++) {
1308
		ret = e_snprintf(buf, len, "%s_%d", base, i);
1309 1310 1311 1312
		if (ret < 0) {
			pr_debug("snprintf() failed: %s\n", strerror(-ret));
			return ret;
		}
1313 1314 1315
		if (!strlist__has_entry(namelist, buf))
			break;
	}
1316 1317 1318 1319 1320 1321
	if (i == MAX_EVENT_INDEX) {
		pr_warning("Too many events are on the same function.\n");
		ret = -ERANGE;
	}

	return ret;
1322 1323
}

1324 1325 1326
static int __add_kprobe_trace_events(struct perf_probe_event *pev,
				     struct kprobe_trace_event *tevs,
				     int ntevs, bool allow_suffix)
1327
{
1328
	int i, fd, ret;
1329
	struct kprobe_trace_event *tev = NULL;
1330 1331
	char buf[64];
	const char *event, *group;
1332
	struct strlist *namelist;
1333

1334
	fd = open_kprobe_events(true);
1335 1336
	if (fd < 0)
		return fd;
1337
	/* Get current event names */
1338
	namelist = get_kprobe_trace_event_names(fd, false);
1339 1340 1341 1342
	if (!namelist) {
		pr_debug("Failed to get current event list.\n");
		return -EIO;
	}
1343

1344
	ret = 0;
1345
	printf("Add new event%s\n", (ntevs > 1) ? "s:" : ":");
1346
	for (i = 0; i < ntevs; i++) {
1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360
		tev = &tevs[i];
		if (pev->event)
			event = pev->event;
		else
			if (pev->point.function)
				event = pev->point.function;
			else
				event = tev->point.symbol;
		if (pev->group)
			group = pev->group;
		else
			group = PERFPROBE_GROUP;

		/* Get an unused new event name */
1361 1362 1363 1364
		ret = get_new_event_name(buf, 64, event,
					 namelist, allow_suffix);
		if (ret < 0)
			break;
1365 1366
		event = buf;

1367 1368 1369 1370 1371 1372
		tev->event = strdup(event);
		tev->group = strdup(group);
		if (tev->event == NULL || tev->group == NULL) {
			ret = -ENOMEM;
			break;
		}
1373 1374 1375
		ret = write_kprobe_trace_event(fd, tev);
		if (ret < 0)
			break;
1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395
		/* Add added event name to namelist */
		strlist__add(namelist, event);

		/* Trick here - save current event/group */
		event = pev->event;
		group = pev->group;
		pev->event = tev->event;
		pev->group = tev->group;
		show_perf_probe_event(pev);
		/* Trick here - restore current event/group */
		pev->event = (char *)event;
		pev->group = (char *)group;

		/*
		 * Probes after the first probe which comes from same
		 * user input are always allowed to add suffix, because
		 * there might be several addresses corresponding to
		 * one code line.
		 */
		allow_suffix = true;
1396
	}
1397 1398 1399 1400 1401 1402 1403

	if (ret >= 0) {
		/* Show how to use the event. */
		printf("\nYou can now use it on all perf tools, such as:\n\n");
		printf("\tperf record -e %s:%s -aR sleep 1\n\n", tev->group,
			 tev->event);
	}
1404

1405
	strlist__delete(namelist);
1406
	close(fd);
1407
	return ret;
1408
}
1409

1410 1411
static int convert_to_kprobe_trace_events(struct perf_probe_event *pev,
					  struct kprobe_trace_event **tevs)
1412 1413
{
	struct symbol *sym;
1414
	int ret = 0, i;
1415 1416
	struct kprobe_trace_event *tev;

1417
	/* Convert perf_probe_event with debuginfo */
1418 1419 1420
	ret = try_to_find_kprobe_trace_events(pev, tevs);
	if (ret != 0)
		return ret;
1421

1422
	/* Allocate trace event buffer */
1423 1424 1425
	tev = *tevs = zalloc(sizeof(struct kprobe_trace_event));
	if (tev == NULL)
		return -ENOMEM;
1426 1427

	/* Copy parameters */
1428 1429 1430 1431 1432
	tev->point.symbol = strdup(pev->point.function);
	if (tev->point.symbol == NULL) {
		ret = -ENOMEM;
		goto error;
	}
1433 1434 1435
	tev->point.offset = pev->point.offset;
	tev->nargs = pev->nargs;
	if (tev->nargs) {
1436 1437 1438
		tev->args = zalloc(sizeof(struct kprobe_trace_arg)
				   * tev->nargs);
		if (tev->args == NULL) {
1439 1440
			ret = -ENOMEM;
			goto error;
1441
		}
1442
		for (i = 0; i < tev->nargs; i++) {
1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461
			if (pev->args[i].name) {
				tev->args[i].name = strdup(pev->args[i].name);
				if (tev->args[i].name == NULL) {
					ret = -ENOMEM;
					goto error;
				}
			}
			tev->args[i].value = strdup(pev->args[i].var);
			if (tev->args[i].value == NULL) {
				ret = -ENOMEM;
				goto error;
			}
			if (pev->args[i].type) {
				tev->args[i].type = strdup(pev->args[i].type);
				if (tev->args[i].type == NULL) {
					ret = -ENOMEM;
					goto error;
				}
			}
1462
		}
1463 1464 1465 1466 1467
	}

	/* Currently just checking function name from symbol map */
	sym = map__find_symbol_by_name(kmaps[MAP__FUNCTION],
				       tev->point.symbol, NULL);
1468 1469 1470
	if (!sym) {
		pr_warning("Kernel symbol \'%s\' not found.\n",
			   tev->point.symbol);
1471 1472 1473
		ret = -ENOENT;
		goto error;
	}
1474

1475 1476 1477 1478 1479
	return 1;
error:
	clear_kprobe_trace_event(tev);
	free(tev);
	*tevs = NULL;
1480
	return ret;
1481 1482 1483 1484 1485 1486 1487 1488
}

struct __event_package {
	struct perf_probe_event		*pev;
	struct kprobe_trace_event	*tevs;
	int				ntevs;
};

1489 1490
int add_perf_probe_events(struct perf_probe_event *pevs, int npevs,
			  bool force_add)
1491
{
1492
	int i, j, ret;
1493 1494
	struct __event_package *pkgs;

1495 1496 1497
	pkgs = zalloc(sizeof(struct __event_package) * npevs);
	if (pkgs == NULL)
		return -ENOMEM;
1498 1499

	/* Init vmlinux path */
1500 1501 1502
	ret = init_vmlinux();
	if (ret < 0)
		return ret;
1503 1504 1505 1506 1507

	/* Loop 1: convert all events */
	for (i = 0; i < npevs; i++) {
		pkgs[i].pev = &pevs[i];
		/* Convert with or without debuginfo */
1508 1509 1510 1511 1512
		ret  = convert_to_kprobe_trace_events(pkgs[i].pev,
						      &pkgs[i].tevs);
		if (ret < 0)
			goto end;
		pkgs[i].ntevs = ret;
1513 1514
	}

1515
	/* Loop 2: add all events */
1516 1517 1518 1519 1520
	for (i = 0; i < npevs && ret >= 0; i++)
		ret = __add_kprobe_trace_events(pkgs[i].pev, pkgs[i].tevs,
						pkgs[i].ntevs, force_add);
end:
	/* Loop 3: cleanup trace events  */
1521
	for (i = 0; i < npevs; i++)
1522 1523 1524 1525
		for (j = 0; j < pkgs[i].ntevs; j++)
			clear_kprobe_trace_event(&pkgs[i].tevs[j]);

	return ret;
1526 1527
}

1528
static int __del_trace_kprobe_event(int fd, struct str_node *ent)
1529 1530 1531
{
	char *p;
	char buf[128];
1532
	int ret;
1533 1534

	/* Convert from perf-probe event to trace-kprobe event */
1535 1536 1537 1538
	ret = e_snprintf(buf, 128, "-:%s", ent->s);
	if (ret < 0)
		goto error;

1539
	p = strchr(buf + 2, ':');
1540 1541 1542 1543 1544 1545
	if (!p) {
		pr_debug("Internal error: %s should have ':' but not.\n",
			 ent->s);
		ret = -ENOTSUP;
		goto error;
	}
1546 1547
	*p = '/';

1548 1549
	pr_debug("Writing event: %s\n", buf);
	ret = write(fd, buf, strlen(buf));
1550 1551 1552
	if (ret < 0)
		goto error;

1553
	printf("Remove event: %s\n", ent->s);
1554 1555 1556 1557
	return 0;
error:
	pr_warning("Failed to delete event: %s\n", strerror(-ret));
	return ret;
1558 1559
}

1560 1561
static int del_trace_kprobe_event(int fd, const char *group,
				  const char *event, struct strlist *namelist)
1562 1563
{
	char buf[128];
1564
	struct str_node *ent, *n;
1565
	int found = 0, ret = 0;
1566

1567 1568 1569 1570 1571
	ret = e_snprintf(buf, 128, "%s:%s", group, event);
	if (ret < 0) {
		pr_err("Failed to copy event.");
		return ret;
	}
1572

1573 1574 1575 1576
	if (strpbrk(buf, "*?")) { /* Glob-exp */
		strlist__for_each_safe(ent, n, namelist)
			if (strglobmatch(ent->s, buf)) {
				found++;
1577 1578 1579
				ret = __del_trace_kprobe_event(fd, ent);
				if (ret < 0)
					break;
1580 1581 1582 1583 1584 1585
				strlist__remove(namelist, ent);
			}
	} else {
		ent = strlist__find(namelist, buf);
		if (ent) {
			found++;
1586 1587 1588
			ret = __del_trace_kprobe_event(fd, ent);
			if (ret >= 0)
				strlist__remove(namelist, ent);
1589 1590
		}
	}
1591 1592 1593 1594
	if (found == 0 && ret >= 0)
		pr_info("Info: Event \"%s\" does not exist.\n", buf);

	return ret;
1595 1596
}

1597
int del_perf_probe_events(struct strlist *dellist)
1598
{
1599
	int fd, ret = 0;
1600 1601 1602 1603 1604
	const char *group, *event;
	char *p, *str;
	struct str_node *ent;
	struct strlist *namelist;

1605
	fd = open_kprobe_events(true);
1606 1607 1608
	if (fd < 0)
		return fd;

1609
	/* Get current event names */
1610
	namelist = get_kprobe_trace_event_names(fd, true);
1611 1612
	if (namelist == NULL)
		return -EINVAL;
1613

1614
	strlist__for_each(ent, dellist) {
1615 1616 1617 1618 1619
		str = strdup(ent->s);
		if (str == NULL) {
			ret = -ENOMEM;
			break;
		}
1620
		pr_debug("Parsing: %s\n", str);
1621 1622 1623 1624 1625 1626
		p = strchr(str, ':');
		if (p) {
			group = str;
			*p = '\0';
			event = p + 1;
		} else {
1627
			group = "*";
1628 1629
			event = str;
		}
1630
		pr_debug("Group: %s, Event: %s\n", group, event);
1631
		ret = del_trace_kprobe_event(fd, group, event, namelist);
1632
		free(str);
1633 1634
		if (ret < 0)
			break;
1635 1636 1637
	}
	strlist__delete(namelist);
	close(fd);
1638 1639

	return ret;
1640 1641
}