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