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