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