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