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