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