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