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