1 /* $NetBSD: fbt.c,v 1.27 2019/07/16 07:26:00 hannken Exp $ */ 2 3 /* 4 * CDDL HEADER START 5 * 6 * The contents of this file are subject to the terms of the 7 * Common Development and Distribution License (the "License"). 8 * You may not use this file except in compliance with the License. 9 * 10 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 11 * or http://www.opensolaris.org/os/licensing. 12 * See the License for the specific language governing permissions 13 * and limitations under the License. 14 * 15 * When distributing Covered Code, include this CDDL HEADER in each 16 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 17 * If applicable, add the following below this CDDL HEADER, with the 18 * fields enclosed by brackets "[]" replaced with your own identifying 19 * information: Portions Copyright [yyyy] [name of copyright owner] 20 * 21 * CDDL HEADER END 22 * 23 * Portions Copyright 2006-2008 John Birrell jb@freebsd.org 24 * Portions Copyright 2010 Darran Hunt darran@NetBSD.org 25 * 26 * $FreeBSD: head/sys/cddl/dev/fbt/fbt.c 309786 2016-12-10 03:13:11Z markj $ 27 * 28 */ 29 30 /* 31 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 32 * Use is subject to license terms. 33 */ 34 35 #include <sys/cdefs.h> 36 #include <sys/proc.h> 37 #include <sys/param.h> 38 #include <sys/systm.h> 39 #include <sys/conf.h> 40 #include <sys/cpuvar.h> 41 #include <sys/fcntl.h> 42 #include <sys/filio.h> 43 #include <sys/kernel.h> 44 #include <sys/kmem.h> 45 #include <sys/ksyms.h> 46 #include <sys/cpu.h> 47 #include <sys/kthread.h> 48 #include <sys/syslimits.h> 49 #include <sys/linker.h> 50 #include <sys/lock.h> 51 #include <sys/malloc.h> 52 #include <sys/module.h> 53 #include <sys/mutex.h> 54 #include <sys/poll.h> 55 #include <sys/proc.h> 56 #include <sys/selinfo.h> 57 #include <sys/syscall.h> 58 #include <sys/uio.h> 59 #include <sys/unistd.h> 60 #include <sys/exec_elf.h> 61 62 #include <sys/dtrace.h> 63 #include <sys/dtrace_bsd.h> 64 #include <sys/kern_ctf.h> 65 #include <sys/dtrace_impl.h> 66 67 #include "fbt.h" 68 69 mod_ctf_t *modptr; 70 71 dtrace_provider_id_t fbt_id; 72 fbt_probe_t **fbt_probetab; 73 int fbt_probetab_mask; 74 static int fbt_probetab_size; 75 76 static dev_type_open(fbt_open); 77 static int fbt_unload(void); 78 static void fbt_getargdesc(void *, dtrace_id_t, void *, dtrace_argdesc_t *); 79 static void fbt_provide_module(void *, modctl_t *); 80 static void fbt_destroy(void *, dtrace_id_t, void *); 81 static int fbt_enable(void *, dtrace_id_t, void *); 82 static void fbt_disable(void *, dtrace_id_t, void *); 83 static void fbt_load(void); 84 static void fbt_suspend(void *, dtrace_id_t, void *); 85 static void fbt_resume(void *, dtrace_id_t, void *); 86 87 static const struct cdevsw fbt_cdevsw = { 88 .d_open = fbt_open, 89 .d_close = noclose, 90 .d_read = noread, 91 .d_write = nowrite, 92 .d_ioctl = noioctl, 93 .d_stop = nostop, 94 .d_tty = notty, 95 .d_poll = nopoll, 96 .d_mmap = nommap, 97 .d_kqfilter = nokqfilter, 98 .d_discard = nodiscard, 99 .d_flag = D_OTHER 100 }; 101 102 static dtrace_pattr_t fbt_attr = { 103 { DTRACE_STABILITY_EVOLVING, DTRACE_STABILITY_EVOLVING, DTRACE_CLASS_COMMON }, 104 { DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_UNKNOWN }, 105 { DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_ISA }, 106 { DTRACE_STABILITY_EVOLVING, DTRACE_STABILITY_EVOLVING, DTRACE_CLASS_COMMON }, 107 { DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_ISA }, 108 }; 109 110 static dtrace_pops_t fbt_pops = { 111 NULL, 112 fbt_provide_module, 113 fbt_enable, 114 fbt_disable, 115 fbt_suspend, 116 fbt_resume, 117 fbt_getargdesc, 118 NULL, 119 NULL, 120 fbt_destroy 121 }; 122 123 #ifdef __FreeBSD__ 124 static int fbt_verbose = 0; 125 126 static struct cdev *fbt_cdev; 127 #endif /* __FreeBSD__ */ 128 129 #ifdef __NetBSD__ 130 specificdata_key_t fbt_module_key; 131 132 #define version xversion 133 #endif /* __NetBSD__ */ 134 135 int 136 fbt_excluded(const char *name) 137 { 138 139 if (strncmp(name, "dtrace_", 7) == 0 && 140 strncmp(name, "dtrace_safe_", 12) != 0) { 141 /* 142 * Anything beginning with "dtrace_" may be called 143 * from probe context unless it explicitly indicates 144 * that it won't be called from probe context by 145 * using the prefix "dtrace_safe_". 146 */ 147 return (1); 148 } 149 150 #ifdef __FreeBSD__ 151 /* 152 * Lock owner methods may be called from probe context. 153 */ 154 if (strcmp(name, "owner_mtx") == 0 || 155 strcmp(name, "owner_rm") == 0 || 156 strcmp(name, "owner_rw") == 0 || 157 strcmp(name, "owner_sx") == 0) 158 return (1); 159 160 /* 161 * When DTrace is built into the kernel we need to exclude 162 * the FBT functions from instrumentation. 163 */ 164 #ifndef _KLD_MODULE 165 if (strncmp(name, "fbt_", 4) == 0) 166 return (1); 167 #endif 168 #endif 169 170 #ifdef __NetBSD__ 171 if (name[0] == '_' && name[1] == '_') 172 return (1); 173 174 if (strcmp(name, "cpu_index") == 0 || 175 strncmp(name, "db_", 3) == 0 || 176 strncmp(name, "ddb_", 4) == 0 || 177 strncmp(name, "kdb_", 4) == 0 || 178 strncmp(name, "lockdebug_", 10) == 0 || 179 strncmp(name, "kauth_", 5) == 0 || 180 strncmp(name, "ktext_write", 11) == 0 || 181 strncmp(name, "fbt_", 4) == 0) { 182 return (1); 183 } 184 #endif 185 186 return (0); 187 } 188 189 static void 190 fbt_doubletrap(void) 191 { 192 fbt_probe_t *fbt; 193 int i; 194 195 for (i = 0; i < fbt_probetab_size; i++) { 196 fbt = fbt_probetab[i]; 197 198 for (; fbt != NULL; fbt = fbt->fbtp_next) 199 fbt_patch_tracepoint(fbt, fbt->fbtp_savedval); 200 } 201 } 202 203 #ifdef __FreeBSD__ 204 static void 205 fbt_provide_module(void *arg, modctl_t *lf) 206 { 207 char modname[MAXPATHLEN]; 208 int i; 209 size_t len; 210 211 strlcpy(modname, lf->filename, sizeof(modname)); 212 len = strlen(modname); 213 if (len > 3 && strcmp(modname + len - 3, ".ko") == 0) 214 modname[len - 3] = '\0'; 215 216 /* 217 * Employees of dtrace and their families are ineligible. Void 218 * where prohibited. 219 */ 220 if (strcmp(modname, "dtrace") == 0) 221 return; 222 223 /* 224 * To register with DTrace, a module must list 'dtrace' as a 225 * dependency in order for the kernel linker to resolve 226 * symbols like dtrace_register(). All modules with such a 227 * dependency are ineligible for FBT tracing. 228 */ 229 for (i = 0; i < lf->ndeps; i++) 230 if (strncmp(lf->deps[i]->filename, "dtrace", 6) == 0) 231 return; 232 233 if (lf->fbt_nentries) { 234 /* 235 * This module has some FBT entries allocated; we're afraid 236 * to screw with it. 237 */ 238 return; 239 } 240 241 /* 242 * List the functions in the module and the symbol values. 243 */ 244 (void) linker_file_function_listall(lf, fbt_provide_module_function, modname); 245 } 246 #endif 247 #ifdef __NetBSD__ 248 static void 249 fbt_provide_module(void *arg, modctl_t *mod) 250 { 251 struct fbt_ksyms_arg fka; 252 struct mod_ctf *mc; 253 char modname[MAXPATHLEN]; 254 int i; 255 size_t len; 256 257 if (mod_ctf_get(mod, &mc)) { 258 printf("fbt: no CTF data for module %s\n", module_name(mod)); 259 return; 260 } 261 262 strlcpy(modname, module_name(mod), sizeof(modname)); 263 len = strlen(modname); 264 if (len > 5 && strcmp(modname + len - 3, ".kmod") == 0) 265 modname[len - 4] = '\0'; 266 267 /* 268 * Employees of dtrace and their families are ineligible. Void 269 * where prohibited. 270 */ 271 if (strcmp(modname, "dtrace") == 0) 272 return; 273 274 /* 275 * The cyclic timer subsystem can be built as a module and DTrace 276 * depends on that, so it is ineligible too. 277 */ 278 if (strcmp(modname, "cyclic") == 0) 279 return; 280 281 /* 282 * To register with DTrace, a module must list 'dtrace' as a 283 * dependency in order for the kernel linker to resolve 284 * symbols like dtrace_register(). All modules with such a 285 * dependency are ineligible for FBT tracing. 286 */ 287 for (i = 0; i < mod->mod_nrequired; i++) { 288 if (strncmp(module_name((*mod->mod_required)[i]), 289 "dtrace", 6) == 0) 290 return; 291 } 292 if (mc->fbt_provided) { 293 return; 294 } 295 296 /* 297 * List the functions in the module and the symbol values. 298 */ 299 memset(&fka, 0, sizeof(fka)); 300 fka.fka_mod = mod; 301 fka.fka_mc = mc; 302 ksyms_mod_foreach(modname, fbt_provide_module_cb, &fka); 303 mc->fbt_provided = true; 304 } 305 306 static void 307 fbt_module_dtor(void *arg) 308 { 309 mod_ctf_t *mc = arg; 310 311 if (mc->ctfalloc) 312 free(mc->ctftab, M_TEMP); 313 kmem_free(mc, sizeof(*mc)); 314 } 315 #endif 316 317 static void 318 fbt_destroy(void *arg, dtrace_id_t id, void *parg) 319 { 320 fbt_probe_t *fbt = parg, *next, *hash, *last; 321 modctl_t *ctl; 322 int ndx; 323 324 do { 325 ctl = fbt->fbtp_ctl; 326 327 #ifdef __FreeBSD__ 328 ctl->mod_fbtentries--; 329 #endif 330 #ifdef __NetBSD__ 331 mod_ctf_t *mc = module_getspecific(ctl, fbt_module_key); 332 mc->fbt_provided = false; 333 #endif 334 335 /* 336 * Now we need to remove this probe from the fbt_probetab. 337 */ 338 ndx = FBT_ADDR2NDX(fbt->fbtp_patchpoint); 339 last = NULL; 340 hash = fbt_probetab[ndx]; 341 342 while (hash != fbt) { 343 ASSERT(hash != NULL); 344 last = hash; 345 hash = hash->fbtp_hashnext; 346 } 347 348 if (last != NULL) { 349 last->fbtp_hashnext = fbt->fbtp_hashnext; 350 } else { 351 fbt_probetab[ndx] = fbt->fbtp_hashnext; 352 } 353 354 next = fbt->fbtp_next; 355 kmem_free(fbt, sizeof(*fbt)); 356 357 fbt = next; 358 } while (fbt != NULL); 359 } 360 361 static int 362 fbt_enable(void *arg, dtrace_id_t id, void *parg) 363 { 364 fbt_probe_t *fbt = parg; 365 modctl_t *ctl = fbt->fbtp_ctl; 366 367 #ifdef __NetBSD__ 368 module_hold(ctl); 369 #else 370 ctl->nenabled++; 371 372 /* 373 * Now check that our modctl has the expected load count. If it 374 * doesn't, this module must have been unloaded and reloaded -- and 375 * we're not going to touch it. 376 */ 377 if (ctl->loadcnt != fbt->fbtp_loadcnt) { 378 if (fbt_verbose) { 379 printf("fbt is failing for probe %s " 380 "(module %s reloaded)", 381 fbt->fbtp_name, module_name(ctl)); 382 } 383 384 return 0; 385 } 386 #endif 387 388 for (; fbt != NULL; fbt = fbt->fbtp_next) 389 fbt_patch_tracepoint(fbt, fbt->fbtp_patchval); 390 return 0; 391 } 392 393 static void 394 fbt_disable(void *arg, dtrace_id_t id, void *parg) 395 { 396 fbt_probe_t *fbt = parg; 397 modctl_t *ctl = fbt->fbtp_ctl; 398 399 #ifndef __NetBSD__ 400 ASSERT(ctl->nenabled > 0); 401 ctl->nenabled--; 402 403 if ((ctl->loadcnt != fbt->fbtp_loadcnt)) 404 return; 405 #endif 406 407 for (; fbt != NULL; fbt = fbt->fbtp_next) 408 fbt_patch_tracepoint(fbt, fbt->fbtp_savedval); 409 410 #ifdef __NetBSD__ 411 module_rele(ctl); 412 #endif 413 } 414 415 static void 416 fbt_suspend(void *arg, dtrace_id_t id, void *parg) 417 { 418 fbt_probe_t *fbt = parg; 419 #ifndef __NetBSD__ 420 modctl_t *ctl = fbt->fbtp_ctl; 421 422 ASSERT(ctl->nenabled > 0); 423 424 if ((ctl->loadcnt != fbt->fbtp_loadcnt)) 425 return; 426 #endif 427 428 for (; fbt != NULL; fbt = fbt->fbtp_next) 429 fbt_patch_tracepoint(fbt, fbt->fbtp_savedval); 430 } 431 432 static void 433 fbt_resume(void *arg, dtrace_id_t id, void *parg) 434 { 435 fbt_probe_t *fbt = parg; 436 #ifndef __NetBSD__ 437 modctl_t *ctl = fbt->fbtp_ctl; 438 439 ASSERT(ctl->nenabled > 0); 440 441 if ((ctl->loadcnt != fbt->fbtp_loadcnt)) 442 return; 443 #endif 444 445 for (; fbt != NULL; fbt = fbt->fbtp_next) 446 fbt_patch_tracepoint(fbt, fbt->fbtp_patchval); 447 } 448 449 static int 450 fbt_ctfoff_init(modctl_t *mod, mod_ctf_t *mc) 451 { 452 const Elf_Sym *symp = mc->symtab; 453 const ctf_header_t *hp = (const ctf_header_t *) mc->ctftab; 454 const uint8_t *ctfdata = mc->ctftab + sizeof(ctf_header_t); 455 int i; 456 uint32_t *ctfoff; 457 uint32_t objtoff = hp->cth_objtoff; 458 uint32_t funcoff = hp->cth_funcoff; 459 ushort_t info; 460 ushort_t vlen; 461 int nsyms = (mc->nmap != NULL) ? mc->nmapsize : mc->nsym; 462 463 /* Sanity check. */ 464 if (hp->cth_magic != CTF_MAGIC) { 465 printf("Bad magic value in CTF data of '%s'\n", 466 module_name(mod)); 467 return (EINVAL); 468 } 469 470 if (mc->symtab == NULL) { 471 printf("No symbol table in '%s'\n", module_name(mod)); 472 return (EINVAL); 473 } 474 475 ctfoff = malloc(sizeof(uint32_t) * nsyms, M_FBT, M_WAITOK); 476 mc->ctfoffp = ctfoff; 477 478 for (i = 0; i < nsyms; i++, ctfoff++, symp++) { 479 if (mc->nmap != NULL) { 480 if (mc->nmap[i] == 0) { 481 printf("%s.%d: Error! Got zero nmap!\n", 482 __func__, __LINE__); 483 continue; 484 } 485 486 /* 487 * CTF expects the unsorted symbol ordering, 488 * so map it from that to the current sorted 489 * symbol table. 490 * ctfoff[new-ind] = oldind symbol info. 491 */ 492 493 /* map old index to new symbol table */ 494 symp = &mc->symtab[mc->nmap[i] - 1]; 495 496 /* map old index to new ctfoff index */ 497 ctfoff = &mc->ctfoffp[mc->nmap[i]-1]; 498 } 499 500 /* 501 * Note that due to how kern_ksyms.c adjusts st_name 502 * to be the offset into a virtual combined strtab, 503 * st_name will never be 0 for loaded modules. 504 */ 505 506 if (symp->st_name == 0 || symp->st_shndx == SHN_UNDEF) { 507 *ctfoff = 0xffffffff; 508 continue; 509 } 510 511 switch (ELF_ST_TYPE(symp->st_info)) { 512 case STT_OBJECT: 513 if (objtoff >= hp->cth_funcoff || 514 (symp->st_shndx == SHN_ABS && symp->st_value == 0)) { 515 *ctfoff = 0xffffffff; 516 break; 517 } 518 519 *ctfoff = objtoff; 520 objtoff += sizeof (ushort_t); 521 break; 522 523 case STT_FUNC: 524 if (funcoff >= hp->cth_typeoff) { 525 *ctfoff = 0xffffffff; 526 break; 527 } 528 529 *ctfoff = funcoff; 530 531 info = *((const ushort_t *)(ctfdata + funcoff)); 532 vlen = CTF_INFO_VLEN(info); 533 534 /* 535 * If we encounter a zero pad at the end, just skip it. 536 * Otherwise skip over the function and its return type 537 * (+2) and the argument list (vlen). 538 */ 539 if (CTF_INFO_KIND(info) == CTF_K_UNKNOWN && vlen == 0) 540 funcoff += sizeof (ushort_t); /* skip pad */ 541 else 542 funcoff += sizeof (ushort_t) * (vlen + 2); 543 break; 544 545 default: 546 *ctfoff = 0xffffffff; 547 break; 548 } 549 } 550 551 return (0); 552 } 553 554 static ssize_t 555 fbt_get_ctt_size(uint8_t version, const ctf_type_t *tp, ssize_t *sizep, 556 ssize_t *incrementp) 557 { 558 ssize_t size, increment; 559 560 if (version > CTF_VERSION_1 && 561 tp->ctt_size == CTF_LSIZE_SENT) { 562 size = CTF_TYPE_LSIZE(tp); 563 increment = sizeof (ctf_type_t); 564 } else { 565 size = tp->ctt_size; 566 increment = sizeof (ctf_stype_t); 567 } 568 569 if (sizep) 570 *sizep = size; 571 if (incrementp) 572 *incrementp = increment; 573 574 return (size); 575 } 576 577 static int 578 fbt_typoff_init(mod_ctf_t *mc) 579 { 580 const ctf_header_t *hp = (const ctf_header_t *) mc->ctftab; 581 const ctf_type_t *tbuf; 582 const ctf_type_t *tend; 583 const ctf_type_t *tp; 584 const uint8_t *ctfdata = mc->ctftab + sizeof(ctf_header_t); 585 int ctf_typemax = 0; 586 uint32_t *xp; 587 ulong_t pop[CTF_K_MAX + 1] = { 0 }; 588 589 590 /* Sanity check. */ 591 if (hp->cth_magic != CTF_MAGIC) 592 return (EINVAL); 593 594 tbuf = (const ctf_type_t *) (ctfdata + hp->cth_typeoff); 595 tend = (const ctf_type_t *) (ctfdata + hp->cth_stroff); 596 597 int child = hp->cth_parname != 0; 598 599 /* 600 * We make two passes through the entire type section. In this first 601 * pass, we count the number of each type and the total number of types. 602 */ 603 for (tp = tbuf; tp < tend; ctf_typemax++) { 604 ushort_t kind = CTF_INFO_KIND(tp->ctt_info); 605 ulong_t vlen = CTF_INFO_VLEN(tp->ctt_info); 606 ssize_t size, increment; 607 608 size_t vbytes; 609 uint_t n; 610 611 (void) fbt_get_ctt_size(hp->cth_version, tp, &size, &increment); 612 613 switch (kind) { 614 case CTF_K_INTEGER: 615 case CTF_K_FLOAT: 616 vbytes = sizeof (uint_t); 617 break; 618 case CTF_K_ARRAY: 619 vbytes = sizeof (ctf_array_t); 620 break; 621 case CTF_K_FUNCTION: 622 vbytes = sizeof (ushort_t) * (vlen + (vlen & 1)); 623 break; 624 case CTF_K_STRUCT: 625 case CTF_K_UNION: 626 if (size < CTF_LSTRUCT_THRESH) { 627 ctf_member_t *mp = (ctf_member_t *) 628 ((uintptr_t)tp + increment); 629 630 vbytes = sizeof (ctf_member_t) * vlen; 631 for (n = vlen; n != 0; n--, mp++) 632 child |= CTF_TYPE_ISCHILD(mp->ctm_type); 633 } else { 634 ctf_lmember_t *lmp = (ctf_lmember_t *) 635 ((uintptr_t)tp + increment); 636 637 vbytes = sizeof (ctf_lmember_t) * vlen; 638 for (n = vlen; n != 0; n--, lmp++) 639 child |= 640 CTF_TYPE_ISCHILD(lmp->ctlm_type); 641 } 642 break; 643 case CTF_K_ENUM: 644 vbytes = sizeof (ctf_enum_t) * vlen; 645 break; 646 case CTF_K_FORWARD: 647 /* 648 * For forward declarations, ctt_type is the CTF_K_* 649 * kind for the tag, so bump that population count too. 650 * If ctt_type is unknown, treat the tag as a struct. 651 */ 652 if (tp->ctt_type == CTF_K_UNKNOWN || 653 tp->ctt_type >= CTF_K_MAX) 654 pop[CTF_K_STRUCT]++; 655 else 656 pop[tp->ctt_type]++; 657 /*FALLTHRU*/ 658 case CTF_K_UNKNOWN: 659 vbytes = 0; 660 break; 661 case CTF_K_POINTER: 662 case CTF_K_TYPEDEF: 663 case CTF_K_VOLATILE: 664 case CTF_K_CONST: 665 case CTF_K_RESTRICT: 666 child |= CTF_TYPE_ISCHILD(tp->ctt_type); 667 vbytes = 0; 668 break; 669 default: 670 printf("%s(%d): detected invalid CTF kind -- %u\n", 671 __func__, __LINE__, kind); 672 return (EIO); 673 } 674 tp = (ctf_type_t *)((uintptr_t)tp + increment + vbytes); 675 pop[kind]++; 676 } 677 678 /* account for a sentinel value below */ 679 ctf_typemax++; 680 mc->typlen = ctf_typemax; 681 682 xp = malloc(sizeof(uint32_t) * ctf_typemax, M_FBT, M_ZERO | M_WAITOK); 683 684 mc->typoffp = xp; 685 686 /* type id 0 is used as a sentinel value */ 687 *xp++ = 0; 688 689 /* 690 * In the second pass, fill in the type offset. 691 */ 692 for (tp = tbuf; tp < tend; xp++) { 693 ushort_t kind = CTF_INFO_KIND(tp->ctt_info); 694 ulong_t vlen = CTF_INFO_VLEN(tp->ctt_info); 695 ssize_t size, increment; 696 697 size_t vbytes; 698 uint_t n; 699 700 (void) fbt_get_ctt_size(hp->cth_version, tp, &size, &increment); 701 702 switch (kind) { 703 case CTF_K_INTEGER: 704 case CTF_K_FLOAT: 705 vbytes = sizeof (uint_t); 706 break; 707 case CTF_K_ARRAY: 708 vbytes = sizeof (ctf_array_t); 709 break; 710 case CTF_K_FUNCTION: 711 vbytes = sizeof (ushort_t) * (vlen + (vlen & 1)); 712 break; 713 case CTF_K_STRUCT: 714 case CTF_K_UNION: 715 if (size < CTF_LSTRUCT_THRESH) { 716 ctf_member_t *mp = (ctf_member_t *) 717 ((uintptr_t)tp + increment); 718 719 vbytes = sizeof (ctf_member_t) * vlen; 720 for (n = vlen; n != 0; n--, mp++) 721 child |= CTF_TYPE_ISCHILD(mp->ctm_type); 722 } else { 723 ctf_lmember_t *lmp = (ctf_lmember_t *) 724 ((uintptr_t)tp + increment); 725 726 vbytes = sizeof (ctf_lmember_t) * vlen; 727 for (n = vlen; n != 0; n--, lmp++) 728 child |= 729 CTF_TYPE_ISCHILD(lmp->ctlm_type); 730 } 731 break; 732 case CTF_K_ENUM: 733 vbytes = sizeof (ctf_enum_t) * vlen; 734 break; 735 case CTF_K_FORWARD: 736 case CTF_K_UNKNOWN: 737 vbytes = 0; 738 break; 739 case CTF_K_POINTER: 740 case CTF_K_TYPEDEF: 741 case CTF_K_VOLATILE: 742 case CTF_K_CONST: 743 case CTF_K_RESTRICT: 744 vbytes = 0; 745 break; 746 default: 747 printf("%s(%d): detected invalid CTF kind -- %u\n", __func__, __LINE__, kind); 748 return (EIO); 749 } 750 *xp = (uint32_t)((uintptr_t) tp - (uintptr_t) ctfdata); 751 tp = (ctf_type_t *)((uintptr_t)tp + increment + vbytes); 752 } 753 754 return (0); 755 } 756 757 /* 758 * CTF Declaration Stack 759 * 760 * In order to implement ctf_type_name(), we must convert a type graph back 761 * into a C type declaration. Unfortunately, a type graph represents a storage 762 * class ordering of the type whereas a type declaration must obey the C rules 763 * for operator precedence, and the two orderings are frequently in conflict. 764 * For example, consider these CTF type graphs and their C declarations: 765 * 766 * CTF_K_POINTER -> CTF_K_FUNCTION -> CTF_K_INTEGER : int (*)() 767 * CTF_K_POINTER -> CTF_K_ARRAY -> CTF_K_INTEGER : int (*)[] 768 * 769 * In each case, parentheses are used to raise operator * to higher lexical 770 * precedence, so the string form of the C declaration cannot be constructed by 771 * walking the type graph links and forming the string from left to right. 772 * 773 * The functions in this file build a set of stacks from the type graph nodes 774 * corresponding to the C operator precedence levels in the appropriate order. 775 * The code in ctf_type_name() can then iterate over the levels and nodes in 776 * lexical precedence order and construct the final C declaration string. 777 */ 778 typedef struct ctf_list { 779 struct ctf_list *l_prev; /* previous pointer or tail pointer */ 780 struct ctf_list *l_next; /* next pointer or head pointer */ 781 } ctf_list_t; 782 783 #define ctf_list_prev(elem) ((void *)(((ctf_list_t *)(elem))->l_prev)) 784 #define ctf_list_next(elem) ((void *)(((ctf_list_t *)(elem))->l_next)) 785 786 typedef enum { 787 CTF_PREC_BASE, 788 CTF_PREC_POINTER, 789 CTF_PREC_ARRAY, 790 CTF_PREC_FUNCTION, 791 CTF_PREC_MAX 792 } ctf_decl_prec_t; 793 794 typedef struct ctf_decl_node { 795 ctf_list_t cd_list; /* linked list pointers */ 796 ctf_id_t cd_type; /* type identifier */ 797 uint_t cd_kind; /* type kind */ 798 uint_t cd_n; /* type dimension if array */ 799 } ctf_decl_node_t; 800 801 typedef struct ctf_decl { 802 ctf_list_t cd_nodes[CTF_PREC_MAX]; /* declaration node stacks */ 803 int cd_order[CTF_PREC_MAX]; /* storage order of decls */ 804 ctf_decl_prec_t cd_qualp; /* qualifier precision */ 805 ctf_decl_prec_t cd_ordp; /* ordered precision */ 806 char *cd_buf; /* buffer for output */ 807 char *cd_ptr; /* buffer location */ 808 char *cd_end; /* buffer limit */ 809 size_t cd_len; /* buffer space required */ 810 int cd_err; /* saved error value */ 811 } ctf_decl_t; 812 813 /* 814 * Simple doubly-linked list append routine. This implementation assumes that 815 * each list element contains an embedded ctf_list_t as the first member. 816 * An additional ctf_list_t is used to store the head (l_next) and tail 817 * (l_prev) pointers. The current head and tail list elements have their 818 * previous and next pointers set to NULL, respectively. 819 */ 820 static void 821 ctf_list_append(ctf_list_t *lp, void *new) 822 { 823 ctf_list_t *p = lp->l_prev; /* p = tail list element */ 824 ctf_list_t *q = new; /* q = new list element */ 825 826 lp->l_prev = q; 827 q->l_prev = p; 828 q->l_next = NULL; 829 830 if (p != NULL) 831 p->l_next = q; 832 else 833 lp->l_next = q; 834 } 835 836 /* 837 * Prepend the specified existing element to the given ctf_list_t. The 838 * existing pointer should be pointing at a struct with embedded ctf_list_t. 839 */ 840 static void 841 ctf_list_prepend(ctf_list_t *lp, void *new) 842 { 843 ctf_list_t *p = new; /* p = new list element */ 844 ctf_list_t *q = lp->l_next; /* q = head list element */ 845 846 lp->l_next = p; 847 p->l_prev = NULL; 848 p->l_next = q; 849 850 if (q != NULL) 851 q->l_prev = p; 852 else 853 lp->l_prev = p; 854 } 855 856 static void 857 ctf_decl_init(ctf_decl_t *cd, char *buf, size_t len) 858 { 859 int i; 860 861 bzero(cd, sizeof (ctf_decl_t)); 862 863 for (i = CTF_PREC_BASE; i < CTF_PREC_MAX; i++) 864 cd->cd_order[i] = CTF_PREC_BASE - 1; 865 866 cd->cd_qualp = CTF_PREC_BASE; 867 cd->cd_ordp = CTF_PREC_BASE; 868 869 cd->cd_buf = buf; 870 cd->cd_ptr = buf; 871 cd->cd_end = buf + len; 872 } 873 874 static void 875 ctf_decl_fini(ctf_decl_t *cd) 876 { 877 ctf_decl_node_t *cdp, *ndp; 878 int i; 879 880 for (i = CTF_PREC_BASE; i < CTF_PREC_MAX; i++) { 881 for (cdp = ctf_list_next(&cd->cd_nodes[i]); 882 cdp != NULL; cdp = ndp) { 883 ndp = ctf_list_next(cdp); 884 free(cdp, M_FBT); 885 } 886 } 887 } 888 889 static const ctf_type_t * 890 ctf_lookup_by_id(mod_ctf_t *mc, ctf_id_t type) 891 { 892 const ctf_type_t *tp; 893 uint32_t offset; 894 uint32_t *typoff = mc->typoffp; 895 896 if (type >= mc->typlen) { 897 printf("%s(%d): type %d exceeds max %ld\n",__func__,__LINE__,(int) type,mc->typlen); 898 return(NULL); 899 } 900 901 /* Check if the type isn't cross-referenced. */ 902 if ((offset = typoff[type]) == 0) { 903 printf("%s(%d): type %d isn't cross referenced\n",__func__,__LINE__, (int) type); 904 return(NULL); 905 } 906 907 tp = (const ctf_type_t *)(mc->ctftab + offset + sizeof(ctf_header_t)); 908 909 return (tp); 910 } 911 912 static void 913 fbt_array_info(mod_ctf_t *mc, ctf_id_t type, ctf_arinfo_t *arp) 914 { 915 const ctf_header_t *hp = (const ctf_header_t *) mc->ctftab; 916 const ctf_type_t *tp; 917 const ctf_array_t *ap; 918 ssize_t increment; 919 920 bzero(arp, sizeof(*arp)); 921 922 if ((tp = ctf_lookup_by_id(mc, type)) == NULL) 923 return; 924 925 if (CTF_INFO_KIND(tp->ctt_info) != CTF_K_ARRAY) 926 return; 927 928 (void) fbt_get_ctt_size(hp->cth_version, tp, NULL, &increment); 929 930 ap = (const ctf_array_t *)((uintptr_t)tp + increment); 931 arp->ctr_contents = ap->cta_contents; 932 arp->ctr_index = ap->cta_index; 933 arp->ctr_nelems = ap->cta_nelems; 934 } 935 936 static const char * 937 ctf_strptr(mod_ctf_t *mc, int name) 938 { 939 const ctf_header_t *hp = (const ctf_header_t *) mc->ctftab;; 940 const char *strp = ""; 941 942 if (name < 0 || name >= hp->cth_strlen) 943 return(strp); 944 945 strp = (const char *)(mc->ctftab + hp->cth_stroff + name + sizeof(ctf_header_t)); 946 947 return (strp); 948 } 949 950 static void 951 ctf_decl_push(ctf_decl_t *cd, mod_ctf_t *mc, ctf_id_t type) 952 { 953 ctf_decl_node_t *cdp; 954 ctf_decl_prec_t prec; 955 uint_t kind, n = 1; 956 int is_qual = 0; 957 958 const ctf_type_t *tp; 959 ctf_arinfo_t ar; 960 961 if ((tp = ctf_lookup_by_id(mc, type)) == NULL) { 962 cd->cd_err = ENOENT; 963 return; 964 } 965 966 switch (kind = CTF_INFO_KIND(tp->ctt_info)) { 967 case CTF_K_ARRAY: 968 fbt_array_info(mc, type, &ar); 969 ctf_decl_push(cd, mc, ar.ctr_contents); 970 n = ar.ctr_nelems; 971 prec = CTF_PREC_ARRAY; 972 break; 973 974 case CTF_K_TYPEDEF: 975 if (ctf_strptr(mc, tp->ctt_name)[0] == '\0') { 976 ctf_decl_push(cd, mc, tp->ctt_type); 977 return; 978 } 979 prec = CTF_PREC_BASE; 980 break; 981 982 case CTF_K_FUNCTION: 983 ctf_decl_push(cd, mc, tp->ctt_type); 984 prec = CTF_PREC_FUNCTION; 985 break; 986 987 case CTF_K_POINTER: 988 ctf_decl_push(cd, mc, tp->ctt_type); 989 prec = CTF_PREC_POINTER; 990 break; 991 992 case CTF_K_VOLATILE: 993 case CTF_K_CONST: 994 case CTF_K_RESTRICT: 995 ctf_decl_push(cd, mc, tp->ctt_type); 996 prec = cd->cd_qualp; 997 is_qual++; 998 break; 999 1000 default: 1001 prec = CTF_PREC_BASE; 1002 } 1003 1004 cdp = malloc(sizeof(*cdp), M_FBT, M_WAITOK); 1005 cdp->cd_type = type; 1006 cdp->cd_kind = kind; 1007 cdp->cd_n = n; 1008 1009 if (ctf_list_next(&cd->cd_nodes[prec]) == NULL) 1010 cd->cd_order[prec] = cd->cd_ordp++; 1011 1012 /* 1013 * Reset cd_qualp to the highest precedence level that we've seen so 1014 * far that can be qualified (CTF_PREC_BASE or CTF_PREC_POINTER). 1015 */ 1016 if (prec > cd->cd_qualp && prec < CTF_PREC_ARRAY) 1017 cd->cd_qualp = prec; 1018 1019 /* 1020 * C array declarators are ordered inside out so prepend them. Also by 1021 * convention qualifiers of base types precede the type specifier (e.g. 1022 * const int vs. int const) even though the two forms are equivalent. 1023 */ 1024 if (kind == CTF_K_ARRAY || (is_qual && prec == CTF_PREC_BASE)) 1025 ctf_list_prepend(&cd->cd_nodes[prec], cdp); 1026 else 1027 ctf_list_append(&cd->cd_nodes[prec], cdp); 1028 } 1029 1030 static void 1031 ctf_decl_sprintf(ctf_decl_t *cd, const char *format, ...) 1032 { 1033 size_t len = (size_t)(cd->cd_end - cd->cd_ptr); 1034 va_list ap; 1035 size_t n; 1036 1037 va_start(ap, format); 1038 n = vsnprintf(cd->cd_ptr, len, format, ap); 1039 va_end(ap); 1040 1041 cd->cd_ptr += MIN(n, len); 1042 cd->cd_len += n; 1043 } 1044 1045 static ssize_t 1046 fbt_type_name(mod_ctf_t *mc, ctf_id_t type, char *buf, size_t len) 1047 { 1048 ctf_decl_t cd; 1049 ctf_decl_node_t *cdp; 1050 ctf_decl_prec_t prec, lp, rp; 1051 int ptr, arr; 1052 uint_t k; 1053 1054 if (mc == NULL && type == CTF_ERR) 1055 return (-1); /* simplify caller code by permitting CTF_ERR */ 1056 1057 ctf_decl_init(&cd, buf, len); 1058 ctf_decl_push(&cd, mc, type); 1059 1060 if (cd.cd_err != 0) { 1061 ctf_decl_fini(&cd); 1062 return (-1); 1063 } 1064 1065 /* 1066 * If the type graph's order conflicts with lexical precedence order 1067 * for pointers or arrays, then we need to surround the declarations at 1068 * the corresponding lexical precedence with parentheses. This can 1069 * result in either a parenthesized pointer (*) as in int (*)() or 1070 * int (*)[], or in a parenthesized pointer and array as in int (*[])(). 1071 */ 1072 ptr = cd.cd_order[CTF_PREC_POINTER] > CTF_PREC_POINTER; 1073 arr = cd.cd_order[CTF_PREC_ARRAY] > CTF_PREC_ARRAY; 1074 1075 rp = arr ? CTF_PREC_ARRAY : ptr ? CTF_PREC_POINTER : -1; 1076 lp = ptr ? CTF_PREC_POINTER : arr ? CTF_PREC_ARRAY : -1; 1077 1078 k = CTF_K_POINTER; /* avoid leading whitespace (see below) */ 1079 1080 for (prec = CTF_PREC_BASE; prec < CTF_PREC_MAX; prec++) { 1081 for (cdp = ctf_list_next(&cd.cd_nodes[prec]); 1082 cdp != NULL; cdp = ctf_list_next(cdp)) { 1083 1084 const ctf_type_t *tp = 1085 ctf_lookup_by_id(mc, cdp->cd_type); 1086 const char *name = ctf_strptr(mc, tp->ctt_name); 1087 1088 if (k != CTF_K_POINTER && k != CTF_K_ARRAY) 1089 ctf_decl_sprintf(&cd, " "); 1090 1091 if (lp == prec) { 1092 ctf_decl_sprintf(&cd, "("); 1093 lp = -1; 1094 } 1095 1096 switch (cdp->cd_kind) { 1097 case CTF_K_INTEGER: 1098 case CTF_K_FLOAT: 1099 case CTF_K_TYPEDEF: 1100 ctf_decl_sprintf(&cd, "%s", name); 1101 break; 1102 case CTF_K_POINTER: 1103 ctf_decl_sprintf(&cd, "*"); 1104 break; 1105 case CTF_K_ARRAY: 1106 ctf_decl_sprintf(&cd, "[%u]", cdp->cd_n); 1107 break; 1108 case CTF_K_FUNCTION: 1109 ctf_decl_sprintf(&cd, "()"); 1110 break; 1111 case CTF_K_STRUCT: 1112 case CTF_K_FORWARD: 1113 ctf_decl_sprintf(&cd, "struct %s", name); 1114 break; 1115 case CTF_K_UNION: 1116 ctf_decl_sprintf(&cd, "union %s", name); 1117 break; 1118 case CTF_K_ENUM: 1119 ctf_decl_sprintf(&cd, "enum %s", name); 1120 break; 1121 case CTF_K_VOLATILE: 1122 ctf_decl_sprintf(&cd, "volatile"); 1123 break; 1124 case CTF_K_CONST: 1125 ctf_decl_sprintf(&cd, "const"); 1126 break; 1127 case CTF_K_RESTRICT: 1128 ctf_decl_sprintf(&cd, "restrict"); 1129 break; 1130 } 1131 1132 k = cdp->cd_kind; 1133 } 1134 1135 if (rp == prec) 1136 ctf_decl_sprintf(&cd, ")"); 1137 } 1138 1139 ctf_decl_fini(&cd); 1140 return (cd.cd_len); 1141 } 1142 1143 static void 1144 fbt_getargdesc(void *arg __unused, dtrace_id_t id __unused, void *parg, dtrace_argdesc_t *desc) 1145 { 1146 const ushort_t *dp; 1147 fbt_probe_t *fbt = parg; 1148 mod_ctf_t *mc; 1149 modctl_t *ctl = fbt->fbtp_ctl; 1150 int ndx = desc->dtargd_ndx; 1151 int symindx = fbt->fbtp_symindx; 1152 uint32_t *ctfoff; 1153 uint32_t offset; 1154 ushort_t info, kind, n; 1155 int nsyms; 1156 1157 if (fbt->fbtp_roffset != 0 && desc->dtargd_ndx == 0) { 1158 (void) strcpy(desc->dtargd_native, "int"); 1159 return; 1160 } 1161 1162 desc->dtargd_ndx = DTRACE_ARGNONE; 1163 1164 /* Get a pointer to the CTF data and its length. */ 1165 if (mod_ctf_get(ctl, &mc) != 0) { 1166 static int report = 0; 1167 if (report < 1) { 1168 report++; 1169 printf("FBT: Error no CTF section found in module \"%s\"\n", 1170 module_name(ctl)); 1171 } 1172 /* No CTF data? Something wrong? *shrug* */ 1173 return; 1174 } 1175 1176 nsyms = (mc->nmap != NULL) ? mc->nmapsize : mc->nsym; 1177 1178 /* Check if this module hasn't been initialised yet. */ 1179 if (mc->ctfoffp == NULL) { 1180 /* 1181 * Initialise the CTF object and function symindx to 1182 * byte offset array. 1183 */ 1184 if (fbt_ctfoff_init(ctl, mc) != 0) 1185 return; 1186 1187 /* Initialise the CTF type to byte offset array. */ 1188 if (fbt_typoff_init(mc) != 0) 1189 return; 1190 } 1191 1192 ctfoff = mc->ctfoffp; 1193 1194 if (ctfoff == NULL || mc->typoffp == NULL) { 1195 return; 1196 } 1197 1198 /* Check if the symbol index is out of range. */ 1199 if (symindx >= nsyms) 1200 return; 1201 1202 /* Check if the symbol isn't cross-referenced. */ 1203 if ((offset = ctfoff[symindx]) == 0xffffffff) 1204 return; 1205 1206 dp = (const ushort_t *)(mc->ctftab + offset + sizeof(ctf_header_t)); 1207 1208 info = *dp++; 1209 kind = CTF_INFO_KIND(info); 1210 n = CTF_INFO_VLEN(info); 1211 1212 if (kind == CTF_K_UNKNOWN && n == 0) { 1213 printf("%s(%d): Unknown function %s!\n",__func__,__LINE__, 1214 fbt->fbtp_name); 1215 return; 1216 } 1217 1218 if (kind != CTF_K_FUNCTION) { 1219 printf("%s(%d): Expected a function %s!\n",__func__,__LINE__, 1220 fbt->fbtp_name); 1221 return; 1222 } 1223 1224 if (fbt->fbtp_roffset != 0) { 1225 /* Only return type is available for args[1] in return probe. */ 1226 if (ndx > 1) 1227 return; 1228 ASSERT(ndx == 1); 1229 } else { 1230 /* Check if the requested argument doesn't exist. */ 1231 if (ndx >= n) 1232 return; 1233 1234 /* Skip the return type and arguments up to the one requested. */ 1235 dp += ndx + 1; 1236 } 1237 1238 if (fbt_type_name(mc, *dp, desc->dtargd_native, sizeof(desc->dtargd_native)) > 0) 1239 desc->dtargd_ndx = ndx; 1240 1241 return; 1242 } 1243 1244 #ifdef __FreeBSD__ 1245 static int 1246 fbt_linker_file_cb(linker_file_t lf, void *arg) 1247 { 1248 1249 fbt_provide_module(arg, lf); 1250 1251 return (0); 1252 } 1253 #endif 1254 1255 static void 1256 fbt_load(void) 1257 { 1258 1259 #ifdef __FreeBSD__ 1260 /* Create the /dev/dtrace/fbt entry. */ 1261 fbt_cdev = make_dev(&fbt_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600, 1262 "dtrace/fbt"); 1263 #endif 1264 #ifdef __NetBSD__ 1265 (void) module_specific_key_create(&fbt_module_key, fbt_module_dtor); 1266 #endif 1267 1268 /* Default the probe table size if not specified. */ 1269 if (fbt_probetab_size == 0) 1270 fbt_probetab_size = FBT_PROBETAB_SIZE; 1271 1272 /* Choose the hash mask for the probe table. */ 1273 fbt_probetab_mask = fbt_probetab_size - 1; 1274 1275 /* Allocate memory for the probe table. */ 1276 fbt_probetab = 1277 malloc(fbt_probetab_size * sizeof (fbt_probe_t *), M_FBT, M_WAITOK | M_ZERO); 1278 1279 dtrace_doubletrap_func = fbt_doubletrap; 1280 dtrace_invop_add(fbt_invop); 1281 1282 if (dtrace_register("fbt", &fbt_attr, DTRACE_PRIV_USER, 1283 NULL, &fbt_pops, NULL, &fbt_id) != 0) 1284 return; 1285 } 1286 1287 1288 static int 1289 fbt_unload(void) 1290 { 1291 int error = 0; 1292 1293 /* De-register the invalid opcode handler. */ 1294 dtrace_invop_remove(fbt_invop); 1295 1296 dtrace_doubletrap_func = NULL; 1297 1298 /* De-register this DTrace provider. */ 1299 if ((error = dtrace_unregister(fbt_id)) != 0) 1300 return (error); 1301 1302 /* Free the probe table. */ 1303 free(fbt_probetab, M_FBT); 1304 fbt_probetab = NULL; 1305 fbt_probetab_mask = 0; 1306 1307 #ifdef __FreeBSD__ 1308 destroy_dev(fbt_cdev); 1309 #endif 1310 #ifdef __NetBSD__ 1311 (void) module_specific_key_delete(fbt_module_key); 1312 #endif 1313 return (error); 1314 } 1315 1316 1317 static int 1318 dtrace_fbt_modcmd(modcmd_t cmd, void *data) 1319 { 1320 int bmajor = -1, cmajor = 352; 1321 int error; 1322 1323 switch (cmd) { 1324 case MODULE_CMD_INIT: 1325 fbt_load(); 1326 return devsw_attach("fbt", NULL, &bmajor, 1327 &fbt_cdevsw, &cmajor); 1328 case MODULE_CMD_FINI: 1329 error = fbt_unload(); 1330 if (error != 0) 1331 return error; 1332 return devsw_detach(NULL, &fbt_cdevsw); 1333 case MODULE_CMD_AUTOUNLOAD: 1334 return EBUSY; 1335 default: 1336 return ENOTTY; 1337 } 1338 } 1339 1340 static int 1341 fbt_open(dev_t dev, int flags, int mode, struct lwp *l) 1342 { 1343 return (0); 1344 } 1345 1346 #ifdef __FreeBSD__ 1347 SYSINIT(fbt_load, SI_SUB_DTRACE_PROVIDER, SI_ORDER_ANY, fbt_load, NULL); 1348 SYSUNINIT(fbt_unload, SI_SUB_DTRACE_PROVIDER, SI_ORDER_ANY, fbt_unload, NULL); 1349 1350 DEV_MODULE(fbt, fbt_modevent, NULL); 1351 MODULE_VERSION(fbt, 1); 1352 MODULE_DEPEND(fbt, dtrace, 1, 1, 1); 1353 MODULE_DEPEND(fbt, opensolaris, 1, 1, 1); 1354 #endif 1355 #ifdef __NetBSD__ 1356 MODULE(MODULE_CLASS_MISC, dtrace_fbt, "dtrace,zlib"); 1357 #endif 1358