xref: /openbsd-src/usr.sbin/btrace/btrace.c (revision 46035553bfdd96e63c94e32da0210227ec2e3cf1)
1 /*	$OpenBSD: btrace.c,v 1.26 2020/12/07 18:28:09 bluhm Exp $ */
2 
3 /*
4  * Copyright (c) 2019 - 2020 Martin Pieuchot <mpi@openbsd.org>
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #include <sys/ioctl.h>
20 #include <sys/exec_elf.h>
21 #include <sys/syscall.h>
22 #include <sys/queue.h>
23 
24 #include <assert.h>
25 #include <err.h>
26 #include <errno.h>
27 #include <fcntl.h>
28 #include <limits.h>
29 #include <locale.h>
30 #include <signal.h>
31 #include <stdarg.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <time.h>
36 #include <unistd.h>
37 
38 #include <dev/dt/dtvar.h>
39 
40 #include "btrace.h"
41 #include "bt_parser.h"
42 
43 #define MINIMUM(a, b)	(((a) < (b)) ? (a) : (b))
44 #define MAXIMUM(a, b)	(((a) > (b)) ? (a) : (b))
45 
46 /*
47  * Maximum number of operands an arithmetic operation can have.  This
48  * is necessary to stop infinite recursion when evaluating expressions.
49  */
50 #define __MAXOPERANDS	5
51 
52 #define __PATH_DEVDT "/dev/dt"
53 
54 __dead void		 usage(void);
55 char			*read_btfile(const char *);
56 
57 /*
58  * Retrieve & parse probe information.
59  */
60 void			 dtpi_cache(int);
61 void			 dtpi_print_list(void);
62 char			*dtpi_func(struct dtioc_probe_info *);
63 int			 dtpi_is_unit(const char *);
64 struct dtioc_probe_info	*dtpi_get_by_value(const char *, const char *,
65 			     const char *);
66 
67 /*
68  * Main loop and rule evaluation.
69  */
70 void			 rules_do(int, int);
71 void			 rules_setup(int, int);
72 void			 rules_apply(struct dt_evt *);
73 void			 rules_teardown(int);
74 void			 rule_eval(struct bt_rule *, struct dt_evt *);
75 void			 rule_printmaps(struct bt_rule *);
76 
77 /*
78  * Language builtins & functions.
79  */
80 uint64_t		 builtin_nsecs(struct dt_evt *);
81 const char		*builtin_kstack(struct dt_evt *);
82 const char		*builtin_arg(struct dt_evt *, enum bt_argtype);
83 void			 stmt_bucketize(struct bt_stmt *, struct dt_evt *);
84 void			 stmt_clear(struct bt_stmt *);
85 void			 stmt_delete(struct bt_stmt *, struct dt_evt *);
86 void			 stmt_insert(struct bt_stmt *, struct dt_evt *);
87 void			 stmt_print(struct bt_stmt *, struct dt_evt *);
88 void			 stmt_store(struct bt_stmt *, struct dt_evt *);
89 void			 stmt_time(struct bt_stmt *, struct dt_evt *);
90 void			 stmt_zero(struct bt_stmt *);
91 struct bt_arg		*ba_read(struct bt_arg *);
92 const char		*ba2hash(struct bt_arg *, struct dt_evt *);
93 const char		*ba2bucket(struct bt_arg *, struct bt_arg *,
94 			     struct dt_evt *, long *);
95 int			 ba2dtflags(struct bt_arg *);
96 
97 /*
98  * Debug routines.
99  */
100 __dead void		 xabort(const char *, ...);
101 void			 debug(const char *, ...);
102 void			 debugx(const char *, ...);
103 const char		*debug_rule_name(struct bt_rule *);
104 void			 debug_dump_filter(struct bt_rule *);
105 void			 debug_dump_rule(struct bt_rule *);
106 
107 struct dtioc_probe_info	*dt_dtpis;	/* array of available probes */
108 size_t			 dt_ndtpi;	/* # of elements in the array */
109 
110 int			 verbose = 0;
111 volatile sig_atomic_t	 quit_pending;
112 
113 static void
114 signal_handler(int sig)
115 {
116 	quit_pending = sig;
117 }
118 
119 
120 int
121 main(int argc, char *argv[])
122 {
123 	int fd = -1, ch, error = 0;
124 	const char *filename = NULL, *btscript = NULL;
125 	const char *errstr;
126 	int showprobes = 0, tracepid = -1;
127 
128 	setlocale(LC_ALL, "");
129 
130 #if notyet
131 	if (pledge("stdio rpath", NULL) == -1)
132 		err(1, "pledge");
133 #endif
134 
135 	while ((ch = getopt(argc, argv, "e:lp:v")) != -1) {
136 		switch (ch) {
137 		case 'e':
138 			btscript = optarg;
139 			break;
140 		case 'l':
141 			showprobes = 1;
142 			break;
143 		case 'p':
144 			if (tracepid != -1)
145 				usage();
146 			tracepid =  strtonum(optarg, 1, INT_MAX, &errstr);
147 			if (errstr != NULL)
148 				errx(1, "invalid pid %s: %s", optarg, errstr);
149 			break;
150 		case 'v':
151 			verbose++;
152 			break;
153 		default:
154 			usage();
155 		}
156 	}
157 
158 	argc -= optind;
159 	argv += optind;
160 
161 	if (argc > 0) {
162 		if (btscript != NULL)
163 			usage();
164 
165 		filename = argv[0];
166 		btscript = read_btfile(filename);
167 		argc--;
168 		argv++;
169 	}
170 
171 	if (argc != 0 || (btscript == NULL && !showprobes))
172 		usage();
173 
174 	if (btscript != NULL) {
175 		error = btparse(btscript, strlen(btscript), filename, 1);
176 		if (error)
177 			return error;
178 	}
179 
180 	if (showprobes || g_nprobes > 0) {
181 		fd = open(__PATH_DEVDT, O_RDONLY);
182 		if (fd == -1)
183 			err(1, "could not open %s", __PATH_DEVDT);
184 	}
185 
186 	if (showprobes) {
187 		dtpi_cache(fd);
188 		dtpi_print_list();
189 	}
190 
191 	if (!TAILQ_EMPTY(&g_rules))
192 		rules_do(fd, tracepid);
193 
194 	if (fd != -1)
195 		close(fd);
196 
197 	return error;
198 }
199 
200 __dead void
201 usage(void)
202 {
203 	fprintf(stderr, "usage: %s [-lv] [-p pid] [-e program|file]\n",
204 	    getprogname());
205 	exit(1);
206 }
207 
208 char *
209 read_btfile(const char *filename)
210 {
211 	static char fcontent[BUFSIZ];
212 	long offset;
213 	FILE *fp;
214 
215 	fp = fopen(filename, "r");
216 	if (fp == NULL)
217 		err(1, "can't open '%s'", filename);
218 
219 	if (fread(fcontent, sizeof(fcontent) - 1, 1, fp) == 0 && errno != 0)
220 		err(1, "can't read '%s'", filename);
221 
222 	fseek(fp, 0, SEEK_END);
223 	offset = ftell(fp);
224 	if ((size_t)offset >= sizeof(fcontent))
225 		errx(1, "couldn't read all of '%s'", filename);
226 
227 	fclose(fp);
228 	return fcontent;
229 }
230 
231 void
232 dtpi_cache(int fd)
233 {
234 	struct dtioc_probe dtpr;
235 
236 	if (dt_dtpis != NULL)
237 		return;
238 
239 	memset(&dtpr, 0, sizeof(dtpr));
240 	if (ioctl(fd, DTIOCGPLIST, &dtpr))
241 		err(1, "DTIOCGPLIST");
242 
243 	dt_ndtpi = (dtpr.dtpr_size / sizeof(*dt_dtpis));
244 	dt_dtpis = reallocarray(NULL, dt_ndtpi, sizeof(*dt_dtpis));
245 	if (dt_dtpis == NULL)
246 		err(1, "malloc");
247 
248 	dtpr.dtpr_probes = dt_dtpis;
249 	if (ioctl(fd, DTIOCGPLIST, &dtpr))
250 		err(1, "DTIOCGPLIST");
251 }
252 
253 void
254 dtpi_print_list(void)
255 {
256 	struct dtioc_probe_info *dtpi;
257 	size_t i;
258 
259 	dtpi = dt_dtpis;
260 	for (i = 0; i < dt_ndtpi; i++, dtpi++) {
261 		printf("%s:%s:%s\n", dtpi->dtpi_prov, dtpi_func(dtpi),
262 		    dtpi->dtpi_name);
263 	}
264 }
265 
266 char *
267 dtpi_func(struct dtioc_probe_info *dtpi)
268 {
269 	char *sysnb, func[DTNAMESIZE];
270 	const char *errstr;
271 	int idx;
272 
273 	if (strncmp(dtpi->dtpi_prov, "syscall", DTNAMESIZE))
274 		return dtpi->dtpi_func;
275 
276 	/* Translate syscall names */
277 	strlcpy(func, dtpi->dtpi_func, sizeof(func));
278 	sysnb = func;
279 	if (strsep(&sysnb, "%") == NULL)
280 		return dtpi->dtpi_func;
281 
282 	idx = strtonum(sysnb, 1, SYS_MAXSYSCALL, &errstr);
283 	if (errstr != NULL)
284 		return dtpi->dtpi_func;
285 
286 	return syscallnames[idx];
287 }
288 
289 int
290 dtpi_is_unit(const char *unit)
291 {
292 	return !strncmp("hz", unit, sizeof("hz"));
293 }
294 
295 struct dtioc_probe_info *
296 dtpi_get_by_value(const char *prov, const char *func, const char *name)
297 {
298 	struct dtioc_probe_info *dtpi;
299 	size_t i;
300 
301 	dtpi = dt_dtpis;
302 	for (i = 0; i < dt_ndtpi; i++, dtpi++) {
303 		if (prov != NULL &&
304 		    strncmp(prov, dtpi->dtpi_prov, DTNAMESIZE))
305 			continue;
306 
307 		if (func != NULL) {
308 			if (dtpi_is_unit(func))
309 				return dtpi;
310 
311 			if (strncmp(func, dtpi_func(dtpi), DTNAMESIZE))
312 				continue;
313 		}
314 
315 		if (strncmp(name, dtpi->dtpi_name, DTNAMESIZE))
316 			continue;
317 
318 		debug("matched probe %s:%s:%s\n", dtpi->dtpi_prov,
319 		    dtpi_func(dtpi), dtpi->dtpi_name);
320 		return dtpi;
321 	}
322 
323 	return NULL;
324 }
325 
326 void
327 rules_do(int fd, int tracepid)
328 {
329 	struct sigaction sa;
330 
331 	memset(&sa, 0, sizeof(sa));
332 	sigemptyset(&sa.sa_mask);
333 	sa.sa_flags = 0;
334 	sa.sa_handler = signal_handler;
335 	if (sigaction(SIGINT, &sa, NULL))
336 		err(1, "sigaction");
337 
338 	rules_setup(fd, tracepid);
339 
340 	while (!quit_pending && g_nprobes > 0) {
341 		static struct dt_evt devtbuf[64];
342 		ssize_t rlen;
343 		size_t i;
344 
345 		rlen = read(fd, devtbuf, sizeof(devtbuf) - 1);
346 		if (rlen == -1) {
347 			if (errno == EINTR && quit_pending) {
348 				printf("\n");
349 				break;
350 			}
351 			err(1, "read");
352 		}
353 
354 		if ((rlen % sizeof(struct dt_evt)) != 0)
355 			err(1, "incorrect read");
356 
357 		for (i = 0; i < rlen / sizeof(struct dt_evt); i++)
358 			rules_apply(&devtbuf[i]);
359 	}
360 
361 	rules_teardown(fd);
362 
363 	if (verbose && fd != -1) {
364 		struct dtioc_stat dtst;
365 
366 		memset(&dtst, 0, sizeof(dtst));
367 		if (ioctl(fd, DTIOCGSTATS, &dtst))
368 			warn("DTIOCGSTATS");
369 
370 		printf("%llu events read\n", dtst.dtst_readevt);
371 		printf("%llu events dropped\n", dtst.dtst_dropevt);
372 	}
373 }
374 
375 static inline enum dt_operand
376 dop2dt(enum bt_operand op)
377 {
378 	switch (op) {
379 	case B_OP_EQ:	return DT_OP_EQ;
380 	case B_OP_NE:	return DT_OP_NE;
381 	case B_OP_NONE:	return DT_OP_NONE;
382 	default:	break;
383 	}
384 	xabort("unknown operand %d", op);
385 }
386 
387 
388 static inline enum dt_filtervar
389 dvar2dt(enum bt_filtervar var)
390 {
391 	switch (var) {
392 	case B_FV_PID:	return DT_FV_PID;
393 	case B_FV_TID:	return DT_FV_TID;
394 	case B_FV_NONE:	return DT_FV_NONE;
395 	default:	break;
396 	}
397 	xabort("unknown filter %d", var);
398 }
399 
400 
401 void
402 rules_setup(int fd, int tracepid)
403 {
404 	struct dtioc_probe_info *dtpi;
405 	struct dtioc_req *dtrq;
406 	struct bt_rule *r, *rbegin = NULL;
407 	struct bt_probe *bp;
408 	struct bt_stmt *bs;
409 	int dokstack = 0, on = 1;
410 
411 	TAILQ_FOREACH(r, &g_rules, br_next) {
412 		debug_dump_rule(r);
413 
414 		if (r->br_type != B_RT_PROBE) {
415 			if (r->br_type == B_RT_BEGIN)
416 				rbegin = r;
417 			continue;
418 		}
419 
420 		bp = r->br_probe;
421 		dtpi_cache(fd);
422 		dtpi = dtpi_get_by_value(bp->bp_prov, bp->bp_func, bp->bp_name);
423 		if (dtpi == NULL) {
424 			errx(1, "probe '%s:%s:%s' not found", bp->bp_prov,
425 			    bp->bp_func, bp->bp_name);
426 		}
427 
428 		dtrq = calloc(1, sizeof(*dtrq));
429 		if (dtrq == NULL)
430 			err(1, "dtrq: 1alloc");
431 
432 		r->br_pbn = dtpi->dtpi_pbn;
433 		dtrq->dtrq_pbn = dtpi->dtpi_pbn;
434 		if (r->br_filter) {
435 			struct bt_filter *df = r->br_filter;
436 
437 			dtrq->dtrq_filter.dtf_operand = dop2dt(df->bf_op);
438 			dtrq->dtrq_filter.dtf_variable = dvar2dt(df->bf_var);
439 			dtrq->dtrq_filter.dtf_value = df->bf_val;
440 		} else if (tracepid != -1) {
441 			dtrq->dtrq_filter.dtf_operand = DT_OP_EQ;
442 			dtrq->dtrq_filter.dtf_variable = DT_FV_PID;
443 			dtrq->dtrq_filter.dtf_value = tracepid;
444 		}
445 		dtrq->dtrq_rate = r->br_probe->bp_rate;
446 
447 		SLIST_FOREACH(bs, &r->br_action, bs_next) {
448 			struct bt_arg *ba;
449 
450 			SLIST_FOREACH(ba, &bs->bs_args, ba_next)
451 				dtrq->dtrq_evtflags |= ba2dtflags(ba);
452 		}
453 
454 		if (dtrq->dtrq_evtflags & DTEVT_KSTACK)
455 			dokstack = 1;
456 		r->br_cookie = dtrq;
457 	}
458 
459 	if (dokstack)
460 		kelf_open();
461 
462 	if (rbegin)
463 		rule_eval(rbegin, NULL);
464 
465 	/* Enable all probes */
466 	TAILQ_FOREACH(r, &g_rules, br_next) {
467 		if (r->br_type != B_RT_PROBE)
468 			continue;
469 
470 		dtrq = r->br_cookie;
471 		if (ioctl(fd, DTIOCPRBENABLE, dtrq))
472 			err(1, "DTIOCPRBENABLE");
473 	}
474 
475 	if (g_nprobes > 0) {
476 		if (ioctl(fd, DTIOCRECORD, &on))
477 			err(1, "DTIOCRECORD");
478 	}
479 }
480 
481 void
482 rules_apply(struct dt_evt *dtev)
483 {
484 	struct bt_rule *r;
485 
486 	TAILQ_FOREACH(r, &g_rules, br_next) {
487 		if (r->br_type != B_RT_PROBE || r->br_pbn != dtev->dtev_pbn)
488 			continue;
489 
490 		rule_eval(r, dtev);
491 	}
492 }
493 
494 void
495 rules_teardown(int fd)
496 {
497 	struct dtioc_req *dtrq;
498 	struct bt_rule *r, *rend = NULL;
499 	int dokstack = 0, off = 0;
500 
501 	if (g_nprobes > 0) {
502 		if (ioctl(fd, DTIOCRECORD, &off))
503 			err(1, "DTIOCRECORD");
504 	}
505 
506 	TAILQ_FOREACH(r, &g_rules, br_next) {
507 		if (r->br_type != B_RT_PROBE) {
508 			if (r->br_type == B_RT_END)
509 				rend = r;
510 			continue;
511 		}
512 
513 		dtrq = r->br_cookie;
514 		if (dtrq->dtrq_evtflags & DTEVT_KSTACK)
515 			dokstack = 1;
516 	}
517 
518 	if (dokstack)
519 		kelf_close();
520 
521 	if (rend)
522 		rule_eval(rend, NULL);
523 	else {
524 		TAILQ_FOREACH(r, &g_rules, br_next)
525 			rule_printmaps(r);
526 	}
527 }
528 
529 void
530 rule_eval(struct bt_rule *r, struct dt_evt *dtev)
531 {
532 	struct bt_stmt *bs;
533 
534 	debug("eval rule '%s'\n", debug_rule_name(r));
535 
536 	SLIST_FOREACH(bs, &r->br_action, bs_next) {
537 		switch (bs->bs_act) {
538 		case B_AC_BUCKETIZE:
539 			stmt_bucketize(bs, dtev);
540 			break;
541 		case B_AC_CLEAR:
542 			stmt_clear(bs);
543 			break;
544 		case B_AC_DELETE:
545 			stmt_delete(bs, dtev);
546 			break;
547 		case B_AC_EXIT:
548 			exit(0);
549 			break;
550 		case B_AC_INSERT:
551 			stmt_insert(bs, dtev);
552 			break;
553 		case B_AC_PRINT:
554 			stmt_print(bs, dtev);
555 			break;
556 		case B_AC_PRINTF:
557 			stmt_printf(bs, dtev);
558 			break;
559 		case B_AC_STORE:
560 			stmt_store(bs, dtev);
561 			break;
562 		case B_AC_TIME:
563 			stmt_time(bs, dtev);
564 			break;
565 		case B_AC_ZERO:
566 			stmt_zero(bs);
567 			break;
568 		default:
569 			xabort("no handler for action type %d", bs->bs_act);
570 		}
571 	}
572 }
573 
574 void
575 rule_printmaps(struct bt_rule *r)
576 {
577 	struct bt_stmt *bs;
578 
579 	SLIST_FOREACH(bs, &r->br_action, bs_next) {
580 		struct bt_arg *ba;
581 
582 		SLIST_FOREACH(ba, &bs->bs_args, ba_next) {
583 			struct bt_var *bv = ba->ba_value;
584 
585 			if (ba->ba_type != B_AT_MAP && ba->ba_type != B_AT_HIST)
586 				continue;
587 
588 			if (bv->bv_value != NULL) {
589 				struct map *map = (struct map *)bv->bv_value;
590 
591 				if (ba->ba_type == B_AT_MAP)
592 					map_print(map, SIZE_T_MAX, bv_name(bv));
593 				else
594 					hist_print((struct hist *)map, bv_name(bv));
595 				map_clear(map);
596 				bv->bv_value = NULL;
597 			}
598 		}
599 	}
600 }
601 
602 time_t
603 builtin_gettime(struct dt_evt *dtev)
604 {
605 	struct timespec ts;
606 
607 	if (dtev == NULL) {
608 		clock_gettime(CLOCK_REALTIME, &ts);
609 		return ts.tv_sec;
610 	}
611 
612 	return dtev->dtev_tsp.tv_sec;
613 }
614 
615 static inline uint64_t
616 TIMESPEC_TO_NSEC(struct timespec *ts)
617 {
618 	return (ts->tv_sec * 1000000000L + ts->tv_nsec);
619 }
620 
621 uint64_t
622 builtin_nsecs(struct dt_evt *dtev)
623 {
624 	struct timespec ts;
625 
626 	if (dtev == NULL) {
627 		clock_gettime(CLOCK_REALTIME, &ts);
628 		return TIMESPEC_TO_NSEC(&ts);
629 	}
630 
631 	return TIMESPEC_TO_NSEC(&dtev->dtev_tsp);
632 }
633 
634 const char *
635 builtin_stack(struct dt_evt *dtev, int kernel)
636 {
637 	struct stacktrace *st = &dtev->dtev_kstack;
638 	static char buf[4096], *bp;
639 	size_t i;
640 	int sz;
641 
642 	if (!kernel || st->st_count == 0)
643 		return "";
644 
645 	buf[0] = '\0';
646 	bp = buf;
647 	sz = sizeof(buf);
648 	for (i = 0; i < st->st_count; i++) {
649 		int l;
650 
651 		l = kelf_snprintsym(bp, sz - 1, st->st_pc[i]);
652 		if (l < 0)
653 			break;
654 		if (l >= sz - 1) {
655 			bp += sz - 1;
656 			sz = 1;
657 			break;
658 		}
659 		bp += l;
660 		sz -= l;
661 	}
662 	snprintf(bp, sz, "\n");
663 
664 	return buf;
665 }
666 
667 const char *
668 builtin_arg(struct dt_evt *dtev, enum bt_argtype dat)
669 {
670 	static char buf[sizeof("18446744073709551615")]; /* UINT64_MAX */
671 
672 	snprintf(buf, sizeof(buf), "%lu",
673 	    dtev->dtev_sysargs[dat - B_AT_BI_ARG0]);
674 
675 	return buf;
676 }
677 
678 /*
679  * Increment a bucket:	{ @h = hist(v); } or { @h = lhist(v, min, max, step); }
680  *
681  * In this case 'h' is represented by `bv' and '(min, max, step)' by `brange'.
682  */
683 void
684 stmt_bucketize(struct bt_stmt *bs, struct dt_evt *dtev)
685 {
686 	struct bt_arg *brange, *bhist = SLIST_FIRST(&bs->bs_args);
687 	struct bt_arg *bval = (struct bt_arg *)bs->bs_var;
688 	struct bt_var *bv = bhist->ba_value;
689 	const char *bucket;
690 	long step = 0;
691 
692 	assert(bhist->ba_type == B_AT_HIST);
693 	assert(SLIST_NEXT(bval, ba_next) == NULL);
694 
695 	brange = bhist->ba_key;
696 	bucket = ba2bucket(bval, brange, dtev, &step);
697 	if (bucket == NULL) {
698 		debug("hist=%p '%s' value=%lu out of range\n", bv->bv_value,
699 		    bv_name(bv), ba2long(bval, dtev));
700 		return;
701 	}
702 	debug("hist=%p '%s' increment bucket=%s\n", bv->bv_value,
703 	    bv_name(bv), bucket);
704 
705 	bv->bv_value = (struct bt_arg *)
706 	    hist_increment((struct hist *)bv->bv_value, bucket, step);
707 }
708 
709 
710 /*
711  * Empty a map:		{ clear(@map); }
712  */
713 void
714 stmt_clear(struct bt_stmt *bs)
715 {
716 	struct bt_arg *ba = SLIST_FIRST(&bs->bs_args);
717 	struct bt_var *bv = ba->ba_value;
718 
719 	assert(bs->bs_var == NULL);
720 	assert(ba->ba_type == B_AT_VAR);
721 
722 	map_clear((struct map *)bv->bv_value);
723 	bv->bv_value = NULL;
724 
725 	debug("map=%p '%s' clear\n", bv->bv_value, bv_name(bv));
726 }
727 
728 /*
729  * Map delete:	 	{ delete(@map[key]); }
730  *
731  * In this case 'map' is represented by `bv' and 'key' by `bkey'.
732  */
733 void
734 stmt_delete(struct bt_stmt *bs, struct dt_evt *dtev)
735 {
736 	struct bt_arg *bkey, *bmap = SLIST_FIRST(&bs->bs_args);
737 	struct bt_var *bv = bmap->ba_value;
738 	const char *hash;
739 
740 	assert(bmap->ba_type == B_AT_MAP);
741 	assert(bs->bs_var == NULL);
742 
743 	bkey = bmap->ba_key;
744 	hash = ba2hash(bkey, dtev);
745 	debug("map=%p '%s' delete key=%p '%s'\n", bv->bv_value, bv_name(bv),
746 	    bkey, hash);
747 
748 	map_delete((struct map *)bv->bv_value, hash);
749 }
750 
751 /*
752  * Map insert:	 	{ @map[key] = 42; }
753  *
754  * In this case 'map' is represented by `bv', 'key' by `bkey' and
755  * '42' by `bval'.
756  */
757 void
758 stmt_insert(struct bt_stmt *bs, struct dt_evt *dtev)
759 {
760 	struct bt_arg *bkey, *bmap = SLIST_FIRST(&bs->bs_args);
761 	struct bt_arg *bval = (struct bt_arg *)bs->bs_var;
762 	struct bt_var *bv = bmap->ba_value;
763 	const char *hash;
764 
765 	assert(bmap->ba_type == B_AT_MAP);
766 	assert(SLIST_NEXT(bval, ba_next) == NULL);
767 
768 	bkey = bmap->ba_key;
769 	hash = ba2hash(bkey, dtev);
770 	debug("map=%p '%s' insert key=%p '%s' bval=%p\n", bv->bv_value,
771 	    bv_name(bv), bkey, hash, bval);
772 
773 	bv->bv_value = (struct bt_arg *)map_insert((struct map *)bv->bv_value,
774 	    hash, bval, dtev);
775 }
776 
777 /*
778  * Print map entries:	{ print(@map[, 8]); }
779  *
780  * In this case the global variable 'map' is pointed at by `ba'
781  * and '8' is represented by `btop'.
782  */
783 void
784 stmt_print(struct bt_stmt *bs, struct dt_evt *dtev)
785 {
786 	struct bt_arg *btop, *ba = SLIST_FIRST(&bs->bs_args);
787 	struct bt_var *bv = ba->ba_value;
788 	size_t top = SIZE_T_MAX;
789 
790 	assert(bs->bs_var == NULL);
791 	assert(ba->ba_type == B_AT_VAR);
792 
793 	/* Parse optional `top' argument. */
794 	btop = SLIST_NEXT(ba, ba_next);
795 	if (btop != NULL) {
796 		assert(SLIST_NEXT(btop, ba_next) == NULL);
797 		top = ba2long(btop, dtev);
798 	}
799 	debug("map=%p '%s' print (top=%d)\n", bv->bv_value, bv_name(bv), top);
800 
801 	map_print((struct map *)bv->bv_value, top, bv_name(bv));
802 }
803 
804 /*
805  * Variable store: 	{ var = 3; }
806  *
807  * In this case '3' is represented by `ba', the argument of a STORE
808  * action.
809  *
810  * If the argument depends of the value of an event (builtin) or is
811  * the result of an operation, its evaluation is stored in a new `ba'.
812  */
813 void
814 stmt_store(struct bt_stmt *bs, struct dt_evt *dtev)
815 {
816 	struct bt_arg *ba = SLIST_FIRST(&bs->bs_args);
817 	struct bt_var *bv = bs->bs_var;
818 
819 	assert(SLIST_NEXT(ba, ba_next) == NULL);
820 
821 	switch (ba->ba_type) {
822 	case B_AT_LONG:
823 		bv->bv_value = ba;
824 		break;
825 	case B_AT_BI_NSECS:
826 		bv->bv_value = ba_new(builtin_nsecs(dtev), B_AT_LONG);
827 		break;
828 	case B_AT_OP_ADD ... B_AT_OP_OR:
829 		bv->bv_value = ba_new(ba2long(ba, dtev), B_AT_LONG);
830 		break;
831 	default:
832 		xabort("store not implemented for type %d", ba->ba_type);
833 	}
834 
835 	debug("bv=%p var '%s' store (%p) \n", bv, bv_name(bv), bv->bv_value);
836 }
837 
838 /*
839  * Print time: 		{ time("%H:%M:%S"); }
840  */
841 void
842 stmt_time(struct bt_stmt *bs, struct dt_evt *dtev)
843 {
844 	struct bt_arg *ba = SLIST_FIRST(&bs->bs_args);
845 	time_t time;
846 	struct tm *tm;
847 	char buf[64];
848 
849 	assert(bs->bs_var == NULL);
850 	assert(ba->ba_type == B_AT_STR);
851 	assert(strlen(ba2str(ba, dtev)) < (sizeof(buf) - 1));
852 
853 	time = builtin_gettime(dtev);
854 	tm = localtime(&time);
855 	strftime(buf, sizeof(buf), ba2str(ba, dtev), tm);
856 	printf("%s", buf);
857 }
858 
859 /*
860  * Set entries to 0:	{ zero(@map); }
861  */
862 void
863 stmt_zero(struct bt_stmt *bs)
864 {
865 	struct bt_arg *ba = SLIST_FIRST(&bs->bs_args);
866 	struct bt_var *bv = ba->ba_value;
867 
868 	assert(bs->bs_var == NULL);
869 	assert(ba->ba_type == B_AT_VAR);
870 
871 	map_zero((struct map *)bv->bv_value);
872 
873 	debug("map=%p '%s' zero\n", bv->bv_value, bv_name(bv));
874 }
875 
876 struct bt_arg *
877 ba_read(struct bt_arg *ba)
878 {
879 	struct bt_var *bv = ba->ba_value;
880 
881 	assert(ba->ba_type == B_AT_VAR);
882 
883 	debug("bv=%p read '%s' (%p)\n", bv, bv_name(bv), bv->bv_value);
884 
885 	return bv->bv_value;
886 }
887 
888 const char *
889 ba2hash(struct bt_arg *ba, struct dt_evt *dtev)
890 {
891 	static char buf[KLEN];
892 	char *hash;
893 	int l, len;
894 
895 	buf[0] = '\0';
896 	l = snprintf(buf, sizeof(buf), "%s", ba2str(ba, dtev));
897 	if (l < 0 || (size_t)l > sizeof(buf)) {
898 		warn("string too long %d > %lu", l, sizeof(buf));
899 		return buf;
900 	}
901 
902 	len = 0;
903 	while ((ba = SLIST_NEXT(ba, ba_next)) != NULL) {
904 		len += l;
905 		hash = buf + len;
906 
907 		l = snprintf(hash, sizeof(buf) - len, ", %s", ba2str(ba, dtev));
908 		if (l < 0 || (size_t)l > (sizeof(buf) - len)) {
909 			warn("hash too long %d > %lu", l + len, sizeof(buf));
910 			break;
911 		}
912 	}
913 
914 	return buf;
915 }
916 
917 static unsigned long
918 next_pow2(unsigned long x)
919 {
920 	size_t i;
921 
922 	x--;
923 	for (i = 0; i < (sizeof(x)  * 8) - 1; i++)
924 		x |= (x >> 1);
925 
926 	return x + 1;
927 }
928 
929 /*
930  * Return the ceiling value the interval holding `ba' or NULL if it is
931  * out of the (min, max) values.
932  */
933 const char *
934 ba2bucket(struct bt_arg *ba, struct bt_arg *brange, struct dt_evt *dtev,
935     long *pstep)
936 {
937 	static char buf[KLEN];
938 	long val, bucket;
939 	int l;
940 
941 	val = ba2long(ba, dtev);
942 	if (brange == NULL)
943 		bucket = next_pow2(val);
944 	else {
945 		long min, max, step;
946 
947 		assert(brange->ba_type == B_AT_LONG);
948 		min = ba2long(brange, NULL);
949 
950 		brange = SLIST_NEXT(brange, ba_next);
951 		assert(brange->ba_type == B_AT_LONG);
952 		max = ba2long(brange, NULL);
953 
954 		if ((val < min) || (val > max))
955 			return NULL;
956 
957 		brange = SLIST_NEXT(brange, ba_next);
958 		assert(brange->ba_type == B_AT_LONG);
959 		step = ba2long(brange, NULL);
960 
961 		bucket = ((val / step) + 1) * step;
962 		*pstep = step;
963 	}
964 
965 	buf[0] = '\0';
966 	l = snprintf(buf, sizeof(buf), "%lu", bucket);
967 	if (l < 0 || (size_t)l > sizeof(buf)) {
968 		warn("string too long %d > %lu", l, sizeof(buf));
969 		return buf;
970 	}
971 
972 	return buf;
973 }
974 
975 /*
976  * Helper to evaluate the operation encoded in `ba' and return its
977  * result.
978  */
979 static inline long
980 baexpr2long(struct bt_arg *ba, struct dt_evt *dtev)
981 {
982 	static long recursions;
983 	struct bt_arg *a, *b;
984 	long first, second, result;
985 
986 	if (++recursions >= __MAXOPERANDS)
987 		errx(1, "too many operands (>%d) in expression", __MAXOPERANDS);
988 
989 	a = ba->ba_value;
990 	b = SLIST_NEXT(a, ba_next);
991 
992 	assert(SLIST_NEXT(b, ba_next) == NULL);
993 
994 	first = ba2long(a, dtev);
995 	second = ba2long(b, dtev);
996 
997 	switch (ba->ba_type) {
998 	case B_AT_OP_ADD:
999 		result = first + second;
1000 		break;
1001 	case B_AT_OP_MINUS:
1002 		result = first - second;
1003 		break;
1004 	case B_AT_OP_MULT:
1005 		result = first * second;
1006 		break;
1007 	case B_AT_OP_DIVIDE:
1008 		result = first / second;
1009 		break;
1010 	case B_AT_OP_AND:
1011 		result = first & second;
1012 		break;
1013 	case B_AT_OP_OR:
1014 		result = first | second;
1015 		break;
1016 	default:
1017 		xabort("unsuported operation %d", ba->ba_type);
1018 	}
1019 
1020 	debug("ba=%p (%ld op %ld) = %ld\n", ba, first, second, result);
1021 
1022 	--recursions;
1023 
1024 	return result;
1025 }
1026 
1027 /*
1028  * Return the representation of `ba' as long.
1029  */
1030 long
1031 ba2long(struct bt_arg *ba, struct dt_evt *dtev)
1032 {
1033 	long val;
1034 
1035 	switch (ba->ba_type) {
1036 	case B_AT_LONG:
1037 		val = (long)ba->ba_value;
1038 		break;
1039 	case B_AT_VAR:
1040 		ba = ba_read(ba);
1041 		val = (long)ba->ba_value;
1042 		break;
1043 	case B_AT_BI_NSECS:
1044 		val = builtin_nsecs(dtev);
1045 		break;
1046 	case B_AT_BI_RETVAL:
1047 		val = dtev->dtev_sysretval[0];
1048 		break;
1049 	case B_AT_OP_ADD ... B_AT_OP_OR:
1050 		val = baexpr2long(ba, dtev);
1051 		break;
1052 	default:
1053 		xabort("no long conversion for type %d", ba->ba_type);
1054 	}
1055 
1056 	return  val;
1057 }
1058 
1059 /*
1060  * Return the representation of `ba' as string.
1061  */
1062 const char *
1063 ba2str(struct bt_arg *ba, struct dt_evt *dtev)
1064 {
1065 	static char buf[sizeof("18446744073709551615")]; /* UINT64_MAX */
1066 	struct bt_var *bv;
1067 	const char *str;
1068 
1069 	buf[0] = '\0';
1070 	switch (ba->ba_type) {
1071 	case B_AT_STR:
1072 		str = (const char *)ba->ba_value;
1073 		break;
1074 	case B_AT_LONG:
1075 		snprintf(buf, sizeof(buf), "%ld",(long)ba->ba_value);
1076 		str = buf;
1077 		break;
1078 	case B_AT_BI_KSTACK:
1079 		str = builtin_stack(dtev, 1);
1080 		break;
1081 	case B_AT_BI_USTACK:
1082 		str = builtin_stack(dtev, 0);
1083 		break;
1084 	case B_AT_BI_COMM:
1085 		str = dtev->dtev_comm;
1086 		break;
1087 	case B_AT_BI_CPU:
1088 		snprintf(buf, sizeof(buf), "%u", dtev->dtev_cpu);
1089 		str = buf;
1090 		break;
1091 	case B_AT_BI_PID:
1092 		snprintf(buf, sizeof(buf), "%d", dtev->dtev_pid);
1093 		str = buf;
1094 		break;
1095 	case B_AT_BI_TID:
1096 		snprintf(buf, sizeof(buf), "%d", dtev->dtev_tid);
1097 		str = buf;
1098 		break;
1099 	case B_AT_BI_NSECS:
1100 		snprintf(buf, sizeof(buf), "%llu", builtin_nsecs(dtev));
1101 		str = buf;
1102 		break;
1103 	case B_AT_BI_ARG0 ... B_AT_BI_ARG9:
1104 		str = builtin_arg(dtev, ba->ba_type);
1105 		break;
1106 	case B_AT_BI_RETVAL:
1107 		snprintf(buf, sizeof(buf), "%ld", (long)dtev->dtev_sysretval[0]);
1108 		str = buf;
1109 		break;
1110 	case B_AT_MAP:
1111 		bv = ba->ba_value;
1112 		str = ba2str(map_get((struct map *)bv->bv_value,
1113 		    ba2str(ba->ba_key, dtev)), dtev);
1114 		break;
1115 	case B_AT_VAR:
1116 		str = ba2str(ba_read(ba), dtev);
1117 		break;
1118 	case B_AT_OP_ADD ... B_AT_OP_OR:
1119 		snprintf(buf, sizeof(buf), "%ld", ba2long(ba, dtev));
1120 		str = buf;
1121 		break;
1122 	case B_AT_MF_COUNT:
1123 	case B_AT_MF_MAX:
1124 	case B_AT_MF_MIN:
1125 	case B_AT_MF_SUM:
1126 		assert(0);
1127 		break;
1128 	default:
1129 		xabort("no string conversion for type %d", ba->ba_type);
1130 	}
1131 
1132 	return str;
1133 }
1134 
1135 /*
1136  * Return dt(4) flags indicating which data should be recorded by the
1137  * kernel, if any, for a given `ba'.
1138  */
1139 int
1140 ba2dtflags(struct bt_arg *ba)
1141 {
1142 	int flags = 0;
1143 
1144 	if (ba->ba_type == B_AT_MAP)
1145 		ba = ba->ba_key;
1146 
1147 	do {
1148 		switch (ba->ba_type) {
1149 		case B_AT_STR:
1150 		case B_AT_LONG:
1151 		case B_AT_VAR:
1152 	    	case B_AT_HIST:
1153 			break;
1154 		case B_AT_BI_KSTACK:
1155 			flags |= DTEVT_KSTACK;
1156 			break;
1157 		case B_AT_BI_USTACK:
1158 			flags |= DTEVT_USTACK;
1159 			break;
1160 		case B_AT_BI_COMM:
1161 			flags |= DTEVT_EXECNAME;
1162 			break;
1163 		case B_AT_BI_CPU:
1164 		case B_AT_BI_PID:
1165 		case B_AT_BI_TID:
1166 		case B_AT_BI_NSECS:
1167 			break;
1168 		case B_AT_BI_ARG0 ... B_AT_BI_ARG9:
1169 			flags |= DTEVT_FUNCARGS;
1170 			break;
1171 		case B_AT_BI_RETVAL:
1172 			break;
1173 		case B_AT_MF_COUNT:
1174 		case B_AT_MF_MAX:
1175 		case B_AT_MF_MIN:
1176 		case B_AT_MF_SUM:
1177 		case B_AT_OP_ADD ... B_AT_OP_OR:
1178 			break;
1179 		default:
1180 			xabort("invalid argument type %d", ba->ba_type);
1181 		}
1182 	} while ((ba = SLIST_NEXT(ba, ba_next)) != NULL);
1183 
1184 	return flags;
1185 }
1186 
1187 long
1188 bacmp(struct bt_arg *a, struct bt_arg *b)
1189 {
1190 	assert(a->ba_type == b->ba_type);
1191 	assert(a->ba_type == B_AT_LONG);
1192 
1193 	return ba2long(a, NULL) - ba2long(b, NULL);
1194 }
1195 
1196 __dead void
1197 xabort(const char *fmt, ...)
1198 {
1199 	va_list ap;
1200 
1201 	va_start(ap, fmt);
1202 	vfprintf(stderr, fmt, ap);
1203 	va_end(ap);
1204 
1205 	fprintf(stderr, "\n");
1206 	abort();
1207 }
1208 
1209 void
1210 debug(const char *fmt, ...)
1211 {
1212 	va_list ap;
1213 
1214 	if (verbose < 2)
1215 		return;
1216 
1217 	fprintf(stderr, "debug: ");
1218 
1219 	va_start(ap, fmt);
1220 	vfprintf(stderr, fmt, ap);
1221 	va_end(ap);
1222 }
1223 
1224 void
1225 debugx(const char *fmt, ...)
1226 {
1227 	va_list ap;
1228 
1229 	if (verbose < 2)
1230 		return;
1231 
1232 	va_start(ap, fmt);
1233 	vfprintf(stderr, fmt, ap);
1234 	va_end(ap);
1235 }
1236 
1237 static inline const char *
1238 debug_getfiltervar(struct bt_filter *df)
1239 {
1240 	switch (df->bf_var) {
1241 	case B_FV_PID:	return "pid";
1242 	case B_FV_TID:	return "tid";
1243 	case B_FV_NONE:	return "";
1244 	default:
1245 		xabort("invalid filtervar %d", df->bf_var);
1246 	}
1247 
1248 
1249 }
1250 
1251 static inline const char *
1252 debug_getfilterop(struct bt_filter *df)
1253 {
1254 	switch (df->bf_op) {
1255 	case B_OP_EQ:	return "==";
1256 	case B_OP_NE:	return "!=";
1257 	case B_OP_NONE:	return "";
1258 	default:
1259 		xabort("invalid operand %d", df->bf_op);
1260 	}
1261 }
1262 
1263 void
1264 debug_dump_filter(struct bt_rule *r)
1265 {
1266 	if (r->br_filter) {
1267 		debugx(" / %s %s %u /", debug_getfiltervar(r->br_filter),
1268 		    debug_getfilterop(r->br_filter), r->br_filter->bf_val);
1269 	}
1270 	debugx("\n");
1271 }
1272 
1273 const char *
1274 debug_rule_name(struct bt_rule *r)
1275 {
1276 	struct bt_probe *bp = r->br_probe;
1277 	static char buf[64];
1278 
1279 	if (r->br_type == B_RT_BEGIN)
1280 		return "BEGIN";
1281 
1282 	if (r->br_type == B_RT_END)
1283 		return "END";
1284 
1285 	assert(r->br_type == B_RT_PROBE);
1286 
1287 	if (r->br_probe->bp_rate) {
1288 		snprintf(buf, sizeof(buf), "%s:%s:%u", bp->bp_prov,
1289 		    bp->bp_unit, bp->bp_rate);
1290 	} else {
1291 		snprintf(buf, sizeof(buf), "%s:%s:%s", bp->bp_prov,
1292 		    bp->bp_unit, bp->bp_name);
1293 	}
1294 
1295 	return buf;
1296 }
1297 
1298 void
1299 debug_dump_rule(struct bt_rule *r)
1300 {
1301 	debug("parsed probe '%s'", debug_rule_name(r));
1302 	debug_dump_filter(r);
1303 }
1304