linux/tools/perf/util/probe-file.c
<<
>>
Prefs
   1/*
   2 * probe-file.c : operate ftrace k/uprobe events files
   3 *
   4 * Written by Masami Hiramatsu <masami.hiramatsu.pt@hitachi.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 */
  17#include <errno.h>
  18#include <sys/stat.h>
  19#include <sys/types.h>
  20#include <sys/uio.h>
  21#include <unistd.h>
  22#include "util.h"
  23#include "event.h"
  24#include "strlist.h"
  25#include "strfilter.h"
  26#include "debug.h"
  27#include "cache.h"
  28#include "color.h"
  29#include "symbol.h"
  30#include "thread.h"
  31#include <api/fs/tracing_path.h>
  32#include "probe-event.h"
  33#include "probe-file.h"
  34#include "session.h"
  35#include "perf_regs.h"
  36#include "string2.h"
  37
  38/* 4096 - 2 ('\n' + '\0') */
  39#define MAX_CMDLEN 4094
  40
  41static void print_open_warning(int err, bool uprobe)
  42{
  43        char sbuf[STRERR_BUFSIZE];
  44
  45        if (err == -ENOENT) {
  46                const char *config;
  47
  48                if (uprobe)
  49                        config = "CONFIG_UPROBE_EVENTS";
  50                else
  51                        config = "CONFIG_KPROBE_EVENTS";
  52
  53                pr_warning("%cprobe_events file does not exist"
  54                           " - please rebuild kernel with %s.\n",
  55                           uprobe ? 'u' : 'k', config);
  56        } else if (err == -ENOTSUP)
  57                pr_warning("Tracefs or debugfs is not mounted.\n");
  58        else
  59                pr_warning("Failed to open %cprobe_events: %s\n",
  60                           uprobe ? 'u' : 'k',
  61                           str_error_r(-err, sbuf, sizeof(sbuf)));
  62}
  63
  64static void print_both_open_warning(int kerr, int uerr)
  65{
  66        /* Both kprobes and uprobes are disabled, warn it. */
  67        if (kerr == -ENOTSUP && uerr == -ENOTSUP)
  68                pr_warning("Tracefs or debugfs is not mounted.\n");
  69        else if (kerr == -ENOENT && uerr == -ENOENT)
  70                pr_warning("Please rebuild kernel with CONFIG_KPROBE_EVENTS "
  71                           "or/and CONFIG_UPROBE_EVENTS.\n");
  72        else {
  73                char sbuf[STRERR_BUFSIZE];
  74                pr_warning("Failed to open kprobe events: %s.\n",
  75                           str_error_r(-kerr, sbuf, sizeof(sbuf)));
  76                pr_warning("Failed to open uprobe events: %s.\n",
  77                           str_error_r(-uerr, sbuf, sizeof(sbuf)));
  78        }
  79}
  80
  81int open_trace_file(const char *trace_file, bool readwrite)
  82{
  83        char buf[PATH_MAX];
  84        int ret;
  85
  86        ret = e_snprintf(buf, PATH_MAX, "%s/%s",
  87                         tracing_path, trace_file);
  88        if (ret >= 0) {
  89                pr_debug("Opening %s write=%d\n", buf, readwrite);
  90                if (readwrite && !probe_event_dry_run)
  91                        ret = open(buf, O_RDWR | O_APPEND, 0);
  92                else
  93                        ret = open(buf, O_RDONLY, 0);
  94
  95                if (ret < 0)
  96                        ret = -errno;
  97        }
  98        return ret;
  99}
 100
 101static int open_kprobe_events(bool readwrite)
 102{
 103        return open_trace_file("kprobe_events", readwrite);
 104}
 105
 106static int open_uprobe_events(bool readwrite)
 107{
 108        return open_trace_file("uprobe_events", readwrite);
 109}
 110
 111int probe_file__open(int flag)
 112{
 113        int fd;
 114
 115        if (flag & PF_FL_UPROBE)
 116                fd = open_uprobe_events(flag & PF_FL_RW);
 117        else
 118                fd = open_kprobe_events(flag & PF_FL_RW);
 119        if (fd < 0)
 120                print_open_warning(fd, flag & PF_FL_UPROBE);
 121
 122        return fd;
 123}
 124
 125int probe_file__open_both(int *kfd, int *ufd, int flag)
 126{
 127        if (!kfd || !ufd)
 128                return -EINVAL;
 129
 130        *kfd = open_kprobe_events(flag & PF_FL_RW);
 131        *ufd = open_uprobe_events(flag & PF_FL_RW);
 132        if (*kfd < 0 && *ufd < 0) {
 133                print_both_open_warning(*kfd, *ufd);
 134                return *kfd;
 135        }
 136
 137        return 0;
 138}
 139
 140/* Get raw string list of current kprobe_events  or uprobe_events */
 141struct strlist *probe_file__get_rawlist(int fd)
 142{
 143        int ret, idx, fddup;
 144        FILE *fp;
 145        char buf[MAX_CMDLEN];
 146        char *p;
 147        struct strlist *sl;
 148
 149        if (fd < 0)
 150                return NULL;
 151
 152        sl = strlist__new(NULL, NULL);
 153        if (sl == NULL)
 154                return NULL;
 155
 156        fddup = dup(fd);
 157        if (fddup < 0)
 158                goto out_free_sl;
 159
 160        fp = fdopen(fddup, "r");
 161        if (!fp)
 162                goto out_close_fddup;
 163
 164        while (!feof(fp)) {
 165                p = fgets(buf, MAX_CMDLEN, fp);
 166                if (!p)
 167                        break;
 168
 169                idx = strlen(p) - 1;
 170                if (p[idx] == '\n')
 171                        p[idx] = '\0';
 172                ret = strlist__add(sl, buf);
 173                if (ret < 0) {
 174                        pr_debug("strlist__add failed (%d)\n", ret);
 175                        goto out_close_fp;
 176                }
 177        }
 178        fclose(fp);
 179
 180        return sl;
 181
 182out_close_fp:
 183        fclose(fp);
 184        goto out_free_sl;
 185out_close_fddup:
 186        close(fddup);
 187out_free_sl:
 188        strlist__delete(sl);
 189        return NULL;
 190}
 191
 192static struct strlist *__probe_file__get_namelist(int fd, bool include_group)
 193{
 194        char buf[128];
 195        struct strlist *sl, *rawlist;
 196        struct str_node *ent;
 197        struct probe_trace_event tev;
 198        int ret = 0;
 199
 200        memset(&tev, 0, sizeof(tev));
 201        rawlist = probe_file__get_rawlist(fd);
 202        if (!rawlist)
 203                return NULL;
 204        sl = strlist__new(NULL, NULL);
 205        strlist__for_each_entry(ent, rawlist) {
 206                ret = parse_probe_trace_command(ent->s, &tev);
 207                if (ret < 0)
 208                        break;
 209                if (include_group) {
 210                        ret = e_snprintf(buf, 128, "%s:%s", tev.group,
 211                                        tev.event);
 212                        if (ret >= 0)
 213                                ret = strlist__add(sl, buf);
 214                } else
 215                        ret = strlist__add(sl, tev.event);
 216                clear_probe_trace_event(&tev);
 217                if (ret < 0)
 218                        break;
 219        }
 220        strlist__delete(rawlist);
 221
 222        if (ret < 0) {
 223                strlist__delete(sl);
 224                return NULL;
 225        }
 226        return sl;
 227}
 228
 229/* Get current perf-probe event names */
 230struct strlist *probe_file__get_namelist(int fd)
 231{
 232        return __probe_file__get_namelist(fd, false);
 233}
 234
 235int probe_file__add_event(int fd, struct probe_trace_event *tev)
 236{
 237        int ret = 0;
 238        char *buf = synthesize_probe_trace_command(tev);
 239        char sbuf[STRERR_BUFSIZE];
 240
 241        if (!buf) {
 242                pr_debug("Failed to synthesize probe trace event.\n");
 243                return -EINVAL;
 244        }
 245
 246        pr_debug("Writing event: %s\n", buf);
 247        if (!probe_event_dry_run) {
 248                if (write(fd, buf, strlen(buf)) < (int)strlen(buf)) {
 249                        ret = -errno;
 250                        pr_warning("Failed to write event: %s\n",
 251                                   str_error_r(errno, sbuf, sizeof(sbuf)));
 252                }
 253        }
 254        free(buf);
 255
 256        return ret;
 257}
 258
 259static int __del_trace_probe_event(int fd, struct str_node *ent)
 260{
 261        char *p;
 262        char buf[128];
 263        int ret;
 264
 265        /* Convert from perf-probe event to trace-probe event */
 266        ret = e_snprintf(buf, 128, "-:%s", ent->s);
 267        if (ret < 0)
 268                goto error;
 269
 270        p = strchr(buf + 2, ':');
 271        if (!p) {
 272                pr_debug("Internal error: %s should have ':' but not.\n",
 273                         ent->s);
 274                ret = -ENOTSUP;
 275                goto error;
 276        }
 277        *p = '/';
 278
 279        pr_debug("Writing event: %s\n", buf);
 280        ret = write(fd, buf, strlen(buf));
 281        if (ret < 0) {
 282                ret = -errno;
 283                goto error;
 284        }
 285
 286        return 0;
 287error:
 288        pr_warning("Failed to delete event: %s\n",
 289                   str_error_r(-ret, buf, sizeof(buf)));
 290        return ret;
 291}
 292
 293int probe_file__get_events(int fd, struct strfilter *filter,
 294                           struct strlist *plist)
 295{
 296        struct strlist *namelist;
 297        struct str_node *ent;
 298        const char *p;
 299        int ret = -ENOENT;
 300
 301        if (!plist)
 302                return -EINVAL;
 303
 304        namelist = __probe_file__get_namelist(fd, true);
 305        if (!namelist)
 306                return -ENOENT;
 307
 308        strlist__for_each_entry(ent, namelist) {
 309                p = strchr(ent->s, ':');
 310                if ((p && strfilter__compare(filter, p + 1)) ||
 311                    strfilter__compare(filter, ent->s)) {
 312                        strlist__add(plist, ent->s);
 313                        ret = 0;
 314                }
 315        }
 316        strlist__delete(namelist);
 317
 318        return ret;
 319}
 320
 321int probe_file__del_strlist(int fd, struct strlist *namelist)
 322{
 323        int ret = 0;
 324        struct str_node *ent;
 325
 326        strlist__for_each_entry(ent, namelist) {
 327                ret = __del_trace_probe_event(fd, ent);
 328                if (ret < 0)
 329                        break;
 330        }
 331        return ret;
 332}
 333
 334int probe_file__del_events(int fd, struct strfilter *filter)
 335{
 336        struct strlist *namelist;
 337        int ret;
 338
 339        namelist = strlist__new(NULL, NULL);
 340        if (!namelist)
 341                return -ENOMEM;
 342
 343        ret = probe_file__get_events(fd, filter, namelist);
 344        if (ret < 0)
 345                return ret;
 346
 347        ret = probe_file__del_strlist(fd, namelist);
 348        strlist__delete(namelist);
 349
 350        return ret;
 351}
 352
 353/* Caller must ensure to remove this entry from list */
 354static void probe_cache_entry__delete(struct probe_cache_entry *entry)
 355{
 356        if (entry) {
 357                BUG_ON(!list_empty(&entry->node));
 358
 359                strlist__delete(entry->tevlist);
 360                clear_perf_probe_event(&entry->pev);
 361                zfree(&entry->spev);
 362                free(entry);
 363        }
 364}
 365
 366static struct probe_cache_entry *
 367probe_cache_entry__new(struct perf_probe_event *pev)
 368{
 369        struct probe_cache_entry *entry = zalloc(sizeof(*entry));
 370
 371        if (entry) {
 372                INIT_LIST_HEAD(&entry->node);
 373                entry->tevlist = strlist__new(NULL, NULL);
 374                if (!entry->tevlist)
 375                        zfree(&entry);
 376                else if (pev) {
 377                        entry->spev = synthesize_perf_probe_command(pev);
 378                        if (!entry->spev ||
 379                            perf_probe_event__copy(&entry->pev, pev) < 0) {
 380                                probe_cache_entry__delete(entry);
 381                                return NULL;
 382                        }
 383                }
 384        }
 385
 386        return entry;
 387}
 388
 389int probe_cache_entry__get_event(struct probe_cache_entry *entry,
 390                                 struct probe_trace_event **tevs)
 391{
 392        struct probe_trace_event *tev;
 393        struct str_node *node;
 394        int ret, i;
 395
 396        ret = strlist__nr_entries(entry->tevlist);
 397        if (ret > probe_conf.max_probes)
 398                return -E2BIG;
 399
 400        *tevs = zalloc(ret * sizeof(*tev));
 401        if (!*tevs)
 402                return -ENOMEM;
 403
 404        i = 0;
 405        strlist__for_each_entry(node, entry->tevlist) {
 406                tev = &(*tevs)[i++];
 407                ret = parse_probe_trace_command(node->s, tev);
 408                if (ret < 0)
 409                        break;
 410        }
 411        return i;
 412}
 413
 414/* For the kernel probe caches, pass target = NULL or DSO__NAME_KALLSYMS */
 415static int probe_cache__open(struct probe_cache *pcache, const char *target)
 416{
 417        char cpath[PATH_MAX];
 418        char sbuildid[SBUILD_ID_SIZE];
 419        char *dir_name = NULL;
 420        bool is_kallsyms = false;
 421        int ret, fd;
 422
 423        if (target && build_id_cache__cached(target)) {
 424                /* This is a cached buildid */
 425                strncpy(sbuildid, target, SBUILD_ID_SIZE);
 426                dir_name = build_id_cache__linkname(sbuildid, NULL, 0);
 427                goto found;
 428        }
 429
 430        if (!target || !strcmp(target, DSO__NAME_KALLSYMS)) {
 431                target = DSO__NAME_KALLSYMS;
 432                is_kallsyms = true;
 433                ret = sysfs__sprintf_build_id("/", sbuildid);
 434        } else
 435                ret = filename__sprintf_build_id(target, sbuildid);
 436
 437        if (ret < 0) {
 438                pr_debug("Failed to get build-id from %s.\n", target);
 439                return ret;
 440        }
 441
 442        /* If we have no buildid cache, make it */
 443        if (!build_id_cache__cached(sbuildid)) {
 444                ret = build_id_cache__add_s(sbuildid, target,
 445                                            is_kallsyms, NULL);
 446                if (ret < 0) {
 447                        pr_debug("Failed to add build-id cache: %s\n", target);
 448                        return ret;
 449                }
 450        }
 451
 452        dir_name = build_id_cache__cachedir(sbuildid, target, is_kallsyms,
 453                                            false);
 454found:
 455        if (!dir_name) {
 456                pr_debug("Failed to get cache from %s\n", target);
 457                return -ENOMEM;
 458        }
 459
 460        snprintf(cpath, PATH_MAX, "%s/probes", dir_name);
 461        fd = open(cpath, O_CREAT | O_RDWR, 0644);
 462        if (fd < 0)
 463                pr_debug("Failed to open cache(%d): %s\n", fd, cpath);
 464        free(dir_name);
 465        pcache->fd = fd;
 466
 467        return fd;
 468}
 469
 470static int probe_cache__load(struct probe_cache *pcache)
 471{
 472        struct probe_cache_entry *entry = NULL;
 473        char buf[MAX_CMDLEN], *p;
 474        int ret = 0, fddup;
 475        FILE *fp;
 476
 477        fddup = dup(pcache->fd);
 478        if (fddup < 0)
 479                return -errno;
 480        fp = fdopen(fddup, "r");
 481        if (!fp) {
 482                close(fddup);
 483                return -EINVAL;
 484        }
 485
 486        while (!feof(fp)) {
 487                if (!fgets(buf, MAX_CMDLEN, fp))
 488                        break;
 489                p = strchr(buf, '\n');
 490                if (p)
 491                        *p = '\0';
 492                /* #perf_probe_event or %sdt_event */
 493                if (buf[0] == '#' || buf[0] == '%') {
 494                        entry = probe_cache_entry__new(NULL);
 495                        if (!entry) {
 496                                ret = -ENOMEM;
 497                                goto out;
 498                        }
 499                        if (buf[0] == '%')
 500                                entry->sdt = true;
 501                        entry->spev = strdup(buf + 1);
 502                        if (entry->spev)
 503                                ret = parse_perf_probe_command(buf + 1,
 504                                                                &entry->pev);
 505                        else
 506                                ret = -ENOMEM;
 507                        if (ret < 0) {
 508                                probe_cache_entry__delete(entry);
 509                                goto out;
 510                        }
 511                        list_add_tail(&entry->node, &pcache->entries);
 512                } else {        /* trace_probe_event */
 513                        if (!entry) {
 514                                ret = -EINVAL;
 515                                goto out;
 516                        }
 517                        strlist__add(entry->tevlist, buf);
 518                }
 519        }
 520out:
 521        fclose(fp);
 522        return ret;
 523}
 524
 525static struct probe_cache *probe_cache__alloc(void)
 526{
 527        struct probe_cache *pcache = zalloc(sizeof(*pcache));
 528
 529        if (pcache) {
 530                INIT_LIST_HEAD(&pcache->entries);
 531                pcache->fd = -EINVAL;
 532        }
 533        return pcache;
 534}
 535
 536void probe_cache__purge(struct probe_cache *pcache)
 537{
 538        struct probe_cache_entry *entry, *n;
 539
 540        list_for_each_entry_safe(entry, n, &pcache->entries, node) {
 541                list_del_init(&entry->node);
 542                probe_cache_entry__delete(entry);
 543        }
 544}
 545
 546void probe_cache__delete(struct probe_cache *pcache)
 547{
 548        if (!pcache)
 549                return;
 550
 551        probe_cache__purge(pcache);
 552        if (pcache->fd > 0)
 553                close(pcache->fd);
 554        free(pcache);
 555}
 556
 557struct probe_cache *probe_cache__new(const char *target)
 558{
 559        struct probe_cache *pcache = probe_cache__alloc();
 560        int ret;
 561
 562        if (!pcache)
 563                return NULL;
 564
 565        ret = probe_cache__open(pcache, target);
 566        if (ret < 0) {
 567                pr_debug("Cache open error: %d\n", ret);
 568                goto out_err;
 569        }
 570
 571        ret = probe_cache__load(pcache);
 572        if (ret < 0) {
 573                pr_debug("Cache read error: %d\n", ret);
 574                goto out_err;
 575        }
 576
 577        return pcache;
 578
 579out_err:
 580        probe_cache__delete(pcache);
 581        return NULL;
 582}
 583
 584static bool streql(const char *a, const char *b)
 585{
 586        if (a == b)
 587                return true;
 588
 589        if (!a || !b)
 590                return false;
 591
 592        return !strcmp(a, b);
 593}
 594
 595struct probe_cache_entry *
 596probe_cache__find(struct probe_cache *pcache, struct perf_probe_event *pev)
 597{
 598        struct probe_cache_entry *entry = NULL;
 599        char *cmd = synthesize_perf_probe_command(pev);
 600
 601        if (!cmd)
 602                return NULL;
 603
 604        for_each_probe_cache_entry(entry, pcache) {
 605                if (pev->sdt) {
 606                        if (entry->pev.event &&
 607                            streql(entry->pev.event, pev->event) &&
 608                            (!pev->group ||
 609                             streql(entry->pev.group, pev->group)))
 610                                goto found;
 611
 612                        continue;
 613                }
 614                /* Hit if same event name or same command-string */
 615                if ((pev->event &&
 616                     (streql(entry->pev.group, pev->group) &&
 617                      streql(entry->pev.event, pev->event))) ||
 618                    (!strcmp(entry->spev, cmd)))
 619                        goto found;
 620        }
 621        entry = NULL;
 622
 623found:
 624        free(cmd);
 625        return entry;
 626}
 627
 628struct probe_cache_entry *
 629probe_cache__find_by_name(struct probe_cache *pcache,
 630                          const char *group, const char *event)
 631{
 632        struct probe_cache_entry *entry = NULL;
 633
 634        for_each_probe_cache_entry(entry, pcache) {
 635                /* Hit if same event name or same command-string */
 636                if (streql(entry->pev.group, group) &&
 637                    streql(entry->pev.event, event))
 638                        goto found;
 639        }
 640        entry = NULL;
 641
 642found:
 643        return entry;
 644}
 645
 646int probe_cache__add_entry(struct probe_cache *pcache,
 647                           struct perf_probe_event *pev,
 648                           struct probe_trace_event *tevs, int ntevs)
 649{
 650        struct probe_cache_entry *entry = NULL;
 651        char *command;
 652        int i, ret = 0;
 653
 654        if (!pcache || !pev || !tevs || ntevs <= 0) {
 655                ret = -EINVAL;
 656                goto out_err;
 657        }
 658
 659        /* Remove old cache entry */
 660        entry = probe_cache__find(pcache, pev);
 661        if (entry) {
 662                list_del_init(&entry->node);
 663                probe_cache_entry__delete(entry);
 664        }
 665
 666        ret = -ENOMEM;
 667        entry = probe_cache_entry__new(pev);
 668        if (!entry)
 669                goto out_err;
 670
 671        for (i = 0; i < ntevs; i++) {
 672                if (!tevs[i].point.symbol)
 673                        continue;
 674
 675                command = synthesize_probe_trace_command(&tevs[i]);
 676                if (!command)
 677                        goto out_err;
 678                strlist__add(entry->tevlist, command);
 679                free(command);
 680        }
 681        list_add_tail(&entry->node, &pcache->entries);
 682        pr_debug("Added probe cache: %d\n", ntevs);
 683        return 0;
 684
 685out_err:
 686        pr_debug("Failed to add probe caches\n");
 687        probe_cache_entry__delete(entry);
 688        return ret;
 689}
 690
 691#ifdef HAVE_GELF_GETNOTE_SUPPORT
 692static unsigned long long sdt_note__get_addr(struct sdt_note *note)
 693{
 694        return note->bit32 ? (unsigned long long)note->addr.a32[0]
 695                 : (unsigned long long)note->addr.a64[0];
 696}
 697
 698static const char * const type_to_suffix[] = {
 699        ":s64", "", "", "", ":s32", "", ":s16", ":s8",
 700        "", ":u8", ":u16", "", ":u32", "", "", "", ":u64"
 701};
 702
 703/*
 704 * Isolate the string number and convert it into a decimal value;
 705 * this will be an index to get suffix of the uprobe name (defining
 706 * the type)
 707 */
 708static int sdt_arg_parse_size(char *n_ptr, const char **suffix)
 709{
 710        long type_idx;
 711
 712        type_idx = strtol(n_ptr, NULL, 10);
 713        if (type_idx < -8 || type_idx > 8) {
 714                pr_debug4("Failed to get a valid sdt type\n");
 715                return -1;
 716        }
 717
 718        *suffix = type_to_suffix[type_idx + 8];
 719        return 0;
 720}
 721
 722static int synthesize_sdt_probe_arg(struct strbuf *buf, int i, const char *arg)
 723{
 724        char *op, *desc = strdup(arg), *new_op = NULL;
 725        const char *suffix = "";
 726        int ret = -1;
 727
 728        if (desc == NULL) {
 729                pr_debug4("Allocation error\n");
 730                return ret;
 731        }
 732
 733        /*
 734         * Argument is in N@OP format. N is size of the argument and OP is
 735         * the actual assembly operand. N can be omitted; in that case
 736         * argument is just OP(without @).
 737         */
 738        op = strchr(desc, '@');
 739        if (op) {
 740                op[0] = '\0';
 741                op++;
 742
 743                if (sdt_arg_parse_size(desc, &suffix))
 744                        goto error;
 745        } else {
 746                op = desc;
 747        }
 748
 749        ret = arch_sdt_arg_parse_op(op, &new_op);
 750
 751        if (ret < 0)
 752                goto error;
 753
 754        if (ret == SDT_ARG_VALID) {
 755                ret = strbuf_addf(buf, " arg%d=%s%s", i + 1, new_op, suffix);
 756                if (ret < 0)
 757                        goto error;
 758        }
 759
 760        ret = 0;
 761error:
 762        free(desc);
 763        free(new_op);
 764        return ret;
 765}
 766
 767static char *synthesize_sdt_probe_command(struct sdt_note *note,
 768                                        const char *pathname,
 769                                        const char *sdtgrp)
 770{
 771        struct strbuf buf;
 772        char *ret = NULL, **args;
 773        int i, args_count;
 774
 775        if (strbuf_init(&buf, 32) < 0)
 776                return NULL;
 777
 778        if (strbuf_addf(&buf, "p:%s/%s %s:0x%llx",
 779                                sdtgrp, note->name, pathname,
 780                                sdt_note__get_addr(note)) < 0)
 781                goto error;
 782
 783        if (!note->args)
 784                goto out;
 785
 786        if (note->args) {
 787                args = argv_split(note->args, &args_count);
 788
 789                for (i = 0; i < args_count; ++i) {
 790                        if (synthesize_sdt_probe_arg(&buf, i, args[i]) < 0)
 791                                goto error;
 792                }
 793        }
 794
 795out:
 796        ret = strbuf_detach(&buf, NULL);
 797error:
 798        strbuf_release(&buf);
 799        return ret;
 800}
 801
 802int probe_cache__scan_sdt(struct probe_cache *pcache, const char *pathname)
 803{
 804        struct probe_cache_entry *entry = NULL;
 805        struct list_head sdtlist;
 806        struct sdt_note *note;
 807        char *buf;
 808        char sdtgrp[64];
 809        int ret;
 810
 811        INIT_LIST_HEAD(&sdtlist);
 812        ret = get_sdt_note_list(&sdtlist, pathname);
 813        if (ret < 0) {
 814                pr_debug4("Failed to get sdt note: %d\n", ret);
 815                return ret;
 816        }
 817        list_for_each_entry(note, &sdtlist, note_list) {
 818                ret = snprintf(sdtgrp, 64, "sdt_%s", note->provider);
 819                if (ret < 0)
 820                        break;
 821                /* Try to find same-name entry */
 822                entry = probe_cache__find_by_name(pcache, sdtgrp, note->name);
 823                if (!entry) {
 824                        entry = probe_cache_entry__new(NULL);
 825                        if (!entry) {
 826                                ret = -ENOMEM;
 827                                break;
 828                        }
 829                        entry->sdt = true;
 830                        ret = asprintf(&entry->spev, "%s:%s=%s", sdtgrp,
 831                                        note->name, note->name);
 832                        if (ret < 0)
 833                                break;
 834                        entry->pev.event = strdup(note->name);
 835                        entry->pev.group = strdup(sdtgrp);
 836                        list_add_tail(&entry->node, &pcache->entries);
 837                }
 838                buf = synthesize_sdt_probe_command(note, pathname, sdtgrp);
 839                if (!buf) {
 840                        ret = -ENOMEM;
 841                        break;
 842                }
 843
 844                strlist__add(entry->tevlist, buf);
 845                free(buf);
 846                entry = NULL;
 847        }
 848        if (entry) {
 849                list_del_init(&entry->node);
 850                probe_cache_entry__delete(entry);
 851        }
 852        cleanup_sdt_note_list(&sdtlist);
 853        return ret;
 854}
 855#endif
 856
 857static int probe_cache_entry__write(struct probe_cache_entry *entry, int fd)
 858{
 859        struct str_node *snode;
 860        struct stat st;
 861        struct iovec iov[3];
 862        const char *prefix = entry->sdt ? "%" : "#";
 863        int ret;
 864        /* Save stat for rollback */
 865        ret = fstat(fd, &st);
 866        if (ret < 0)
 867                return ret;
 868
 869        pr_debug("Writing cache: %s%s\n", prefix, entry->spev);
 870        iov[0].iov_base = (void *)prefix; iov[0].iov_len = 1;
 871        iov[1].iov_base = entry->spev; iov[1].iov_len = strlen(entry->spev);
 872        iov[2].iov_base = (void *)"\n"; iov[2].iov_len = 1;
 873        ret = writev(fd, iov, 3);
 874        if (ret < (int)iov[1].iov_len + 2)
 875                goto rollback;
 876
 877        strlist__for_each_entry(snode, entry->tevlist) {
 878                iov[0].iov_base = (void *)snode->s;
 879                iov[0].iov_len = strlen(snode->s);
 880                iov[1].iov_base = (void *)"\n"; iov[1].iov_len = 1;
 881                ret = writev(fd, iov, 2);
 882                if (ret < (int)iov[0].iov_len + 1)
 883                        goto rollback;
 884        }
 885        return 0;
 886
 887rollback:
 888        /* Rollback to avoid cache file corruption */
 889        if (ret > 0)
 890                ret = -1;
 891        if (ftruncate(fd, st.st_size) < 0)
 892                ret = -2;
 893
 894        return ret;
 895}
 896
 897int probe_cache__commit(struct probe_cache *pcache)
 898{
 899        struct probe_cache_entry *entry;
 900        int ret = 0;
 901
 902        /* TBD: if we do not update existing entries, skip it */
 903        ret = lseek(pcache->fd, 0, SEEK_SET);
 904        if (ret < 0)
 905                goto out;
 906
 907        ret = ftruncate(pcache->fd, 0);
 908        if (ret < 0)
 909                goto out;
 910
 911        for_each_probe_cache_entry(entry, pcache) {
 912                ret = probe_cache_entry__write(entry, pcache->fd);
 913                pr_debug("Cache committed: %d\n", ret);
 914                if (ret < 0)
 915                        break;
 916        }
 917out:
 918        return ret;
 919}
 920
 921static bool probe_cache_entry__compare(struct probe_cache_entry *entry,
 922                                       struct strfilter *filter)
 923{
 924        char buf[128], *ptr = entry->spev;
 925
 926        if (entry->pev.event) {
 927                snprintf(buf, 128, "%s:%s", entry->pev.group, entry->pev.event);
 928                ptr = buf;
 929        }
 930        return strfilter__compare(filter, ptr);
 931}
 932
 933int probe_cache__filter_purge(struct probe_cache *pcache,
 934                              struct strfilter *filter)
 935{
 936        struct probe_cache_entry *entry, *tmp;
 937
 938        list_for_each_entry_safe(entry, tmp, &pcache->entries, node) {
 939                if (probe_cache_entry__compare(entry, filter)) {
 940                        pr_info("Removed cached event: %s\n", entry->spev);
 941                        list_del_init(&entry->node);
 942                        probe_cache_entry__delete(entry);
 943                }
 944        }
 945        return 0;
 946}
 947
 948static int probe_cache__show_entries(struct probe_cache *pcache,
 949                                     struct strfilter *filter)
 950{
 951        struct probe_cache_entry *entry;
 952
 953        for_each_probe_cache_entry(entry, pcache) {
 954                if (probe_cache_entry__compare(entry, filter))
 955                        printf("%s\n", entry->spev);
 956        }
 957        return 0;
 958}
 959
 960/* Show all cached probes */
 961int probe_cache__show_all_caches(struct strfilter *filter)
 962{
 963        struct probe_cache *pcache;
 964        struct strlist *bidlist;
 965        struct str_node *nd;
 966        char *buf = strfilter__string(filter);
 967
 968        pr_debug("list cache with filter: %s\n", buf);
 969        free(buf);
 970
 971        bidlist = build_id_cache__list_all(true);
 972        if (!bidlist) {
 973                pr_debug("Failed to get buildids: %d\n", errno);
 974                return -EINVAL;
 975        }
 976        strlist__for_each_entry(nd, bidlist) {
 977                pcache = probe_cache__new(nd->s);
 978                if (!pcache)
 979                        continue;
 980                if (!list_empty(&pcache->entries)) {
 981                        buf = build_id_cache__origname(nd->s);
 982                        printf("%s (%s):\n", buf, nd->s);
 983                        free(buf);
 984                        probe_cache__show_entries(pcache, filter);
 985                }
 986                probe_cache__delete(pcache);
 987        }
 988        strlist__delete(bidlist);
 989
 990        return 0;
 991}
 992
 993enum ftrace_readme {
 994        FTRACE_README_PROBE_TYPE_X = 0,
 995        FTRACE_README_KRETPROBE_OFFSET,
 996        FTRACE_README_END,
 997};
 998
 999static struct {
1000        const char *pattern;
1001        bool avail;
1002} ftrace_readme_table[] = {
1003#define DEFINE_TYPE(idx, pat)                   \
1004        [idx] = {.pattern = pat, .avail = false}
1005        DEFINE_TYPE(FTRACE_README_PROBE_TYPE_X, "*type: * x8/16/32/64,*"),
1006        DEFINE_TYPE(FTRACE_README_KRETPROBE_OFFSET, "*place (kretprobe): *"),
1007};
1008
1009static bool scan_ftrace_readme(enum ftrace_readme type)
1010{
1011        int fd;
1012        FILE *fp;
1013        char *buf = NULL;
1014        size_t len = 0;
1015        bool ret = false;
1016        static bool scanned = false;
1017
1018        if (scanned)
1019                goto result;
1020
1021        fd = open_trace_file("README", false);
1022        if (fd < 0)
1023                return ret;
1024
1025        fp = fdopen(fd, "r");
1026        if (!fp) {
1027                close(fd);
1028                return ret;
1029        }
1030
1031        while (getline(&buf, &len, fp) > 0)
1032                for (enum ftrace_readme i = 0; i < FTRACE_README_END; i++)
1033                        if (!ftrace_readme_table[i].avail)
1034                                ftrace_readme_table[i].avail =
1035                                        strglobmatch(buf, ftrace_readme_table[i].pattern);
1036        scanned = true;
1037
1038        fclose(fp);
1039        free(buf);
1040
1041result:
1042        if (type >= FTRACE_README_END)
1043                return false;
1044
1045        return ftrace_readme_table[type].avail;
1046}
1047
1048bool probe_type_is_available(enum probe_type type)
1049{
1050        if (type >= PROBE_TYPE_END)
1051                return false;
1052        else if (type == PROBE_TYPE_X)
1053                return scan_ftrace_readme(FTRACE_README_PROBE_TYPE_X);
1054
1055        return true;
1056}
1057
1058bool kretprobe_offset_is_supported(void)
1059{
1060        return scan_ftrace_readme(FTRACE_README_KRETPROBE_OFFSET);
1061}
1062