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