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