xref: /openbsd-src/usr.sbin/btrace/btrace.c (revision fc405d53b73a2d73393cb97f684863d17b583e38)
1 /*	$OpenBSD: btrace.c,v 1.70 2023/05/12 14:14:16 claudio 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/stat.h>
22 #include <sys/syscall.h>
23 #include <sys/queue.h>
24 
25 #include <assert.h>
26 #include <err.h>
27 #include <errno.h>
28 #include <fcntl.h>
29 #include <limits.h>
30 #include <locale.h>
31 #include <paths.h>
32 #include <signal.h>
33 #include <stdarg.h>
34 #include <stdbool.h>
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <string.h>
38 #include <time.h>
39 #include <unistd.h>
40 
41 #include <dev/dt/dtvar.h>
42 
43 #include "btrace.h"
44 #include "bt_parser.h"
45 
46 #define MINIMUM(a, b)	(((a) < (b)) ? (a) : (b))
47 #define MAXIMUM(a, b)	(((a) > (b)) ? (a) : (b))
48 
49 /*
50  * Maximum number of operands an arithmetic operation can have.  This
51  * is necessary to stop infinite recursion when evaluating expressions.
52  */
53 #define __MAXOPERANDS	5
54 
55 #define __PATH_DEVDT "/dev/dt"
56 
57 __dead void		 usage(void);
58 char			*read_btfile(const char *, size_t *);
59 
60 /*
61  * Retrieve & parse probe information.
62  */
63 void			 dtpi_cache(int);
64 void			 dtpi_print_list(int);
65 const char		*dtpi_func(struct dtioc_probe_info *);
66 int			 dtpi_is_unit(const char *);
67 struct dtioc_probe_info	*dtpi_get_by_value(const char *, const char *,
68 			     const char *);
69 
70 /*
71  * Main loop and rule evaluation.
72  */
73 void			 rules_do(int);
74 void			 rules_setup(int);
75 void			 rules_apply(int, struct dt_evt *);
76 void			 rules_teardown(int);
77 void			 rule_eval(struct bt_rule *, struct dt_evt *);
78 void			 rule_printmaps(struct bt_rule *);
79 
80 /*
81  * Language builtins & functions.
82  */
83 uint64_t		 builtin_nsecs(struct dt_evt *);
84 const char		*builtin_kstack(struct dt_evt *);
85 const char		*builtin_arg(struct dt_evt *, enum bt_argtype);
86 struct bt_arg		*fn_str(struct bt_arg *, struct dt_evt *, char *);
87 void			 stmt_eval(struct bt_stmt *, struct dt_evt *);
88 void			 stmt_bucketize(struct bt_stmt *, struct dt_evt *);
89 void			 stmt_clear(struct bt_stmt *);
90 void			 stmt_delete(struct bt_stmt *, struct dt_evt *);
91 void			 stmt_insert(struct bt_stmt *, struct dt_evt *);
92 void			 stmt_print(struct bt_stmt *, struct dt_evt *);
93 void			 stmt_store(struct bt_stmt *, struct dt_evt *);
94 bool			 stmt_test(struct bt_stmt *, struct dt_evt *);
95 void			 stmt_time(struct bt_stmt *, struct dt_evt *);
96 void			 stmt_zero(struct bt_stmt *);
97 struct bt_arg		*ba_read(struct bt_arg *);
98 const char		*ba2hash(struct bt_arg *, struct dt_evt *);
99 long			 baexpr2long(struct bt_arg *, struct dt_evt *);
100 const char		*ba2bucket(struct bt_arg *, struct bt_arg *,
101 			     struct dt_evt *, long *);
102 int			 ba2dtflags(struct bt_arg *);
103 
104 /*
105  * Debug routines.
106  */
107 __dead void		 xabort(const char *, ...);
108 void			 debug(const char *, ...);
109 void			 debugx(const char *, ...);
110 const char		*debug_probe_name(struct bt_probe *);
111 void			 debug_dump_term(struct bt_arg *);
112 void			 debug_dump_expr(struct bt_arg *);
113 void			 debug_dump_filter(struct bt_rule *);
114 
115 struct dtioc_probe_info	*dt_dtpis;	/* array of available probes */
116 size_t			 dt_ndtpi;	/* # of elements in the array */
117 struct dtioc_arg_info  **dt_args;	/* array of probe arguments */
118 
119 struct dt_evt		 bt_devt;	/* fake event for BEGIN/END */
120 uint64_t		 bt_filtered;	/* # of events filtered out */
121 
122 struct syms		*kelf, *uelf;
123 
124 char			**vargs;
125 int			 nargs = 0;
126 int			 verbose = 0;
127 int			 dtfd;
128 volatile sig_atomic_t	 quit_pending;
129 
130 static void
131 signal_handler(int sig)
132 {
133 	quit_pending = sig;
134 }
135 
136 
137 int
138 main(int argc, char *argv[])
139 {
140 	int fd = -1, ch, error = 0;
141 	const char *filename = NULL, *btscript = NULL;
142 	int showprobes = 0, noaction = 0;
143 	size_t btslen = 0;
144 
145 	setlocale(LC_ALL, "");
146 
147 	while ((ch = getopt(argc, argv, "e:lnp:v")) != -1) {
148 		switch (ch) {
149 		case 'e':
150 			btscript = optarg;
151 			btslen = strlen(btscript);
152 			break;
153 		case 'l':
154 			showprobes = 1;
155 			break;
156 		case 'n':
157 			noaction = 1;
158 			break;
159 		case 'p':
160 			uelf = kelf_open(optarg);
161 			break;
162 		case 'v':
163 			verbose++;
164 			break;
165 		default:
166 			usage();
167 		}
168 	}
169 
170 	argc -= optind;
171 	argv += optind;
172 
173 	if (argc > 0 && btscript == NULL)
174 		filename = argv[0];
175 
176 	 /* Cannot pledge due to special ioctl()s */
177 	if (unveil(__PATH_DEVDT, "r") == -1)
178 		err(1, "unveil %s", __PATH_DEVDT);
179 	if (unveil(_PATH_KSYMS, "r") == -1)
180 		err(1, "unveil %s", _PATH_KSYMS);
181 	if (filename != NULL) {
182 		if (unveil(filename, "r") == -1)
183 			err(1, "unveil %s", filename);
184 	}
185 	if (unveil(NULL, NULL) == -1)
186 		err(1, "unveil");
187 
188 	if (filename != NULL) {
189 		btscript = read_btfile(filename, &btslen);
190 		argc--;
191 		argv++;
192 	}
193 
194 	nargs = argc;
195 	vargs = argv;
196 
197 	if (btscript == NULL && !showprobes)
198 		usage();
199 
200 	if (btscript != NULL) {
201 		error = btparse(btscript, btslen, filename, 1);
202 		if (error)
203 			return error;
204 	}
205 
206 	if (noaction)
207 		return error;
208 
209 	if (showprobes || g_nprobes > 0) {
210 		fd = open(__PATH_DEVDT, O_RDONLY);
211 		if (fd == -1)
212 			err(1, "could not open %s", __PATH_DEVDT);
213 		dtfd = fd;
214 	}
215 
216 	if (showprobes) {
217 		dtpi_cache(fd);
218 		dtpi_print_list(fd);
219 	}
220 
221 	if (!TAILQ_EMPTY(&g_rules))
222 		rules_do(fd);
223 
224 	if (fd != -1)
225 		close(fd);
226 
227 	return error;
228 }
229 
230 __dead void
231 usage(void)
232 {
233 	fprintf(stderr, "usage: %s [-lnv] [-e program | file] [argument ...]\n",
234 	    getprogname());
235 	exit(1);
236 }
237 
238 char *
239 read_btfile(const char *filename, size_t *len)
240 {
241 	FILE *fp;
242 	char *fcontent;
243 	struct stat st;
244 	size_t fsize;
245 
246 	if (stat(filename, &st))
247 		err(1, "can't stat '%s'", filename);
248 
249 	fsize = st.st_size;
250 	fcontent = malloc(fsize + 1);
251 	if (fcontent == NULL)
252 		err(1, "malloc");
253 
254 	fp = fopen(filename, "r");
255 	if (fp == NULL)
256 		err(1, "can't open '%s'", filename);
257 
258 	if (fread(fcontent, 1, fsize, fp) != fsize)
259 		err(1, "can't read '%s'", filename);
260 	fcontent[fsize] = '\0';
261 
262 	fclose(fp);
263 	*len = fsize;
264 	return fcontent;
265 }
266 
267 void
268 dtpi_cache(int fd)
269 {
270 	struct dtioc_probe dtpr;
271 
272 	if (dt_dtpis != NULL)
273 		return;
274 
275 	memset(&dtpr, 0, sizeof(dtpr));
276 	if (ioctl(fd, DTIOCGPLIST, &dtpr))
277 		err(1, "DTIOCGPLIST");
278 
279 	dt_ndtpi = dtpr.dtpr_size / sizeof(*dt_dtpis);
280 	dt_dtpis = reallocarray(NULL, dt_ndtpi, sizeof(*dt_dtpis));
281 	if (dt_dtpis == NULL)
282 		err(1, NULL);
283 
284 	dtpr.dtpr_probes = dt_dtpis;
285 	if (ioctl(fd, DTIOCGPLIST, &dtpr))
286 		err(1, "DTIOCGPLIST");
287 }
288 
289 void
290 dtai_cache(int fd, struct dtioc_probe_info *dtpi)
291 {
292 	struct dtioc_arg dtar;
293 
294 	if (dt_args == NULL) {
295 		dt_args = calloc(dt_ndtpi, sizeof(*dt_args));
296 		if (dt_args == NULL)
297 			err(1, NULL);
298 	}
299 
300 	if (dt_args[dtpi->dtpi_pbn - 1] != NULL)
301 		return;
302 
303 	dt_args[dtpi->dtpi_pbn - 1] = reallocarray(NULL, dtpi->dtpi_nargs,
304 	    sizeof(**dt_args));
305 	if (dt_args[dtpi->dtpi_pbn - 1] == NULL)
306 		err(1, NULL);
307 
308 	dtar.dtar_pbn = dtpi->dtpi_pbn;
309 	dtar.dtar_size = dtpi->dtpi_nargs * sizeof(**dt_args);
310 	dtar.dtar_args = dt_args[dtpi->dtpi_pbn - 1];
311 	if (ioctl(fd, DTIOCGARGS, &dtar))
312 		err(1, "DTIOCGARGS");
313 }
314 
315 void
316 dtpi_print_list(int fd)
317 {
318 	struct dtioc_probe_info *dtpi;
319 	struct dtioc_arg_info *dtai;
320 	size_t i, j;
321 
322 	dtpi = dt_dtpis;
323 	for (i = 0; i < dt_ndtpi; i++, dtpi++) {
324 		printf("%s:%s:%s", dtpi->dtpi_prov, dtpi_func(dtpi),
325 		    dtpi->dtpi_name);
326 		if (strncmp(dtpi->dtpi_prov, "tracepoint", DTNAMESIZE) == 0) {
327 			dtai_cache(fd, dtpi);
328 			dtai = dt_args[dtpi->dtpi_pbn - 1];
329 			printf("(");
330 			for (j = 0; j < dtpi->dtpi_nargs; j++, dtai++) {
331 				if (j > 0)
332 					printf(", ");
333 				printf("%s", dtai->dtai_argtype);
334 			}
335 			printf(")");
336 		}
337 		printf("\n");
338 	}
339 }
340 
341 const char *
342 dtpi_func(struct dtioc_probe_info *dtpi)
343 {
344 	char *sysnb, func[DTNAMESIZE];
345 	const char *errstr;
346 	int idx;
347 
348 	if (strncmp(dtpi->dtpi_prov, "syscall", DTNAMESIZE))
349 		return dtpi->dtpi_func;
350 
351 	/* Translate syscall names */
352 	strlcpy(func, dtpi->dtpi_func, sizeof(func));
353 	sysnb = func;
354 	if (strsep(&sysnb, "%") == NULL)
355 		return dtpi->dtpi_func;
356 
357 	idx = strtonum(sysnb, 1, SYS_MAXSYSCALL, &errstr);
358 	if (errstr != NULL)
359 		return dtpi->dtpi_func;
360 
361 	return syscallnames[idx];
362 }
363 
364 int
365 dtpi_is_unit(const char *unit)
366 {
367 	return !strncmp("hz", unit, sizeof("hz"));
368 }
369 
370 struct dtioc_probe_info *
371 dtpi_get_by_value(const char *prov, const char *func, const char *name)
372 {
373 	struct dtioc_probe_info *dtpi;
374 	size_t i;
375 
376 	dtpi = dt_dtpis;
377 	for (i = 0; i < dt_ndtpi; i++, dtpi++) {
378 		if (prov != NULL &&
379 		    strncmp(prov, dtpi->dtpi_prov, DTNAMESIZE))
380 			continue;
381 
382 		if (func != NULL) {
383 			if (dtpi_is_unit(func))
384 				return dtpi;
385 
386 			if (strncmp(func, dtpi_func(dtpi), DTNAMESIZE))
387 				continue;
388 		}
389 
390 		if (strncmp(name, dtpi->dtpi_name, DTNAMESIZE))
391 			continue;
392 
393 		debug("matched probe %s:%s:%s\n", dtpi->dtpi_prov,
394 		    dtpi_func(dtpi), dtpi->dtpi_name);
395 		return dtpi;
396 	}
397 
398 	return NULL;
399 }
400 
401 void
402 rules_do(int fd)
403 {
404 	struct sigaction sa;
405 
406 	memset(&sa, 0, sizeof(sa));
407 	sigemptyset(&sa.sa_mask);
408 	sa.sa_flags = 0;
409 	sa.sa_handler = signal_handler;
410 	if (sigaction(SIGINT, &sa, NULL))
411 		err(1, "sigaction");
412 	if (sigaction(SIGTERM, &sa, NULL))
413 		err(1, "sigaction");
414 
415 	rules_setup(fd);
416 
417 	while (!quit_pending && g_nprobes > 0) {
418 		static struct dt_evt devtbuf[64];
419 		ssize_t rlen;
420 		size_t i;
421 
422 		rlen = read(fd, devtbuf, sizeof(devtbuf) - 1);
423 		if (rlen == -1) {
424 			if (errno == EINTR && quit_pending) {
425 				printf("\n");
426 				break;
427 			}
428 			err(1, "read");
429 		}
430 
431 		if ((rlen % sizeof(struct dt_evt)) != 0)
432 			err(1, "incorrect read");
433 
434 		for (i = 0; i < rlen / sizeof(struct dt_evt); i++)
435 			rules_apply(fd, &devtbuf[i]);
436 	}
437 
438 	rules_teardown(fd);
439 
440 	if (verbose && fd != -1) {
441 		struct dtioc_stat dtst;
442 
443 		memset(&dtst, 0, sizeof(dtst));
444 		if (ioctl(fd, DTIOCGSTATS, &dtst))
445 			warn("DTIOCGSTATS");
446 
447 		printf("%llu events read\n", dtst.dtst_readevt);
448 		printf("%llu events dropped\n", dtst.dtst_dropevt);
449 		printf("%llu events filtered\n", bt_filtered);
450 	}
451 }
452 
453 void
454 rules_setup(int fd)
455 {
456 	struct dtioc_probe_info *dtpi;
457 	struct dtioc_req *dtrq;
458 	struct bt_rule *r, *rbegin = NULL;
459 	struct bt_probe *bp;
460 	struct bt_stmt *bs;
461 	struct bt_arg *ba;
462 	int dokstack = 0, on = 1;
463 	uint64_t evtflags;
464 
465 	TAILQ_FOREACH(r, &g_rules, br_next) {
466 		evtflags = 0;
467 
468 		if (r->br_filter != NULL &&
469 		    r->br_filter->bf_condition != NULL)  {
470 
471 			bs = r->br_filter->bf_condition;
472 			ba = SLIST_FIRST(&bs->bs_args);
473 
474 			evtflags |= ba2dtflags(ba);
475 		}
476 
477 		SLIST_FOREACH(bs, &r->br_action, bs_next) {
478 			SLIST_FOREACH(ba, &bs->bs_args, ba_next)
479 				evtflags |= ba2dtflags(ba);
480 
481 			/* Also check the value for map/hist insertion */
482 			switch (bs->bs_act) {
483 			case B_AC_BUCKETIZE:
484 			case B_AC_INSERT:
485 				ba = (struct bt_arg *)bs->bs_var;
486 				evtflags |= ba2dtflags(ba);
487 				break;
488 			default:
489 				break;
490 			}
491 		}
492 
493 		SLIST_FOREACH(bp, &r->br_probes, bp_next) {
494 			debug("parsed probe '%s'", debug_probe_name(bp));
495 			debug_dump_filter(r);
496 
497 			if (bp->bp_type != B_PT_PROBE) {
498 				if (bp->bp_type == B_PT_BEGIN)
499 					rbegin = r;
500 				continue;
501 			}
502 
503 			dtpi_cache(fd);
504 			dtpi = dtpi_get_by_value(bp->bp_prov, bp->bp_func,
505 			    bp->bp_name);
506 			if (dtpi == NULL) {
507 				errx(1, "probe '%s:%s:%s' not found",
508 				    bp->bp_prov, bp->bp_func, bp->bp_name);
509 			}
510 
511 			dtrq = calloc(1, sizeof(*dtrq));
512 			if (dtrq == NULL)
513 				err(1, "dtrq: 1alloc");
514 
515 			bp->bp_pbn = dtpi->dtpi_pbn;
516 			dtrq->dtrq_pbn = dtpi->dtpi_pbn;
517 			dtrq->dtrq_rate = bp->bp_rate;
518 			dtrq->dtrq_evtflags = evtflags;
519 			if (dtrq->dtrq_evtflags & DTEVT_KSTACK)
520 				dokstack = 1;
521 			bp->bp_cookie = dtrq;
522 		}
523 	}
524 
525 	if (dokstack)
526 		kelf = kelf_open(_PATH_KSYMS);
527 
528 	/* Initialize "fake" event for BEGIN/END */
529 	bt_devt.dtev_pbn = -1;
530 	strlcpy(bt_devt.dtev_comm, getprogname(), sizeof(bt_devt.dtev_comm));
531 	bt_devt.dtev_pid = getpid();
532 	bt_devt.dtev_tid = getthrid();
533 	clock_gettime(CLOCK_REALTIME, &bt_devt.dtev_tsp);
534 
535 	if (rbegin)
536 		rule_eval(rbegin, &bt_devt);
537 
538 	/* Enable all probes */
539 	TAILQ_FOREACH(r, &g_rules, br_next) {
540 		SLIST_FOREACH(bp, &r->br_probes, bp_next) {
541 			if (bp->bp_type != B_PT_PROBE)
542 				continue;
543 
544 			dtrq = bp->bp_cookie;
545 			if (ioctl(fd, DTIOCPRBENABLE, dtrq))
546 				err(1, "DTIOCPRBENABLE");
547 		}
548 	}
549 
550 	if (g_nprobes > 0) {
551 		if (ioctl(fd, DTIOCRECORD, &on))
552 			err(1, "DTIOCRECORD");
553 	}
554 }
555 
556 void
557 rules_apply(int fd, struct dt_evt *dtev)
558 {
559 	struct bt_rule *r;
560 	struct bt_probe *bp;
561 
562 	TAILQ_FOREACH(r, &g_rules, br_next) {
563 		SLIST_FOREACH(bp, &r->br_probes, bp_next) {
564 			if (bp->bp_type != B_PT_PROBE ||
565 			    bp->bp_pbn != dtev->dtev_pbn)
566 				continue;
567 
568 			dtai_cache(fd, &dt_dtpis[dtev->dtev_pbn - 1]);
569 			rule_eval(r, dtev);
570 		}
571 	}
572 }
573 
574 void
575 rules_teardown(int fd)
576 {
577 	struct dtioc_req *dtrq;
578 	struct bt_probe *bp;
579 	struct bt_rule *r, *rend = NULL;
580 	int dokstack = 0, off = 0;
581 
582 	if (g_nprobes > 0) {
583 		if (ioctl(fd, DTIOCRECORD, &off))
584 			err(1, "DTIOCRECORD");
585 	}
586 
587 	TAILQ_FOREACH(r, &g_rules, br_next) {
588 		SLIST_FOREACH(bp, &r->br_probes, bp_next) {
589 			if (bp->bp_type != B_PT_PROBE) {
590 				if (bp->bp_type == B_PT_END)
591 					rend = r;
592 				continue;
593 			}
594 
595 			dtrq = bp->bp_cookie;
596 			if (ioctl(fd, DTIOCPRBDISABLE, dtrq))
597 				err(1, "DTIOCPRBDISABLE");
598 			if (dtrq->dtrq_evtflags & DTEVT_KSTACK)
599 				dokstack = 1;
600 		}
601 	}
602 
603 	kelf_close(kelf);
604 	kelf = NULL;
605 	kelf_close(uelf);
606 	uelf = NULL;
607 
608 	/* Update "fake" event for BEGIN/END */
609 	clock_gettime(CLOCK_REALTIME, &bt_devt.dtev_tsp);
610 
611 	if (rend)
612 		rule_eval(rend, &bt_devt);
613 
614 	/* Print non-empty map & hist */
615 	TAILQ_FOREACH(r, &g_rules, br_next)
616 		rule_printmaps(r);
617 }
618 
619 void
620 rule_eval(struct bt_rule *r, struct dt_evt *dtev)
621 {
622 	struct bt_stmt *bs;
623 	struct bt_probe *bp;
624 
625 	SLIST_FOREACH(bp, &r->br_probes, bp_next) {
626 		debug("eval rule '%s'", debug_probe_name(bp));
627 		debug_dump_filter(r);
628 	}
629 
630 	if (r->br_filter != NULL && r->br_filter->bf_condition != NULL) {
631 		if (stmt_test(r->br_filter->bf_condition, dtev) == false) {
632 			bt_filtered++;
633 			return;
634 		}
635 	}
636 
637 	SLIST_FOREACH(bs, &r->br_action, bs_next) {
638 		if ((bs->bs_act == B_AC_TEST) && stmt_test(bs, dtev) == true) {
639 			struct bt_stmt *bbs = (struct bt_stmt *)bs->bs_var;
640 
641 			while (bbs != NULL) {
642 				stmt_eval(bbs, dtev);
643 				bbs = SLIST_NEXT(bbs, bs_next);
644 			}
645 
646 			continue;
647 		}
648 
649 		stmt_eval(bs, dtev);
650 	}
651 }
652 
653 void
654 rule_printmaps(struct bt_rule *r)
655 {
656 	struct bt_stmt *bs;
657 
658 	SLIST_FOREACH(bs, &r->br_action, bs_next) {
659 		struct bt_arg *ba;
660 
661 		SLIST_FOREACH(ba, &bs->bs_args, ba_next) {
662 			struct bt_var *bv = ba->ba_value;
663 			struct map *map;
664 
665 			if (ba->ba_type != B_AT_MAP && ba->ba_type != B_AT_HIST)
666 				continue;
667 
668 			map = (struct map *)bv->bv_value;
669 			if (map == NULL)
670 				continue;
671 
672 			if (ba->ba_type == B_AT_MAP)
673 				map_print(map, SIZE_T_MAX, bv_name(bv));
674 			else
675 				hist_print((struct hist *)map, bv_name(bv));
676 			map_clear(map);
677 			bv->bv_value = NULL;
678 		}
679 	}
680 }
681 
682 time_t
683 builtin_gettime(struct dt_evt *dtev)
684 {
685 	struct timespec ts;
686 
687 	if (dtev == NULL) {
688 		clock_gettime(CLOCK_REALTIME, &ts);
689 		return ts.tv_sec;
690 	}
691 
692 	return dtev->dtev_tsp.tv_sec;
693 }
694 
695 static inline uint64_t
696 TIMESPEC_TO_NSEC(struct timespec *ts)
697 {
698 	return (ts->tv_sec * 1000000000L + ts->tv_nsec);
699 }
700 
701 uint64_t
702 builtin_nsecs(struct dt_evt *dtev)
703 {
704 	struct timespec ts;
705 
706 	if (dtev == NULL) {
707 		clock_gettime(CLOCK_REALTIME, &ts);
708 		return TIMESPEC_TO_NSEC(&ts);
709 	}
710 
711 	return TIMESPEC_TO_NSEC(&dtev->dtev_tsp);
712 }
713 
714 const char *
715 builtin_stack(struct dt_evt *dtev, int kernel, unsigned long offset)
716 {
717 	struct stacktrace *st = &dtev->dtev_kstack;
718 	static char buf[4096];
719 	const char *last = "\nkernel\n";
720 	char *bp;
721 	size_t i;
722 	int sz;
723 
724 	if (!kernel) {
725 		st = &dtev->dtev_ustack;
726 		last = "\nuserland\n";
727 	} else if (st->st_count == 0) {
728 		return "\nuserland\n";
729 	}
730 
731 	buf[0] = '\0';
732 	bp = buf;
733 	sz = sizeof(buf);
734 	for (i = 0; i < st->st_count; i++) {
735 		int l;
736 
737 		if (!kernel)
738 			l = kelf_snprintsym(uelf, bp, sz - 1, st->st_pc[i],
739 			    offset);
740 		else
741 			l = kelf_snprintsym(kelf, bp, sz - 1, st->st_pc[i],
742 			    offset);
743 		if (l < 0)
744 			break;
745 		if (l >= sz - 1) {
746 			bp += sz - 1;
747 			sz = 1;
748 			break;
749 		}
750 		bp += l;
751 		sz -= l;
752 	}
753 	snprintf(bp, sz, "%s", last);
754 
755 	return buf;
756 }
757 
758 const char *
759 builtin_arg(struct dt_evt *dtev, enum bt_argtype dat)
760 {
761 	static char buf[sizeof("18446744073709551615")]; /* UINT64_MAX */
762 	unsigned int argn;
763 	struct dtioc_arg_info *dtai;
764 	const char *argtype, *fmt;
765 	long value;
766 
767 	dtai = dt_args[dtev->dtev_pbn - 1];
768 	argn = dat - B_AT_BI_ARG0;
769 	argtype = dtai[argn].dtai_argtype;
770 
771 	if (strncmp(argtype, "int", DTNAMESIZE) == 0) {
772 		fmt = "%d";
773 		value = (int)dtev->dtev_args[argn];
774 	} else {
775 		fmt = "%lu";
776 		value = dtev->dtev_args[argn];
777 	}
778 
779 	snprintf(buf, sizeof(buf), fmt, dtev->dtev_args[argn]);
780 
781 	return buf;
782 }
783 
784 void
785 stmt_eval(struct bt_stmt *bs, struct dt_evt *dtev)
786 {
787 	switch (bs->bs_act) {
788 	case B_AC_BUCKETIZE:
789 		stmt_bucketize(bs, dtev);
790 		break;
791 	case B_AC_CLEAR:
792 		stmt_clear(bs);
793 		break;
794 	case B_AC_DELETE:
795 		stmt_delete(bs, dtev);
796 		break;
797 	case B_AC_EXIT:
798 		exit(0);
799 		break;
800 	case B_AC_INSERT:
801 		stmt_insert(bs, dtev);
802 		break;
803 	case B_AC_PRINT:
804 		stmt_print(bs, dtev);
805 		break;
806 	case B_AC_PRINTF:
807 		stmt_printf(bs, dtev);
808 		break;
809 	case B_AC_STORE:
810 		stmt_store(bs, dtev);
811 		break;
812 	case B_AC_TEST:
813 		/* done before */
814 		break;
815 	case B_AC_TIME:
816 		stmt_time(bs, dtev);
817 		break;
818 	case B_AC_ZERO:
819 		stmt_zero(bs);
820 		break;
821 	default:
822 		xabort("no handler for action type %d", bs->bs_act);
823 	}
824 }
825 
826 /*
827  * Increment a bucket:	{ @h = hist(v); } or { @h = lhist(v, min, max, step); }
828  *
829  * In this case 'h' is represented by `bv' and '(min, max, step)' by `brange'.
830  */
831 void
832 stmt_bucketize(struct bt_stmt *bs, struct dt_evt *dtev)
833 {
834 	struct bt_arg *brange, *bhist = SLIST_FIRST(&bs->bs_args);
835 	struct bt_arg *bval = (struct bt_arg *)bs->bs_var;
836 	struct bt_var *bv = bhist->ba_value;
837 	const char *bucket;
838 	long step = 0;
839 
840 	assert(bhist->ba_type == B_AT_HIST);
841 	assert(SLIST_NEXT(bval, ba_next) == NULL);
842 
843 	brange = bhist->ba_key;
844 	bucket = ba2bucket(bval, brange, dtev, &step);
845 	if (bucket == NULL) {
846 		debug("hist=%p '%s' value=%lu out of range\n", bv->bv_value,
847 		    bv_name(bv), ba2long(bval, dtev));
848 		return;
849 	}
850 	debug("hist=%p '%s' increment bucket '%s'\n", bv->bv_value,
851 	    bv_name(bv), bucket);
852 
853 	bv->bv_value = (struct bt_arg *)
854 	    hist_increment((struct hist *)bv->bv_value, bucket, step);
855 	bv->bv_type = B_VT_HIST;
856 }
857 
858 
859 /*
860  * Empty a map:		{ clear(@map); }
861  */
862 void
863 stmt_clear(struct bt_stmt *bs)
864 {
865 	struct bt_arg *ba = SLIST_FIRST(&bs->bs_args);
866 	struct bt_var *bv = ba->ba_value;
867 	struct map *map;
868 
869 	assert(bs->bs_var == NULL);
870 	assert(ba->ba_type == B_AT_VAR);
871 
872 	map = (struct map *)bv->bv_value;
873 	if (map == NULL)
874 		return;
875 
876 	if (bv->bv_type != B_VT_MAP && bv->bv_type != B_VT_HIST)
877 		errx(1, "invalid variable type for clear(%s)", ba_name(ba));
878 
879 	map_clear(map);
880 	bv->bv_value = NULL;
881 
882 	debug("map=%p '%s' clear\n", map, bv_name(bv));
883 }
884 
885 /*
886  * Map delete:	 	{ delete(@map[key]); }
887  *
888  * In this case 'map' is represented by `bv' and 'key' by `bkey'.
889  */
890 void
891 stmt_delete(struct bt_stmt *bs, struct dt_evt *dtev)
892 {
893 	struct bt_arg *bkey, *bmap = SLIST_FIRST(&bs->bs_args);
894 	struct bt_var *bv = bmap->ba_value;
895 	struct map *map;
896 	const char *hash;
897 
898 	assert(bmap->ba_type == B_AT_MAP);
899 	assert(bs->bs_var == NULL);
900 
901 	map = (struct map *)bv->bv_value;
902 	if (map == NULL)
903 		return;
904 
905 	bkey = bmap->ba_key;
906 	hash = ba2hash(bkey, dtev);
907 	debug("map=%p '%s' delete key=%p '%s'\n", map, bv_name(bv), bkey, hash);
908 
909 	map_delete(map, hash);
910 }
911 
912 /*
913  * Map insert:	 	{ @map[key] = 42; }
914  *
915  * In this case 'map' is represented by `bv', 'key' by `bkey' and
916  * '42' by `bval'.
917  */
918 void
919 stmt_insert(struct bt_stmt *bs, struct dt_evt *dtev)
920 {
921 	struct bt_arg *bkey, *bmap = SLIST_FIRST(&bs->bs_args);
922 	struct bt_arg *bval = (struct bt_arg *)bs->bs_var;
923 	struct bt_var *bv = bmap->ba_value;
924 	struct map *map;
925 	const char *hash;
926 
927 	assert(bmap->ba_type == B_AT_MAP);
928 	assert(SLIST_NEXT(bval, ba_next) == NULL);
929 
930 	bkey = bmap->ba_key;
931 	hash = ba2hash(bkey, dtev);
932 
933 	/* map is NULL before first insert or after clear() */
934 	map = (struct map *)bv->bv_value;
935 	map = map_insert(map, hash, bval, dtev);
936 
937 	debug("map=%p '%s' insert key=%p '%s' bval=%p\n", map,
938 	    bv_name(bv), bkey, hash, bval);
939 
940 	bv->bv_value = (struct bt_arg *)map;
941 	bv->bv_type = B_VT_MAP;
942 }
943 
944 /*
945  * Print variables:	{ print(890); print(@map[, 8]); print(comm); }
946  *
947  * In this case the global variable 'map' is pointed at by `ba'
948  * and '8' is represented by `btop'.
949  */
950 void
951 stmt_print(struct bt_stmt *bs, struct dt_evt *dtev)
952 {
953 	struct bt_arg *btop, *ba = SLIST_FIRST(&bs->bs_args);
954 	struct bt_var *bv = ba->ba_value;
955 	struct map *map;
956 	size_t top = SIZE_T_MAX;
957 
958 	assert(bs->bs_var == NULL);
959 
960 	/* Parse optional `top' argument. */
961 	btop = SLIST_NEXT(ba, ba_next);
962 	if (btop != NULL) {
963 		assert(SLIST_NEXT(btop, ba_next) == NULL);
964 		top = ba2long(btop, dtev);
965 	}
966 
967 	/* Static argument. */
968 	if (ba->ba_type != B_AT_VAR) {
969 		assert(btop == NULL);
970 		printf("%s\n", ba2str(ba, dtev));
971 		return;
972 	}
973 
974 	map = (struct map *)bv->bv_value;
975 	if (map == NULL)
976 		return;
977 
978 	debug("map=%p '%s' print (top=%d)\n", bv->bv_value, bv_name(bv), top);
979 
980 	if (bv->bv_type == B_VT_MAP)
981 		map_print(map, top, bv_name(bv));
982 	else if (bv->bv_type == B_VT_HIST)
983 		hist_print((struct hist *)map, bv_name(bv));
984 	else
985 		printf("%s\n", ba2str(ba, dtev));
986 }
987 
988 /*
989  * Variable store: 	{ @var = 3; }
990  *
991  * In this case '3' is represented by `ba', the argument of a STORE
992  * action.
993  *
994  * If the argument depends of the value of an event (builtin) or is
995  * the result of an operation, its evaluation is stored in a new `ba'.
996  */
997 void
998 stmt_store(struct bt_stmt *bs, struct dt_evt *dtev)
999 {
1000 	struct bt_arg *ba = SLIST_FIRST(&bs->bs_args);
1001 	struct bt_var *bv = bs->bs_var;
1002 
1003 	assert(SLIST_NEXT(ba, ba_next) == NULL);
1004 
1005 	switch (ba->ba_type) {
1006 	case B_AT_STR:
1007 		bv->bv_value = ba;
1008 		bv->bv_type = B_VT_STR;
1009 		break;
1010 	case B_AT_LONG:
1011 		bv->bv_value = ba;
1012 		bv->bv_type = B_VT_LONG;
1013 		break;
1014 	case B_AT_BI_NSECS:
1015 		bv->bv_value = ba_new(builtin_nsecs(dtev), B_AT_LONG);
1016 		bv->bv_type = B_VT_LONG;
1017 		break;
1018 	case B_AT_BI_ARG0 ... B_AT_BI_ARG9:
1019 	/* FALLTHROUGH */
1020 	case B_AT_OP_PLUS ... B_AT_OP_LOR:
1021 		bv->bv_value = ba_new(ba2long(ba, dtev), B_AT_LONG);
1022 		bv->bv_type = B_VT_LONG;
1023 		break;
1024 	case B_AT_FN_STR:
1025 		bv->bv_value = ba_new(ba2str(ba, dtev), B_AT_STR);
1026 		bv->bv_type = B_VT_STR;
1027 		break;
1028 	default:
1029 		xabort("store not implemented for type %d", ba->ba_type);
1030 	}
1031 
1032 	debug("bv=%p var '%s' store (%p)\n", bv, bv_name(bv), bv->bv_value);
1033 }
1034 
1035 /*
1036  * String conversion	{ str($1); string($1, 3); }
1037  *
1038  * Since fn_str is currently only called in ba2str, *buf should be a pointer
1039  * to the static buffer provided by ba2str.
1040  */
1041 struct bt_arg *
1042 fn_str(struct bt_arg *ba, struct dt_evt *dtev, char *buf)
1043 {
1044 	struct bt_arg *arg, *index;
1045 	ssize_t len = STRLEN;
1046 
1047 	assert(ba->ba_type == B_AT_FN_STR);
1048 
1049 	arg = (struct bt_arg*)ba->ba_value;
1050 	assert(arg != NULL);
1051 
1052 	index = SLIST_NEXT(arg, ba_next);
1053 	if (index != NULL) {
1054 		/* Should have only 1 optional argument. */
1055 		assert(SLIST_NEXT(index, ba_next) == NULL);
1056 		len = MINIMUM(ba2long(index, dtev) + 1, STRLEN);
1057 	}
1058 
1059 	/* All negative lengths behave the same as a zero length. */
1060 	if (len < 1)
1061 		return ba_new("", B_AT_STR);
1062 
1063 	strlcpy(buf, ba2str(arg, dtev), len);
1064 	return ba_new(buf, B_AT_STR);
1065 }
1066 
1067 /*
1068  * Expression test:	{ if (expr) stmt; }
1069  */
1070 bool
1071 stmt_test(struct bt_stmt *bs, struct dt_evt *dtev)
1072 {
1073 	struct bt_arg *ba;
1074 
1075 	if (bs == NULL)
1076 		return true;
1077 
1078 	ba = SLIST_FIRST(&bs->bs_args);
1079 
1080 	return baexpr2long(ba, dtev) != 0;
1081 }
1082 
1083 /*
1084  * Print time: 		{ time("%H:%M:%S"); }
1085  */
1086 void
1087 stmt_time(struct bt_stmt *bs, struct dt_evt *dtev)
1088 {
1089 	struct bt_arg *ba = SLIST_FIRST(&bs->bs_args);
1090 	time_t time;
1091 	struct tm *tm;
1092 	char buf[64];
1093 
1094 	assert(bs->bs_var == NULL);
1095 	assert(ba->ba_type == B_AT_STR);
1096 	assert(strlen(ba2str(ba, dtev)) < (sizeof(buf) - 1));
1097 
1098 	time = builtin_gettime(dtev);
1099 	tm = localtime(&time);
1100 	strftime(buf, sizeof(buf), ba2str(ba, dtev), tm);
1101 	printf("%s", buf);
1102 }
1103 
1104 /*
1105  * Set entries to 0:	{ zero(@map); }
1106  */
1107 void
1108 stmt_zero(struct bt_stmt *bs)
1109 {
1110 	struct bt_arg *ba = SLIST_FIRST(&bs->bs_args);
1111 	struct bt_var *bv = ba->ba_value;
1112 	struct map *map;
1113 
1114 	assert(bs->bs_var == NULL);
1115 	assert(ba->ba_type == B_AT_VAR);
1116 
1117 	map = (struct map *)bv->bv_value;
1118 	if (map == NULL)
1119 		return;
1120 
1121 	if (bv->bv_type != B_VT_MAP && bv->bv_type != B_VT_HIST)
1122 		errx(1, "invalid variable type for zero(%s)", ba_name(ba));
1123 
1124 	map_zero(map);
1125 
1126 	debug("map=%p '%s' zero\n", map, bv_name(bv));
1127 }
1128 
1129 struct bt_arg *
1130 ba_read(struct bt_arg *ba)
1131 {
1132 	struct bt_var *bv = ba->ba_value;
1133 
1134 	assert(ba->ba_type == B_AT_VAR);
1135 
1136 	debug("bv=%p read '%s' (%p)\n", bv, bv_name(bv), bv->bv_value);
1137 
1138 	/* Handle map/hist access after clear(). */
1139 	if (bv->bv_value == NULL)
1140 		return &g_nullba;
1141 
1142 	return bv->bv_value;
1143 }
1144 
1145 const char *
1146 ba2hash(struct bt_arg *ba, struct dt_evt *dtev)
1147 {
1148 	static char buf[KLEN];
1149 	char *hash;
1150 	int l, len;
1151 
1152 	buf[0] = '\0';
1153 	l = snprintf(buf, sizeof(buf), "%s", ba2str(ba, dtev));
1154 	if (l < 0 || (size_t)l > sizeof(buf)) {
1155 		warn("string too long %d > %lu", l, sizeof(buf));
1156 		return buf;
1157 	}
1158 
1159 	len = 0;
1160 	while ((ba = SLIST_NEXT(ba, ba_next)) != NULL) {
1161 		len += l;
1162 		hash = buf + len;
1163 
1164 		l = snprintf(hash, sizeof(buf) - len, ", %s", ba2str(ba, dtev));
1165 		if (l < 0 || (size_t)l > (sizeof(buf) - len)) {
1166 			warn("hash too long %d > %lu", l + len, sizeof(buf));
1167 			break;
1168 		}
1169 	}
1170 
1171 	return buf;
1172 }
1173 
1174 static unsigned long
1175 next_pow2(unsigned long x)
1176 {
1177 	size_t i;
1178 
1179 	x--;
1180 	for (i = 0; i < (sizeof(x)  * 8) - 1; i++)
1181 		x |= (x >> 1);
1182 
1183 	return x + 1;
1184 }
1185 
1186 /*
1187  * Return the ceiling value the interval holding `ba' or NULL if it is
1188  * out of the (min, max) values.
1189  */
1190 const char *
1191 ba2bucket(struct bt_arg *ba, struct bt_arg *brange, struct dt_evt *dtev,
1192     long *pstep)
1193 {
1194 	static char buf[KLEN];
1195 	long val, bucket;
1196 	int l;
1197 
1198 	val = ba2long(ba, dtev);
1199 	if (brange == NULL)
1200 		bucket = next_pow2(val);
1201 	else {
1202 		long min, max, step;
1203 
1204 		assert(brange->ba_type == B_AT_LONG);
1205 		min = ba2long(brange, NULL);
1206 
1207 		brange = SLIST_NEXT(brange, ba_next);
1208 		assert(brange->ba_type == B_AT_LONG);
1209 		max = ba2long(brange, NULL);
1210 
1211 		if ((val < min) || (val > max))
1212 			return NULL;
1213 
1214 		brange = SLIST_NEXT(brange, ba_next);
1215 		assert(brange->ba_type == B_AT_LONG);
1216 		step = ba2long(brange, NULL);
1217 
1218 		bucket = ((val / step) + 1) * step;
1219 		*pstep = step;
1220 	}
1221 
1222 	buf[0] = '\0';
1223 	l = snprintf(buf, sizeof(buf), "%lu", bucket);
1224 	if (l < 0 || (size_t)l > sizeof(buf)) {
1225 		warn("string too long %d > %lu", l, sizeof(buf));
1226 		return buf;
1227 	}
1228 
1229 	return buf;
1230 }
1231 
1232 /*
1233  * Evaluate the operation encoded in `ba' and return its result.
1234  */
1235 long
1236 baexpr2long(struct bt_arg *ba, struct dt_evt *dtev)
1237 {
1238 	static long recursions;
1239 	struct bt_arg *lhs, *rhs;
1240 	long lval, rval, result;
1241 
1242 	if (++recursions >= __MAXOPERANDS)
1243 		errx(1, "too many operands (>%d) in expression", __MAXOPERANDS);
1244 
1245 	lhs = ba->ba_value;
1246 	rhs = SLIST_NEXT(lhs, ba_next);
1247 
1248 	/*
1249 	 * String comparison also use '==' and '!='.
1250 	 */
1251 	if (lhs->ba_type == B_AT_STR ||
1252 	    (rhs != NULL && rhs->ba_type == B_AT_STR)) {
1253 	    	char lstr[STRLEN], rstr[STRLEN];
1254 
1255 		strlcpy(lstr, ba2str(lhs, dtev), sizeof(lstr));
1256 		strlcpy(rstr, ba2str(rhs, dtev), sizeof(rstr));
1257 
1258 	    	result = strncmp(lstr, rstr, STRLEN) == 0;
1259 
1260 		switch (ba->ba_type) {
1261 		case B_AT_OP_EQ:
1262 			break;
1263 		case B_AT_OP_NE:
1264 	    		result = !result;
1265 			break;
1266 		default:
1267 			warnx("operation '%d' unsupported on strings",
1268 			    ba->ba_type);
1269 			result = 1;
1270 		}
1271 
1272 		debug("ba=%p eval '(%s %s %s) = %d'\n", ba, lstr, ba_name(ba),
1273 		   rstr, result);
1274 
1275 		goto out;
1276 	}
1277 
1278 	lval = ba2long(lhs, dtev);
1279 	if (rhs == NULL) {
1280 		rval = 0;
1281 	} else {
1282 		assert(SLIST_NEXT(rhs, ba_next) == NULL);
1283 		rval = ba2long(rhs, dtev);
1284 	}
1285 
1286 	switch (ba->ba_type) {
1287 	case B_AT_OP_PLUS:
1288 		result = lval + rval;
1289 		break;
1290 	case B_AT_OP_MINUS:
1291 		result = lval - rval;
1292 		break;
1293 	case B_AT_OP_MULT:
1294 		result = lval * rval;
1295 		break;
1296 	case B_AT_OP_DIVIDE:
1297 		result = lval / rval;
1298 		break;
1299 	case B_AT_OP_BAND:
1300 		result = lval & rval;
1301 		break;
1302 	case B_AT_OP_XOR:
1303 		result = lval ^ rval;
1304 		break;
1305 	case B_AT_OP_BOR:
1306 		result = lval | rval;
1307 		break;
1308 	case B_AT_OP_EQ:
1309 		result = (lval == rval);
1310 		break;
1311 	case B_AT_OP_NE:
1312 		result = (lval != rval);
1313 		break;
1314 	case B_AT_OP_LE:
1315 		result = (lval <= rval);
1316 		break;
1317 	case B_AT_OP_LT:
1318 		result = (lval < rval);
1319 		break;
1320 	case B_AT_OP_GE:
1321 		result = (lval >= rval);
1322 		break;
1323 	case B_AT_OP_GT:
1324 		result = (lval > rval);
1325 		break;
1326 	case B_AT_OP_LAND:
1327 		result = (lval && rval);
1328 		break;
1329 	case B_AT_OP_LOR:
1330 		result = (lval || rval);
1331 		break;
1332 	default:
1333 		xabort("unsupported operation %d", ba->ba_type);
1334 	}
1335 
1336 	debug("ba=%p eval '(%ld %s %ld) = %d'\n", ba, lval, ba_name(ba),
1337 	   rval, result);
1338 
1339 out:
1340 	--recursions;
1341 
1342 	return result;
1343 }
1344 
1345 const char *
1346 ba_name(struct bt_arg *ba)
1347 {
1348 	switch (ba->ba_type) {
1349 	case B_AT_STR:
1350 		return (const char *)ba->ba_value;
1351 	case B_AT_LONG:
1352 		return ba2str(ba, NULL);
1353 	case B_AT_NIL:
1354 		return "0";
1355 	case B_AT_VAR:
1356 	case B_AT_MAP:
1357 	case B_AT_HIST:
1358 		break;
1359 	case B_AT_BI_PID:
1360 		return "pid";
1361 	case B_AT_BI_TID:
1362 		return "tid";
1363 	case B_AT_BI_COMM:
1364 		return "comm";
1365 	case B_AT_BI_CPU:
1366 		return "cpu";
1367 	case B_AT_BI_NSECS:
1368 		return "nsecs";
1369 	case B_AT_BI_KSTACK:
1370 		return "kstack";
1371 	case B_AT_BI_USTACK:
1372 		return "ustack";
1373 	case B_AT_BI_ARG0:
1374 		return "arg0";
1375 	case B_AT_BI_ARG1:
1376 		return "arg1";
1377 	case B_AT_BI_ARG2:
1378 		return "arg2";
1379 	case B_AT_BI_ARG3:
1380 		return "arg3";
1381 	case B_AT_BI_ARG4:
1382 		return "arg4";
1383 	case B_AT_BI_ARG5:
1384 		return "arg5";
1385 	case B_AT_BI_ARG6:
1386 		return "arg6";
1387 	case B_AT_BI_ARG7:
1388 		return "arg7";
1389 	case B_AT_BI_ARG8:
1390 		return "arg8";
1391 	case B_AT_BI_ARG9:
1392 		return "arg9";
1393 	case B_AT_BI_ARGS:
1394 		return "args";
1395 	case B_AT_BI_RETVAL:
1396 		return "retval";
1397 	case B_AT_BI_PROBE:
1398 		return "probe";
1399 	case B_AT_FN_STR:
1400 		return "str";
1401 	case B_AT_OP_PLUS:
1402 		return "+";
1403 	case B_AT_OP_MINUS:
1404 		return "-";
1405 	case B_AT_OP_MULT:
1406 		return "*";
1407 	case B_AT_OP_DIVIDE:
1408 		return "/";
1409 	case B_AT_OP_BAND:
1410 		return "&";
1411 	case B_AT_OP_XOR:
1412 		return "^";
1413 	case B_AT_OP_BOR:
1414 		return "|";
1415 	case B_AT_OP_EQ:
1416 		return "==";
1417 	case B_AT_OP_NE:
1418 		return "!=";
1419 	case B_AT_OP_LE:
1420 		return "<=";
1421 	case B_AT_OP_LT:
1422 		return "<";
1423 	case B_AT_OP_GE:
1424 		return ">=";
1425 	case B_AT_OP_GT:
1426 		return ">";
1427 	case B_AT_OP_LAND:
1428 		return "&&";
1429 	case B_AT_OP_LOR:
1430 		return "||";
1431 	default:
1432 		xabort("unsupported type %d", ba->ba_type);
1433 	}
1434 
1435 	assert(ba->ba_type == B_AT_VAR || ba->ba_type == B_AT_MAP ||
1436 	    ba->ba_type == B_AT_HIST);
1437 
1438 	static char buf[64];
1439 	size_t sz;
1440 	int l;
1441 
1442 	buf[0] = '@';
1443 	buf[1] = '\0';
1444 	sz = sizeof(buf) - 1;
1445 	l = snprintf(buf+1, sz, "%s", bv_name(ba->ba_value));
1446 	if (l < 0 || (size_t)l > sz) {
1447 		warn("string too long %d > %zu", l, sz);
1448 		return buf;
1449 	}
1450 
1451 	if (ba->ba_type == B_AT_MAP) {
1452 		sz -= l;
1453 		l = snprintf(buf+1+l, sz, "[%s]", ba_name(ba->ba_key));
1454 		if (l < 0 || (size_t)l > sz) {
1455 			warn("string too long %d > %zu", l, sz);
1456 			return buf;
1457 		}
1458 	}
1459 
1460 	return buf;
1461 }
1462 
1463 /*
1464  * Return the representation of `ba' as long.
1465  */
1466 long
1467 ba2long(struct bt_arg *ba, struct dt_evt *dtev)
1468 {
1469 	struct bt_var *bv;
1470 	long val;
1471 
1472 	switch (ba->ba_type) {
1473 	case B_AT_LONG:
1474 		val = (long)ba->ba_value;
1475 		break;
1476 	case B_AT_VAR:
1477 		ba = ba_read(ba);
1478 		val = (long)ba->ba_value;
1479 		break;
1480 	case B_AT_MAP:
1481 		bv = ba->ba_value;
1482 		/* Uninitialized map */
1483 		if (bv->bv_value == NULL)
1484 			return 0;
1485 		val = ba2long(map_get((struct map *)bv->bv_value,
1486 		    ba2str(ba->ba_key, dtev)), dtev);
1487 		break;
1488 	case B_AT_NIL:
1489 		val = 0L;
1490 		break;
1491 	case B_AT_BI_PID:
1492 		val = dtev->dtev_pid;
1493 		break;
1494 	case B_AT_BI_TID:
1495 		val = dtev->dtev_tid;
1496 		break;
1497 	case B_AT_BI_CPU:
1498 		val = dtev->dtev_cpu;
1499 		break;
1500 	case B_AT_BI_NSECS:
1501 		val = builtin_nsecs(dtev);
1502 		break;
1503 	case B_AT_BI_ARG0 ... B_AT_BI_ARG9:
1504 		val = dtev->dtev_args[ba->ba_type - B_AT_BI_ARG0];
1505 		break;
1506 	case B_AT_BI_RETVAL:
1507 		val = dtev->dtev_retval[0];
1508 		break;
1509 	case B_AT_BI_PROBE:
1510 		val = dtev->dtev_pbn;
1511 		break;
1512 	case B_AT_OP_PLUS ... B_AT_OP_LOR:
1513 		val = baexpr2long(ba, dtev);
1514 		break;
1515 	default:
1516 		xabort("no long conversion for type %d", ba->ba_type);
1517 	}
1518 
1519 	return  val;
1520 }
1521 
1522 /*
1523  * Return the representation of `ba' as string.
1524  */
1525 const char *
1526 ba2str(struct bt_arg *ba, struct dt_evt *dtev)
1527 {
1528 	static char buf[STRLEN];
1529 	struct bt_var *bv;
1530 	struct dtioc_probe_info *dtpi;
1531 	const char *str;
1532 
1533 	buf[0] = '\0';
1534 	switch (ba->ba_type) {
1535 	case B_AT_STR:
1536 		str = (const char *)ba->ba_value;
1537 		break;
1538 	case B_AT_LONG:
1539 		snprintf(buf, sizeof(buf), "%ld",(long)ba->ba_value);
1540 		str = buf;
1541 		break;
1542 	case B_AT_NIL:
1543 		str = "";
1544 		break;
1545 	case B_AT_BI_KSTACK:
1546 		str = builtin_stack(dtev, 1, 0);
1547 		break;
1548 	case B_AT_BI_USTACK:
1549 		str = builtin_stack(dtev, 0, dt_get_offset(dtev->dtev_pid));
1550 		break;
1551 	case B_AT_BI_COMM:
1552 		str = dtev->dtev_comm;
1553 		break;
1554 	case B_AT_BI_CPU:
1555 		snprintf(buf, sizeof(buf), "%u", dtev->dtev_cpu);
1556 		str = buf;
1557 		break;
1558 	case B_AT_BI_PID:
1559 		snprintf(buf, sizeof(buf), "%d", dtev->dtev_pid);
1560 		str = buf;
1561 		break;
1562 	case B_AT_BI_TID:
1563 		snprintf(buf, sizeof(buf), "%d", dtev->dtev_tid);
1564 		str = buf;
1565 		break;
1566 	case B_AT_BI_NSECS:
1567 		snprintf(buf, sizeof(buf), "%llu", builtin_nsecs(dtev));
1568 		str = buf;
1569 		break;
1570 	case B_AT_BI_ARG0 ... B_AT_BI_ARG9:
1571 		str = builtin_arg(dtev, ba->ba_type);
1572 		break;
1573 	case B_AT_BI_RETVAL:
1574 		snprintf(buf, sizeof(buf), "%ld", (long)dtev->dtev_retval[0]);
1575 		str = buf;
1576 		break;
1577 	case B_AT_BI_PROBE:
1578 		dtpi = &dt_dtpis[dtev->dtev_pbn - 1];
1579 		if (dtpi != NULL)
1580 			snprintf(buf, sizeof(buf), "%s:%s:%s",
1581 			    dtpi->dtpi_prov, dtpi_func(dtpi), dtpi->dtpi_name);
1582 		else
1583 			snprintf(buf, sizeof(buf), "%u", dtev->dtev_pbn);
1584 		str = buf;
1585 		break;
1586 	case B_AT_MAP:
1587 		bv = ba->ba_value;
1588 		/* Uninitialized map */
1589 		if (bv->bv_value == NULL) {
1590 			str = buf;
1591 			break;
1592 		}
1593 		str = ba2str(map_get((struct map *)bv->bv_value,
1594 		    ba2str(ba->ba_key, dtev)), dtev);
1595 		break;
1596 	case B_AT_VAR:
1597 		str = ba2str(ba_read(ba), dtev);
1598 		break;
1599 	case B_AT_FN_STR:
1600 		str = (const char*)(fn_str(ba, dtev, buf))->ba_value;
1601 		break;
1602 	case B_AT_OP_PLUS ... B_AT_OP_LOR:
1603 		snprintf(buf, sizeof(buf), "%ld", ba2long(ba, dtev));
1604 		str = buf;
1605 		break;
1606 	case B_AT_MF_COUNT:
1607 	case B_AT_MF_MAX:
1608 	case B_AT_MF_MIN:
1609 	case B_AT_MF_SUM:
1610 		assert(0);
1611 		break;
1612 	default:
1613 		xabort("no string conversion for type %d", ba->ba_type);
1614 	}
1615 
1616 	return str;
1617 }
1618 
1619 /*
1620  * Return dt(4) flags indicating which data should be recorded by the
1621  * kernel, if any, for a given `ba'.
1622  */
1623 int
1624 ba2dtflags(struct bt_arg *ba)
1625 {
1626 	static long recursions;
1627 	struct bt_arg *bval;
1628 	int flags = 0;
1629 
1630 	if (++recursions >= __MAXOPERANDS)
1631 		errx(1, "too many operands (>%d) in expression", __MAXOPERANDS);
1632 
1633 	do {
1634 		if (ba->ba_type == B_AT_MAP)
1635 			bval = ba->ba_key;
1636 		else
1637 			bval = ba;
1638 
1639 		switch (bval->ba_type) {
1640 		case B_AT_STR:
1641 		case B_AT_LONG:
1642 		case B_AT_VAR:
1643 	    	case B_AT_HIST:
1644 		case B_AT_NIL:
1645 			break;
1646 		case B_AT_BI_KSTACK:
1647 			flags |= DTEVT_KSTACK;
1648 			break;
1649 		case B_AT_BI_USTACK:
1650 			flags |= DTEVT_USTACK;
1651 			break;
1652 		case B_AT_BI_COMM:
1653 			flags |= DTEVT_EXECNAME;
1654 			break;
1655 		case B_AT_BI_CPU:
1656 		case B_AT_BI_PID:
1657 		case B_AT_BI_TID:
1658 		case B_AT_BI_NSECS:
1659 			break;
1660 		case B_AT_BI_ARG0 ... B_AT_BI_ARG9:
1661 			flags |= DTEVT_FUNCARGS;
1662 			break;
1663 		case B_AT_BI_RETVAL:
1664 		case B_AT_BI_PROBE:
1665 			break;
1666 		case B_AT_MF_COUNT:
1667 		case B_AT_MF_MAX:
1668 		case B_AT_MF_MIN:
1669 		case B_AT_MF_SUM:
1670 		case B_AT_FN_STR:
1671 			break;
1672 		case B_AT_OP_PLUS ... B_AT_OP_LOR:
1673 			flags |= ba2dtflags(bval->ba_value);
1674 			break;
1675 		default:
1676 			xabort("invalid argument type %d", bval->ba_type);
1677 		}
1678 	} while ((ba = SLIST_NEXT(ba, ba_next)) != NULL);
1679 
1680 	--recursions;
1681 
1682 	return flags;
1683 }
1684 
1685 long
1686 bacmp(struct bt_arg *a, struct bt_arg *b)
1687 {
1688 	assert(a->ba_type == b->ba_type);
1689 	assert(a->ba_type == B_AT_LONG);
1690 
1691 	return ba2long(a, NULL) - ba2long(b, NULL);
1692 }
1693 
1694 __dead void
1695 xabort(const char *fmt, ...)
1696 {
1697 	va_list ap;
1698 
1699 	va_start(ap, fmt);
1700 	vfprintf(stderr, fmt, ap);
1701 	va_end(ap);
1702 
1703 	fprintf(stderr, "\n");
1704 	abort();
1705 }
1706 
1707 void
1708 debug(const char *fmt, ...)
1709 {
1710 	va_list ap;
1711 
1712 	if (verbose < 2)
1713 		return;
1714 
1715 	fprintf(stderr, "debug: ");
1716 
1717 	va_start(ap, fmt);
1718 	vfprintf(stderr, fmt, ap);
1719 	va_end(ap);
1720 }
1721 
1722 void
1723 debugx(const char *fmt, ...)
1724 {
1725 	va_list ap;
1726 
1727 	if (verbose < 2)
1728 		return;
1729 
1730 	va_start(ap, fmt);
1731 	vfprintf(stderr, fmt, ap);
1732 	va_end(ap);
1733 }
1734 
1735 void
1736 debug_dump_term(struct bt_arg *ba)
1737 {
1738 	switch (ba->ba_type) {
1739 	case B_AT_LONG:
1740 		debugx("%s", ba2str(ba, NULL));
1741 		break;
1742 	case B_AT_OP_PLUS ... B_AT_OP_LOR:
1743 		debug_dump_expr(ba);
1744 		break;
1745 	default:
1746 		debugx("%s", ba_name(ba));
1747 	}
1748 }
1749 
1750 void
1751 debug_dump_expr(struct bt_arg *ba)
1752 {
1753 	struct bt_arg *lhs, *rhs;
1754 
1755 	lhs = ba->ba_value;
1756 	rhs = SLIST_NEXT(lhs, ba_next);
1757 
1758 	/* Left */
1759 	debug_dump_term(lhs);
1760 
1761 	/* Right */
1762 	if (rhs != NULL) {
1763 		debugx(" %s ", ba_name(ba));
1764 		debug_dump_term(rhs);
1765 	} else {
1766 		if (ba->ba_type != B_AT_OP_NE)
1767 			debugx(" %s NULL", ba_name(ba));
1768 	}
1769 }
1770 
1771 void
1772 debug_dump_filter(struct bt_rule *r)
1773 {
1774 	struct bt_stmt *bs;
1775 
1776 	if (verbose < 2)
1777 		return;
1778 
1779 	if (r->br_filter == NULL) {
1780 		debugx("\n");
1781 		return;
1782 	}
1783 
1784 	bs = r->br_filter->bf_condition;
1785 
1786 	debugx(" /");
1787 	debug_dump_expr(SLIST_FIRST(&bs->bs_args));
1788 	debugx("/\n");
1789 }
1790 
1791 const char *
1792 debug_probe_name(struct bt_probe *bp)
1793 {
1794 	static char buf[64];
1795 
1796 	if (verbose < 2)
1797 		return "";
1798 
1799 	if (bp->bp_type == B_PT_BEGIN)
1800 		return "BEGIN";
1801 
1802 	if (bp->bp_type == B_PT_END)
1803 		return "END";
1804 
1805 	assert(bp->bp_type == B_PT_PROBE);
1806 
1807 	if (bp->bp_rate) {
1808 		snprintf(buf, sizeof(buf), "%s:%s:%u", bp->bp_prov,
1809 		    bp->bp_unit, bp->bp_rate);
1810 	} else {
1811 		snprintf(buf, sizeof(buf), "%s:%s:%s", bp->bp_prov,
1812 		    bp->bp_unit, bp->bp_name);
1813 	}
1814 
1815 	return buf;
1816 }
1817 
1818 unsigned long
1819 dt_get_offset(pid_t pid)
1820 {
1821 	static struct dtioc_getaux	cache[32];
1822 	static int			next;
1823 	struct dtioc_getaux		*aux = NULL;
1824 	int				 i;
1825 
1826 	for (i = 0; i < 32; i++) {
1827 		if (cache[i].dtga_pid != pid)
1828 			continue;
1829 		aux = cache + i;
1830 		break;
1831 	}
1832 
1833 	if (aux == NULL) {
1834 		aux = &cache[next++];
1835 		next %= 32;
1836 
1837 		aux->dtga_pid = pid;
1838 		if (ioctl(dtfd, DTIOCGETAUXBASE, aux))
1839 			aux->dtga_auxbase = 0;
1840 	}
1841 
1842 	return aux->dtga_auxbase;
1843 }
1844