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