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