xref: /openbsd-src/usr.sbin/btrace/btrace.c (revision f1dd7b858388b4a23f4f67a4957ec5ff656ebbe8)
1 /*	$OpenBSD: btrace.c,v 1.35 2021/04/22 09:36:39 mpi Exp $ */
2 
3 /*
4  * Copyright (c) 2019 - 2020 Martin Pieuchot <mpi@openbsd.org>
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #include <sys/ioctl.h>
20 #include <sys/exec_elf.h>
21 #include <sys/syscall.h>
22 #include <sys/queue.h>
23 
24 #include <assert.h>
25 #include <err.h>
26 #include <errno.h>
27 #include <fcntl.h>
28 #include <limits.h>
29 #include <locale.h>
30 #include <signal.h>
31 #include <stdarg.h>
32 #include <stdbool.h>
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include <time.h>
37 #include <unistd.h>
38 
39 #include <dev/dt/dtvar.h>
40 
41 #include "btrace.h"
42 #include "bt_parser.h"
43 
44 #define MINIMUM(a, b)	(((a) < (b)) ? (a) : (b))
45 #define MAXIMUM(a, b)	(((a) > (b)) ? (a) : (b))
46 
47 /*
48  * Maximum number of operands an arithmetic operation can have.  This
49  * is necessary to stop infinite recursion when evaluating expressions.
50  */
51 #define __MAXOPERANDS	5
52 
53 #define __PATH_DEVDT "/dev/dt"
54 
55 __dead void		 usage(void);
56 char			*read_btfile(const char *);
57 
58 /*
59  * Retrieve & parse probe information.
60  */
61 void			 dtpi_cache(int);
62 void			 dtpi_print_list(void);
63 char			*dtpi_func(struct dtioc_probe_info *);
64 int			 dtpi_is_unit(const char *);
65 struct dtioc_probe_info	*dtpi_get_by_value(const char *, const char *,
66 			     const char *);
67 
68 /*
69  * Main loop and rule evaluation.
70  */
71 void			 rules_do(int);
72 void			 rules_setup(int);
73 void			 rules_apply(struct dt_evt *);
74 void			 rules_teardown(int);
75 void			 rule_eval(struct bt_rule *, struct dt_evt *);
76 void			 rule_printmaps(struct bt_rule *);
77 
78 /*
79  * Language builtins & functions.
80  */
81 uint64_t		 builtin_nsecs(struct dt_evt *);
82 const char		*builtin_kstack(struct dt_evt *);
83 const char		*builtin_arg(struct dt_evt *, enum bt_argtype);
84 void			 stmt_bucketize(struct bt_stmt *, struct dt_evt *);
85 void			 stmt_clear(struct bt_stmt *);
86 void			 stmt_delete(struct bt_stmt *, struct dt_evt *);
87 void			 stmt_insert(struct bt_stmt *, struct dt_evt *);
88 void			 stmt_print(struct bt_stmt *, struct dt_evt *);
89 void			 stmt_store(struct bt_stmt *, struct dt_evt *);
90 bool			 stmt_test(struct bt_stmt *, struct dt_evt *);
91 void			 stmt_time(struct bt_stmt *, struct dt_evt *);
92 void			 stmt_zero(struct bt_stmt *);
93 struct bt_arg		*ba_read(struct bt_arg *);
94 const char		*ba2hash(struct bt_arg *, struct dt_evt *);
95 long			 baexpr2long(struct bt_arg *, struct dt_evt *);
96 const char		*ba2bucket(struct bt_arg *, struct bt_arg *,
97 			     struct dt_evt *, long *);
98 int			 ba2dtflags(struct bt_arg *);
99 
100 /*
101  * Debug routines.
102  */
103 __dead void		 xabort(const char *, ...);
104 void			 debug(const char *, ...);
105 void			 debugx(const char *, ...);
106 const char		*debug_rule_name(struct bt_rule *);
107 void			 debug_dump_filter(struct bt_rule *);
108 
109 struct dtioc_probe_info	*dt_dtpis;	/* array of available probes */
110 size_t			 dt_ndtpi;	/* # of elements in the array */
111 
112 struct dt_evt		 bt_devt;	/* fake event for BEGIN/END */
113 uint64_t		 bt_filtered;	/* # of events filtered out */
114 
115 int			 vargs[1];
116 int			 verbose = 0;
117 volatile sig_atomic_t	 quit_pending;
118 
119 static void
120 signal_handler(int sig)
121 {
122 	quit_pending = sig;
123 }
124 
125 
126 int
127 main(int argc, char *argv[])
128 {
129 	int fd = -1, ch, error = 0;
130 	const char *filename = NULL, *btscript = NULL;
131 	const char *errstr;
132 	int showprobes = 0, noaction = 0;
133 
134 	setlocale(LC_ALL, "");
135 
136 #if notyet
137 	if (pledge("stdio rpath", NULL) == -1)
138 		err(1, "pledge");
139 #endif
140 
141 	while ((ch = getopt(argc, argv, "e:lnp:v")) != -1) {
142 		switch (ch) {
143 		case 'e':
144 			btscript = optarg;
145 			break;
146 		case 'l':
147 			showprobes = 1;
148 			break;
149 		case 'n':
150 			noaction = 1;
151 			break;
152 		case 'v':
153 			verbose++;
154 			break;
155 		default:
156 			usage();
157 		}
158 	}
159 
160 	argc -= optind;
161 	argv += optind;
162 
163 	if (argc > 0) {
164 		if (btscript != NULL)
165 			usage();
166 
167 		filename = argv[0];
168 		btscript = read_btfile(filename);
169 		argc--;
170 		argv++;
171 	}
172 
173 	if (argc == 1) {
174 		vargs[0] = strtonum(*argv, 1, INT_MAX, &errstr);
175 		if (errstr != NULL)
176 			errx(1, "invalid argument %s: %s", *argv, errstr);
177 		argc--;
178 		argv++;
179 	}
180 
181 	if (argc != 0 || (btscript == NULL && !showprobes))
182 		usage();
183 
184 	if (btscript != NULL) {
185 		error = btparse(btscript, strlen(btscript), filename, 1);
186 		if (error)
187 			return error;
188 	}
189 
190 	if (noaction)
191 		return error;
192 
193 	if (showprobes || g_nprobes > 0) {
194 		fd = open(__PATH_DEVDT, O_RDONLY);
195 		if (fd == -1)
196 			err(1, "could not open %s", __PATH_DEVDT);
197 	}
198 
199 	if (showprobes) {
200 		dtpi_cache(fd);
201 		dtpi_print_list();
202 	}
203 
204 	if (!TAILQ_EMPTY(&g_rules))
205 		rules_do(fd);
206 
207 	if (fd != -1)
208 		close(fd);
209 
210 	return error;
211 }
212 
213 __dead void
214 usage(void)
215 {
216 	fprintf(stderr, "usage: %s [-lnv] [-e program | file]\n",
217 	    getprogname());
218 	exit(1);
219 }
220 
221 char *
222 read_btfile(const char *filename)
223 {
224 	static char fcontent[BUFSIZ];
225 	long offset;
226 	FILE *fp;
227 
228 	fp = fopen(filename, "r");
229 	if (fp == NULL)
230 		err(1, "can't open '%s'", filename);
231 
232 	if (fread(fcontent, sizeof(fcontent) - 1, 1, fp) == 0 && errno != 0)
233 		err(1, "can't read '%s'", filename);
234 
235 	fseek(fp, 0, SEEK_END);
236 	offset = ftell(fp);
237 	if ((size_t)offset >= sizeof(fcontent))
238 		errx(1, "couldn't read all of '%s'", filename);
239 
240 	fclose(fp);
241 	return fcontent;
242 }
243 
244 void
245 dtpi_cache(int fd)
246 {
247 	struct dtioc_probe dtpr;
248 
249 	if (dt_dtpis != NULL)
250 		return;
251 
252 	memset(&dtpr, 0, sizeof(dtpr));
253 	if (ioctl(fd, DTIOCGPLIST, &dtpr))
254 		err(1, "DTIOCGPLIST");
255 
256 	dt_ndtpi = (dtpr.dtpr_size / sizeof(*dt_dtpis));
257 	dt_dtpis = reallocarray(NULL, dt_ndtpi, sizeof(*dt_dtpis));
258 	if (dt_dtpis == NULL)
259 		err(1, "malloc");
260 
261 	dtpr.dtpr_probes = dt_dtpis;
262 	if (ioctl(fd, DTIOCGPLIST, &dtpr))
263 		err(1, "DTIOCGPLIST");
264 }
265 
266 void
267 dtpi_print_list(void)
268 {
269 	struct dtioc_probe_info *dtpi;
270 	size_t i;
271 
272 	dtpi = dt_dtpis;
273 	for (i = 0; i < dt_ndtpi; i++, dtpi++) {
274 		printf("%s:%s:%s\n", dtpi->dtpi_prov, dtpi_func(dtpi),
275 		    dtpi->dtpi_name);
276 	}
277 }
278 
279 char *
280 dtpi_func(struct dtioc_probe_info *dtpi)
281 {
282 	char *sysnb, func[DTNAMESIZE];
283 	const char *errstr;
284 	int idx;
285 
286 	if (strncmp(dtpi->dtpi_prov, "syscall", DTNAMESIZE))
287 		return dtpi->dtpi_func;
288 
289 	/* Translate syscall names */
290 	strlcpy(func, dtpi->dtpi_func, sizeof(func));
291 	sysnb = func;
292 	if (strsep(&sysnb, "%") == NULL)
293 		return dtpi->dtpi_func;
294 
295 	idx = strtonum(sysnb, 1, SYS_MAXSYSCALL, &errstr);
296 	if (errstr != NULL)
297 		return dtpi->dtpi_func;
298 
299 	return syscallnames[idx];
300 }
301 
302 int
303 dtpi_is_unit(const char *unit)
304 {
305 	return !strncmp("hz", unit, sizeof("hz"));
306 }
307 
308 struct dtioc_probe_info *
309 dtpi_get_by_value(const char *prov, const char *func, const char *name)
310 {
311 	struct dtioc_probe_info *dtpi;
312 	size_t i;
313 
314 	dtpi = dt_dtpis;
315 	for (i = 0; i < dt_ndtpi; i++, dtpi++) {
316 		if (prov != NULL &&
317 		    strncmp(prov, dtpi->dtpi_prov, DTNAMESIZE))
318 			continue;
319 
320 		if (func != NULL) {
321 			if (dtpi_is_unit(func))
322 				return dtpi;
323 
324 			if (strncmp(func, dtpi_func(dtpi), DTNAMESIZE))
325 				continue;
326 		}
327 
328 		if (strncmp(name, dtpi->dtpi_name, DTNAMESIZE))
329 			continue;
330 
331 		debug("matched probe %s:%s:%s\n", dtpi->dtpi_prov,
332 		    dtpi_func(dtpi), dtpi->dtpi_name);
333 		return dtpi;
334 	}
335 
336 	return NULL;
337 }
338 
339 void
340 rules_do(int fd)
341 {
342 	struct sigaction sa;
343 
344 	memset(&sa, 0, sizeof(sa));
345 	sigemptyset(&sa.sa_mask);
346 	sa.sa_flags = 0;
347 	sa.sa_handler = signal_handler;
348 	if (sigaction(SIGINT, &sa, NULL))
349 		err(1, "sigaction");
350 
351 	rules_setup(fd);
352 
353 	while (!quit_pending && g_nprobes > 0) {
354 		static struct dt_evt devtbuf[64];
355 		ssize_t rlen;
356 		size_t i;
357 
358 		rlen = read(fd, devtbuf, sizeof(devtbuf) - 1);
359 		if (rlen == -1) {
360 			if (errno == EINTR && quit_pending) {
361 				printf("\n");
362 				break;
363 			}
364 			err(1, "read");
365 		}
366 
367 		if ((rlen % sizeof(struct dt_evt)) != 0)
368 			err(1, "incorrect read");
369 
370 		for (i = 0; i < rlen / sizeof(struct dt_evt); i++)
371 			rules_apply(&devtbuf[i]);
372 	}
373 
374 	rules_teardown(fd);
375 
376 	if (verbose && fd != -1) {
377 		struct dtioc_stat dtst;
378 
379 		memset(&dtst, 0, sizeof(dtst));
380 		if (ioctl(fd, DTIOCGSTATS, &dtst))
381 			warn("DTIOCGSTATS");
382 
383 		printf("%llu events read\n", dtst.dtst_readevt);
384 		printf("%llu events dropped\n", dtst.dtst_dropevt);
385 		printf("%llu events filtered\n", bt_filtered);
386 	}
387 }
388 
389 void
390 rules_setup(int fd)
391 {
392 	struct dtioc_probe_info *dtpi;
393 	struct dtioc_req *dtrq;
394 	struct bt_rule *r, *rbegin = NULL;
395 	struct bt_probe *bp;
396 	struct bt_stmt *bs;
397 	int dokstack = 0, on = 1;
398 
399 	TAILQ_FOREACH(r, &g_rules, br_next) {
400 		debug("parsed probe '%s'", debug_rule_name(r));
401 		debug_dump_filter(r);
402 
403 		if (r->br_type != B_RT_PROBE) {
404 			if (r->br_type == B_RT_BEGIN)
405 				rbegin = r;
406 			continue;
407 		}
408 
409 		bp = r->br_probe;
410 		dtpi_cache(fd);
411 		dtpi = dtpi_get_by_value(bp->bp_prov, bp->bp_func, bp->bp_name);
412 		if (dtpi == NULL) {
413 			errx(1, "probe '%s:%s:%s' not found", bp->bp_prov,
414 			    bp->bp_func, bp->bp_name);
415 		}
416 
417 		dtrq = calloc(1, sizeof(*dtrq));
418 		if (dtrq == NULL)
419 			err(1, "dtrq: 1alloc");
420 
421 		r->br_pbn = dtpi->dtpi_pbn;
422 		dtrq->dtrq_pbn = dtpi->dtpi_pbn;
423 		dtrq->dtrq_rate = r->br_probe->bp_rate;
424 
425 		SLIST_FOREACH(bs, &r->br_action, bs_next) {
426 			struct bt_arg *ba;
427 
428 			SLIST_FOREACH(ba, &bs->bs_args, ba_next)
429 				dtrq->dtrq_evtflags |= ba2dtflags(ba);
430 		}
431 
432 		if (dtrq->dtrq_evtflags & DTEVT_KSTACK)
433 			dokstack = 1;
434 		r->br_cookie = dtrq;
435 	}
436 
437 	if (dokstack)
438 		kelf_open();
439 
440 	/* Initialize "fake" event for BEGIN/END */
441 	bt_devt.dtev_pbn = -1;
442 	memcpy(&bt_devt.dtev_comm, getprogname(), sizeof(bt_devt.dtev_comm));
443 	bt_devt.dtev_pid = getpid();
444 	bt_devt.dtev_tid = getthrid();
445 
446 	if (rbegin)
447 		rule_eval(rbegin, &bt_devt);
448 
449 	/* Enable all probes */
450 	TAILQ_FOREACH(r, &g_rules, br_next) {
451 		if (r->br_type != B_RT_PROBE)
452 			continue;
453 
454 		dtrq = r->br_cookie;
455 		if (ioctl(fd, DTIOCPRBENABLE, dtrq))
456 			err(1, "DTIOCPRBENABLE");
457 	}
458 
459 	if (g_nprobes > 0) {
460 		if (ioctl(fd, DTIOCRECORD, &on))
461 			err(1, "DTIOCRECORD");
462 	}
463 }
464 
465 void
466 rules_apply(struct dt_evt *dtev)
467 {
468 	struct bt_rule *r;
469 
470 	TAILQ_FOREACH(r, &g_rules, br_next) {
471 		if (r->br_type != B_RT_PROBE || r->br_pbn != dtev->dtev_pbn)
472 			continue;
473 
474 		rule_eval(r, dtev);
475 	}
476 }
477 
478 void
479 rules_teardown(int fd)
480 {
481 	struct dtioc_req *dtrq;
482 	struct bt_rule *r, *rend = NULL;
483 	int dokstack = 0, off = 0;
484 
485 	if (g_nprobes > 0) {
486 		if (ioctl(fd, DTIOCRECORD, &off))
487 			err(1, "DTIOCRECORD");
488 	}
489 
490 	TAILQ_FOREACH(r, &g_rules, br_next) {
491 		if (r->br_type != B_RT_PROBE) {
492 			if (r->br_type == B_RT_END)
493 				rend = r;
494 			continue;
495 		}
496 
497 		dtrq = r->br_cookie;
498 		if (dtrq->dtrq_evtflags & DTEVT_KSTACK)
499 			dokstack = 1;
500 	}
501 
502 	if (dokstack)
503 		kelf_close();
504 
505 	if (rend)
506 		rule_eval(rend, &bt_devt);
507 	else {
508 		debug("eval default 'end' rule\n");
509 
510 		TAILQ_FOREACH(r, &g_rules, br_next)
511 			rule_printmaps(r);
512 	}
513 }
514 
515 void
516 rule_eval(struct bt_rule *r, struct dt_evt *dtev)
517 {
518 	struct bt_stmt *bs;
519 
520 	debug("eval rule '%s'", debug_rule_name(r));
521 	debug_dump_filter(r);
522 
523 	if (r->br_filter != NULL && r->br_filter->bf_condition != NULL) {
524 		if (stmt_test(r->br_filter->bf_condition, dtev) == false) {
525 			bt_filtered++;
526 			return;
527 		}
528 	}
529 
530 	SLIST_FOREACH(bs, &r->br_action, bs_next) {
531 		switch (bs->bs_act) {
532 		case B_AC_BUCKETIZE:
533 			stmt_bucketize(bs, dtev);
534 			break;
535 		case B_AC_CLEAR:
536 			stmt_clear(bs);
537 			break;
538 		case B_AC_DELETE:
539 			stmt_delete(bs, dtev);
540 			break;
541 		case B_AC_EXIT:
542 			exit(0);
543 			break;
544 		case B_AC_INSERT:
545 			stmt_insert(bs, dtev);
546 			break;
547 		case B_AC_PRINT:
548 			stmt_print(bs, dtev);
549 			break;
550 		case B_AC_PRINTF:
551 			stmt_printf(bs, dtev);
552 			break;
553 		case B_AC_STORE:
554 			stmt_store(bs, dtev);
555 			break;
556 		case B_AC_TIME:
557 			stmt_time(bs, dtev);
558 			break;
559 		case B_AC_ZERO:
560 			stmt_zero(bs);
561 			break;
562 		default:
563 			xabort("no handler for action type %d", bs->bs_act);
564 		}
565 	}
566 }
567 
568 void
569 rule_printmaps(struct bt_rule *r)
570 {
571 	struct bt_stmt *bs;
572 
573 	SLIST_FOREACH(bs, &r->br_action, bs_next) {
574 		struct bt_arg *ba;
575 
576 		SLIST_FOREACH(ba, &bs->bs_args, ba_next) {
577 			struct bt_var *bv = ba->ba_value;
578 			struct map *map;
579 
580 			if (ba->ba_type != B_AT_MAP && ba->ba_type != B_AT_HIST)
581 				continue;
582 
583 			map = (struct map *)bv->bv_value;
584 			if (map == NULL)
585 				continue;
586 
587 			if (ba->ba_type == B_AT_MAP)
588 				map_print(map, SIZE_T_MAX, bv_name(bv));
589 			else
590 				hist_print((struct hist *)map, bv_name(bv));
591 			map_clear(map);
592 			bv->bv_value = NULL;
593 		}
594 	}
595 }
596 
597 time_t
598 builtin_gettime(struct dt_evt *dtev)
599 {
600 	struct timespec ts;
601 
602 	if (dtev == NULL) {
603 		clock_gettime(CLOCK_REALTIME, &ts);
604 		return ts.tv_sec;
605 	}
606 
607 	return dtev->dtev_tsp.tv_sec;
608 }
609 
610 static inline uint64_t
611 TIMESPEC_TO_NSEC(struct timespec *ts)
612 {
613 	return (ts->tv_sec * 1000000000L + ts->tv_nsec);
614 }
615 
616 uint64_t
617 builtin_nsecs(struct dt_evt *dtev)
618 {
619 	struct timespec ts;
620 
621 	if (dtev == NULL) {
622 		clock_gettime(CLOCK_REALTIME, &ts);
623 		return TIMESPEC_TO_NSEC(&ts);
624 	}
625 
626 	return TIMESPEC_TO_NSEC(&dtev->dtev_tsp);
627 }
628 
629 const char *
630 builtin_stack(struct dt_evt *dtev, int kernel)
631 {
632 	struct stacktrace *st = &dtev->dtev_kstack;
633 	static char buf[4096], *bp;
634 	size_t i;
635 	int sz;
636 
637 	if (!kernel || st->st_count == 0)
638 		return "";
639 
640 	buf[0] = '\0';
641 	bp = buf;
642 	sz = sizeof(buf);
643 	for (i = 0; i < st->st_count; i++) {
644 		int l;
645 
646 		l = kelf_snprintsym(bp, sz - 1, st->st_pc[i]);
647 		if (l < 0)
648 			break;
649 		if (l >= sz - 1) {
650 			bp += sz - 1;
651 			sz = 1;
652 			break;
653 		}
654 		bp += l;
655 		sz -= l;
656 	}
657 	snprintf(bp, sz, "\n");
658 
659 	return buf;
660 }
661 
662 const char *
663 builtin_arg(struct dt_evt *dtev, enum bt_argtype dat)
664 {
665 	static char buf[sizeof("18446744073709551615")]; /* UINT64_MAX */
666 
667 	snprintf(buf, sizeof(buf), "%lu",
668 	    dtev->dtev_sysargs[dat - B_AT_BI_ARG0]);
669 
670 	return buf;
671 }
672 
673 /*
674  * Increment a bucket:	{ @h = hist(v); } or { @h = lhist(v, min, max, step); }
675  *
676  * In this case 'h' is represented by `bv' and '(min, max, step)' by `brange'.
677  */
678 void
679 stmt_bucketize(struct bt_stmt *bs, struct dt_evt *dtev)
680 {
681 	struct bt_arg *brange, *bhist = SLIST_FIRST(&bs->bs_args);
682 	struct bt_arg *bval = (struct bt_arg *)bs->bs_var;
683 	struct bt_var *bv = bhist->ba_value;
684 	const char *bucket;
685 	long step = 0;
686 
687 	assert(bhist->ba_type == B_AT_HIST);
688 	assert(SLIST_NEXT(bval, ba_next) == NULL);
689 
690 	brange = bhist->ba_key;
691 	bucket = ba2bucket(bval, brange, dtev, &step);
692 	if (bucket == NULL) {
693 		debug("hist=%p '%s' value=%lu out of range\n", bv->bv_value,
694 		    bv_name(bv), ba2long(bval, dtev));
695 		return;
696 	}
697 	debug("hist=%p '%s' increment bucket '%s'\n", bv->bv_value,
698 	    bv_name(bv), bucket);
699 
700 	bv->bv_value = (struct bt_arg *)
701 	    hist_increment((struct hist *)bv->bv_value, bucket, step);
702 	bv->bv_type = B_VT_HIST;
703 }
704 
705 
706 /*
707  * Empty a map:		{ clear(@map); }
708  */
709 void
710 stmt_clear(struct bt_stmt *bs)
711 {
712 	struct bt_arg *ba = SLIST_FIRST(&bs->bs_args);
713 	struct bt_var *bv = ba->ba_value;
714 
715 	assert(bs->bs_var == NULL);
716 	assert(ba->ba_type == B_AT_VAR);
717 
718 	map_clear((struct map *)bv->bv_value);
719 	bv->bv_value = NULL;
720 
721 	debug("map=%p '%s' clear\n", bv->bv_value, bv_name(bv));
722 }
723 
724 /*
725  * Map delete:	 	{ delete(@map[key]); }
726  *
727  * In this case 'map' is represented by `bv' and 'key' by `bkey'.
728  */
729 void
730 stmt_delete(struct bt_stmt *bs, struct dt_evt *dtev)
731 {
732 	struct bt_arg *bkey, *bmap = SLIST_FIRST(&bs->bs_args);
733 	struct bt_var *bv = bmap->ba_value;
734 	const char *hash;
735 
736 	assert(bmap->ba_type == B_AT_MAP);
737 	assert(bs->bs_var == NULL);
738 
739 	bkey = bmap->ba_key;
740 	hash = ba2hash(bkey, dtev);
741 	debug("map=%p '%s' delete key=%p '%s'\n", bv->bv_value, bv_name(bv),
742 	    bkey, hash);
743 
744 	map_delete((struct map *)bv->bv_value, hash);
745 }
746 
747 /*
748  * Map insert:	 	{ @map[key] = 42; }
749  *
750  * In this case 'map' is represented by `bv', 'key' by `bkey' and
751  * '42' by `bval'.
752  */
753 void
754 stmt_insert(struct bt_stmt *bs, struct dt_evt *dtev)
755 {
756 	struct bt_arg *bkey, *bmap = SLIST_FIRST(&bs->bs_args);
757 	struct bt_arg *bval = (struct bt_arg *)bs->bs_var;
758 	struct bt_var *bv = bmap->ba_value;
759 	const char *hash;
760 
761 	assert(bmap->ba_type == B_AT_MAP);
762 	assert(SLIST_NEXT(bval, ba_next) == NULL);
763 
764 	bkey = bmap->ba_key;
765 	hash = ba2hash(bkey, dtev);
766 	debug("map=%p '%s' insert key=%p '%s' bval=%p\n", bv->bv_value,
767 	    bv_name(bv), bkey, hash, bval);
768 
769 	bv->bv_value = (struct bt_arg *)map_insert((struct map *)bv->bv_value,
770 	    hash, bval, dtev);
771 	bv->bv_type = B_VT_MAP;
772 }
773 
774 /*
775  * Print variables:	{ print(890); print(@map[, 8]); print(comm); }
776  *
777  * In this case the global variable 'map' is pointed at by `ba'
778  * and '8' is represented by `btop'.
779  */
780 void
781 stmt_print(struct bt_stmt *bs, struct dt_evt *dtev)
782 {
783 	struct bt_arg *btop, *ba = SLIST_FIRST(&bs->bs_args);
784 	struct bt_var *bv = ba->ba_value;
785 	size_t top = SIZE_T_MAX;
786 
787 	assert(bs->bs_var == NULL);
788 
789 	/* Parse optional `top' argument. */
790 	btop = SLIST_NEXT(ba, ba_next);
791 	if (btop != NULL) {
792 		assert(SLIST_NEXT(btop, ba_next) == NULL);
793 		top = ba2long(btop, dtev);
794 	}
795 
796 	/* Static argument. */
797 	if (ba->ba_type != B_AT_VAR) {
798 		assert(btop == NULL);
799 		printf("%s\n", ba2str(ba, dtev));
800 		return;
801 	}
802 
803 	debug("map=%p '%s' print (top=%d)\n", bv->bv_value, bv_name(bv), top);
804 
805 	/* Empty? */
806 	if (bv->bv_value == NULL)
807 		return;
808 
809 	if (bv->bv_type == B_VT_MAP)
810 		map_print((struct map *)bv->bv_value, top, bv_name(bv));
811 	else if (bv->bv_type == B_VT_HIST)
812 		hist_print((struct hist *)bv->bv_value, bv_name(bv));
813 	else
814 		printf("%s\n", ba2str(ba, dtev));
815 }
816 
817 /*
818  * Variable store: 	{ @var = 3; }
819  *
820  * In this case '3' is represented by `ba', the argument of a STORE
821  * action.
822  *
823  * If the argument depends of the value of an event (builtin) or is
824  * the result of an operation, its evaluation is stored in a new `ba'.
825  */
826 void
827 stmt_store(struct bt_stmt *bs, struct dt_evt *dtev)
828 {
829 	struct bt_arg *ba = SLIST_FIRST(&bs->bs_args);
830 	struct bt_var *bv = bs->bs_var;
831 
832 	assert(SLIST_NEXT(ba, ba_next) == NULL);
833 
834 	switch (ba->ba_type) {
835 	case B_AT_STR:
836 		bv->bv_value = ba;
837 		bv->bv_type = B_VT_STR;
838 		break;
839 	case B_AT_LONG:
840 		bv->bv_value = ba;
841 		bv->bv_type = B_VT_LONG;
842 		break;
843 	case B_AT_BI_NSECS:
844 		bv->bv_value = ba_new(builtin_nsecs(dtev), B_AT_LONG);
845 		bv->bv_type = B_VT_LONG;
846 		break;
847 	case B_AT_OP_PLUS ... B_AT_OP_LOR:
848 		bv->bv_value = ba_new(ba2long(ba, dtev), B_AT_LONG);
849 		bv->bv_type = B_VT_LONG;
850 		break;
851 	default:
852 		xabort("store not implemented for type %d", ba->ba_type);
853 	}
854 
855 	debug("bv=%p var '%s' store (%p) \n", bv, bv_name(bv), bv->bv_value);
856 }
857 
858 /*
859  * Expression test:	{ if (expr) stmt; }
860  */
861 bool
862 stmt_test(struct bt_stmt *bs, struct dt_evt *dtev)
863 {
864 	struct bt_arg *bop;
865 
866 	if (bs == NULL)
867 		return true;
868 
869 	assert(bs->bs_var == NULL);
870 	bop = SLIST_FIRST(&bs->bs_args);
871 
872 	return baexpr2long(bop, dtev) != 0;
873 }
874 
875 /*
876  * Print time: 		{ time("%H:%M:%S"); }
877  */
878 void
879 stmt_time(struct bt_stmt *bs, struct dt_evt *dtev)
880 {
881 	struct bt_arg *ba = SLIST_FIRST(&bs->bs_args);
882 	time_t time;
883 	struct tm *tm;
884 	char buf[64];
885 
886 	assert(bs->bs_var == NULL);
887 	assert(ba->ba_type == B_AT_STR);
888 	assert(strlen(ba2str(ba, dtev)) < (sizeof(buf) - 1));
889 
890 	time = builtin_gettime(dtev);
891 	tm = localtime(&time);
892 	strftime(buf, sizeof(buf), ba2str(ba, dtev), tm);
893 	printf("%s", buf);
894 }
895 
896 /*
897  * Set entries to 0:	{ zero(@map); }
898  */
899 void
900 stmt_zero(struct bt_stmt *bs)
901 {
902 	struct bt_arg *ba = SLIST_FIRST(&bs->bs_args);
903 	struct bt_var *bv = ba->ba_value;
904 
905 	assert(bs->bs_var == NULL);
906 	assert(ba->ba_type == B_AT_VAR);
907 
908 	map_zero((struct map *)bv->bv_value);
909 
910 	debug("map=%p '%s' zero\n", bv->bv_value, bv_name(bv));
911 }
912 
913 struct bt_arg *
914 ba_read(struct bt_arg *ba)
915 {
916 	struct bt_var *bv = ba->ba_value;
917 
918 	assert(ba->ba_type == B_AT_VAR);
919 
920 	debug("bv=%p read '%s' (%p)\n", bv, bv_name(bv), bv->bv_value);
921 
922 	return bv->bv_value;
923 }
924 
925 const char *
926 ba2hash(struct bt_arg *ba, struct dt_evt *dtev)
927 {
928 	static char buf[KLEN];
929 	char *hash;
930 	int l, len;
931 
932 	buf[0] = '\0';
933 	l = snprintf(buf, sizeof(buf), "%s", ba2str(ba, dtev));
934 	if (l < 0 || (size_t)l > sizeof(buf)) {
935 		warn("string too long %d > %lu", l, sizeof(buf));
936 		return buf;
937 	}
938 
939 	len = 0;
940 	while ((ba = SLIST_NEXT(ba, ba_next)) != NULL) {
941 		len += l;
942 		hash = buf + len;
943 
944 		l = snprintf(hash, sizeof(buf) - len, ", %s", ba2str(ba, dtev));
945 		if (l < 0 || (size_t)l > (sizeof(buf) - len)) {
946 			warn("hash too long %d > %lu", l + len, sizeof(buf));
947 			break;
948 		}
949 	}
950 
951 	return buf;
952 }
953 
954 static unsigned long
955 next_pow2(unsigned long x)
956 {
957 	size_t i;
958 
959 	x--;
960 	for (i = 0; i < (sizeof(x)  * 8) - 1; i++)
961 		x |= (x >> 1);
962 
963 	return x + 1;
964 }
965 
966 /*
967  * Return the ceiling value the interval holding `ba' or NULL if it is
968  * out of the (min, max) values.
969  */
970 const char *
971 ba2bucket(struct bt_arg *ba, struct bt_arg *brange, struct dt_evt *dtev,
972     long *pstep)
973 {
974 	static char buf[KLEN];
975 	long val, bucket;
976 	int l;
977 
978 	val = ba2long(ba, dtev);
979 	if (brange == NULL)
980 		bucket = next_pow2(val);
981 	else {
982 		long min, max, step;
983 
984 		assert(brange->ba_type == B_AT_LONG);
985 		min = ba2long(brange, NULL);
986 
987 		brange = SLIST_NEXT(brange, ba_next);
988 		assert(brange->ba_type == B_AT_LONG);
989 		max = ba2long(brange, NULL);
990 
991 		if ((val < min) || (val > max))
992 			return NULL;
993 
994 		brange = SLIST_NEXT(brange, ba_next);
995 		assert(brange->ba_type == B_AT_LONG);
996 		step = ba2long(brange, NULL);
997 
998 		bucket = ((val / step) + 1) * step;
999 		*pstep = step;
1000 	}
1001 
1002 	buf[0] = '\0';
1003 	l = snprintf(buf, sizeof(buf), "%lu", bucket);
1004 	if (l < 0 || (size_t)l > sizeof(buf)) {
1005 		warn("string too long %d > %lu", l, sizeof(buf));
1006 		return buf;
1007 	}
1008 
1009 	return buf;
1010 }
1011 
1012 /*
1013  * Evaluate the operation encoded in `ba' and return its result.
1014  */
1015 long
1016 baexpr2long(struct bt_arg *ba, struct dt_evt *dtev)
1017 {
1018 	static long recursions;
1019 	struct bt_arg *a, *b;
1020 	long first, second, result;
1021 
1022 	if (++recursions >= __MAXOPERANDS)
1023 		errx(1, "too many operands (>%d) in expression", __MAXOPERANDS);
1024 
1025 	a = ba->ba_value;
1026 	first = ba2long(a, dtev);
1027 
1028 	b = SLIST_NEXT(a, ba_next);
1029 
1030 	if (b == NULL) {
1031 		second = 0;
1032 	} else {
1033 		assert(SLIST_NEXT(b, ba_next) == NULL);
1034 		second = ba2long(b, dtev);
1035 	}
1036 
1037 	switch (ba->ba_type) {
1038 	case B_AT_OP_PLUS:
1039 		result = first + second;
1040 		break;
1041 	case B_AT_OP_MINUS:
1042 		result = first - second;
1043 		break;
1044 	case B_AT_OP_MULT:
1045 		result = first * second;
1046 		break;
1047 	case B_AT_OP_DIVIDE:
1048 		result = first / second;
1049 		break;
1050 	case B_AT_OP_BAND:
1051 		result = first & second;
1052 		break;
1053 	case B_AT_OP_BOR:
1054 		result = first | second;
1055 		break;
1056 	case B_AT_OP_EQ:
1057 		result = (first == second);
1058 		break;
1059 	case B_AT_OP_NE:
1060 		result = (first != second);
1061 		break;
1062 	case B_AT_OP_LE:
1063 		result = (first <= second);
1064 		break;
1065 	case B_AT_OP_GE:
1066 		result = (first >= second);
1067 		break;
1068 	case B_AT_OP_LAND:
1069 		result = (first && second);
1070 		break;
1071 	case B_AT_OP_LOR:
1072 		result = (first || second);
1073 		break;
1074 	default:
1075 		xabort("unsuported operation %d", ba->ba_type);
1076 	}
1077 
1078 	debug("ba=%p '%ld %s %ld = %ld'\n", ba, first, ba_name(ba), second,
1079 	   result);
1080 
1081 	--recursions;
1082 
1083 	return result;
1084 }
1085 
1086 const char *
1087 ba_name(struct bt_arg *ba)
1088 {
1089 	switch (ba->ba_type) {
1090 	case B_AT_VAR:
1091 	case B_AT_MAP:
1092 		break;
1093 	case B_AT_BI_PID:
1094 		return "pid";
1095 	case B_AT_BI_TID:
1096 		return "tid";
1097 	case B_AT_OP_PLUS:
1098 		return "+";
1099 	case B_AT_OP_MINUS:
1100 		return "-";
1101 	case B_AT_OP_MULT:
1102 		return "*";
1103 	case B_AT_OP_DIVIDE:
1104 		return "/";
1105 	case B_AT_OP_BAND:
1106 		return "&";
1107 	case B_AT_OP_BOR:
1108 		return "|";
1109 	case B_AT_OP_EQ:
1110 		return "==";
1111 	case B_AT_OP_NE:
1112 		return "!=";
1113 	case B_AT_OP_LE:
1114 		return "<=";
1115 	case B_AT_OP_GE:
1116 		return ">=";
1117 	case B_AT_OP_LAND:
1118 		return "&&";
1119 	case B_AT_OP_LOR:
1120 		return "||";
1121 	default:
1122 		xabort("unsuported type %d", ba->ba_type);
1123 	}
1124 
1125 	assert(ba->ba_type == B_AT_VAR || ba->ba_type == B_AT_MAP);
1126 
1127 	static char buf[64];
1128 	size_t sz;
1129 	int l;
1130 
1131 	buf[0] = '@';
1132 	buf[1] = '\0';
1133 	sz = sizeof(buf) - 1;
1134 	l = snprintf(buf+1, sz, "%s", bv_name(ba->ba_value));
1135 	if (l < 0 || (size_t)l > sz) {
1136 		warn("string too long %d > %zu", l, sz);
1137 		return buf;
1138 	}
1139 
1140 	if (ba->ba_type == B_AT_MAP) {
1141 		sz -= l;
1142 		l = snprintf(buf+1+l, sz, "[%s]", ba_name(ba->ba_key));
1143 		if (l < 0 || (size_t)l > sz) {
1144 			warn("string too long %d > %zu", l, sz);
1145 			return buf;
1146 		}
1147 	}
1148 
1149 	return buf;
1150 }
1151 
1152 /*
1153  * Return the representation of `ba' as long.
1154  */
1155 long
1156 ba2long(struct bt_arg *ba, struct dt_evt *dtev)
1157 {
1158 	struct bt_var *bv;
1159 	long val;
1160 
1161 	switch (ba->ba_type) {
1162 	case B_AT_LONG:
1163 		val = (long)ba->ba_value;
1164 		break;
1165 	case B_AT_VAR:
1166 		ba = ba_read(ba);
1167 		val = (long)ba->ba_value;
1168 		break;
1169 	case B_AT_MAP:
1170 		bv = ba->ba_value;
1171 		/* Unitialized map */
1172 		if (bv->bv_value == NULL)
1173 			return 0;
1174 		val = ba2long(map_get((struct map *)bv->bv_value,
1175 		    ba2str(ba->ba_key, dtev)), dtev);
1176 		break;
1177 	case B_AT_BI_PID:
1178 		val = dtev->dtev_pid;
1179 		break;
1180 	case B_AT_BI_TID:
1181 		val = dtev->dtev_tid;
1182 		break;
1183 	case B_AT_BI_NSECS:
1184 		val = builtin_nsecs(dtev);
1185 		break;
1186 	case B_AT_BI_RETVAL:
1187 		val = dtev->dtev_sysretval[0];
1188 		break;
1189 	case B_AT_OP_PLUS ... B_AT_OP_LOR:
1190 		val = baexpr2long(ba, dtev);
1191 		break;
1192 	default:
1193 		xabort("no long conversion for type %d", ba->ba_type);
1194 	}
1195 
1196 	return  val;
1197 }
1198 
1199 /*
1200  * Return the representation of `ba' as string.
1201  */
1202 const char *
1203 ba2str(struct bt_arg *ba, struct dt_evt *dtev)
1204 {
1205 	static char buf[sizeof("18446744073709551615")]; /* UINT64_MAX */
1206 	struct bt_var *bv;
1207 	const char *str;
1208 
1209 	buf[0] = '\0';
1210 	switch (ba->ba_type) {
1211 	case B_AT_STR:
1212 		str = (const char *)ba->ba_value;
1213 		break;
1214 	case B_AT_LONG:
1215 		snprintf(buf, sizeof(buf), "%ld",(long)ba->ba_value);
1216 		str = buf;
1217 		break;
1218 	case B_AT_BI_KSTACK:
1219 		str = builtin_stack(dtev, 1);
1220 		break;
1221 	case B_AT_BI_USTACK:
1222 		str = builtin_stack(dtev, 0);
1223 		break;
1224 	case B_AT_BI_COMM:
1225 		str = dtev->dtev_comm;
1226 		break;
1227 	case B_AT_BI_CPU:
1228 		snprintf(buf, sizeof(buf), "%u", dtev->dtev_cpu);
1229 		str = buf;
1230 		break;
1231 	case B_AT_BI_PID:
1232 		snprintf(buf, sizeof(buf), "%d", dtev->dtev_pid);
1233 		str = buf;
1234 		break;
1235 	case B_AT_BI_TID:
1236 		snprintf(buf, sizeof(buf), "%d", dtev->dtev_tid);
1237 		str = buf;
1238 		break;
1239 	case B_AT_BI_NSECS:
1240 		snprintf(buf, sizeof(buf), "%llu", builtin_nsecs(dtev));
1241 		str = buf;
1242 		break;
1243 	case B_AT_BI_ARG0 ... B_AT_BI_ARG9:
1244 		str = builtin_arg(dtev, ba->ba_type);
1245 		break;
1246 	case B_AT_BI_RETVAL:
1247 		snprintf(buf, sizeof(buf), "%ld", (long)dtev->dtev_sysretval[0]);
1248 		str = buf;
1249 		break;
1250 	case B_AT_MAP:
1251 		bv = ba->ba_value;
1252 		str = ba2str(map_get((struct map *)bv->bv_value,
1253 		    ba2str(ba->ba_key, dtev)), dtev);
1254 		break;
1255 	case B_AT_VAR:
1256 		str = ba2str(ba_read(ba), dtev);
1257 		break;
1258 	case B_AT_OP_PLUS ... B_AT_OP_LOR:
1259 		snprintf(buf, sizeof(buf), "%ld", ba2long(ba, dtev));
1260 		str = buf;
1261 		break;
1262 	case B_AT_MF_COUNT:
1263 	case B_AT_MF_MAX:
1264 	case B_AT_MF_MIN:
1265 	case B_AT_MF_SUM:
1266 		assert(0);
1267 		break;
1268 	default:
1269 		xabort("no string conversion for type %d", ba->ba_type);
1270 	}
1271 
1272 	return str;
1273 }
1274 
1275 /*
1276  * Return dt(4) flags indicating which data should be recorded by the
1277  * kernel, if any, for a given `ba'.
1278  */
1279 int
1280 ba2dtflags(struct bt_arg *ba)
1281 {
1282 	int flags = 0;
1283 
1284 	if (ba->ba_type == B_AT_MAP)
1285 		ba = ba->ba_key;
1286 
1287 	do {
1288 		switch (ba->ba_type) {
1289 		case B_AT_STR:
1290 		case B_AT_LONG:
1291 		case B_AT_VAR:
1292 	    	case B_AT_HIST:
1293 			break;
1294 		case B_AT_BI_KSTACK:
1295 			flags |= DTEVT_KSTACK;
1296 			break;
1297 		case B_AT_BI_USTACK:
1298 			flags |= DTEVT_USTACK;
1299 			break;
1300 		case B_AT_BI_COMM:
1301 			flags |= DTEVT_EXECNAME;
1302 			break;
1303 		case B_AT_BI_CPU:
1304 		case B_AT_BI_PID:
1305 		case B_AT_BI_TID:
1306 		case B_AT_BI_NSECS:
1307 			break;
1308 		case B_AT_BI_ARG0 ... B_AT_BI_ARG9:
1309 			flags |= DTEVT_FUNCARGS;
1310 			break;
1311 		case B_AT_BI_RETVAL:
1312 			break;
1313 		case B_AT_MF_COUNT:
1314 		case B_AT_MF_MAX:
1315 		case B_AT_MF_MIN:
1316 		case B_AT_MF_SUM:
1317 		case B_AT_OP_PLUS ... B_AT_OP_LOR:
1318 			break;
1319 		default:
1320 			xabort("invalid argument type %d", ba->ba_type);
1321 		}
1322 	} while ((ba = SLIST_NEXT(ba, ba_next)) != NULL);
1323 
1324 	return flags;
1325 }
1326 
1327 long
1328 bacmp(struct bt_arg *a, struct bt_arg *b)
1329 {
1330 	assert(a->ba_type == b->ba_type);
1331 	assert(a->ba_type == B_AT_LONG);
1332 
1333 	return ba2long(a, NULL) - ba2long(b, NULL);
1334 }
1335 
1336 __dead void
1337 xabort(const char *fmt, ...)
1338 {
1339 	va_list ap;
1340 
1341 	va_start(ap, fmt);
1342 	vfprintf(stderr, fmt, ap);
1343 	va_end(ap);
1344 
1345 	fprintf(stderr, "\n");
1346 	abort();
1347 }
1348 
1349 void
1350 debug(const char *fmt, ...)
1351 {
1352 	va_list ap;
1353 
1354 	if (verbose < 2)
1355 		return;
1356 
1357 	fprintf(stderr, "debug: ");
1358 
1359 	va_start(ap, fmt);
1360 	vfprintf(stderr, fmt, ap);
1361 	va_end(ap);
1362 }
1363 
1364 void
1365 debugx(const char *fmt, ...)
1366 {
1367 	va_list ap;
1368 
1369 	if (verbose < 2)
1370 		return;
1371 
1372 	va_start(ap, fmt);
1373 	vfprintf(stderr, fmt, ap);
1374 	va_end(ap);
1375 }
1376 
1377 void
1378 debug_dump_filter(struct bt_rule *r)
1379 {
1380 	if (r->br_filter != NULL) {
1381 		struct bt_stmt *bs = r->br_filter->bf_condition;
1382 		struct bt_arg *bop = SLIST_FIRST(&bs->bs_args);
1383 		struct bt_arg *a, *b;
1384 
1385 		a = bop->ba_value;
1386 		b = SLIST_NEXT(a, ba_next);
1387 
1388 		debugx(" / %s %s %s /", ba_name(a), ba_name(bop),
1389 		    (b != NULL) ? ba_name(b) : "NULL");
1390 	}
1391 	debugx("\n");
1392 }
1393 
1394 const char *
1395 debug_rule_name(struct bt_rule *r)
1396 {
1397 	struct bt_probe *bp = r->br_probe;
1398 	static char buf[64];
1399 
1400 	if (r->br_type == B_RT_BEGIN)
1401 		return "BEGIN";
1402 
1403 	if (r->br_type == B_RT_END)
1404 		return "END";
1405 
1406 	assert(r->br_type == B_RT_PROBE);
1407 
1408 	if (r->br_probe->bp_rate) {
1409 		snprintf(buf, sizeof(buf), "%s:%s:%u", bp->bp_prov,
1410 		    bp->bp_unit, bp->bp_rate);
1411 	} else {
1412 		snprintf(buf, sizeof(buf), "%s:%s:%s", bp->bp_prov,
1413 		    bp->bp_unit, bp->bp_name);
1414 	}
1415 
1416 	return buf;
1417 }
1418