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