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