1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 * 21 * Portions Copyright 2006-2008 John Birrell jb@freebsd.org 22 * 23 * $FreeBSD$ 24 * 25 */ 26 27 /* 28 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 29 * Use is subject to license terms. 30 */ 31 32 #include <sys/cdefs.h> 33 #include <sys/param.h> 34 #include <sys/systm.h> 35 #include <sys/conf.h> 36 #include <sys/cpuvar.h> 37 #include <sys/endian.h> 38 #include <sys/fcntl.h> 39 #include <sys/filio.h> 40 #include <sys/kdb.h> 41 #include <sys/kernel.h> 42 #include <sys/kmem.h> 43 #include <sys/kthread.h> 44 #include <sys/limits.h> 45 #include <sys/linker.h> 46 #include <sys/lock.h> 47 #include <sys/malloc.h> 48 #include <sys/module.h> 49 #include <sys/mutex.h> 50 #include <sys/pcpu.h> 51 #include <sys/poll.h> 52 #include <sys/proc.h> 53 #include <sys/selinfo.h> 54 #include <sys/smp.h> 55 #include <sys/syscall.h> 56 #include <sys/sysent.h> 57 #include <sys/sysproto.h> 58 #include <sys/uio.h> 59 #include <sys/unistd.h> 60 #include <machine/stdarg.h> 61 62 #include <sys/dtrace.h> 63 #include <sys/dtrace_bsd.h> 64 65 #include "fbt.h" 66 67 MALLOC_DEFINE(M_FBT, "fbt", "Function Boundary Tracing"); 68 69 dtrace_provider_id_t fbt_id; 70 fbt_probe_t **fbt_probetab; 71 int fbt_probetab_mask; 72 73 static d_open_t fbt_open; 74 static int fbt_unload(void); 75 static void fbt_getargdesc(void *, dtrace_id_t, void *, dtrace_argdesc_t *); 76 static void fbt_provide_module(void *, modctl_t *); 77 static void fbt_destroy(void *, dtrace_id_t, void *); 78 static void fbt_enable(void *, dtrace_id_t, void *); 79 static void fbt_disable(void *, dtrace_id_t, void *); 80 static void fbt_load(void *); 81 static void fbt_suspend(void *, dtrace_id_t, void *); 82 static void fbt_resume(void *, dtrace_id_t, void *); 83 84 static struct cdevsw fbt_cdevsw = { 85 .d_version = D_VERSION, 86 .d_open = fbt_open, 87 .d_name = "fbt", 88 }; 89 90 static dtrace_pattr_t fbt_attr = { 91 { DTRACE_STABILITY_EVOLVING, DTRACE_STABILITY_EVOLVING, DTRACE_CLASS_COMMON }, 92 { DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_UNKNOWN }, 93 { DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_ISA }, 94 { DTRACE_STABILITY_EVOLVING, DTRACE_STABILITY_EVOLVING, DTRACE_CLASS_COMMON }, 95 { DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_ISA }, 96 }; 97 98 static dtrace_pops_t fbt_pops = { 99 .dtps_provide = NULL, 100 .dtps_provide_module = fbt_provide_module, 101 .dtps_enable = fbt_enable, 102 .dtps_disable = fbt_disable, 103 .dtps_suspend = fbt_suspend, 104 .dtps_resume = fbt_resume, 105 .dtps_getargdesc = fbt_getargdesc, 106 .dtps_getargval = NULL, 107 .dtps_usermode = NULL, 108 .dtps_destroy = fbt_destroy 109 }; 110 111 static struct cdev *fbt_cdev; 112 static int fbt_probetab_size; 113 static int fbt_verbose = 0; 114 115 int 116 fbt_excluded(const char *name) 117 { 118 119 if (strncmp(name, "dtrace_", 7) == 0 && 120 strncmp(name, "dtrace_safe_", 12) != 0) { 121 /* 122 * Anything beginning with "dtrace_" may be called 123 * from probe context unless it explicitly indicates 124 * that it won't be called from probe context by 125 * using the prefix "dtrace_safe_". 126 */ 127 return (1); 128 } 129 130 /* 131 * Omit instrumentation of functions that are probably in DDB. It 132 * makes it too hard to debug broken FBT. 133 * 134 * NB: kdb_enter() can be excluded, but its call to printf() can't be. 135 * This is generally OK since we're not yet in debugging context. 136 */ 137 if (strncmp(name, "db_", 3) == 0 || 138 strncmp(name, "kdb_", 4) == 0) 139 return (1); 140 141 /* 142 * Lock owner methods may be called from probe context. 143 */ 144 if (strcmp(name, "owner_mtx") == 0 || 145 strcmp(name, "owner_rm") == 0 || 146 strcmp(name, "owner_rw") == 0 || 147 strcmp(name, "owner_sx") == 0) 148 return (1); 149 150 /* 151 * Stack unwinders may be called from probe context on some 152 * platforms. 153 */ 154 #if defined(__aarch64__) || defined(__riscv) 155 if (strcmp(name, "unwind_frame") == 0) 156 return (1); 157 #endif 158 159 /* 160 * When DTrace is built into the kernel we need to exclude 161 * the FBT functions from instrumentation. 162 */ 163 #ifndef _KLD_MODULE 164 if (strncmp(name, "fbt_", 4) == 0) 165 return (1); 166 #endif 167 168 return (0); 169 } 170 171 static void 172 fbt_doubletrap(void) 173 { 174 fbt_probe_t *fbt; 175 int i; 176 177 for (i = 0; i < fbt_probetab_size; i++) { 178 fbt = fbt_probetab[i]; 179 180 for (; fbt != NULL; fbt = fbt->fbtp_probenext) 181 fbt_patch_tracepoint(fbt, fbt->fbtp_savedval); 182 } 183 } 184 185 static void 186 fbt_provide_module(void *arg, modctl_t *lf) 187 { 188 char modname[MAXPATHLEN]; 189 int i; 190 size_t len; 191 192 strlcpy(modname, lf->filename, sizeof(modname)); 193 len = strlen(modname); 194 if (len > 3 && strcmp(modname + len - 3, ".ko") == 0) 195 modname[len - 3] = '\0'; 196 197 /* 198 * Employees of dtrace and their families are ineligible. Void 199 * where prohibited. 200 */ 201 if (strcmp(modname, "dtrace") == 0) 202 return; 203 204 /* 205 * To register with DTrace, a module must list 'dtrace' as a 206 * dependency in order for the kernel linker to resolve 207 * symbols like dtrace_register(). All modules with such a 208 * dependency are ineligible for FBT tracing. 209 */ 210 for (i = 0; i < lf->ndeps; i++) 211 if (strncmp(lf->deps[i]->filename, "dtrace", 6) == 0) 212 return; 213 214 if (lf->fbt_nentries) { 215 /* 216 * This module has some FBT entries allocated; we're afraid 217 * to screw with it. 218 */ 219 return; 220 } 221 222 /* 223 * List the functions in the module and the symbol values. 224 */ 225 (void) linker_file_function_listall(lf, fbt_provide_module_function, modname); 226 } 227 228 static void 229 fbt_destroy_one(fbt_probe_t *fbt) 230 { 231 fbt_probe_t *hash, *hashprev, *next; 232 int ndx; 233 234 ndx = FBT_ADDR2NDX(fbt->fbtp_patchpoint); 235 for (hash = fbt_probetab[ndx], hashprev = NULL; hash != NULL; 236 hashprev = hash, hash = hash->fbtp_hashnext) { 237 if (hash == fbt) { 238 if ((next = fbt->fbtp_tracenext) != NULL) 239 next->fbtp_hashnext = hash->fbtp_hashnext; 240 else 241 next = hash->fbtp_hashnext; 242 if (hashprev != NULL) 243 hashprev->fbtp_hashnext = next; 244 else 245 fbt_probetab[ndx] = next; 246 goto free; 247 } else if (hash->fbtp_patchpoint == fbt->fbtp_patchpoint) { 248 for (next = hash; next->fbtp_tracenext != NULL; 249 next = next->fbtp_tracenext) { 250 if (fbt == next->fbtp_tracenext) { 251 next->fbtp_tracenext = 252 fbt->fbtp_tracenext; 253 goto free; 254 } 255 } 256 } 257 } 258 panic("probe %p not found in hash table", fbt); 259 free: 260 free(fbt, M_FBT); 261 } 262 263 static void 264 fbt_destroy(void *arg, dtrace_id_t id, void *parg) 265 { 266 fbt_probe_t *fbt = parg, *next; 267 modctl_t *ctl; 268 269 do { 270 ctl = fbt->fbtp_ctl; 271 ctl->fbt_nentries--; 272 273 next = fbt->fbtp_probenext; 274 fbt_destroy_one(fbt); 275 fbt = next; 276 } while (fbt != NULL); 277 } 278 279 static void 280 fbt_enable(void *arg, dtrace_id_t id, void *parg) 281 { 282 fbt_probe_t *fbt = parg; 283 modctl_t *ctl = fbt->fbtp_ctl; 284 285 ctl->nenabled++; 286 287 /* 288 * Now check that our modctl has the expected load count. If it 289 * doesn't, this module must have been unloaded and reloaded -- and 290 * we're not going to touch it. 291 */ 292 if (ctl->loadcnt != fbt->fbtp_loadcnt) { 293 if (fbt_verbose) { 294 printf("fbt is failing for probe %s " 295 "(module %s reloaded)", 296 fbt->fbtp_name, ctl->filename); 297 } 298 299 return; 300 } 301 302 for (; fbt != NULL; fbt = fbt->fbtp_probenext) { 303 fbt_patch_tracepoint(fbt, fbt->fbtp_patchval); 304 fbt->fbtp_enabled++; 305 } 306 } 307 308 static void 309 fbt_disable(void *arg, dtrace_id_t id, void *parg) 310 { 311 fbt_probe_t *fbt = parg, *hash; 312 modctl_t *ctl = fbt->fbtp_ctl; 313 314 ASSERT(ctl->nenabled > 0); 315 ctl->nenabled--; 316 317 if ((ctl->loadcnt != fbt->fbtp_loadcnt)) 318 return; 319 320 for (; fbt != NULL; fbt = fbt->fbtp_probenext) { 321 fbt->fbtp_enabled--; 322 323 for (hash = fbt_probetab[FBT_ADDR2NDX(fbt->fbtp_patchpoint)]; 324 hash != NULL; hash = hash->fbtp_hashnext) { 325 if (hash->fbtp_patchpoint == fbt->fbtp_patchpoint) { 326 for (; hash != NULL; hash = hash->fbtp_tracenext) 327 if (hash->fbtp_enabled > 0) 328 break; 329 break; 330 } 331 } 332 if (hash == NULL) 333 fbt_patch_tracepoint(fbt, fbt->fbtp_savedval); 334 } 335 } 336 337 static void 338 fbt_suspend(void *arg, dtrace_id_t id, void *parg) 339 { 340 fbt_probe_t *fbt = parg; 341 modctl_t *ctl = fbt->fbtp_ctl; 342 343 ASSERT(ctl->nenabled > 0); 344 345 if ((ctl->loadcnt != fbt->fbtp_loadcnt)) 346 return; 347 348 for (; fbt != NULL; fbt = fbt->fbtp_probenext) 349 fbt_patch_tracepoint(fbt, fbt->fbtp_savedval); 350 } 351 352 static void 353 fbt_resume(void *arg, dtrace_id_t id, void *parg) 354 { 355 fbt_probe_t *fbt = parg; 356 modctl_t *ctl = fbt->fbtp_ctl; 357 358 ASSERT(ctl->nenabled > 0); 359 360 if ((ctl->loadcnt != fbt->fbtp_loadcnt)) 361 return; 362 363 for (; fbt != NULL; fbt = fbt->fbtp_probenext) 364 fbt_patch_tracepoint(fbt, fbt->fbtp_patchval); 365 } 366 367 static int 368 fbt_ctfoff_init(modctl_t *lf, linker_ctf_t *lc) 369 { 370 const Elf_Sym *symp = lc->symtab; 371 const ctf_header_t *hp = (const ctf_header_t *) lc->ctftab; 372 const uint8_t *ctfdata = lc->ctftab + sizeof(ctf_header_t); 373 size_t idwidth; 374 int i; 375 uint32_t *ctfoff; 376 uint32_t objtoff = hp->cth_objtoff; 377 uint32_t funcoff = hp->cth_funcoff; 378 uint_t kind, info, vlen; 379 380 /* Sanity check. */ 381 if (hp->cth_magic != CTF_MAGIC) { 382 printf("Bad magic value in CTF data of '%s'\n",lf->pathname); 383 return (EINVAL); 384 } 385 386 if (lc->symtab == NULL) { 387 printf("No symbol table in '%s'\n",lf->pathname); 388 return (EINVAL); 389 } 390 391 ctfoff = malloc(sizeof(uint32_t) * lc->nsym, M_LINKER, M_WAITOK); 392 *lc->ctfoffp = ctfoff; 393 394 idwidth = hp->cth_version == CTF_VERSION_2 ? 2 : 4; 395 396 for (i = 0; i < lc->nsym; i++, ctfoff++, symp++) { 397 if (symp->st_name == 0 || symp->st_shndx == SHN_UNDEF) { 398 *ctfoff = 0xffffffff; 399 continue; 400 } 401 402 switch (ELF_ST_TYPE(symp->st_info)) { 403 case STT_OBJECT: 404 if (objtoff >= hp->cth_funcoff || 405 (symp->st_shndx == SHN_ABS && symp->st_value == 0)) { 406 *ctfoff = 0xffffffff; 407 break; 408 } 409 410 *ctfoff = objtoff; 411 objtoff += idwidth; 412 break; 413 414 case STT_FUNC: 415 if (funcoff >= hp->cth_typeoff) { 416 *ctfoff = 0xffffffff; 417 break; 418 } 419 420 *ctfoff = funcoff; 421 422 info = 0; 423 memcpy(&info, ctfdata + funcoff, idwidth); 424 if (hp->cth_version == CTF_VERSION_2) { 425 kind = CTF_V2_INFO_KIND(info); 426 vlen = CTF_V2_INFO_VLEN(info); 427 } else { 428 kind = CTF_V3_INFO_KIND(info); 429 vlen = CTF_V3_INFO_VLEN(info); 430 } 431 432 /* 433 * If we encounter a zero pad at the end, just skip it. 434 * Otherwise skip over the function and its return type 435 * (+2) and the argument list (vlen). 436 */ 437 if (kind == CTF_K_UNKNOWN && vlen == 0) 438 funcoff += idwidth; 439 else 440 funcoff += idwidth * (vlen + 2); 441 break; 442 443 default: 444 *ctfoff = 0xffffffff; 445 break; 446 } 447 } 448 449 return (0); 450 } 451 452 static void 453 fbt_get_ctt_index(uint8_t version, const void *v, uint_t *indexp, 454 uint_t *typep, int *ischildp) 455 { 456 uint_t index, type; 457 int ischild; 458 459 if (version == CTF_VERSION_2) { 460 const struct ctf_type_v2 *ctt = v; 461 462 type = ctt->ctt_type; 463 index = CTF_V2_TYPE_TO_INDEX(ctt->ctt_type); 464 ischild = CTF_V2_TYPE_ISCHILD(ctt->ctt_type); 465 } else { 466 const struct ctf_type_v3 *ctt = v; 467 468 type = ctt->ctt_type; 469 index = CTF_V3_TYPE_TO_INDEX(ctt->ctt_type); 470 ischild = CTF_V3_TYPE_ISCHILD(ctt->ctt_type); 471 } 472 473 if (indexp != NULL) 474 *indexp = index; 475 if (typep != NULL) 476 *typep = type; 477 if (ischildp != NULL) 478 *ischildp = ischild; 479 } 480 481 static ssize_t 482 fbt_get_ctt_size(uint8_t version, const void *tp, ssize_t *sizep, 483 ssize_t *incrementp) 484 { 485 ssize_t size, increment; 486 487 if (version == CTF_VERSION_2) { 488 const struct ctf_type_v2 *ctt = tp; 489 490 if (ctt->ctt_size == CTF_V2_LSIZE_SENT) { 491 size = CTF_TYPE_LSIZE(ctt); 492 increment = sizeof (struct ctf_type_v2); 493 } else { 494 size = ctt->ctt_size; 495 increment = sizeof (struct ctf_stype_v2); 496 } 497 } else { 498 const struct ctf_type_v3 *ctt = tp; 499 500 if (ctt->ctt_size == CTF_V3_LSIZE_SENT) { 501 size = CTF_TYPE_LSIZE(ctt); 502 increment = sizeof (struct ctf_type_v3); 503 } else { 504 size = ctt->ctt_size; 505 increment = sizeof (struct ctf_stype_v3); 506 } 507 } 508 509 if (sizep) 510 *sizep = size; 511 if (incrementp) 512 *incrementp = increment; 513 514 return (size); 515 } 516 517 static void 518 fbt_get_ctt_info(uint8_t version, const void *tp, uint_t *kindp, uint_t *vlenp, 519 int *isrootp) 520 { 521 uint_t kind, vlen; 522 int isroot; 523 524 if (version == CTF_VERSION_2) { 525 const struct ctf_type_v2 *ctt = tp; 526 527 kind = CTF_V2_INFO_KIND(ctt->ctt_info); 528 vlen = CTF_V2_INFO_VLEN(ctt->ctt_info); 529 isroot = CTF_V2_INFO_ISROOT(ctt->ctt_info); 530 } else { 531 const struct ctf_type_v3 *ctt = tp; 532 533 kind = CTF_V3_INFO_KIND(ctt->ctt_info); 534 vlen = CTF_V3_INFO_VLEN(ctt->ctt_info); 535 isroot = CTF_V3_INFO_ISROOT(ctt->ctt_info); 536 } 537 538 if (kindp != NULL) 539 *kindp = kind; 540 if (vlenp != NULL) 541 *vlenp = vlen; 542 if (isrootp != NULL) 543 *isrootp = isroot; 544 } 545 546 static int 547 fbt_typoff_init(linker_ctf_t *lc) 548 { 549 const ctf_header_t *hp = (const ctf_header_t *) lc->ctftab; 550 const void *tbuf, *tend, *tp; 551 const uint8_t *ctfdata = lc->ctftab + sizeof(ctf_header_t); 552 size_t idwidth; 553 int ctf_typemax = 0; 554 uint32_t *xp; 555 ulong_t pop[CTF_K_MAX + 1] = { 0 }; 556 uint8_t version; 557 558 /* Sanity check. */ 559 if (hp->cth_magic != CTF_MAGIC) 560 return (EINVAL); 561 562 version = hp->cth_version; 563 idwidth = version == CTF_VERSION_2 ? 2 : 4; 564 565 tbuf = (const void *) (ctfdata + hp->cth_typeoff); 566 tend = (const void *) (ctfdata + hp->cth_stroff); 567 568 /* 569 * We make two passes through the entire type section. In this first 570 * pass, we count the number of each type and the total number of types. 571 */ 572 for (tp = tbuf; tp < tend; ctf_typemax++) { 573 uint_t kind, type, vlen; 574 ssize_t size, increment; 575 size_t vbytes; 576 577 (void) fbt_get_ctt_size(version, tp, &size, &increment); 578 fbt_get_ctt_info(version, tp, &kind, &vlen, NULL); 579 fbt_get_ctt_index(version, tp, NULL, &type, NULL); 580 581 switch (kind) { 582 case CTF_K_INTEGER: 583 case CTF_K_FLOAT: 584 vbytes = sizeof (uint_t); 585 break; 586 case CTF_K_ARRAY: 587 if (version == CTF_VERSION_2) 588 vbytes = sizeof (struct ctf_array_v2); 589 else 590 vbytes = sizeof (struct ctf_array_v3); 591 break; 592 case CTF_K_FUNCTION: 593 vbytes = roundup2(idwidth * vlen, sizeof(uint32_t)); 594 break; 595 case CTF_K_STRUCT: 596 case CTF_K_UNION: 597 if (version == CTF_VERSION_2) { 598 if (size < CTF_V2_LSTRUCT_THRESH) 599 vbytes = 600 sizeof (struct ctf_member_v2) * vlen; 601 else 602 vbytes = 603 sizeof (struct ctf_lmember_v2) * vlen; 604 } else { 605 if (size < CTF_V3_LSTRUCT_THRESH) 606 vbytes = 607 sizeof (struct ctf_member_v3) * vlen; 608 else 609 vbytes = 610 sizeof (struct ctf_lmember_v3) * vlen; 611 } 612 break; 613 case CTF_K_ENUM: 614 vbytes = sizeof (ctf_enum_t) * vlen; 615 break; 616 case CTF_K_FORWARD: 617 /* 618 * For forward declarations, ctt_type is the CTF_K_* 619 * kind for the tag, so bump that population count too. 620 * If ctt_type is unknown, treat the tag as a struct. 621 */ 622 if (type == CTF_K_UNKNOWN || type >= CTF_K_MAX) 623 pop[CTF_K_STRUCT]++; 624 else 625 pop[type]++; 626 /*FALLTHRU*/ 627 case CTF_K_UNKNOWN: 628 vbytes = 0; 629 break; 630 case CTF_K_POINTER: 631 case CTF_K_TYPEDEF: 632 case CTF_K_VOLATILE: 633 case CTF_K_CONST: 634 case CTF_K_RESTRICT: 635 vbytes = 0; 636 break; 637 default: 638 printf("%s(%d): detected invalid CTF kind -- %u\n", __func__, __LINE__, kind); 639 return (EIO); 640 } 641 tp = (const void *)((uintptr_t)tp + increment + vbytes); 642 pop[kind]++; 643 } 644 645 /* account for a sentinel value below */ 646 ctf_typemax++; 647 *lc->typlenp = ctf_typemax; 648 649 xp = malloc(sizeof(uint32_t) * ctf_typemax, M_LINKER, 650 M_ZERO | M_WAITOK); 651 652 *lc->typoffp = xp; 653 654 /* type id 0 is used as a sentinel value */ 655 *xp++ = 0; 656 657 /* 658 * In the second pass, fill in the type offset. 659 */ 660 for (tp = tbuf; tp < tend; xp++) { 661 ssize_t size, increment; 662 uint_t kind, vlen; 663 664 size_t vbytes; 665 666 (void) fbt_get_ctt_size(version, tp, &size, &increment); 667 fbt_get_ctt_info(version, tp, &kind, &vlen, NULL); 668 669 switch (kind) { 670 case CTF_K_INTEGER: 671 case CTF_K_FLOAT: 672 vbytes = sizeof (uint_t); 673 break; 674 case CTF_K_ARRAY: 675 if (version == CTF_VERSION_2) 676 vbytes = sizeof (struct ctf_array_v2); 677 else 678 vbytes = sizeof (struct ctf_array_v3); 679 break; 680 case CTF_K_FUNCTION: 681 vbytes = roundup2(idwidth * vlen, sizeof(uint32_t)); 682 break; 683 case CTF_K_STRUCT: 684 case CTF_K_UNION: 685 if (version == CTF_VERSION_2) { 686 if (size < CTF_V2_LSTRUCT_THRESH) 687 vbytes = 688 sizeof (struct ctf_member_v2) * vlen; 689 else 690 vbytes = 691 sizeof (struct ctf_lmember_v2) * vlen; 692 } else { 693 if (size < CTF_V3_LSTRUCT_THRESH) 694 vbytes = 695 sizeof (struct ctf_member_v3) * vlen; 696 else 697 vbytes = 698 sizeof (struct ctf_lmember_v3) * vlen; 699 } 700 break; 701 case CTF_K_ENUM: 702 vbytes = sizeof (ctf_enum_t) * vlen; 703 break; 704 case CTF_K_FORWARD: 705 case CTF_K_UNKNOWN: 706 vbytes = 0; 707 break; 708 case CTF_K_POINTER: 709 case CTF_K_TYPEDEF: 710 case CTF_K_VOLATILE: 711 case CTF_K_CONST: 712 case CTF_K_RESTRICT: 713 vbytes = 0; 714 break; 715 default: 716 printf("%s(%d): detected invalid CTF kind -- %u\n", __func__, __LINE__, kind); 717 return (EIO); 718 } 719 *xp = (uint32_t)((uintptr_t) tp - (uintptr_t) ctfdata); 720 tp = (const void *)((uintptr_t)tp + increment + vbytes); 721 } 722 723 return (0); 724 } 725 726 /* 727 * CTF Declaration Stack 728 * 729 * In order to implement ctf_type_name(), we must convert a type graph back 730 * into a C type declaration. Unfortunately, a type graph represents a storage 731 * class ordering of the type whereas a type declaration must obey the C rules 732 * for operator precedence, and the two orderings are frequently in conflict. 733 * For example, consider these CTF type graphs and their C declarations: 734 * 735 * CTF_K_POINTER -> CTF_K_FUNCTION -> CTF_K_INTEGER : int (*)() 736 * CTF_K_POINTER -> CTF_K_ARRAY -> CTF_K_INTEGER : int (*)[] 737 * 738 * In each case, parentheses are used to raise operator * to higher lexical 739 * precedence, so the string form of the C declaration cannot be constructed by 740 * walking the type graph links and forming the string from left to right. 741 * 742 * The functions in this file build a set of stacks from the type graph nodes 743 * corresponding to the C operator precedence levels in the appropriate order. 744 * The code in ctf_type_name() can then iterate over the levels and nodes in 745 * lexical precedence order and construct the final C declaration string. 746 */ 747 typedef struct ctf_list { 748 struct ctf_list *l_prev; /* previous pointer or tail pointer */ 749 struct ctf_list *l_next; /* next pointer or head pointer */ 750 } ctf_list_t; 751 752 #define ctf_list_prev(elem) ((void *)(((ctf_list_t *)(elem))->l_prev)) 753 #define ctf_list_next(elem) ((void *)(((ctf_list_t *)(elem))->l_next)) 754 755 typedef enum { 756 CTF_PREC_BASE, 757 CTF_PREC_POINTER, 758 CTF_PREC_ARRAY, 759 CTF_PREC_FUNCTION, 760 CTF_PREC_MAX 761 } ctf_decl_prec_t; 762 763 typedef struct ctf_decl_node { 764 ctf_list_t cd_list; /* linked list pointers */ 765 ctf_id_t cd_type; /* type identifier */ 766 uint_t cd_kind; /* type kind */ 767 uint_t cd_n; /* type dimension if array */ 768 } ctf_decl_node_t; 769 770 typedef struct ctf_decl { 771 ctf_list_t cd_nodes[CTF_PREC_MAX]; /* declaration node stacks */ 772 int cd_order[CTF_PREC_MAX]; /* storage order of decls */ 773 ctf_decl_prec_t cd_qualp; /* qualifier precision */ 774 ctf_decl_prec_t cd_ordp; /* ordered precision */ 775 char *cd_buf; /* buffer for output */ 776 char *cd_ptr; /* buffer location */ 777 char *cd_end; /* buffer limit */ 778 size_t cd_len; /* buffer space required */ 779 int cd_err; /* saved error value */ 780 } ctf_decl_t; 781 782 /* 783 * Simple doubly-linked list append routine. This implementation assumes that 784 * each list element contains an embedded ctf_list_t as the first member. 785 * An additional ctf_list_t is used to store the head (l_next) and tail 786 * (l_prev) pointers. The current head and tail list elements have their 787 * previous and next pointers set to NULL, respectively. 788 */ 789 static void 790 ctf_list_append(ctf_list_t *lp, void *new) 791 { 792 ctf_list_t *p = lp->l_prev; /* p = tail list element */ 793 ctf_list_t *q = new; /* q = new list element */ 794 795 lp->l_prev = q; 796 q->l_prev = p; 797 q->l_next = NULL; 798 799 if (p != NULL) 800 p->l_next = q; 801 else 802 lp->l_next = q; 803 } 804 805 /* 806 * Prepend the specified existing element to the given ctf_list_t. The 807 * existing pointer should be pointing at a struct with embedded ctf_list_t. 808 */ 809 static void 810 ctf_list_prepend(ctf_list_t *lp, void *new) 811 { 812 ctf_list_t *p = new; /* p = new list element */ 813 ctf_list_t *q = lp->l_next; /* q = head list element */ 814 815 lp->l_next = p; 816 p->l_prev = NULL; 817 p->l_next = q; 818 819 if (q != NULL) 820 q->l_prev = p; 821 else 822 lp->l_prev = p; 823 } 824 825 static void 826 ctf_decl_init(ctf_decl_t *cd, char *buf, size_t len) 827 { 828 int i; 829 830 bzero(cd, sizeof (ctf_decl_t)); 831 832 for (i = CTF_PREC_BASE; i < CTF_PREC_MAX; i++) 833 cd->cd_order[i] = CTF_PREC_BASE - 1; 834 835 cd->cd_qualp = CTF_PREC_BASE; 836 cd->cd_ordp = CTF_PREC_BASE; 837 838 cd->cd_buf = buf; 839 cd->cd_ptr = buf; 840 cd->cd_end = buf + len; 841 } 842 843 static void 844 ctf_decl_fini(ctf_decl_t *cd) 845 { 846 ctf_decl_node_t *cdp, *ndp; 847 int i; 848 849 for (i = CTF_PREC_BASE; i < CTF_PREC_MAX; i++) { 850 for (cdp = ctf_list_next(&cd->cd_nodes[i]); 851 cdp != NULL; cdp = ndp) { 852 ndp = ctf_list_next(cdp); 853 free(cdp, M_FBT); 854 } 855 } 856 } 857 858 static const void * 859 ctf_lookup_by_id(linker_ctf_t *lc, ctf_id_t type) 860 { 861 const void *tp; 862 uint32_t offset; 863 uint32_t *typoff = *lc->typoffp; 864 865 if (type >= *lc->typlenp) { 866 printf("%s(%d): type %d exceeds max %ld\n",__func__,__LINE__,(int) type,*lc->typlenp); 867 return(NULL); 868 } 869 870 /* Check if the type isn't cross-referenced. */ 871 if ((offset = typoff[type]) == 0) { 872 printf("%s(%d): type %d isn't cross referenced\n",__func__,__LINE__, (int) type); 873 return(NULL); 874 } 875 876 tp = (const void *) (lc->ctftab + offset + sizeof(ctf_header_t)); 877 878 return (tp); 879 } 880 881 static void 882 fbt_array_info(linker_ctf_t *lc, ctf_id_t type, ctf_arinfo_t *arp) 883 { 884 const ctf_header_t *hp = (const ctf_header_t *) lc->ctftab; 885 const void *tp; 886 ssize_t increment; 887 uint_t kind; 888 889 bzero(arp, sizeof(*arp)); 890 891 if ((tp = ctf_lookup_by_id(lc, type)) == NULL) 892 return; 893 894 fbt_get_ctt_info(hp->cth_version, tp, &kind, NULL, NULL); 895 if (kind != CTF_K_ARRAY) 896 return; 897 898 (void) fbt_get_ctt_size(hp->cth_version, tp, NULL, &increment); 899 900 if (hp->cth_version == CTF_VERSION_2) { 901 const struct ctf_array_v2 *ap; 902 903 ap = (const struct ctf_array_v2 *)((uintptr_t)tp + increment); 904 arp->ctr_contents = ap->cta_contents; 905 arp->ctr_index = ap->cta_index; 906 arp->ctr_nelems = ap->cta_nelems; 907 } else { 908 const struct ctf_array_v3 *ap; 909 910 ap = (const struct ctf_array_v3 *)((uintptr_t)tp + increment); 911 arp->ctr_contents = ap->cta_contents; 912 arp->ctr_index = ap->cta_index; 913 arp->ctr_nelems = ap->cta_nelems; 914 } 915 } 916 917 static const char * 918 ctf_strptr(linker_ctf_t *lc, int name) 919 { 920 const ctf_header_t *hp = (const ctf_header_t *) lc->ctftab; 921 const char *strp = ""; 922 923 if (name < 0 || name >= hp->cth_strlen) 924 return(strp); 925 926 strp = (const char *)(lc->ctftab + hp->cth_stroff + name + sizeof(ctf_header_t)); 927 928 return (strp); 929 } 930 931 static const char * 932 ctf_type_rname(linker_ctf_t *lc, const void *v) 933 { 934 const ctf_header_t *hp = (const ctf_header_t *) lc->ctftab; 935 uint_t name; 936 937 if (hp->cth_version == CTF_VERSION_2) { 938 const struct ctf_type_v2 *ctt = v; 939 940 name = ctt->ctt_name; 941 } else { 942 const struct ctf_type_v3 *ctt = v; 943 944 name = ctt->ctt_name; 945 } 946 947 return (ctf_strptr(lc, name)); 948 } 949 950 static void 951 ctf_decl_push(ctf_decl_t *cd, linker_ctf_t *lc, ctf_id_t type) 952 { 953 const ctf_header_t *hp = (const ctf_header_t *) lc->ctftab; 954 ctf_decl_node_t *cdp; 955 ctf_decl_prec_t prec; 956 uint_t kind, n = 1, t; 957 int is_qual = 0; 958 959 const void *tp; 960 ctf_arinfo_t ar; 961 962 if ((tp = ctf_lookup_by_id(lc, type)) == NULL) { 963 cd->cd_err = ENOENT; 964 return; 965 } 966 967 fbt_get_ctt_info(hp->cth_version, tp, &kind, NULL, NULL); 968 fbt_get_ctt_index(hp->cth_version, tp, NULL, &t, NULL); 969 970 switch (kind) { 971 case CTF_K_ARRAY: 972 fbt_array_info(lc, type, &ar); 973 ctf_decl_push(cd, lc, ar.ctr_contents); 974 n = ar.ctr_nelems; 975 prec = CTF_PREC_ARRAY; 976 break; 977 978 case CTF_K_TYPEDEF: 979 if (ctf_type_rname(lc, tp)[0] == '\0') { 980 ctf_decl_push(cd, lc, t); 981 return; 982 } 983 prec = CTF_PREC_BASE; 984 break; 985 986 case CTF_K_FUNCTION: 987 ctf_decl_push(cd, lc, t); 988 prec = CTF_PREC_FUNCTION; 989 break; 990 991 case CTF_K_POINTER: 992 ctf_decl_push(cd, lc, t); 993 prec = CTF_PREC_POINTER; 994 break; 995 996 case CTF_K_VOLATILE: 997 case CTF_K_CONST: 998 case CTF_K_RESTRICT: 999 ctf_decl_push(cd, lc, t); 1000 prec = cd->cd_qualp; 1001 is_qual++; 1002 break; 1003 1004 default: 1005 prec = CTF_PREC_BASE; 1006 } 1007 1008 cdp = malloc(sizeof(*cdp), M_FBT, M_WAITOK); 1009 cdp->cd_type = type; 1010 cdp->cd_kind = kind; 1011 cdp->cd_n = n; 1012 1013 if (ctf_list_next(&cd->cd_nodes[prec]) == NULL) 1014 cd->cd_order[prec] = cd->cd_ordp++; 1015 1016 /* 1017 * Reset cd_qualp to the highest precedence level that we've seen so 1018 * far that can be qualified (CTF_PREC_BASE or CTF_PREC_POINTER). 1019 */ 1020 if (prec > cd->cd_qualp && prec < CTF_PREC_ARRAY) 1021 cd->cd_qualp = prec; 1022 1023 /* 1024 * C array declarators are ordered inside out so prepend them. Also by 1025 * convention qualifiers of base types precede the type specifier (e.g. 1026 * const int vs. int const) even though the two forms are equivalent. 1027 */ 1028 if (kind == CTF_K_ARRAY || (is_qual && prec == CTF_PREC_BASE)) 1029 ctf_list_prepend(&cd->cd_nodes[prec], cdp); 1030 else 1031 ctf_list_append(&cd->cd_nodes[prec], cdp); 1032 } 1033 1034 static void 1035 ctf_decl_sprintf(ctf_decl_t *cd, const char *format, ...) 1036 { 1037 size_t len = (size_t)(cd->cd_end - cd->cd_ptr); 1038 va_list ap; 1039 size_t n; 1040 1041 va_start(ap, format); 1042 n = vsnprintf(cd->cd_ptr, len, format, ap); 1043 va_end(ap); 1044 1045 cd->cd_ptr += MIN(n, len); 1046 cd->cd_len += n; 1047 } 1048 1049 static ssize_t 1050 fbt_type_name(linker_ctf_t *lc, ctf_id_t type, char *buf, size_t len) 1051 { 1052 ctf_decl_t cd; 1053 ctf_decl_node_t *cdp; 1054 ctf_decl_prec_t prec, lp, rp; 1055 int ptr, arr; 1056 uint_t k; 1057 1058 if (lc == NULL && type == CTF_ERR) 1059 return (-1); /* simplify caller code by permitting CTF_ERR */ 1060 1061 ctf_decl_init(&cd, buf, len); 1062 ctf_decl_push(&cd, lc, type); 1063 1064 if (cd.cd_err != 0) { 1065 ctf_decl_fini(&cd); 1066 return (-1); 1067 } 1068 1069 /* 1070 * If the type graph's order conflicts with lexical precedence order 1071 * for pointers or arrays, then we need to surround the declarations at 1072 * the corresponding lexical precedence with parentheses. This can 1073 * result in either a parenthesized pointer (*) as in int (*)() or 1074 * int (*)[], or in a parenthesized pointer and array as in int (*[])(). 1075 */ 1076 ptr = cd.cd_order[CTF_PREC_POINTER] > CTF_PREC_POINTER; 1077 arr = cd.cd_order[CTF_PREC_ARRAY] > CTF_PREC_ARRAY; 1078 1079 rp = arr ? CTF_PREC_ARRAY : ptr ? CTF_PREC_POINTER : -1; 1080 lp = ptr ? CTF_PREC_POINTER : arr ? CTF_PREC_ARRAY : -1; 1081 1082 k = CTF_K_POINTER; /* avoid leading whitespace (see below) */ 1083 1084 for (prec = CTF_PREC_BASE; prec < CTF_PREC_MAX; prec++) { 1085 for (cdp = ctf_list_next(&cd.cd_nodes[prec]); 1086 cdp != NULL; cdp = ctf_list_next(cdp)) { 1087 1088 const void *tp = ctf_lookup_by_id(lc, cdp->cd_type); 1089 const char *name = ctf_type_rname(lc, tp); 1090 1091 if (k != CTF_K_POINTER && k != CTF_K_ARRAY) 1092 ctf_decl_sprintf(&cd, " "); 1093 1094 if (lp == prec) { 1095 ctf_decl_sprintf(&cd, "("); 1096 lp = -1; 1097 } 1098 1099 switch (cdp->cd_kind) { 1100 case CTF_K_INTEGER: 1101 case CTF_K_FLOAT: 1102 case CTF_K_TYPEDEF: 1103 ctf_decl_sprintf(&cd, "%s", name); 1104 break; 1105 case CTF_K_POINTER: 1106 ctf_decl_sprintf(&cd, "*"); 1107 break; 1108 case CTF_K_ARRAY: 1109 ctf_decl_sprintf(&cd, "[%u]", cdp->cd_n); 1110 break; 1111 case CTF_K_FUNCTION: 1112 ctf_decl_sprintf(&cd, "()"); 1113 break; 1114 case CTF_K_STRUCT: 1115 case CTF_K_FORWARD: 1116 ctf_decl_sprintf(&cd, "struct %s", name); 1117 break; 1118 case CTF_K_UNION: 1119 ctf_decl_sprintf(&cd, "union %s", name); 1120 break; 1121 case CTF_K_ENUM: 1122 ctf_decl_sprintf(&cd, "enum %s", name); 1123 break; 1124 case CTF_K_VOLATILE: 1125 ctf_decl_sprintf(&cd, "volatile"); 1126 break; 1127 case CTF_K_CONST: 1128 ctf_decl_sprintf(&cd, "const"); 1129 break; 1130 case CTF_K_RESTRICT: 1131 ctf_decl_sprintf(&cd, "restrict"); 1132 break; 1133 } 1134 1135 k = cdp->cd_kind; 1136 } 1137 1138 if (rp == prec) 1139 ctf_decl_sprintf(&cd, ")"); 1140 } 1141 1142 ctf_decl_fini(&cd); 1143 return (cd.cd_len); 1144 } 1145 1146 static void 1147 fbt_getargdesc(void *arg __unused, dtrace_id_t id __unused, void *parg, dtrace_argdesc_t *desc) 1148 { 1149 const ctf_header_t *hp; 1150 const char *dp; 1151 fbt_probe_t *fbt = parg; 1152 linker_ctf_t lc; 1153 modctl_t *ctl = fbt->fbtp_ctl; 1154 size_t idwidth; 1155 int ndx = desc->dtargd_ndx; 1156 int symindx = fbt->fbtp_symindx; 1157 uint32_t *ctfoff; 1158 uint32_t offset, type; 1159 uint_t info, n; 1160 ushort_t kind; 1161 1162 if (fbt->fbtp_roffset != 0 && desc->dtargd_ndx == 0) { 1163 (void) strcpy(desc->dtargd_native, "int"); 1164 return; 1165 } 1166 1167 desc->dtargd_ndx = DTRACE_ARGNONE; 1168 1169 /* Get a pointer to the CTF data and it's length. */ 1170 if (linker_ctf_get(ctl, &lc) != 0) 1171 /* No CTF data? Something wrong? *shrug* */ 1172 return; 1173 1174 /* Check if this module hasn't been initialised yet. */ 1175 if (*lc.ctfoffp == NULL) { 1176 /* 1177 * Initialise the CTF object and function symindx to 1178 * byte offset array. 1179 */ 1180 if (fbt_ctfoff_init(ctl, &lc) != 0) 1181 return; 1182 1183 /* Initialise the CTF type to byte offset array. */ 1184 if (fbt_typoff_init(&lc) != 0) 1185 return; 1186 } 1187 1188 ctfoff = *lc.ctfoffp; 1189 1190 if (ctfoff == NULL || *lc.typoffp == NULL) 1191 return; 1192 1193 /* Check if the symbol index is out of range. */ 1194 if (symindx >= lc.nsym) 1195 return; 1196 1197 /* Check if the symbol isn't cross-referenced. */ 1198 if ((offset = ctfoff[symindx]) == 0xffffffff) 1199 return; 1200 1201 hp = (const ctf_header_t *) lc.ctftab; 1202 idwidth = hp->cth_version == CTF_VERSION_2 ? 2 : 4; 1203 dp = (const char *)(lc.ctftab + offset + sizeof(ctf_header_t)); 1204 1205 info = 0; 1206 memcpy(&info, dp, idwidth); 1207 dp += idwidth; 1208 if (hp->cth_version == CTF_VERSION_2) { 1209 kind = CTF_V2_INFO_KIND(info); 1210 n = CTF_V2_INFO_VLEN(info); 1211 } else { 1212 kind = CTF_V3_INFO_KIND(info); 1213 n = CTF_V3_INFO_VLEN(info); 1214 } 1215 1216 if (kind == CTF_K_UNKNOWN && n == 0) { 1217 printf("%s(%d): Unknown function!\n",__func__,__LINE__); 1218 return; 1219 } 1220 1221 if (kind != CTF_K_FUNCTION) { 1222 printf("%s(%d): Expected a function!\n",__func__,__LINE__); 1223 return; 1224 } 1225 1226 if (fbt->fbtp_roffset != 0) { 1227 /* Only return type is available for args[1] in return probe. */ 1228 if (ndx > 1) 1229 return; 1230 ASSERT(ndx == 1); 1231 } else { 1232 /* Check if the requested argument doesn't exist. */ 1233 if (ndx >= n) 1234 return; 1235 1236 /* Skip the return type and arguments up to the one requested. */ 1237 dp += idwidth * (ndx + 1); 1238 } 1239 1240 type = 0; 1241 memcpy(&type, dp, idwidth); 1242 if (fbt_type_name(&lc, type, desc->dtargd_native, sizeof(desc->dtargd_native)) > 0) 1243 desc->dtargd_ndx = ndx; 1244 } 1245 1246 static int 1247 fbt_linker_file_cb(linker_file_t lf, void *arg) 1248 { 1249 1250 fbt_provide_module(arg, lf); 1251 1252 return (0); 1253 } 1254 1255 static void 1256 fbt_load(void *dummy) 1257 { 1258 /* Create the /dev/dtrace/fbt entry. */ 1259 fbt_cdev = make_dev(&fbt_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600, 1260 "dtrace/fbt"); 1261 1262 /* Default the probe table size if not specified. */ 1263 if (fbt_probetab_size == 0) 1264 fbt_probetab_size = FBT_PROBETAB_SIZE; 1265 1266 /* Choose the hash mask for the probe table. */ 1267 fbt_probetab_mask = fbt_probetab_size - 1; 1268 1269 /* Allocate memory for the probe table. */ 1270 fbt_probetab = 1271 malloc(fbt_probetab_size * sizeof (fbt_probe_t *), M_FBT, M_WAITOK | M_ZERO); 1272 1273 dtrace_doubletrap_func = fbt_doubletrap; 1274 dtrace_invop_add(fbt_invop); 1275 1276 if (dtrace_register("fbt", &fbt_attr, DTRACE_PRIV_USER, 1277 NULL, &fbt_pops, NULL, &fbt_id) != 0) 1278 return; 1279 1280 /* Create probes for the kernel and already-loaded modules. */ 1281 linker_file_foreach(fbt_linker_file_cb, NULL); 1282 } 1283 1284 static int 1285 fbt_unload() 1286 { 1287 int error = 0; 1288 1289 /* De-register the invalid opcode handler. */ 1290 dtrace_invop_remove(fbt_invop); 1291 1292 dtrace_doubletrap_func = NULL; 1293 1294 /* De-register this DTrace provider. */ 1295 if ((error = dtrace_unregister(fbt_id)) != 0) 1296 return (error); 1297 1298 /* Free the probe table. */ 1299 free(fbt_probetab, M_FBT); 1300 fbt_probetab = NULL; 1301 fbt_probetab_mask = 0; 1302 1303 destroy_dev(fbt_cdev); 1304 1305 return (error); 1306 } 1307 1308 static int 1309 fbt_modevent(module_t mod __unused, int type, void *data __unused) 1310 { 1311 int error = 0; 1312 1313 switch (type) { 1314 case MOD_LOAD: 1315 break; 1316 1317 case MOD_UNLOAD: 1318 break; 1319 1320 case MOD_SHUTDOWN: 1321 break; 1322 1323 default: 1324 error = EOPNOTSUPP; 1325 break; 1326 1327 } 1328 1329 return (error); 1330 } 1331 1332 static int 1333 fbt_open(struct cdev *dev __unused, int oflags __unused, int devtype __unused, struct thread *td __unused) 1334 { 1335 return (0); 1336 } 1337 1338 SYSINIT(fbt_load, SI_SUB_DTRACE_PROVIDER, SI_ORDER_ANY, fbt_load, NULL); 1339 SYSUNINIT(fbt_unload, SI_SUB_DTRACE_PROVIDER, SI_ORDER_ANY, fbt_unload, NULL); 1340 1341 DEV_MODULE(fbt, fbt_modevent, NULL); 1342 MODULE_VERSION(fbt, 1); 1343 MODULE_DEPEND(fbt, dtrace, 1, 1, 1); 1344 MODULE_DEPEND(fbt, opensolaris, 1, 1, 1); 1345