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