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