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