~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/perf/util/probe-event.c

Version: ~ [ linux-5.3 ] ~ [ linux-5.2.15 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.73 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.144 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.193 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.193 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.73 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.102 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  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 #include <sys/utsname.h>
 23 #include <sys/types.h>
 24 #include <sys/stat.h>
 25 #include <fcntl.h>
 26 #include <errno.h>
 27 #include <stdio.h>
 28 #include <unistd.h>
 29 #include <stdlib.h>
 30 #include <string.h>
 31 #include <stdarg.h>
 32 #include <limits.h>
 33 #include <elf.h>
 34 
 35 #include "util.h"
 36 #include "event.h"
 37 #include "strlist.h"
 38 #include "debug.h"
 39 #include "cache.h"
 40 #include "color.h"
 41 #include "symbol.h"
 42 #include "thread.h"
 43 #include "debugfs.h"
 44 #include "trace-event.h"        /* For __maybe_unused */
 45 #include "probe-event.h"
 46 #include "probe-finder.h"
 47 #include "session.h"
 48 
 49 #define MAX_CMDLEN 256
 50 #define MAX_PROBE_ARGS 128
 51 #define PERFPROBE_GROUP "probe"
 52 
 53 bool probe_event_dry_run;       /* Dry run flag */
 54 
 55 #define semantic_error(msg ...) pr_err("Semantic error :" msg)
 56 
 57 /* If there is no space to write, returns -E2BIG. */
 58 static int e_snprintf(char *str, size_t size, const char *format, ...)
 59         __attribute__((format(printf, 3, 4)));
 60 
 61 static int e_snprintf(char *str, size_t size, const char *format, ...)
 62 {
 63         int ret;
 64         va_list ap;
 65         va_start(ap, format);
 66         ret = vsnprintf(str, size, format, ap);
 67         va_end(ap);
 68         if (ret >= (int)size)
 69                 ret = -E2BIG;
 70         return ret;
 71 }
 72 
 73 static char *synthesize_perf_probe_point(struct perf_probe_point *pp);
 74 static int convert_name_to_addr(struct perf_probe_event *pev,
 75                                 const char *exec);
 76 static struct machine machine;
 77 
 78 /* Initialize symbol maps and path of vmlinux/modules */
 79 static int init_vmlinux(void)
 80 {
 81         int ret;
 82 
 83         symbol_conf.sort_by_name = true;
 84         if (symbol_conf.vmlinux_name == NULL)
 85                 symbol_conf.try_vmlinux_path = true;
 86         else
 87                 pr_debug("Use vmlinux: %s\n", symbol_conf.vmlinux_name);
 88         ret = symbol__init();
 89         if (ret < 0) {
 90                 pr_debug("Failed to init symbol map.\n");
 91                 goto out;
 92         }
 93 
 94         ret = machine__init(&machine, "", HOST_KERNEL_ID);
 95         if (ret < 0)
 96                 goto out;
 97 
 98         if (machine__create_kernel_maps(&machine) < 0) {
 99                 pr_debug("machine__create_kernel_maps() failed.\n");
100                 goto out;
101         }
102 out:
103         if (ret < 0)
104                 pr_warning("Failed to init vmlinux path.\n");
105         return ret;
106 }
107 
108 static struct symbol *__find_kernel_function_by_name(const char *name,
109                                                      struct map **mapp)
110 {
111         return machine__find_kernel_function_by_name(&machine, name, mapp,
112                                                      NULL);
113 }
114 
115 static struct map *kernel_get_module_map(const char *module)
116 {
117         struct rb_node *nd;
118         struct map_groups *grp = &machine.kmaps;
119 
120         /* A file path -- this is an offline module */
121         if (module && strchr(module, '/'))
122                 return machine__new_module(&machine, 0, module);
123 
124         if (!module)
125                 module = "kernel";
126 
127         for (nd = rb_first(&grp->maps[MAP__FUNCTION]); nd; nd = rb_next(nd)) {
128                 struct map *pos = rb_entry(nd, struct map, rb_node);
129                 if (strncmp(pos->dso->short_name + 1, module,
130                             pos->dso->short_name_len - 2) == 0) {
131                         return pos;
132                 }
133         }
134         return NULL;
135 }
136 
137 static struct dso *kernel_get_module_dso(const char *module)
138 {
139         struct dso *dso;
140         struct map *map;
141         const char *vmlinux_name;
142 
143         if (module) {
144                 list_for_each_entry(dso, &machine.kernel_dsos, node) {
145                         if (strncmp(dso->short_name + 1, module,
146                                     dso->short_name_len - 2) == 0)
147                                 goto found;
148                 }
149                 pr_debug("Failed to find module %s.\n", module);
150                 return NULL;
151         }
152 
153         map = machine.vmlinux_maps[MAP__FUNCTION];
154         dso = map->dso;
155 
156         vmlinux_name = symbol_conf.vmlinux_name;
157         if (vmlinux_name) {
158                 if (dso__load_vmlinux(dso, map, vmlinux_name, NULL) <= 0)
159                         return NULL;
160         } else {
161                 if (dso__load_vmlinux_path(dso, map, NULL) <= 0) {
162                         pr_debug("Failed to load kernel map.\n");
163                         return NULL;
164                 }
165         }
166 found:
167         return dso;
168 }
169 
170 const char *kernel_get_module_path(const char *module)
171 {
172         struct dso *dso = kernel_get_module_dso(module);
173         return (dso) ? dso->long_name : NULL;
174 }
175 
176 static int init_user_exec(void)
177 {
178         int ret = 0;
179 
180         symbol_conf.try_vmlinux_path = false;
181         symbol_conf.sort_by_name = true;
182         ret = symbol__init();
183 
184         if (ret < 0)
185                 pr_debug("Failed to init symbol map.\n");
186 
187         return ret;
188 }
189 
190 static int convert_to_perf_probe_point(struct probe_trace_point *tp,
191                                         struct perf_probe_point *pp)
192 {
193         pp->function = strdup(tp->symbol);
194 
195         if (pp->function == NULL)
196                 return -ENOMEM;
197 
198         pp->offset = tp->offset;
199         pp->retprobe = tp->retprobe;
200 
201         return 0;
202 }
203 
204 #ifdef DWARF_SUPPORT
205 /* Open new debuginfo of given module */
206 static struct debuginfo *open_debuginfo(const char *module)
207 {
208         const char *path;
209 
210         /* A file path -- this is an offline module */
211         if (module && strchr(module, '/'))
212                 path = module;
213         else {
214                 path = kernel_get_module_path(module);
215 
216                 if (!path) {
217                         pr_err("Failed to find path of %s module.\n",
218                                module ?: "kernel");
219                         return NULL;
220                 }
221         }
222         return debuginfo__new(path);
223 }
224 
225 /*
226  * Convert trace point to probe point with debuginfo
227  * Currently only handles kprobes.
228  */
229 static int kprobe_convert_to_perf_probe(struct probe_trace_point *tp,
230                                         struct perf_probe_point *pp)
231 {
232         struct symbol *sym;
233         struct map *map;
234         u64 addr;
235         int ret = -ENOENT;
236         struct debuginfo *dinfo;
237 
238         sym = __find_kernel_function_by_name(tp->symbol, &map);
239         if (sym) {
240                 addr = map->unmap_ip(map, sym->start + tp->offset);
241                 pr_debug("try to find %s+%ld@%" PRIx64 "\n", tp->symbol,
242                          tp->offset, addr);
243 
244                 dinfo = debuginfo__new_online_kernel(addr);
245                 if (dinfo) {
246                         ret = debuginfo__find_probe_point(dinfo,
247                                                  (unsigned long)addr, pp);
248                         debuginfo__delete(dinfo);
249                 } else {
250                         pr_debug("Failed to open debuginfo at 0x%" PRIx64 "\n",
251                                  addr);
252                         ret = -ENOENT;
253                 }
254         }
255         if (ret <= 0) {
256                 pr_debug("Failed to find corresponding probes from "
257                          "debuginfo. Use kprobe event information.\n");
258                 return convert_to_perf_probe_point(tp, pp);
259         }
260         pp->retprobe = tp->retprobe;
261 
262         return 0;
263 }
264 
265 static int add_module_to_probe_trace_events(struct probe_trace_event *tevs,
266                                             int ntevs, const char *module)
267 {
268         int i, ret = 0;
269         char *tmp;
270 
271         if (!module)
272                 return 0;
273 
274         tmp = strrchr(module, '/');
275         if (tmp) {
276                 /* This is a module path -- get the module name */
277                 module = strdup(tmp + 1);
278                 if (!module)
279                         return -ENOMEM;
280                 tmp = strchr(module, '.');
281                 if (tmp)
282                         *tmp = '\0';
283                 tmp = (char *)module;   /* For free() */
284         }
285 
286         for (i = 0; i < ntevs; i++) {
287                 tevs[i].point.module = strdup(module);
288                 if (!tevs[i].point.module) {
289                         ret = -ENOMEM;
290                         break;
291                 }
292         }
293 
294         if (tmp)
295                 free(tmp);
296 
297         return ret;
298 }
299 
300 /* Try to find perf_probe_event with debuginfo */
301 static int try_to_find_probe_trace_events(struct perf_probe_event *pev,
302                                           struct probe_trace_event **tevs,
303                                           int max_tevs, const char *target)
304 {
305         bool need_dwarf = perf_probe_event_need_dwarf(pev);
306         struct debuginfo *dinfo;
307         int ntevs, ret = 0;
308 
309         if (pev->uprobes) {
310                 if (need_dwarf) {
311                         pr_warning("Debuginfo-analysis is not yet supported"
312                                         " with -x/--exec option.\n");
313                         return -ENOSYS;
314                 }
315                 return convert_name_to_addr(pev, target);
316         }
317 
318         dinfo = open_debuginfo(target);
319 
320         if (!dinfo) {
321                 if (need_dwarf) {
322                         pr_warning("Failed to open debuginfo file.\n");
323                         return -ENOENT;
324                 }
325                 pr_debug("Could not open debuginfo. Try to use symbols.\n");
326                 return 0;
327         }
328 
329         /* Searching trace events corresponding to a probe event */
330         ntevs = debuginfo__find_trace_events(dinfo, pev, tevs, max_tevs);
331 
332         debuginfo__delete(dinfo);
333 
334         if (ntevs > 0) {        /* Succeeded to find trace events */
335                 pr_debug("find %d probe_trace_events.\n", ntevs);
336                 if (target)
337                         ret = add_module_to_probe_trace_events(*tevs, ntevs,
338                                                                target);
339                 return ret < 0 ? ret : ntevs;
340         }
341 
342         if (ntevs == 0) {       /* No error but failed to find probe point. */
343                 pr_warning("Probe point '%s' not found.\n",
344                            synthesize_perf_probe_point(&pev->point));
345                 return -ENOENT;
346         }
347         /* Error path : ntevs < 0 */
348         pr_debug("An error occurred in debuginfo analysis (%d).\n", ntevs);
349         if (ntevs == -EBADF) {
350                 pr_warning("Warning: No dwarf info found in the vmlinux - "
351                         "please rebuild kernel with CONFIG_DEBUG_INFO=y.\n");
352                 if (!need_dwarf) {
353                         pr_debug("Trying to use symbols.\n");
354                         return 0;
355                 }
356         }
357         return ntevs;
358 }
359 
360 /*
361  * Find a src file from a DWARF tag path. Prepend optional source path prefix
362  * and chop off leading directories that do not exist. Result is passed back as
363  * a newly allocated path on success.
364  * Return 0 if file was found and readable, -errno otherwise.
365  */
366 static int get_real_path(const char *raw_path, const char *comp_dir,
367                          char **new_path)
368 {
369         const char *prefix = symbol_conf.source_prefix;
370 
371         if (!prefix) {
372                 if (raw_path[0] != '/' && comp_dir)
373                         /* If not an absolute path, try to use comp_dir */
374                         prefix = comp_dir;
375                 else {
376                         if (access(raw_path, R_OK) == 0) {
377                                 *new_path = strdup(raw_path);
378                                 return 0;
379                         } else
380                                 return -errno;
381                 }
382         }
383 
384         *new_path = malloc((strlen(prefix) + strlen(raw_path) + 2));
385         if (!*new_path)
386                 return -ENOMEM;
387 
388         for (;;) {
389                 sprintf(*new_path, "%s/%s", prefix, raw_path);
390 
391                 if (access(*new_path, R_OK) == 0)
392                         return 0;
393 
394                 if (!symbol_conf.source_prefix)
395                         /* In case of searching comp_dir, don't retry */
396                         return -errno;
397 
398                 switch (errno) {
399                 case ENAMETOOLONG:
400                 case ENOENT:
401                 case EROFS:
402                 case EFAULT:
403                         raw_path = strchr(++raw_path, '/');
404                         if (!raw_path) {
405                                 free(*new_path);
406                                 *new_path = NULL;
407                                 return -ENOENT;
408                         }
409                         continue;
410 
411                 default:
412                         free(*new_path);
413                         *new_path = NULL;
414                         return -errno;
415                 }
416         }
417 }
418 
419 #define LINEBUF_SIZE 256
420 #define NR_ADDITIONAL_LINES 2
421 
422 static int __show_one_line(FILE *fp, int l, bool skip, bool show_num)
423 {
424         char buf[LINEBUF_SIZE];
425         const char *color = show_num ? "" : PERF_COLOR_BLUE;
426         const char *prefix = NULL;
427 
428         do {
429                 if (fgets(buf, LINEBUF_SIZE, fp) == NULL)
430                         goto error;
431                 if (skip)
432                         continue;
433                 if (!prefix) {
434                         prefix = show_num ? "%7d  " : "         ";
435                         color_fprintf(stdout, color, prefix, l);
436                 }
437                 color_fprintf(stdout, color, "%s", buf);
438 
439         } while (strchr(buf, '\n') == NULL);
440 
441         return 1;
442 error:
443         if (ferror(fp)) {
444                 pr_warning("File read error: %s\n", strerror(errno));
445                 return -1;
446         }
447         return 0;
448 }
449 
450 static int _show_one_line(FILE *fp, int l, bool skip, bool show_num)
451 {
452         int rv = __show_one_line(fp, l, skip, show_num);
453         if (rv == 0) {
454                 pr_warning("Source file is shorter than expected.\n");
455                 rv = -1;
456         }
457         return rv;
458 }
459 
460 #define show_one_line_with_num(f,l)     _show_one_line(f,l,false,true)
461 #define show_one_line(f,l)              _show_one_line(f,l,false,false)
462 #define skip_one_line(f,l)              _show_one_line(f,l,true,false)
463 #define show_one_line_or_eof(f,l)       __show_one_line(f,l,false,false)
464 
465 /*
466  * Show line-range always requires debuginfo to find source file and
467  * line number.
468  */
469 int show_line_range(struct line_range *lr, const char *module)
470 {
471         int l = 1;
472         struct line_node *ln;
473         struct debuginfo *dinfo;
474         FILE *fp;
475         int ret;
476         char *tmp;
477 
478         /* Search a line range */
479         ret = init_vmlinux();
480         if (ret < 0)
481                 return ret;
482 
483         dinfo = open_debuginfo(module);
484         if (!dinfo) {
485                 pr_warning("Failed to open debuginfo file.\n");
486                 return -ENOENT;
487         }
488 
489         ret = debuginfo__find_line_range(dinfo, lr);
490         debuginfo__delete(dinfo);
491         if (ret == 0) {
492                 pr_warning("Specified source line is not found.\n");
493                 return -ENOENT;
494         } else if (ret < 0) {
495                 pr_warning("Debuginfo analysis failed. (%d)\n", ret);
496                 return ret;
497         }
498 
499         /* Convert source file path */
500         tmp = lr->path;
501         ret = get_real_path(tmp, lr->comp_dir, &lr->path);
502         free(tmp);      /* Free old path */
503         if (ret < 0) {
504                 pr_warning("Failed to find source file. (%d)\n", ret);
505                 return ret;
506         }
507 
508         setup_pager();
509 
510         if (lr->function)
511                 fprintf(stdout, "<%s@%s:%d>\n", lr->function, lr->path,
512                         lr->start - lr->offset);
513         else
514                 fprintf(stdout, "<%s:%d>\n", lr->path, lr->start);
515 
516         fp = fopen(lr->path, "r");
517         if (fp == NULL) {
518                 pr_warning("Failed to open %s: %s\n", lr->path,
519                            strerror(errno));
520                 return -errno;
521         }
522         /* Skip to starting line number */
523         while (l < lr->start) {
524                 ret = skip_one_line(fp, l++);
525                 if (ret < 0)
526                         goto end;
527         }
528 
529         list_for_each_entry(ln, &lr->line_list, list) {
530                 for (; ln->line > l; l++) {
531                         ret = show_one_line(fp, l - lr->offset);
532                         if (ret < 0)
533                                 goto end;
534                 }
535                 ret = show_one_line_with_num(fp, l++ - lr->offset);
536                 if (ret < 0)
537                         goto end;
538         }
539 
540         if (lr->end == INT_MAX)
541                 lr->end = l + NR_ADDITIONAL_LINES;
542         while (l <= lr->end) {
543                 ret = show_one_line_or_eof(fp, l++ - lr->offset);
544                 if (ret <= 0)
545                         break;
546         }
547 end:
548         fclose(fp);
549         return ret;
550 }
551 
552 static int show_available_vars_at(struct debuginfo *dinfo,
553                                   struct perf_probe_event *pev,
554                                   int max_vls, struct strfilter *_filter,
555                                   bool externs)
556 {
557         char *buf;
558         int ret, i, nvars;
559         struct str_node *node;
560         struct variable_list *vls = NULL, *vl;
561         const char *var;
562 
563         buf = synthesize_perf_probe_point(&pev->point);
564         if (!buf)
565                 return -EINVAL;
566         pr_debug("Searching variables at %s\n", buf);
567 
568         ret = debuginfo__find_available_vars_at(dinfo, pev, &vls,
569                                                 max_vls, externs);
570         if (ret <= 0) {
571                 pr_err("Failed to find variables at %s (%d)\n", buf, ret);
572                 goto end;
573         }
574         /* Some variables are found */
575         fprintf(stdout, "Available variables at %s\n", buf);
576         for (i = 0; i < ret; i++) {
577                 vl = &vls[i];
578                 /*
579                  * A probe point might be converted to
580                  * several trace points.
581                  */
582                 fprintf(stdout, "\t@<%s+%lu>\n", vl->point.symbol,
583                         vl->point.offset);
584                 free(vl->point.symbol);
585                 nvars = 0;
586                 if (vl->vars) {
587                         strlist__for_each(node, vl->vars) {
588                                 var = strchr(node->s, '\t') + 1;
589                                 if (strfilter__compare(_filter, var)) {
590                                         fprintf(stdout, "\t\t%s\n", node->s);
591                                         nvars++;
592                                 }
593                         }
594                         strlist__delete(vl->vars);
595                 }
596                 if (nvars == 0)
597                         fprintf(stdout, "\t\t(No matched variables)\n");
598         }
599         free(vls);
600 end:
601         free(buf);
602         return ret;
603 }
604 
605 /* Show available variables on given probe point */
606 int show_available_vars(struct perf_probe_event *pevs, int npevs,
607                         int max_vls, const char *module,
608                         struct strfilter *_filter, bool externs)
609 {
610         int i, ret = 0;
611         struct debuginfo *dinfo;
612 
613         ret = init_vmlinux();
614         if (ret < 0)
615                 return ret;
616 
617         dinfo = open_debuginfo(module);
618         if (!dinfo) {
619                 pr_warning("Failed to open debuginfo file.\n");
620                 return -ENOENT;
621         }
622 
623         setup_pager();
624 
625         for (i = 0; i < npevs && ret >= 0; i++)
626                 ret = show_available_vars_at(dinfo, &pevs[i], max_vls, _filter,
627                                              externs);
628 
629         debuginfo__delete(dinfo);
630         return ret;
631 }
632 
633 #else   /* !DWARF_SUPPORT */
634 
635 static int kprobe_convert_to_perf_probe(struct probe_trace_point *tp,
636                                         struct perf_probe_point *pp)
637 {
638         struct symbol *sym;
639 
640         sym = __find_kernel_function_by_name(tp->symbol, NULL);
641         if (!sym) {
642                 pr_err("Failed to find symbol %s in kernel.\n", tp->symbol);
643                 return -ENOENT;
644         }
645 
646         return convert_to_perf_probe_point(tp, pp);
647 }
648 
649 static int try_to_find_probe_trace_events(struct perf_probe_event *pev,
650                                 struct probe_trace_event **tevs __maybe_unused,
651                                 int max_tevs __maybe_unused, const char *target)
652 {
653         if (perf_probe_event_need_dwarf(pev)) {
654                 pr_warning("Debuginfo-analysis is not supported.\n");
655                 return -ENOSYS;
656         }
657 
658         if (pev->uprobes)
659                 return convert_name_to_addr(pev, target);
660 
661         return 0;
662 }
663 
664 int show_line_range(struct line_range *lr __maybe_unused,
665                     const char *module __maybe_unused)
666 {
667         pr_warning("Debuginfo-analysis is not supported.\n");
668         return -ENOSYS;
669 }
670 
671 int show_available_vars(struct perf_probe_event *pevs __maybe_unused,
672                         int npevs __maybe_unused, int max_vls __maybe_unused,
673                         const char *module __maybe_unused,
674                         struct strfilter *filter __maybe_unused,
675                         bool externs __maybe_unused)
676 {
677         pr_warning("Debuginfo-analysis is not supported.\n");
678         return -ENOSYS;
679 }
680 #endif
681 
682 static int parse_line_num(char **ptr, int *val, const char *what)
683 {
684         const char *start = *ptr;
685 
686         errno = 0;
687         *val = strtol(*ptr, ptr, 0);
688         if (errno || *ptr == start) {
689                 semantic_error("'%s' is not a valid number.\n", what);
690                 return -EINVAL;
691         }
692         return 0;
693 }
694 
695 /*
696  * Stuff 'lr' according to the line range described by 'arg'.
697  * The line range syntax is described by:
698  *
699  *         SRC[:SLN[+NUM|-ELN]]
700  *         FNC[@SRC][:SLN[+NUM|-ELN]]
701  */
702 int parse_line_range_desc(const char *arg, struct line_range *lr)
703 {
704         char *range, *file, *name = strdup(arg);
705         int err;
706 
707         if (!name)
708                 return -ENOMEM;
709 
710         lr->start = 0;
711         lr->end = INT_MAX;
712 
713         range = strchr(name, ':');
714         if (range) {
715                 *range++ = '\0';
716 
717                 err = parse_line_num(&range, &lr->start, "start line");
718                 if (err)
719                         goto err;
720 
721                 if (*range == '+' || *range == '-') {
722                         const char c = *range++;
723 
724                         err = parse_line_num(&range, &lr->end, "end line");
725                         if (err)
726                                 goto err;
727 
728                         if (c == '+') {
729                                 lr->end += lr->start;
730                                 /*
731                                  * Adjust the number of lines here.
732                                  * If the number of lines == 1, the
733                                  * the end of line should be equal to
734                                  * the start of line.
735                                  */
736                                 lr->end--;
737                         }
738                 }
739 
740                 pr_debug("Line range is %d to %d\n", lr->start, lr->end);
741 
742                 err = -EINVAL;
743                 if (lr->start > lr->end) {
744                         semantic_error("Start line must be smaller"
745                                        " than end line.\n");
746                         goto err;
747                 }
748                 if (*range != '\0') {
749                         semantic_error("Tailing with invalid str '%s'.\n", range);
750                         goto err;
751                 }
752         }
753 
754         file = strchr(name, '@');
755         if (file) {
756                 *file = '\0';
757                 lr->file = strdup(++file);
758                 if (lr->file == NULL) {
759                         err = -ENOMEM;
760                         goto err;
761                 }
762                 lr->function = name;
763         } else if (strchr(name, '.'))
764                 lr->file = name;
765         else
766                 lr->function = name;
767 
768         return 0;
769 err:
770         free(name);
771         return err;
772 }
773 
774 /* Check the name is good for event/group */
775 static bool check_event_name(const char *name)
776 {
777         if (!isalpha(*name) && *name != '_')
778                 return false;
779         while (*++name != '\0') {
780                 if (!isalpha(*name) && !isdigit(*name) && *name != '_')
781                         return false;
782         }
783         return true;
784 }
785 
786 /* Parse probepoint definition. */
787 static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
788 {
789         struct perf_probe_point *pp = &pev->point;
790         char *ptr, *tmp;
791         char c, nc = 0;
792         /*
793          * <Syntax>
794          * perf probe [EVENT=]SRC[:LN|;PTN]
795          * perf probe [EVENT=]FUNC[@SRC][+OFFS|%return|:LN|;PAT]
796          *
797          * TODO:Group name support
798          */
799 
800         ptr = strpbrk(arg, ";=@+%");
801         if (ptr && *ptr == '=') {       /* Event name */
802                 *ptr = '\0';
803                 tmp = ptr + 1;
804                 if (strchr(arg, ':')) {
805                         semantic_error("Group name is not supported yet.\n");
806                         return -ENOTSUP;
807                 }
808                 if (!check_event_name(arg)) {
809                         semantic_error("%s is bad for event name -it must "
810                                        "follow C symbol-naming rule.\n", arg);
811                         return -EINVAL;
812                 }
813                 pev->event = strdup(arg);
814                 if (pev->event == NULL)
815                         return -ENOMEM;
816                 pev->group = NULL;
817                 arg = tmp;
818         }
819 
820         ptr = strpbrk(arg, ";:+@%");
821         if (ptr) {
822                 nc = *ptr;
823                 *ptr++ = '\0';
824         }
825 
826         tmp = strdup(arg);
827         if (tmp == NULL)
828                 return -ENOMEM;
829 
830         /* Check arg is function or file and copy it */
831         if (strchr(tmp, '.'))   /* File */
832                 pp->file = tmp;
833         else                    /* Function */
834                 pp->function = tmp;
835 
836         /* Parse other options */
837         while (ptr) {
838                 arg = ptr;
839                 c = nc;
840                 if (c == ';') { /* Lazy pattern must be the last part */
841                         pp->lazy_line = strdup(arg);
842                         if (pp->lazy_line == NULL)
843                                 return -ENOMEM;
844                         break;
845                 }
846                 ptr = strpbrk(arg, ";:+@%");
847                 if (ptr) {
848                         nc = *ptr;
849                         *ptr++ = '\0';
850                 }
851                 switch (c) {
852                 case ':':       /* Line number */
853                         pp->line = strtoul(arg, &tmp, 0);
854                         if (*tmp != '\0') {
855                                 semantic_error("There is non-digit char"
856                                                " in line number.\n");
857                                 return -EINVAL;
858                         }
859                         break;
860                 case '+':       /* Byte offset from a symbol */
861                         pp->offset = strtoul(arg, &tmp, 0);
862                         if (*tmp != '\0') {
863                                 semantic_error("There is non-digit character"
864                                                 " in offset.\n");
865                                 return -EINVAL;
866                         }
867                         break;
868                 case '@':       /* File name */
869                         if (pp->file) {
870                                 semantic_error("SRC@SRC is not allowed.\n");
871                                 return -EINVAL;
872                         }
873                         pp->file = strdup(arg);
874                         if (pp->file == NULL)
875                                 return -ENOMEM;
876                         break;
877                 case '%':       /* Probe places */
878                         if (strcmp(arg, "return") == 0) {
879                                 pp->retprobe = 1;
880                         } else {        /* Others not supported yet */
881                                 semantic_error("%%%s is not supported.\n", arg);
882                                 return -ENOTSUP;
883                         }
884                         break;
885                 default:        /* Buggy case */
886                         pr_err("This program has a bug at %s:%d.\n",
887                                 __FILE__, __LINE__);
888                         return -ENOTSUP;
889                         break;
890                 }
891         }
892 
893         /* Exclusion check */
894         if (pp->lazy_line && pp->line) {
895                 semantic_error("Lazy pattern can't be used with"
896                                " line number.\n");
897                 return -EINVAL;
898         }
899 
900         if (pp->lazy_line && pp->offset) {
901                 semantic_error("Lazy pattern can't be used with offset.\n");
902                 return -EINVAL;
903         }
904 
905         if (pp->line && pp->offset) {
906                 semantic_error("Offset can't be used with line number.\n");
907                 return -EINVAL;
908         }
909 
910         if (!pp->line && !pp->lazy_line && pp->file && !pp->function) {
911                 semantic_error("File always requires line number or "
912                                "lazy pattern.\n");
913                 return -EINVAL;
914         }
915 
916         if (pp->offset && !pp->function) {
917                 semantic_error("Offset requires an entry function.\n");
918                 return -EINVAL;
919         }
920 
921         if (pp->retprobe && !pp->function) {
922                 semantic_error("Return probe requires an entry function.\n");
923                 return -EINVAL;
924         }
925 
926         if ((pp->offset || pp->line || pp->lazy_line) && pp->retprobe) {
927                 semantic_error("Offset/Line/Lazy pattern can't be used with "
928                                "return probe.\n");
929                 return -EINVAL;
930         }
931 
932         pr_debug("symbol:%s file:%s line:%d offset:%lu return:%d lazy:%s\n",
933                  pp->function, pp->file, pp->line, pp->offset, pp->retprobe,
934                  pp->lazy_line);
935         return 0;
936 }
937 
938 /* Parse perf-probe event argument */
939 static int parse_perf_probe_arg(char *str, struct perf_probe_arg *arg)
940 {
941         char *tmp, *goodname;
942         struct perf_probe_arg_field **fieldp;
943 
944         pr_debug("parsing arg: %s into ", str);
945 
946         tmp = strchr(str, '=');
947         if (tmp) {
948                 arg->name = strndup(str, tmp - str);
949                 if (arg->name == NULL)
950                         return -ENOMEM;
951                 pr_debug("name:%s ", arg->name);
952                 str = tmp + 1;
953         }
954 
955         tmp = strchr(str, ':');
956         if (tmp) {      /* Type setting */
957                 *tmp = '\0';
958                 arg->type = strdup(tmp + 1);
959                 if (arg->type == NULL)
960                         return -ENOMEM;
961                 pr_debug("type:%s ", arg->type);
962         }
963 
964         tmp = strpbrk(str, "-.[");
965         if (!is_c_varname(str) || !tmp) {
966                 /* A variable, register, symbol or special value */
967                 arg->var = strdup(str);
968                 if (arg->var == NULL)
969                         return -ENOMEM;
970                 pr_debug("%s\n", arg->var);
971                 return 0;
972         }
973 
974         /* Structure fields or array element */
975         arg->var = strndup(str, tmp - str);
976         if (arg->var == NULL)
977                 return -ENOMEM;
978         goodname = arg->var;
979         pr_debug("%s, ", arg->var);
980         fieldp = &arg->field;
981 
982         do {
983                 *fieldp = zalloc(sizeof(struct perf_probe_arg_field));
984                 if (*fieldp == NULL)
985                         return -ENOMEM;
986                 if (*tmp == '[') {      /* Array */
987                         str = tmp;
988                         (*fieldp)->index = strtol(str + 1, &tmp, 0);
989                         (*fieldp)->ref = true;
990                         if (*tmp != ']' || tmp == str + 1) {
991                                 semantic_error("Array index must be a"
992                                                 " number.\n");
993                                 return -EINVAL;
994                         }
995                         tmp++;
996                         if (*tmp == '\0')
997                                 tmp = NULL;
998                 } else {                /* Structure */
999                         if (*tmp == '.') {
1000                                 str = tmp + 1;
1001                                 (*fieldp)->ref = false;
1002                         } else if (tmp[1] == '>') {
1003                                 str = tmp + 2;
1004                                 (*fieldp)->ref = true;
1005                         } else {
1006                                 semantic_error("Argument parse error: %s\n",
1007                                                str);
1008                                 return -EINVAL;
1009                         }
1010                         tmp = strpbrk(str, "-.[");
1011                 }
1012                 if (tmp) {
1013                         (*fieldp)->name = strndup(str, tmp - str);
1014                         if ((*fieldp)->name == NULL)
1015                                 return -ENOMEM;
1016                         if (*str != '[')
1017                                 goodname = (*fieldp)->name;
1018                         pr_debug("%s(%d), ", (*fieldp)->name, (*fieldp)->ref);
1019                         fieldp = &(*fieldp)->next;
1020                 }
1021         } while (tmp);
1022         (*fieldp)->name = strdup(str);
1023         if ((*fieldp)->name == NULL)
1024                 return -ENOMEM;
1025         if (*str != '[')
1026                 goodname = (*fieldp)->name;
1027         pr_debug("%s(%d)\n", (*fieldp)->name, (*fieldp)->ref);
1028 
1029         /* If no name is specified, set the last field name (not array index)*/
1030         if (!arg->name) {
1031                 arg->name = strdup(goodname);
1032                 if (arg->name == NULL)
1033                         return -ENOMEM;
1034         }
1035         return 0;
1036 }
1037 
1038 /* Parse perf-probe event command */
1039 int parse_perf_probe_command(const char *cmd, struct perf_probe_event *pev)
1040 {
1041         char **argv;
1042         int argc, i, ret = 0;
1043 
1044         argv = argv_split(cmd, &argc);
1045         if (!argv) {
1046                 pr_debug("Failed to split arguments.\n");
1047                 return -ENOMEM;
1048         }
1049         if (argc - 1 > MAX_PROBE_ARGS) {
1050                 semantic_error("Too many probe arguments (%d).\n", argc - 1);
1051                 ret = -ERANGE;
1052                 goto out;
1053         }
1054         /* Parse probe point */
1055         ret = parse_perf_probe_point(argv[0], pev);
1056         if (ret < 0)
1057                 goto out;
1058 
1059         /* Copy arguments and ensure return probe has no C argument */
1060         pev->nargs = argc - 1;
1061         pev->args = zalloc(sizeof(struct perf_probe_arg) * pev->nargs);
1062         if (pev->args == NULL) {
1063                 ret = -ENOMEM;
1064                 goto out;
1065         }
1066         for (i = 0; i < pev->nargs && ret >= 0; i++) {
1067                 ret = parse_perf_probe_arg(argv[i + 1], &pev->args[i]);
1068                 if (ret >= 0 &&
1069                     is_c_varname(pev->args[i].var) && pev->point.retprobe) {
1070                         semantic_error("You can't specify local variable for"
1071                                        " kretprobe.\n");
1072                         ret = -EINVAL;
1073                 }
1074         }
1075 out:
1076         argv_free(argv);
1077 
1078         return ret;
1079 }
1080 
1081 /* Return true if this perf_probe_event requires debuginfo */
1082 bool perf_probe_event_need_dwarf(struct perf_probe_event *pev)
1083 {
1084         int i;
1085 
1086         if (pev->point.file || pev->point.line || pev->point.lazy_line)
1087                 return true;
1088 
1089         for (i = 0; i < pev->nargs; i++)
1090                 if (is_c_varname(pev->args[i].var))
1091                         return true;
1092 
1093         return false;
1094 }
1095 
1096 /* Parse probe_events event into struct probe_point */
1097 static int parse_probe_trace_command(const char *cmd,
1098                                      struct probe_trace_event *tev)
1099 {
1100         struct probe_trace_point *tp = &tev->point;
1101         char pr;
1102         char *p;
1103         char *argv0_str = NULL, *fmt, *fmt1_str, *fmt2_str, *fmt3_str;
1104         int ret, i, argc;
1105         char **argv;
1106 
1107         pr_debug("Parsing probe_events: %s\n", cmd);
1108         argv = argv_split(cmd, &argc);
1109         if (!argv) {
1110                 pr_debug("Failed to split arguments.\n");
1111                 return -ENOMEM;
1112         }
1113         if (argc < 2) {
1114                 semantic_error("Too few probe arguments.\n");
1115                 ret = -ERANGE;
1116                 goto out;
1117         }
1118 
1119         /* Scan event and group name. */
1120         argv0_str = strdup(argv[0]);
1121         if (argv0_str == NULL) {
1122                 ret = -ENOMEM;
1123                 goto out;
1124         }
1125         fmt1_str = strtok_r(argv0_str, ":", &fmt);
1126         fmt2_str = strtok_r(NULL, "/", &fmt);
1127         fmt3_str = strtok_r(NULL, " \t", &fmt);
1128         if (fmt1_str == NULL || strlen(fmt1_str) != 1 || fmt2_str == NULL
1129             || fmt3_str == NULL) {
1130                 semantic_error("Failed to parse event name: %s\n", argv[0]);
1131                 ret = -EINVAL;
1132                 goto out;
1133         }
1134         pr = fmt1_str[0];
1135         tev->group = strdup(fmt2_str);
1136         tev->event = strdup(fmt3_str);
1137         if (tev->group == NULL || tev->event == NULL) {
1138                 ret = -ENOMEM;
1139                 goto out;
1140         }
1141         pr_debug("Group:%s Event:%s probe:%c\n", tev->group, tev->event, pr);
1142 
1143         tp->retprobe = (pr == 'r');
1144 
1145         /* Scan module name(if there), function name and offset */
1146         p = strchr(argv[1], ':');
1147         if (p) {
1148                 tp->module = strndup(argv[1], p - argv[1]);
1149                 p++;
1150         } else
1151                 p = argv[1];
1152         fmt1_str = strtok_r(p, "+", &fmt);
1153         tp->symbol = strdup(fmt1_str);
1154         if (tp->symbol == NULL) {
1155                 ret = -ENOMEM;
1156                 goto out;
1157         }
1158         fmt2_str = strtok_r(NULL, "", &fmt);
1159         if (fmt2_str == NULL)
1160                 tp->offset = 0;
1161         else
1162                 tp->offset = strtoul(fmt2_str, NULL, 10);
1163 
1164         tev->nargs = argc - 2;
1165         tev->args = zalloc(sizeof(struct probe_trace_arg) * tev->nargs);
1166         if (tev->args == NULL) {
1167                 ret = -ENOMEM;
1168                 goto out;
1169         }
1170         for (i = 0; i < tev->nargs; i++) {
1171                 p = strchr(argv[i + 2], '=');
1172                 if (p)  /* We don't need which register is assigned. */
1173                         *p++ = '\0';
1174                 else
1175                         p = argv[i + 2];
1176                 tev->args[i].name = strdup(argv[i + 2]);
1177                 /* TODO: parse regs and offset */
1178                 tev->args[i].value = strdup(p);
1179                 if (tev->args[i].name == NULL || tev->args[i].value == NULL) {
1180                         ret = -ENOMEM;
1181                         goto out;
1182                 }
1183         }
1184         ret = 0;
1185 out:
1186         free(argv0_str);
1187         argv_free(argv);
1188         return ret;
1189 }
1190 
1191 /* Compose only probe arg */
1192 int synthesize_perf_probe_arg(struct perf_probe_arg *pa, char *buf, size_t len)
1193 {
1194         struct perf_probe_arg_field *field = pa->field;
1195         int ret;
1196         char *tmp = buf;
1197 
1198         if (pa->name && pa->var)
1199                 ret = e_snprintf(tmp, len, "%s=%s", pa->name, pa->var);
1200         else
1201                 ret = e_snprintf(tmp, len, "%s", pa->name ? pa->name : pa->var);
1202         if (ret <= 0)
1203                 goto error;
1204         tmp += ret;
1205         len -= ret;
1206 
1207         while (field) {
1208                 if (field->name[0] == '[')
1209                         ret = e_snprintf(tmp, len, "%s", field->name);
1210                 else
1211                         ret = e_snprintf(tmp, len, "%s%s",
1212                                          field->ref ? "->" : ".", field->name);
1213                 if (ret <= 0)
1214                         goto error;
1215                 tmp += ret;
1216                 len -= ret;
1217                 field = field->next;
1218         }
1219 
1220         if (pa->type) {
1221                 ret = e_snprintf(tmp, len, ":%s", pa->type);
1222                 if (ret <= 0)
1223                         goto error;
1224                 tmp += ret;
1225                 len -= ret;
1226         }
1227 
1228         return tmp - buf;
1229 error:
1230         pr_debug("Failed to synthesize perf probe argument: %s\n",
1231                  strerror(-ret));
1232         return ret;
1233 }
1234 
1235 /* Compose only probe point (not argument) */
1236 static char *synthesize_perf_probe_point(struct perf_probe_point *pp)
1237 {
1238         char *buf, *tmp;
1239         char offs[32] = "", line[32] = "", file[32] = "";
1240         int ret, len;
1241 
1242         buf = zalloc(MAX_CMDLEN);
1243         if (buf == NULL) {
1244                 ret = -ENOMEM;
1245                 goto error;
1246         }
1247         if (pp->offset) {
1248                 ret = e_snprintf(offs, 32, "+%lu", pp->offset);
1249                 if (ret <= 0)
1250                         goto error;
1251         }
1252         if (pp->line) {
1253                 ret = e_snprintf(line, 32, ":%d", pp->line);
1254                 if (ret <= 0)
1255                         goto error;
1256         }
1257         if (pp->file) {
1258                 tmp = pp->file;
1259                 len = strlen(tmp);
1260                 if (len > 30) {
1261                         tmp = strchr(pp->file + len - 30, '/');
1262                         tmp = tmp ? tmp + 1 : pp->file + len - 30;
1263                 }
1264                 ret = e_snprintf(file, 32, "@%s", tmp);
1265                 if (ret <= 0)
1266                         goto error;
1267         }
1268 
1269         if (pp->function)
1270                 ret = e_snprintf(buf, MAX_CMDLEN, "%s%s%s%s%s", pp->function,
1271                                  offs, pp->retprobe ? "%return" : "", line,
1272                                  file);
1273         else
1274                 ret = e_snprintf(buf, MAX_CMDLEN, "%s%s", file, line);
1275         if (ret <= 0)
1276                 goto error;
1277 
1278         return buf;
1279 error:
1280         pr_debug("Failed to synthesize perf probe point: %s\n",
1281                  strerror(-ret));
1282         if (buf)
1283                 free(buf);
1284         return NULL;
1285 }
1286 
1287 #if 0
1288 char *synthesize_perf_probe_command(struct perf_probe_event *pev)
1289 {
1290         char *buf;
1291         int i, len, ret;
1292 
1293         buf = synthesize_perf_probe_point(&pev->point);
1294         if (!buf)
1295                 return NULL;
1296 
1297         len = strlen(buf);
1298         for (i = 0; i < pev->nargs; i++) {
1299                 ret = e_snprintf(&buf[len], MAX_CMDLEN - len, " %s",
1300                                  pev->args[i].name);
1301                 if (ret <= 0) {
1302                         free(buf);
1303                         return NULL;
1304                 }
1305                 len += ret;
1306         }
1307 
1308         return buf;
1309 }
1310 #endif
1311 
1312 static int __synthesize_probe_trace_arg_ref(struct probe_trace_arg_ref *ref,
1313                                              char **buf, size_t *buflen,
1314                                              int depth)
1315 {
1316         int ret;
1317         if (ref->next) {
1318                 depth = __synthesize_probe_trace_arg_ref(ref->next, buf,
1319                                                          buflen, depth + 1);
1320                 if (depth < 0)
1321                         goto out;
1322         }
1323 
1324         ret = e_snprintf(*buf, *buflen, "%+ld(", ref->offset);
1325         if (ret < 0)
1326                 depth = ret;
1327         else {
1328                 *buf += ret;
1329                 *buflen -= ret;
1330         }
1331 out:
1332         return depth;
1333 
1334 }
1335 
1336 static int synthesize_probe_trace_arg(struct probe_trace_arg *arg,
1337                                        char *buf, size_t buflen)
1338 {
1339         struct probe_trace_arg_ref *ref = arg->ref;
1340         int ret, depth = 0;
1341         char *tmp = buf;
1342 
1343         /* Argument name or separator */
1344         if (arg->name)
1345                 ret = e_snprintf(buf, buflen, " %s=", arg->name);
1346         else
1347                 ret = e_snprintf(buf, buflen, " ");
1348         if (ret < 0)
1349                 return ret;
1350         buf += ret;
1351         buflen -= ret;
1352 
1353         /* Special case: @XXX */
1354         if (arg->value[0] == '@' && arg->ref)
1355                         ref = ref->next;
1356 
1357         /* Dereferencing arguments */
1358         if (ref) {
1359                 depth = __synthesize_probe_trace_arg_ref(ref, &buf,
1360                                                           &buflen, 1);
1361                 if (depth < 0)
1362                         return depth;
1363         }
1364 
1365         /* Print argument value */
1366         if (arg->value[0] == '@' && arg->ref)
1367                 ret = e_snprintf(buf, buflen, "%s%+ld", arg->value,
1368                                  arg->ref->offset);
1369         else
1370                 ret = e_snprintf(buf, buflen, "%s", arg->value);
1371         if (ret < 0)
1372                 return ret;
1373         buf += ret;
1374         buflen -= ret;
1375 
1376         /* Closing */
1377         while (depth--) {
1378                 ret = e_snprintf(buf, buflen, ")");
1379                 if (ret < 0)
1380                         return ret;
1381                 buf += ret;
1382                 buflen -= ret;
1383         }
1384         /* Print argument type */
1385         if (arg->type) {
1386                 ret = e_snprintf(buf, buflen, ":%s", arg->type);
1387                 if (ret <= 0)
1388                         return ret;
1389                 buf += ret;
1390         }
1391 
1392         return buf - tmp;
1393 }
1394 
1395 char *synthesize_probe_trace_command(struct probe_trace_event *tev)
1396 {
1397         struct probe_trace_point *tp = &tev->point;
1398         char *buf;
1399         int i, len, ret;
1400 
1401         buf = zalloc(MAX_CMDLEN);
1402         if (buf == NULL)
1403                 return NULL;
1404 
1405         if (tev->uprobes)
1406                 len = e_snprintf(buf, MAX_CMDLEN, "%c:%s/%s %s:%s",
1407                                  tp->retprobe ? 'r' : 'p',
1408                                  tev->group, tev->event,
1409                                  tp->module, tp->symbol);
1410         else
1411                 len = e_snprintf(buf, MAX_CMDLEN, "%c:%s/%s %s%s%s+%lu",
1412                                  tp->retprobe ? 'r' : 'p',
1413                                  tev->group, tev->event,
1414                                  tp->module ?: "", tp->module ? ":" : "",
1415                                  tp->symbol, tp->offset);
1416 
1417         if (len <= 0)
1418                 goto error;
1419 
1420         for (i = 0; i < tev->nargs; i++) {
1421                 ret = synthesize_probe_trace_arg(&tev->args[i], buf + len,
1422                                                   MAX_CMDLEN - len);
1423                 if (ret <= 0)
1424                         goto error;
1425                 len += ret;
1426         }
1427 
1428         return buf;
1429 error:
1430         free(buf);
1431         return NULL;
1432 }
1433 
1434 static int convert_to_perf_probe_event(struct probe_trace_event *tev,
1435                                struct perf_probe_event *pev, bool is_kprobe)
1436 {
1437         char buf[64] = "";
1438         int i, ret;
1439 
1440         /* Convert event/group name */
1441         pev->event = strdup(tev->event);
1442         pev->group = strdup(tev->group);
1443         if (pev->event == NULL || pev->group == NULL)
1444                 return -ENOMEM;
1445 
1446         /* Convert trace_point to probe_point */
1447         if (is_kprobe)
1448                 ret = kprobe_convert_to_perf_probe(&tev->point, &pev->point);
1449         else
1450                 ret = convert_to_perf_probe_point(&tev->point, &pev->point);
1451 
1452         if (ret < 0)
1453                 return ret;
1454 
1455         /* Convert trace_arg to probe_arg */
1456         pev->nargs = tev->nargs;
1457         pev->args = zalloc(sizeof(struct perf_probe_arg) * pev->nargs);
1458         if (pev->args == NULL)
1459                 return -ENOMEM;
1460         for (i = 0; i < tev->nargs && ret >= 0; i++) {
1461                 if (tev->args[i].name)
1462                         pev->args[i].name = strdup(tev->args[i].name);
1463                 else {
1464                         ret = synthesize_probe_trace_arg(&tev->args[i],
1465                                                           buf, 64);
1466                         pev->args[i].name = strdup(buf);
1467                 }
1468                 if (pev->args[i].name == NULL && ret >= 0)
1469                         ret = -ENOMEM;
1470         }
1471 
1472         if (ret < 0)
1473                 clear_perf_probe_event(pev);
1474 
1475         return ret;
1476 }
1477 
1478 void clear_perf_probe_event(struct perf_probe_event *pev)
1479 {
1480         struct perf_probe_point *pp = &pev->point;
1481         struct perf_probe_arg_field *field, *next;
1482         int i;
1483 
1484         if (pev->event)
1485                 free(pev->event);
1486         if (pev->group)
1487                 free(pev->group);
1488         if (pp->file)
1489                 free(pp->file);
1490         if (pp->function)
1491                 free(pp->function);
1492         if (pp->lazy_line)
1493                 free(pp->lazy_line);
1494         for (i = 0; i < pev->nargs; i++) {
1495                 if (pev->args[i].name)
1496                         free(pev->args[i].name);
1497                 if (pev->args[i].var)
1498                         free(pev->args[i].var);
1499                 if (pev->args[i].type)
1500                         free(pev->args[i].type);
1501                 field = pev->args[i].field;
1502                 while (field) {
1503                         next = field->next;
1504                         if (field->name)
1505                                 free(field->name);
1506                         free(field);
1507                         field = next;
1508                 }
1509         }
1510         if (pev->args)
1511                 free(pev->args);
1512         memset(pev, 0, sizeof(*pev));
1513 }
1514 
1515 static void clear_probe_trace_event(struct probe_trace_event *tev)
1516 {
1517         struct probe_trace_arg_ref *ref, *next;
1518         int i;
1519 
1520         if (tev->event)
1521                 free(tev->event);
1522         if (tev->group)
1523                 free(tev->group);
1524         if (tev->point.symbol)
1525                 free(tev->point.symbol);
1526         if (tev->point.module)
1527                 free(tev->point.module);
1528         for (i = 0; i < tev->nargs; i++) {
1529                 if (tev->args[i].name)
1530                         free(tev->args[i].name);
1531                 if (tev->args[i].value)
1532                         free(tev->args[i].value);
1533                 if (tev->args[i].type)
1534                         free(tev->args[i].type);
1535                 ref = tev->args[i].ref;
1536                 while (ref) {
1537                         next = ref->next;
1538                         free(ref);
1539                         ref = next;
1540                 }
1541         }
1542         if (tev->args)
1543                 free(tev->args);
1544         memset(tev, 0, sizeof(*tev));
1545 }
1546 
1547 static void print_warn_msg(const char *file, bool is_kprobe)
1548 {
1549 
1550         if (errno == ENOENT) {
1551                 const char *config;
1552 
1553                 if (!is_kprobe)
1554                         config = "CONFIG_UPROBE_EVENTS";
1555                 else
1556                         config = "CONFIG_KPROBE_EVENTS";
1557 
1558                 pr_warning("%s file does not exist - please rebuild kernel"
1559                                 " with %s.\n", file, config);
1560         } else
1561                 pr_warning("Failed to open %s file: %s\n", file,
1562                                 strerror(errno));
1563 }
1564 
1565 static int open_probe_events(const char *trace_file, bool readwrite,
1566                                 bool is_kprobe)
1567 {
1568         char buf[PATH_MAX];
1569         const char *__debugfs;
1570         int ret;
1571 
1572         __debugfs = debugfs_find_mountpoint();
1573         if (__debugfs == NULL) {
1574                 pr_warning("Debugfs is not mounted.\n");
1575                 return -ENOENT;
1576         }
1577 
1578         ret = e_snprintf(buf, PATH_MAX, "%s/%s", __debugfs, trace_file);
1579         if (ret >= 0) {
1580                 pr_debug("Opening %s write=%d\n", buf, readwrite);
1581                 if (readwrite && !probe_event_dry_run)
1582                         ret = open(buf, O_RDWR, O_APPEND);
1583                 else
1584                         ret = open(buf, O_RDONLY, 0);
1585 
1586                 if (ret < 0)
1587                         print_warn_msg(buf, is_kprobe);
1588         }
1589         return ret;
1590 }
1591 
1592 static int open_kprobe_events(bool readwrite)
1593 {
1594         return open_probe_events("tracing/kprobe_events", readwrite, true);
1595 }
1596 
1597 static int open_uprobe_events(bool readwrite)
1598 {
1599         return open_probe_events("tracing/uprobe_events", readwrite, false);
1600 }
1601 
1602 /* Get raw string list of current kprobe_events  or uprobe_events */
1603 static struct strlist *get_probe_trace_command_rawlist(int fd)
1604 {
1605         int ret, idx;
1606         FILE *fp;
1607         char buf[MAX_CMDLEN];
1608         char *p;
1609         struct strlist *sl;
1610 
1611         sl = strlist__new(true, NULL);
1612 
1613         fp = fdopen(dup(fd), "r");
1614         while (!feof(fp)) {
1615                 p = fgets(buf, MAX_CMDLEN, fp);
1616                 if (!p)
1617                         break;
1618 
1619                 idx = strlen(p) - 1;
1620                 if (p[idx] == '\n')
1621                         p[idx] = '\0';
1622                 ret = strlist__add(sl, buf);
1623                 if (ret < 0) {
1624                         pr_debug("strlist__add failed: %s\n", strerror(-ret));
1625                         strlist__delete(sl);
1626                         return NULL;
1627                 }
1628         }
1629         fclose(fp);
1630 
1631         return sl;
1632 }
1633 
1634 /* Show an event */
1635 static int show_perf_probe_event(struct perf_probe_event *pev)
1636 {
1637         int i, ret;
1638         char buf[128];
1639         char *place;
1640 
1641         /* Synthesize only event probe point */
1642         place = synthesize_perf_probe_point(&pev->point);
1643         if (!place)
1644                 return -EINVAL;
1645 
1646         ret = e_snprintf(buf, 128, "%s:%s", pev->group, pev->event);
1647         if (ret < 0)
1648                 return ret;
1649 
1650         printf("  %-20s (on %s", buf, place);
1651 
1652         if (pev->nargs > 0) {
1653                 printf(" with");
1654                 for (i = 0; i < pev->nargs; i++) {
1655                         ret = synthesize_perf_probe_arg(&pev->args[i],
1656                                                         buf, 128);
1657                         if (ret < 0)
1658                                 break;
1659                         printf(" %s", buf);
1660                 }
1661         }
1662         printf(")\n");
1663         free(place);
1664         return ret;
1665 }
1666 
1667 static int __show_perf_probe_events(int fd, bool is_kprobe)
1668 {
1669         int ret = 0;
1670         struct probe_trace_event tev;
1671         struct perf_probe_event pev;
1672         struct strlist *rawlist;
1673         struct str_node *ent;
1674 
1675         memset(&tev, 0, sizeof(tev));
1676         memset(&pev, 0, sizeof(pev));
1677 
1678         rawlist = get_probe_trace_command_rawlist(fd);
1679         if (!rawlist)
1680                 return -ENOENT;
1681 
1682         strlist__for_each(ent, rawlist) {
1683                 ret = parse_probe_trace_command(ent->s, &tev);
1684                 if (ret >= 0) {
1685                         ret = convert_to_perf_probe_event(&tev, &pev,
1686                                                                 is_kprobe);
1687                         if (ret >= 0)
1688                                 ret = show_perf_probe_event(&pev);
1689                 }
1690                 clear_perf_probe_event(&pev);
1691                 clear_probe_trace_event(&tev);
1692                 if (ret < 0)
1693                         break;
1694         }
1695         strlist__delete(rawlist);
1696 
1697         return ret;
1698 }
1699 
1700 /* List up current perf-probe events */
1701 int show_perf_probe_events(void)
1702 {
1703         int fd, ret;
1704 
1705         setup_pager();
1706         fd = open_kprobe_events(false);
1707 
1708         if (fd < 0)
1709                 return fd;
1710 
1711         ret = init_vmlinux();
1712         if (ret < 0)
1713                 return ret;
1714 
1715         ret = __show_perf_probe_events(fd, true);
1716         close(fd);
1717 
1718         fd = open_uprobe_events(false);
1719         if (fd >= 0) {
1720                 ret = __show_perf_probe_events(fd, false);
1721                 close(fd);
1722         }
1723 
1724         return ret;
1725 }
1726 
1727 /* Get current perf-probe event names */
1728 static struct strlist *get_probe_trace_event_names(int fd, bool include_group)
1729 {
1730         char buf[128];
1731         struct strlist *sl, *rawlist;
1732         struct str_node *ent;
1733         struct probe_trace_event tev;
1734         int ret = 0;
1735 
1736         memset(&tev, 0, sizeof(tev));
1737         rawlist = get_probe_trace_command_rawlist(fd);
1738         sl = strlist__new(true, NULL);
1739         strlist__for_each(ent, rawlist) {
1740                 ret = parse_probe_trace_command(ent->s, &tev);
1741                 if (ret < 0)
1742                         break;
1743                 if (include_group) {
1744                         ret = e_snprintf(buf, 128, "%s:%s", tev.group,
1745                                         tev.event);
1746                         if (ret >= 0)
1747                                 ret = strlist__add(sl, buf);
1748                 } else
1749                         ret = strlist__add(sl, tev.event);
1750                 clear_probe_trace_event(&tev);
1751                 if (ret < 0)
1752                         break;
1753         }
1754         strlist__delete(rawlist);
1755 
1756         if (ret < 0) {
1757                 strlist__delete(sl);
1758                 return NULL;
1759         }
1760         return sl;
1761 }
1762 
1763 static int write_probe_trace_event(int fd, struct probe_trace_event *tev)
1764 {
1765         int ret = 0;
1766         char *buf = synthesize_probe_trace_command(tev);
1767 
1768         if (!buf) {
1769                 pr_debug("Failed to synthesize probe trace event.\n");
1770                 return -EINVAL;
1771         }
1772 
1773         pr_debug("Writing event: %s\n", buf);
1774         if (!probe_event_dry_run) {
1775                 ret = write(fd, buf, strlen(buf));
1776                 if (ret <= 0)
1777                         pr_warning("Failed to write event: %s\n",
1778                                    strerror(errno));
1779         }
1780         free(buf);
1781         return ret;
1782 }
1783 
1784 static int get_new_event_name(char *buf, size_t len, const char *base,
1785                               struct strlist *namelist, bool allow_suffix)
1786 {
1787         int i, ret;
1788 
1789         /* Try no suffix */
1790         ret = e_snprintf(buf, len, "%s", base);
1791         if (ret < 0) {
1792                 pr_debug("snprintf() failed: %s\n", strerror(-ret));
1793                 return ret;
1794         }
1795         if (!strlist__has_entry(namelist, buf))
1796                 return 0;
1797 
1798         if (!allow_suffix) {
1799                 pr_warning("Error: event \"%s\" already exists. "
1800                            "(Use -f to force duplicates.)\n", base);
1801                 return -EEXIST;
1802         }
1803 
1804         /* Try to add suffix */
1805         for (i = 1; i < MAX_EVENT_INDEX; i++) {
1806                 ret = e_snprintf(buf, len, "%s_%d", base, i);
1807                 if (ret < 0) {
1808                         pr_debug("snprintf() failed: %s\n", strerror(-ret));
1809                         return ret;
1810                 }
1811                 if (!strlist__has_entry(namelist, buf))
1812                         break;
1813         }
1814         if (i == MAX_EVENT_INDEX) {
1815                 pr_warning("Too many events are on the same function.\n");
1816                 ret = -ERANGE;
1817         }
1818 
1819         return ret;
1820 }
1821 
1822 static int __add_probe_trace_events(struct perf_probe_event *pev,
1823                                      struct probe_trace_event *tevs,
1824                                      int ntevs, bool allow_suffix)
1825 {
1826         int i, fd, ret;
1827         struct probe_trace_event *tev = NULL;
1828         char buf[64];
1829         const char *event, *group;
1830         struct strlist *namelist;
1831 
1832         if (pev->uprobes)
1833                 fd = open_uprobe_events(true);
1834         else
1835                 fd = open_kprobe_events(true);
1836 
1837         if (fd < 0)
1838                 return fd;
1839         /* Get current event names */
1840         namelist = get_probe_trace_event_names(fd, false);
1841         if (!namelist) {
1842                 pr_debug("Failed to get current event list.\n");
1843                 return -EIO;
1844         }
1845 
1846         ret = 0;
1847         printf("Added new event%s\n", (ntevs > 1) ? "s:" : ":");
1848         for (i = 0; i < ntevs; i++) {
1849                 tev = &tevs[i];
1850                 if (pev->event)
1851                         event = pev->event;
1852                 else
1853                         if (pev->point.function)
1854                                 event = pev->point.function;
1855                         else
1856                                 event = tev->point.symbol;
1857                 if (pev->group)
1858                         group = pev->group;
1859                 else
1860                         group = PERFPROBE_GROUP;
1861 
1862                 /* Get an unused new event name */
1863                 ret = get_new_event_name(buf, 64, event,
1864                                          namelist, allow_suffix);
1865                 if (ret < 0)
1866                         break;
1867                 event = buf;
1868 
1869                 tev->event = strdup(event);
1870                 tev->group = strdup(group);
1871                 if (tev->event == NULL || tev->group == NULL) {
1872                         ret = -ENOMEM;
1873                         break;
1874                 }
1875                 ret = write_probe_trace_event(fd, tev);
1876                 if (ret < 0)
1877                         break;
1878                 /* Add added event name to namelist */
1879                 strlist__add(namelist, event);
1880 
1881                 /* Trick here - save current event/group */
1882                 event = pev->event;
1883                 group = pev->group;
1884                 pev->event = tev->event;
1885                 pev->group = tev->group;
1886                 show_perf_probe_event(pev);
1887                 /* Trick here - restore current event/group */
1888                 pev->event = (char *)event;
1889                 pev->group = (char *)group;
1890 
1891                 /*
1892                  * Probes after the first probe which comes from same
1893                  * user input are always allowed to add suffix, because
1894                  * there might be several addresses corresponding to
1895                  * one code line.
1896                  */
1897                 allow_suffix = true;
1898         }
1899 
1900         if (ret >= 0) {
1901                 /* Show how to use the event. */
1902                 printf("\nYou can now use it in all perf tools, such as:\n\n");
1903                 printf("\tperf record -e %s:%s -aR sleep 1\n\n", tev->group,
1904                          tev->event);
1905         }
1906 
1907         strlist__delete(namelist);
1908         close(fd);
1909         return ret;
1910 }
1911 
1912 static int convert_to_probe_trace_events(struct perf_probe_event *pev,
1913                                           struct probe_trace_event **tevs,
1914                                           int max_tevs, const char *target)
1915 {
1916         struct symbol *sym;
1917         int ret = 0, i;
1918         struct probe_trace_event *tev;
1919 
1920         /* Convert perf_probe_event with debuginfo */
1921         ret = try_to_find_probe_trace_events(pev, tevs, max_tevs, target);
1922         if (ret != 0)
1923                 return ret;     /* Found in debuginfo or got an error */
1924 
1925         /* Allocate trace event buffer */
1926         tev = *tevs = zalloc(sizeof(struct probe_trace_event));
1927         if (tev == NULL)
1928                 return -ENOMEM;
1929 
1930         /* Copy parameters */
1931         tev->point.symbol = strdup(pev->point.function);
1932         if (tev->point.symbol == NULL) {
1933                 ret = -ENOMEM;
1934                 goto error;
1935         }
1936 
1937         if (target) {
1938                 tev->point.module = strdup(target);
1939                 if (tev->point.module == NULL) {
1940                         ret = -ENOMEM;
1941                         goto error;
1942                 }
1943         }
1944 
1945         tev->point.offset = pev->point.offset;
1946         tev->point.retprobe = pev->point.retprobe;
1947         tev->nargs = pev->nargs;
1948         tev->uprobes = pev->uprobes;
1949 
1950         if (tev->nargs) {
1951                 tev->args = zalloc(sizeof(struct probe_trace_arg)
1952                                    * tev->nargs);
1953                 if (tev->args == NULL) {
1954                         ret = -ENOMEM;
1955                         goto error;
1956                 }
1957                 for (i = 0; i < tev->nargs; i++) {
1958                         if (pev->args[i].name) {
1959                                 tev->args[i].name = strdup(pev->args[i].name);
1960                                 if (tev->args[i].name == NULL) {
1961                                         ret = -ENOMEM;
1962                                         goto error;
1963                                 }
1964                         }
1965                         tev->args[i].value = strdup(pev->args[i].var);
1966                         if (tev->args[i].value == NULL) {
1967                                 ret = -ENOMEM;
1968                                 goto error;
1969                         }
1970                         if (pev->args[i].type) {
1971                                 tev->args[i].type = strdup(pev->args[i].type);
1972                                 if (tev->args[i].type == NULL) {
1973                                         ret = -ENOMEM;
1974                                         goto error;
1975                                 }
1976                         }
1977                 }
1978         }
1979 
1980         if (pev->uprobes)
1981                 return 1;
1982 
1983         /* Currently just checking function name from symbol map */
1984         sym = __find_kernel_function_by_name(tev->point.symbol, NULL);
1985         if (!sym) {
1986                 pr_warning("Kernel symbol \'%s\' not found.\n",
1987                            tev->point.symbol);
1988                 ret = -ENOENT;
1989                 goto error;
1990         } else if (tev->point.offset > sym->end - sym->start) {
1991                 pr_warning("Offset specified is greater than size of %s\n",
1992                            tev->point.symbol);
1993                 ret = -ENOENT;
1994                 goto error;
1995 
1996         }
1997 
1998         return 1;
1999 error:
2000         clear_probe_trace_event(tev);
2001         free(tev);
2002         *tevs = NULL;
2003         return ret;
2004 }
2005 
2006 struct __event_package {
2007         struct perf_probe_event         *pev;
2008         struct probe_trace_event        *tevs;
2009         int                             ntevs;
2010 };
2011 
2012 int add_perf_probe_events(struct perf_probe_event *pevs, int npevs,
2013                           int max_tevs, const char *target, bool force_add)
2014 {
2015         int i, j, ret;
2016         struct __event_package *pkgs;
2017 
2018         ret = 0;
2019         pkgs = zalloc(sizeof(struct __event_package) * npevs);
2020 
2021         if (pkgs == NULL)
2022                 return -ENOMEM;
2023 
2024         if (!pevs->uprobes)
2025                 /* Init vmlinux path */
2026                 ret = init_vmlinux();
2027         else
2028                 ret = init_user_exec();
2029 
2030         if (ret < 0) {
2031                 free(pkgs);
2032                 return ret;
2033         }
2034 
2035         /* Loop 1: convert all events */
2036         for (i = 0; i < npevs; i++) {
2037                 pkgs[i].pev = &pevs[i];
2038                 /* Convert with or without debuginfo */
2039                 ret  = convert_to_probe_trace_events(pkgs[i].pev,
2040                                                      &pkgs[i].tevs,
2041                                                      max_tevs,
2042                                                      target);
2043                 if (ret < 0)
2044                         goto end;
2045                 pkgs[i].ntevs = ret;
2046         }
2047 
2048         /* Loop 2: add all events */
2049         for (i = 0; i < npevs; i++) {
2050                 ret = __add_probe_trace_events(pkgs[i].pev, pkgs[i].tevs,
2051                                                 pkgs[i].ntevs, force_add);
2052                 if (ret < 0)
2053                         break;
2054         }
2055 end:
2056         /* Loop 3: cleanup and free trace events  */
2057         for (i = 0; i < npevs; i++) {
2058                 for (j = 0; j < pkgs[i].ntevs; j++)
2059                         clear_probe_trace_event(&pkgs[i].tevs[j]);
2060                 free(pkgs[i].tevs);
2061         }
2062         free(pkgs);
2063 
2064         return ret;
2065 }
2066 
2067 static int __del_trace_probe_event(int fd, struct str_node *ent)
2068 {
2069         char *p;
2070         char buf[128];
2071         int ret;
2072 
2073         /* Convert from perf-probe event to trace-probe event */
2074         ret = e_snprintf(buf, 128, "-:%s", ent->s);
2075         if (ret < 0)
2076                 goto error;
2077 
2078         p = strchr(buf + 2, ':');
2079         if (!p) {
2080                 pr_debug("Internal error: %s should have ':' but not.\n",
2081                          ent->s);
2082                 ret = -ENOTSUP;
2083                 goto error;
2084         }
2085         *p = '/';
2086 
2087         pr_debug("Writing event: %s\n", buf);
2088         ret = write(fd, buf, strlen(buf));
2089         if (ret < 0) {
2090                 ret = -errno;
2091                 goto error;
2092         }
2093 
2094         printf("Removed event: %s\n", ent->s);
2095         return 0;
2096 error:
2097         pr_warning("Failed to delete event: %s\n", strerror(-ret));
2098         return ret;
2099 }
2100 
2101 static int del_trace_probe_event(int fd, const char *buf,
2102                                                   struct strlist *namelist)
2103 {
2104         struct str_node *ent, *n;
2105         int ret = -1;
2106 
2107         if (strpbrk(buf, "*?")) { /* Glob-exp */
2108                 strlist__for_each_safe(ent, n, namelist)
2109                         if (strglobmatch(ent->s, buf)) {
2110                                 ret = __del_trace_probe_event(fd, ent);
2111                                 if (ret < 0)
2112                                         break;
2113                                 strlist__remove(namelist, ent);
2114                         }
2115         } else {
2116                 ent = strlist__find(namelist, buf);
2117                 if (ent) {
2118                         ret = __del_trace_probe_event(fd, ent);
2119                         if (ret >= 0)
2120                                 strlist__remove(namelist, ent);
2121                 }
2122         }
2123 
2124         return ret;
2125 }
2126 
2127 int del_perf_probe_events(struct strlist *dellist)
2128 {
2129         int ret = -1, ufd = -1, kfd = -1;
2130         char buf[128];
2131         const char *group, *event;
2132         char *p, *str;
2133         struct str_node *ent;
2134         struct strlist *namelist = NULL, *unamelist = NULL;
2135 
2136         /* Get current event names */
2137         kfd = open_kprobe_events(true);
2138         if (kfd < 0)
2139                 return kfd;
2140 
2141         namelist = get_probe_trace_event_names(kfd, true);
2142         ufd = open_uprobe_events(true);
2143 
2144         if (ufd >= 0)
2145                 unamelist = get_probe_trace_event_names(ufd, true);
2146 
2147         if (namelist == NULL && unamelist == NULL)
2148                 goto error;
2149 
2150         strlist__for_each(ent, dellist) {
2151                 str = strdup(ent->s);
2152                 if (str == NULL) {
2153                         ret = -ENOMEM;
2154                         goto error;
2155                 }
2156                 pr_debug("Parsing: %s\n", str);
2157                 p = strchr(str, ':');
2158                 if (p) {
2159                         group = str;
2160                         *p = '\0';
2161                         event = p + 1;
2162                 } else {
2163                         group = "*";
2164                         event = str;
2165                 }
2166 
2167                 ret = e_snprintf(buf, 128, "%s:%s", group, event);
2168                 if (ret < 0) {
2169                         pr_err("Failed to copy event.");
2170                         free(str);
2171                         goto error;
2172                 }
2173 
2174                 pr_debug("Group: %s, Event: %s\n", group, event);
2175 
2176                 if (namelist)
2177                         ret = del_trace_probe_event(kfd, buf, namelist);
2178 
2179                 if (unamelist && ret != 0)
2180                         ret = del_trace_probe_event(ufd, buf, unamelist);
2181 
2182                 if (ret != 0)
2183                         pr_info("Info: Event \"%s\" does not exist.\n", buf);
2184 
2185                 free(str);
2186         }
2187 
2188 error:
2189         if (kfd >= 0) {
2190                 strlist__delete(namelist);
2191                 close(kfd);
2192         }
2193 
2194         if (ufd >= 0) {
2195                 strlist__delete(unamelist);
2196                 close(ufd);
2197         }
2198 
2199         return ret;
2200 }
2201 
2202 /* TODO: don't use a global variable for filter ... */
2203 static struct strfilter *available_func_filter;
2204 
2205 /*
2206  * If a symbol corresponds to a function with global binding and
2207  * matches filter return 0. For all others return 1.
2208  */
2209 static int filter_available_functions(struct map *map __maybe_unused,
2210                                       struct symbol *sym)
2211 {
2212         if (sym->binding == STB_GLOBAL &&
2213             strfilter__compare(available_func_filter, sym->name))
2214                 return 0;
2215         return 1;
2216 }
2217 
2218 static int __show_available_funcs(struct map *map)
2219 {
2220         if (map__load(map, filter_available_functions)) {
2221                 pr_err("Failed to load map.\n");
2222                 return -EINVAL;
2223         }
2224         if (!dso__sorted_by_name(map->dso, map->type))
2225                 dso__sort_by_name(map->dso, map->type);
2226 
2227         dso__fprintf_symbols_by_name(map->dso, map->type, stdout);
2228         return 0;
2229 }
2230 
2231 static int available_kernel_funcs(const char *module)
2232 {
2233         struct map *map;
2234         int ret;
2235 
2236         ret = init_vmlinux();
2237         if (ret < 0)
2238                 return ret;
2239 
2240         map = kernel_get_module_map(module);
2241         if (!map) {
2242                 pr_err("Failed to find %s map.\n", (module) ? : "kernel");
2243                 return -EINVAL;
2244         }
2245         return __show_available_funcs(map);
2246 }
2247 
2248 static int available_user_funcs(const char *target)
2249 {
2250         struct map *map;
2251         int ret;
2252 
2253         ret = init_user_exec();
2254         if (ret < 0)
2255                 return ret;
2256 
2257         map = dso__new_map(target);
2258         ret = __show_available_funcs(map);
2259         dso__delete(map->dso);
2260         map__delete(map);
2261         return ret;
2262 }
2263 
2264 int show_available_funcs(const char *target, struct strfilter *_filter,
2265                                         bool user)
2266 {
2267         setup_pager();
2268         available_func_filter = _filter;
2269 
2270         if (!user)
2271                 return available_kernel_funcs(target);
2272 
2273         return available_user_funcs(target);
2274 }
2275 
2276 /*
2277  * uprobe_events only accepts address:
2278  * Convert function and any offset to address
2279  */
2280 static int convert_name_to_addr(struct perf_probe_event *pev, const char *exec)
2281 {
2282         struct perf_probe_point *pp = &pev->point;
2283         struct symbol *sym;
2284         struct map *map = NULL;
2285         char *function = NULL, *name = NULL;
2286         int ret = -EINVAL;
2287         unsigned long long vaddr = 0;
2288 
2289         if (!pp->function) {
2290                 pr_warning("No function specified for uprobes");
2291                 goto out;
2292         }
2293 
2294         function = strdup(pp->function);
2295         if (!function) {
2296                 pr_warning("Failed to allocate memory by strdup.\n");
2297                 ret = -ENOMEM;
2298                 goto out;
2299         }
2300 
2301         name = realpath(exec, NULL);
2302         if (!name) {
2303                 pr_warning("Cannot find realpath for %s.\n", exec);
2304                 goto out;
2305         }
2306         map = dso__new_map(name);
2307         if (!map) {
2308                 pr_warning("Cannot find appropriate DSO for %s.\n", exec);
2309                 goto out;
2310         }
2311         available_func_filter = strfilter__new(function, NULL);
2312         if (map__load(map, filter_available_functions)) {
2313                 pr_err("Failed to load map.\n");
2314                 goto out;
2315         }
2316 
2317         sym = map__find_symbol_by_name(map, function, NULL);
2318         if (!sym) {
2319                 pr_warning("Cannot find %s in DSO %s\n", function, exec);
2320                 goto out;
2321         }
2322 
2323         if (map->start > sym->start)
2324                 vaddr = map->start;
2325         vaddr += sym->start + pp->offset + map->pgoff;
2326         pp->offset = 0;
2327 
2328         if (!pev->event) {
2329                 pev->event = function;
2330                 function = NULL;
2331         }
2332         if (!pev->group) {
2333                 char *ptr1, *ptr2, *exec_copy;
2334 
2335                 pev->group = zalloc(sizeof(char *) * 64);
2336                 exec_copy = strdup(exec);
2337                 if (!exec_copy) {
2338                         ret = -ENOMEM;
2339                         pr_warning("Failed to copy exec string.\n");
2340                         goto out;
2341                 }
2342 
2343                 ptr1 = strdup(basename(exec_copy));
2344                 if (ptr1) {
2345                         ptr2 = strpbrk(ptr1, "-._");
2346                         if (ptr2)
2347                                 *ptr2 = '\0';
2348                         e_snprintf(pev->group, 64, "%s_%s", PERFPROBE_GROUP,
2349                                         ptr1);
2350                         free(ptr1);
2351                 }
2352                 free(exec_copy);
2353         }
2354         free(pp->function);
2355         pp->function = zalloc(sizeof(char *) * MAX_PROBE_ARGS);
2356         if (!pp->function) {
2357                 ret = -ENOMEM;
2358                 pr_warning("Failed to allocate memory by zalloc.\n");
2359                 goto out;
2360         }
2361         e_snprintf(pp->function, MAX_PROBE_ARGS, "0x%llx", vaddr);
2362         ret = 0;
2363 
2364 out:
2365         if (map) {
2366                 dso__delete(map->dso);
2367                 map__delete(map);
2368         }
2369         if (function)
2370                 free(function);
2371         if (name)
2372                 free(name);
2373         return ret;
2374 }
2375 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp