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