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