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