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