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