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.
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.
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]
21 * Portions Copyright 2006-2008 John Birrell jb@freebsd.org
28 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
29 * Use is subject to license terms.
32 #include <sys/cdefs.h>
33 #include <sys/param.h>
34 #include <sys/systm.h>
36 #include <sys/cpuvar.h>
37 #include <sys/fcntl.h>
38 #include <sys/filio.h>
40 #include <sys/kernel.h>
42 #include <sys/kthread.h>
43 #include <sys/limits.h>
44 #include <sys/linker.h>
46 #include <sys/malloc.h>
47 #include <sys/module.h>
48 #include <sys/mutex.h>
52 #include <sys/selinfo.h>
54 #include <sys/syscall.h>
55 #include <sys/sysent.h>
56 #include <sys/sysproto.h>
58 #include <sys/unistd.h>
59 #include <machine/stdarg.h>
61 #include <sys/dtrace.h>
62 #include <sys/dtrace_bsd.h>
66 MALLOC_DEFINE(M_FBT, "fbt", "Function Boundary Tracing");
68 dtrace_provider_id_t fbt_id;
69 fbt_probe_t **fbt_probetab;
70 int fbt_probetab_mask;
72 static d_open_t fbt_open;
73 static int fbt_unload(void);
74 static void fbt_getargdesc(void *, dtrace_id_t, void *, dtrace_argdesc_t *);
75 static void fbt_provide_module(void *, modctl_t *);
76 static void fbt_destroy(void *, dtrace_id_t, void *);
77 static void fbt_enable(void *, dtrace_id_t, void *);
78 static void fbt_disable(void *, dtrace_id_t, void *);
79 static void fbt_load(void *);
80 static void fbt_suspend(void *, dtrace_id_t, void *);
81 static void fbt_resume(void *, dtrace_id_t, void *);
83 static struct cdevsw fbt_cdevsw = {
84 .d_version = D_VERSION,
89 static dtrace_pattr_t fbt_attr = {
90 { DTRACE_STABILITY_EVOLVING, DTRACE_STABILITY_EVOLVING, DTRACE_CLASS_COMMON },
91 { DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_UNKNOWN },
92 { DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_ISA },
93 { DTRACE_STABILITY_EVOLVING, DTRACE_STABILITY_EVOLVING, DTRACE_CLASS_COMMON },
94 { DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_ISA },
97 static dtrace_pops_t fbt_pops = {
110 static struct cdev *fbt_cdev;
111 static int fbt_probetab_size;
112 static int fbt_verbose = 0;
115 fbt_excluded(const char *name)
118 if (strncmp(name, "dtrace_", 7) == 0 &&
119 strncmp(name, "dtrace_safe_", 12) != 0) {
121 * Anything beginning with "dtrace_" may be called
122 * from probe context unless it explicitly indicates
123 * that it won't be called from probe context by
124 * using the prefix "dtrace_safe_".
129 /* Exclude some internal functions */
130 if (name[0] == '_' && name[1] == '_')
134 * When DTrace is built into the kernel we need to exclude
135 * the FBT functions from instrumentation.
138 if (strncmp(name, "fbt_", 4) == 0)
151 for (i = 0; i < fbt_probetab_size; i++) {
152 fbt = fbt_probetab[i];
154 for (; fbt != NULL; fbt = fbt->fbtp_next)
155 fbt_patch_tracepoint(fbt, fbt->fbtp_savedval);
160 fbt_provide_module(void *arg, modctl_t *lf)
162 char modname[MAXPATHLEN];
166 strlcpy(modname, lf->filename, sizeof(modname));
167 len = strlen(modname);
168 if (len > 3 && strcmp(modname + len - 3, ".ko") == 0)
169 modname[len - 3] = '\0';
172 * Employees of dtrace and their families are ineligible. Void
175 if (strcmp(modname, "dtrace") == 0)
179 * To register with DTrace, a module must list 'dtrace' as a
180 * dependency in order for the kernel linker to resolve
181 * symbols like dtrace_register(). All modules with such a
182 * dependency are ineligible for FBT tracing.
184 for (i = 0; i < lf->ndeps; i++)
185 if (strncmp(lf->deps[i]->filename, "dtrace", 6) == 0)
188 if (lf->fbt_nentries) {
190 * This module has some FBT entries allocated; we're afraid
197 * List the functions in the module and the symbol values.
199 (void) linker_file_function_listall(lf, fbt_provide_module_function, modname);
203 fbt_destroy(void *arg, dtrace_id_t id, void *parg)
205 fbt_probe_t *fbt = parg, *next, *hash, *last;
215 * Now we need to remove this probe from the fbt_probetab.
217 ndx = FBT_ADDR2NDX(fbt->fbtp_patchpoint);
219 hash = fbt_probetab[ndx];
221 while (hash != fbt) {
222 ASSERT(hash != NULL);
224 hash = hash->fbtp_hashnext;
228 last->fbtp_hashnext = fbt->fbtp_hashnext;
230 fbt_probetab[ndx] = fbt->fbtp_hashnext;
233 next = fbt->fbtp_next;
237 } while (fbt != NULL);
241 fbt_enable(void *arg, dtrace_id_t id, void *parg)
243 fbt_probe_t *fbt = parg;
244 modctl_t *ctl = fbt->fbtp_ctl;
249 * Now check that our modctl has the expected load count. If it
250 * doesn't, this module must have been unloaded and reloaded -- and
251 * we're not going to touch it.
253 if (ctl->loadcnt != fbt->fbtp_loadcnt) {
255 printf("fbt is failing for probe %s "
256 "(module %s reloaded)",
257 fbt->fbtp_name, ctl->filename);
263 for (; fbt != NULL; fbt = fbt->fbtp_next)
264 fbt_patch_tracepoint(fbt, fbt->fbtp_patchval);
268 fbt_disable(void *arg, dtrace_id_t id, void *parg)
270 fbt_probe_t *fbt = parg;
271 modctl_t *ctl = fbt->fbtp_ctl;
273 ASSERT(ctl->nenabled > 0);
276 if ((ctl->loadcnt != fbt->fbtp_loadcnt))
279 for (; fbt != NULL; fbt = fbt->fbtp_next)
280 fbt_patch_tracepoint(fbt, fbt->fbtp_savedval);
284 fbt_suspend(void *arg, dtrace_id_t id, void *parg)
286 fbt_probe_t *fbt = parg;
287 modctl_t *ctl = fbt->fbtp_ctl;
289 ASSERT(ctl->nenabled > 0);
291 if ((ctl->loadcnt != fbt->fbtp_loadcnt))
294 for (; fbt != NULL; fbt = fbt->fbtp_next)
295 fbt_patch_tracepoint(fbt, fbt->fbtp_savedval);
299 fbt_resume(void *arg, dtrace_id_t id, void *parg)
301 fbt_probe_t *fbt = parg;
302 modctl_t *ctl = fbt->fbtp_ctl;
304 ASSERT(ctl->nenabled > 0);
306 if ((ctl->loadcnt != fbt->fbtp_loadcnt))
309 for (; fbt != NULL; fbt = fbt->fbtp_next)
310 fbt_patch_tracepoint(fbt, fbt->fbtp_patchval);
314 fbt_ctfoff_init(modctl_t *lf, linker_ctf_t *lc)
316 const Elf_Sym *symp = lc->symtab;;
317 const ctf_header_t *hp = (const ctf_header_t *) lc->ctftab;
318 const uint8_t *ctfdata = lc->ctftab + sizeof(ctf_header_t);
321 uint32_t objtoff = hp->cth_objtoff;
322 uint32_t funcoff = hp->cth_funcoff;
327 if (hp->cth_magic != CTF_MAGIC) {
328 printf("Bad magic value in CTF data of '%s'\n",lf->pathname);
332 if (lc->symtab == NULL) {
333 printf("No symbol table in '%s'\n",lf->pathname);
337 ctfoff = malloc(sizeof(uint32_t) * lc->nsym, M_LINKER, M_WAITOK);
338 *lc->ctfoffp = ctfoff;
340 for (i = 0; i < lc->nsym; i++, ctfoff++, symp++) {
341 if (symp->st_name == 0 || symp->st_shndx == SHN_UNDEF) {
342 *ctfoff = 0xffffffff;
346 switch (ELF_ST_TYPE(symp->st_info)) {
348 if (objtoff >= hp->cth_funcoff ||
349 (symp->st_shndx == SHN_ABS && symp->st_value == 0)) {
350 *ctfoff = 0xffffffff;
355 objtoff += sizeof (ushort_t);
359 if (funcoff >= hp->cth_typeoff) {
360 *ctfoff = 0xffffffff;
366 info = *((const ushort_t *)(ctfdata + funcoff));
367 vlen = CTF_INFO_VLEN(info);
370 * If we encounter a zero pad at the end, just skip it.
371 * Otherwise skip over the function and its return type
372 * (+2) and the argument list (vlen).
374 if (CTF_INFO_KIND(info) == CTF_K_UNKNOWN && vlen == 0)
375 funcoff += sizeof (ushort_t); /* skip pad */
377 funcoff += sizeof (ushort_t) * (vlen + 2);
381 *ctfoff = 0xffffffff;
390 fbt_get_ctt_size(uint8_t version, const ctf_type_t *tp, ssize_t *sizep,
393 ssize_t size, increment;
395 if (version > CTF_VERSION_1 &&
396 tp->ctt_size == CTF_LSIZE_SENT) {
397 size = CTF_TYPE_LSIZE(tp);
398 increment = sizeof (ctf_type_t);
401 increment = sizeof (ctf_stype_t);
407 *incrementp = increment;
413 fbt_typoff_init(linker_ctf_t *lc)
415 const ctf_header_t *hp = (const ctf_header_t *) lc->ctftab;
416 const ctf_type_t *tbuf;
417 const ctf_type_t *tend;
418 const ctf_type_t *tp;
419 const uint8_t *ctfdata = lc->ctftab + sizeof(ctf_header_t);
422 ulong_t pop[CTF_K_MAX + 1] = { 0 };
426 if (hp->cth_magic != CTF_MAGIC)
429 tbuf = (const ctf_type_t *) (ctfdata + hp->cth_typeoff);
430 tend = (const ctf_type_t *) (ctfdata + hp->cth_stroff);
432 int child = hp->cth_parname != 0;
435 * We make two passes through the entire type section. In this first
436 * pass, we count the number of each type and the total number of types.
438 for (tp = tbuf; tp < tend; ctf_typemax++) {
439 ushort_t kind = CTF_INFO_KIND(tp->ctt_info);
440 ulong_t vlen = CTF_INFO_VLEN(tp->ctt_info);
441 ssize_t size, increment;
446 (void) fbt_get_ctt_size(hp->cth_version, tp, &size, &increment);
451 vbytes = sizeof (uint_t);
454 vbytes = sizeof (ctf_array_t);
457 vbytes = sizeof (ushort_t) * (vlen + (vlen & 1));
461 if (size < CTF_LSTRUCT_THRESH) {
462 ctf_member_t *mp = (ctf_member_t *)
463 ((uintptr_t)tp + increment);
465 vbytes = sizeof (ctf_member_t) * vlen;
466 for (n = vlen; n != 0; n--, mp++)
467 child |= CTF_TYPE_ISCHILD(mp->ctm_type);
469 ctf_lmember_t *lmp = (ctf_lmember_t *)
470 ((uintptr_t)tp + increment);
472 vbytes = sizeof (ctf_lmember_t) * vlen;
473 for (n = vlen; n != 0; n--, lmp++)
475 CTF_TYPE_ISCHILD(lmp->ctlm_type);
479 vbytes = sizeof (ctf_enum_t) * vlen;
483 * For forward declarations, ctt_type is the CTF_K_*
484 * kind for the tag, so bump that population count too.
485 * If ctt_type is unknown, treat the tag as a struct.
487 if (tp->ctt_type == CTF_K_UNKNOWN ||
488 tp->ctt_type >= CTF_K_MAX)
501 child |= CTF_TYPE_ISCHILD(tp->ctt_type);
505 printf("%s(%d): detected invalid CTF kind -- %u\n", __func__, __LINE__, kind);
508 tp = (ctf_type_t *)((uintptr_t)tp + increment + vbytes);
512 /* account for a sentinel value below */
514 *lc->typlenp = ctf_typemax;
516 xp = malloc(sizeof(uint32_t) * ctf_typemax, M_LINKER,
521 /* type id 0 is used as a sentinel value */
525 * In the second pass, fill in the type offset.
527 for (tp = tbuf; tp < tend; xp++) {
528 ushort_t kind = CTF_INFO_KIND(tp->ctt_info);
529 ulong_t vlen = CTF_INFO_VLEN(tp->ctt_info);
530 ssize_t size, increment;
535 (void) fbt_get_ctt_size(hp->cth_version, tp, &size, &increment);
540 vbytes = sizeof (uint_t);
543 vbytes = sizeof (ctf_array_t);
546 vbytes = sizeof (ushort_t) * (vlen + (vlen & 1));
550 if (size < CTF_LSTRUCT_THRESH) {
551 ctf_member_t *mp = (ctf_member_t *)
552 ((uintptr_t)tp + increment);
554 vbytes = sizeof (ctf_member_t) * vlen;
555 for (n = vlen; n != 0; n--, mp++)
556 child |= CTF_TYPE_ISCHILD(mp->ctm_type);
558 ctf_lmember_t *lmp = (ctf_lmember_t *)
559 ((uintptr_t)tp + increment);
561 vbytes = sizeof (ctf_lmember_t) * vlen;
562 for (n = vlen; n != 0; n--, lmp++)
564 CTF_TYPE_ISCHILD(lmp->ctlm_type);
568 vbytes = sizeof (ctf_enum_t) * vlen;
582 printf("%s(%d): detected invalid CTF kind -- %u\n", __func__, __LINE__, kind);
585 *xp = (uint32_t)((uintptr_t) tp - (uintptr_t) ctfdata);
586 tp = (ctf_type_t *)((uintptr_t)tp + increment + vbytes);
593 * CTF Declaration Stack
595 * In order to implement ctf_type_name(), we must convert a type graph back
596 * into a C type declaration. Unfortunately, a type graph represents a storage
597 * class ordering of the type whereas a type declaration must obey the C rules
598 * for operator precedence, and the two orderings are frequently in conflict.
599 * For example, consider these CTF type graphs and their C declarations:
601 * CTF_K_POINTER -> CTF_K_FUNCTION -> CTF_K_INTEGER : int (*)()
602 * CTF_K_POINTER -> CTF_K_ARRAY -> CTF_K_INTEGER : int (*)[]
604 * In each case, parentheses are used to raise operator * to higher lexical
605 * precedence, so the string form of the C declaration cannot be constructed by
606 * walking the type graph links and forming the string from left to right.
608 * The functions in this file build a set of stacks from the type graph nodes
609 * corresponding to the C operator precedence levels in the appropriate order.
610 * The code in ctf_type_name() can then iterate over the levels and nodes in
611 * lexical precedence order and construct the final C declaration string.
613 typedef struct ctf_list {
614 struct ctf_list *l_prev; /* previous pointer or tail pointer */
615 struct ctf_list *l_next; /* next pointer or head pointer */
618 #define ctf_list_prev(elem) ((void *)(((ctf_list_t *)(elem))->l_prev))
619 #define ctf_list_next(elem) ((void *)(((ctf_list_t *)(elem))->l_next))
629 typedef struct ctf_decl_node {
630 ctf_list_t cd_list; /* linked list pointers */
631 ctf_id_t cd_type; /* type identifier */
632 uint_t cd_kind; /* type kind */
633 uint_t cd_n; /* type dimension if array */
636 typedef struct ctf_decl {
637 ctf_list_t cd_nodes[CTF_PREC_MAX]; /* declaration node stacks */
638 int cd_order[CTF_PREC_MAX]; /* storage order of decls */
639 ctf_decl_prec_t cd_qualp; /* qualifier precision */
640 ctf_decl_prec_t cd_ordp; /* ordered precision */
641 char *cd_buf; /* buffer for output */
642 char *cd_ptr; /* buffer location */
643 char *cd_end; /* buffer limit */
644 size_t cd_len; /* buffer space required */
645 int cd_err; /* saved error value */
649 * Simple doubly-linked list append routine. This implementation assumes that
650 * each list element contains an embedded ctf_list_t as the first member.
651 * An additional ctf_list_t is used to store the head (l_next) and tail
652 * (l_prev) pointers. The current head and tail list elements have their
653 * previous and next pointers set to NULL, respectively.
656 ctf_list_append(ctf_list_t *lp, void *new)
658 ctf_list_t *p = lp->l_prev; /* p = tail list element */
659 ctf_list_t *q = new; /* q = new list element */
672 * Prepend the specified existing element to the given ctf_list_t. The
673 * existing pointer should be pointing at a struct with embedded ctf_list_t.
676 ctf_list_prepend(ctf_list_t *lp, void *new)
678 ctf_list_t *p = new; /* p = new list element */
679 ctf_list_t *q = lp->l_next; /* q = head list element */
692 ctf_decl_init(ctf_decl_t *cd, char *buf, size_t len)
696 bzero(cd, sizeof (ctf_decl_t));
698 for (i = CTF_PREC_BASE; i < CTF_PREC_MAX; i++)
699 cd->cd_order[i] = CTF_PREC_BASE - 1;
701 cd->cd_qualp = CTF_PREC_BASE;
702 cd->cd_ordp = CTF_PREC_BASE;
706 cd->cd_end = buf + len;
710 ctf_decl_fini(ctf_decl_t *cd)
712 ctf_decl_node_t *cdp, *ndp;
715 for (i = CTF_PREC_BASE; i < CTF_PREC_MAX; i++) {
716 for (cdp = ctf_list_next(&cd->cd_nodes[i]);
717 cdp != NULL; cdp = ndp) {
718 ndp = ctf_list_next(cdp);
724 static const ctf_type_t *
725 ctf_lookup_by_id(linker_ctf_t *lc, ctf_id_t type)
727 const ctf_type_t *tp;
729 uint32_t *typoff = *lc->typoffp;
731 if (type >= *lc->typlenp) {
732 printf("%s(%d): type %d exceeds max %ld\n",__func__,__LINE__,(int) type,*lc->typlenp);
736 /* Check if the type isn't cross-referenced. */
737 if ((offset = typoff[type]) == 0) {
738 printf("%s(%d): type %d isn't cross referenced\n",__func__,__LINE__, (int) type);
742 tp = (const ctf_type_t *)(lc->ctftab + offset + sizeof(ctf_header_t));
748 fbt_array_info(linker_ctf_t *lc, ctf_id_t type, ctf_arinfo_t *arp)
750 const ctf_header_t *hp = (const ctf_header_t *) lc->ctftab;
751 const ctf_type_t *tp;
752 const ctf_array_t *ap;
755 bzero(arp, sizeof(*arp));
757 if ((tp = ctf_lookup_by_id(lc, type)) == NULL)
760 if (CTF_INFO_KIND(tp->ctt_info) != CTF_K_ARRAY)
763 (void) fbt_get_ctt_size(hp->cth_version, tp, NULL, &increment);
765 ap = (const ctf_array_t *)((uintptr_t)tp + increment);
766 arp->ctr_contents = ap->cta_contents;
767 arp->ctr_index = ap->cta_index;
768 arp->ctr_nelems = ap->cta_nelems;
772 ctf_strptr(linker_ctf_t *lc, int name)
774 const ctf_header_t *hp = (const ctf_header_t *) lc->ctftab;;
775 const char *strp = "";
777 if (name < 0 || name >= hp->cth_strlen)
780 strp = (const char *)(lc->ctftab + hp->cth_stroff + name + sizeof(ctf_header_t));
786 ctf_decl_push(ctf_decl_t *cd, linker_ctf_t *lc, ctf_id_t type)
788 ctf_decl_node_t *cdp;
789 ctf_decl_prec_t prec;
793 const ctf_type_t *tp;
796 if ((tp = ctf_lookup_by_id(lc, type)) == NULL) {
801 switch (kind = CTF_INFO_KIND(tp->ctt_info)) {
803 fbt_array_info(lc, type, &ar);
804 ctf_decl_push(cd, lc, ar.ctr_contents);
806 prec = CTF_PREC_ARRAY;
810 if (ctf_strptr(lc, tp->ctt_name)[0] == '\0') {
811 ctf_decl_push(cd, lc, tp->ctt_type);
814 prec = CTF_PREC_BASE;
818 ctf_decl_push(cd, lc, tp->ctt_type);
819 prec = CTF_PREC_FUNCTION;
823 ctf_decl_push(cd, lc, tp->ctt_type);
824 prec = CTF_PREC_POINTER;
830 ctf_decl_push(cd, lc, tp->ctt_type);
836 prec = CTF_PREC_BASE;
839 cdp = malloc(sizeof(*cdp), M_FBT, M_WAITOK);
844 if (ctf_list_next(&cd->cd_nodes[prec]) == NULL)
845 cd->cd_order[prec] = cd->cd_ordp++;
848 * Reset cd_qualp to the highest precedence level that we've seen so
849 * far that can be qualified (CTF_PREC_BASE or CTF_PREC_POINTER).
851 if (prec > cd->cd_qualp && prec < CTF_PREC_ARRAY)
855 * C array declarators are ordered inside out so prepend them. Also by
856 * convention qualifiers of base types precede the type specifier (e.g.
857 * const int vs. int const) even though the two forms are equivalent.
859 if (kind == CTF_K_ARRAY || (is_qual && prec == CTF_PREC_BASE))
860 ctf_list_prepend(&cd->cd_nodes[prec], cdp);
862 ctf_list_append(&cd->cd_nodes[prec], cdp);
866 ctf_decl_sprintf(ctf_decl_t *cd, const char *format, ...)
868 size_t len = (size_t)(cd->cd_end - cd->cd_ptr);
872 va_start(ap, format);
873 n = vsnprintf(cd->cd_ptr, len, format, ap);
876 cd->cd_ptr += MIN(n, len);
881 fbt_type_name(linker_ctf_t *lc, ctf_id_t type, char *buf, size_t len)
884 ctf_decl_node_t *cdp;
885 ctf_decl_prec_t prec, lp, rp;
889 if (lc == NULL && type == CTF_ERR)
890 return (-1); /* simplify caller code by permitting CTF_ERR */
892 ctf_decl_init(&cd, buf, len);
893 ctf_decl_push(&cd, lc, type);
895 if (cd.cd_err != 0) {
901 * If the type graph's order conflicts with lexical precedence order
902 * for pointers or arrays, then we need to surround the declarations at
903 * the corresponding lexical precedence with parentheses. This can
904 * result in either a parenthesized pointer (*) as in int (*)() or
905 * int (*)[], or in a parenthesized pointer and array as in int (*[])().
907 ptr = cd.cd_order[CTF_PREC_POINTER] > CTF_PREC_POINTER;
908 arr = cd.cd_order[CTF_PREC_ARRAY] > CTF_PREC_ARRAY;
910 rp = arr ? CTF_PREC_ARRAY : ptr ? CTF_PREC_POINTER : -1;
911 lp = ptr ? CTF_PREC_POINTER : arr ? CTF_PREC_ARRAY : -1;
913 k = CTF_K_POINTER; /* avoid leading whitespace (see below) */
915 for (prec = CTF_PREC_BASE; prec < CTF_PREC_MAX; prec++) {
916 for (cdp = ctf_list_next(&cd.cd_nodes[prec]);
917 cdp != NULL; cdp = ctf_list_next(cdp)) {
919 const ctf_type_t *tp =
920 ctf_lookup_by_id(lc, cdp->cd_type);
921 const char *name = ctf_strptr(lc, tp->ctt_name);
923 if (k != CTF_K_POINTER && k != CTF_K_ARRAY)
924 ctf_decl_sprintf(&cd, " ");
927 ctf_decl_sprintf(&cd, "(");
931 switch (cdp->cd_kind) {
935 ctf_decl_sprintf(&cd, "%s", name);
938 ctf_decl_sprintf(&cd, "*");
941 ctf_decl_sprintf(&cd, "[%u]", cdp->cd_n);
944 ctf_decl_sprintf(&cd, "()");
948 ctf_decl_sprintf(&cd, "struct %s", name);
951 ctf_decl_sprintf(&cd, "union %s", name);
954 ctf_decl_sprintf(&cd, "enum %s", name);
957 ctf_decl_sprintf(&cd, "volatile");
960 ctf_decl_sprintf(&cd, "const");
963 ctf_decl_sprintf(&cd, "restrict");
971 ctf_decl_sprintf(&cd, ")");
979 fbt_getargdesc(void *arg __unused, dtrace_id_t id __unused, void *parg, dtrace_argdesc_t *desc)
982 fbt_probe_t *fbt = parg;
984 modctl_t *ctl = fbt->fbtp_ctl;
985 int ndx = desc->dtargd_ndx;
986 int symindx = fbt->fbtp_symindx;
989 ushort_t info, kind, n;
991 if (fbt->fbtp_roffset != 0 && desc->dtargd_ndx == 0) {
992 (void) strcpy(desc->dtargd_native, "int");
996 desc->dtargd_ndx = DTRACE_ARGNONE;
998 /* Get a pointer to the CTF data and it's length. */
999 if (linker_ctf_get(ctl, &lc) != 0)
1000 /* No CTF data? Something wrong? *shrug* */
1003 /* Check if this module hasn't been initialised yet. */
1004 if (*lc.ctfoffp == NULL) {
1006 * Initialise the CTF object and function symindx to
1007 * byte offset array.
1009 if (fbt_ctfoff_init(ctl, &lc) != 0)
1012 /* Initialise the CTF type to byte offset array. */
1013 if (fbt_typoff_init(&lc) != 0)
1017 ctfoff = *lc.ctfoffp;
1019 if (ctfoff == NULL || *lc.typoffp == NULL)
1022 /* Check if the symbol index is out of range. */
1023 if (symindx >= lc.nsym)
1026 /* Check if the symbol isn't cross-referenced. */
1027 if ((offset = ctfoff[symindx]) == 0xffffffff)
1030 dp = (const ushort_t *)(lc.ctftab + offset + sizeof(ctf_header_t));
1033 kind = CTF_INFO_KIND(info);
1034 n = CTF_INFO_VLEN(info);
1036 if (kind == CTF_K_UNKNOWN && n == 0) {
1037 printf("%s(%d): Unknown function!\n",__func__,__LINE__);
1041 if (kind != CTF_K_FUNCTION) {
1042 printf("%s(%d): Expected a function!\n",__func__,__LINE__);
1046 if (fbt->fbtp_roffset != 0) {
1047 /* Only return type is available for args[1] in return probe. */
1052 /* Check if the requested argument doesn't exist. */
1056 /* Skip the return type and arguments up to the one requested. */
1060 if (fbt_type_name(&lc, *dp, desc->dtargd_native, sizeof(desc->dtargd_native)) > 0)
1061 desc->dtargd_ndx = ndx;
1067 fbt_linker_file_cb(linker_file_t lf, void *arg)
1070 fbt_provide_module(arg, lf);
1076 fbt_load(void *dummy)
1078 /* Create the /dev/dtrace/fbt entry. */
1079 fbt_cdev = make_dev(&fbt_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600,
1082 /* Default the probe table size if not specified. */
1083 if (fbt_probetab_size == 0)
1084 fbt_probetab_size = FBT_PROBETAB_SIZE;
1086 /* Choose the hash mask for the probe table. */
1087 fbt_probetab_mask = fbt_probetab_size - 1;
1089 /* Allocate memory for the probe table. */
1091 malloc(fbt_probetab_size * sizeof (fbt_probe_t *), M_FBT, M_WAITOK | M_ZERO);
1093 dtrace_doubletrap_func = fbt_doubletrap;
1094 dtrace_invop_add(fbt_invop);
1096 if (dtrace_register("fbt", &fbt_attr, DTRACE_PRIV_USER,
1097 NULL, &fbt_pops, NULL, &fbt_id) != 0)
1100 /* Create probes for the kernel and already-loaded modules. */
1101 linker_file_foreach(fbt_linker_file_cb, NULL);
1109 /* De-register the invalid opcode handler. */
1110 dtrace_invop_remove(fbt_invop);
1112 dtrace_doubletrap_func = NULL;
1114 /* De-register this DTrace provider. */
1115 if ((error = dtrace_unregister(fbt_id)) != 0)
1118 /* Free the probe table. */
1119 free(fbt_probetab, M_FBT);
1120 fbt_probetab = NULL;
1121 fbt_probetab_mask = 0;
1123 destroy_dev(fbt_cdev);
1129 fbt_modevent(module_t mod __unused, int type, void *data __unused)
1153 fbt_open(struct cdev *dev __unused, int oflags __unused, int devtype __unused, struct thread *td __unused)
1158 SYSINIT(fbt_load, SI_SUB_DTRACE_PROVIDER, SI_ORDER_ANY, fbt_load, NULL);
1159 SYSUNINIT(fbt_unload, SI_SUB_DTRACE_PROVIDER, SI_ORDER_ANY, fbt_unload, NULL);
1161 DEV_MODULE(fbt, fbt_modevent, NULL);
1162 MODULE_VERSION(fbt, 1);
1163 MODULE_DEPEND(fbt, dtrace, 1, 1, 1);
1164 MODULE_DEPEND(fbt, opensolaris, 1, 1, 1);