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