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