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