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