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/endian.h>
38 #include <sys/fcntl.h>
39 #include <sys/filio.h>
41 #include <sys/kernel.h>
43 #include <sys/kthread.h>
44 #include <sys/limits.h>
45 #include <sys/linker.h>
47 #include <sys/malloc.h>
48 #include <sys/module.h>
49 #include <sys/mutex.h>
53 #include <sys/selinfo.h>
55 #include <sys/syscall.h>
56 #include <sys/sysent.h>
57 #include <sys/sysproto.h>
59 #include <sys/unistd.h>
60 #include <machine/stdarg.h>
62 #include <sys/dtrace.h>
63 #include <sys/dtrace_bsd.h>
67 MALLOC_DEFINE(M_FBT, "fbt", "Function Boundary Tracing");
69 dtrace_provider_id_t fbt_id;
70 fbt_probe_t **fbt_probetab;
71 int fbt_probetab_mask;
73 static d_open_t fbt_open;
74 static int fbt_unload(void);
75 static void fbt_getargdesc(void *, dtrace_id_t, void *, dtrace_argdesc_t *);
76 static void fbt_provide_module(void *, modctl_t *);
77 static void fbt_destroy(void *, dtrace_id_t, void *);
78 static void fbt_enable(void *, dtrace_id_t, void *);
79 static void fbt_disable(void *, dtrace_id_t, void *);
80 static void fbt_load(void *);
81 static void fbt_suspend(void *, dtrace_id_t, void *);
82 static void fbt_resume(void *, dtrace_id_t, void *);
84 static struct cdevsw fbt_cdevsw = {
85 .d_version = D_VERSION,
90 static dtrace_pattr_t fbt_attr = {
91 { DTRACE_STABILITY_EVOLVING, DTRACE_STABILITY_EVOLVING, DTRACE_CLASS_COMMON },
92 { DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_UNKNOWN },
93 { DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_ISA },
94 { DTRACE_STABILITY_EVOLVING, DTRACE_STABILITY_EVOLVING, DTRACE_CLASS_COMMON },
95 { DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_ISA },
98 static dtrace_pops_t fbt_pops = {
100 .dtps_provide_module = fbt_provide_module,
101 .dtps_enable = fbt_enable,
102 .dtps_disable = fbt_disable,
103 .dtps_suspend = fbt_suspend,
104 .dtps_resume = fbt_resume,
105 .dtps_getargdesc = fbt_getargdesc,
106 .dtps_getargval = NULL,
107 .dtps_usermode = NULL,
108 .dtps_destroy = fbt_destroy
111 static struct cdev *fbt_cdev;
112 static int fbt_probetab_size;
113 static int fbt_verbose = 0;
116 fbt_excluded(const char *name)
119 if (strncmp(name, "dtrace_", 7) == 0 &&
120 strncmp(name, "dtrace_safe_", 12) != 0) {
122 * Anything beginning with "dtrace_" may be called
123 * from probe context unless it explicitly indicates
124 * that it won't be called from probe context by
125 * using the prefix "dtrace_safe_".
131 * Lock owner methods may be called from probe context.
133 if (strcmp(name, "owner_mtx") == 0 ||
134 strcmp(name, "owner_rm") == 0 ||
135 strcmp(name, "owner_rw") == 0 ||
136 strcmp(name, "owner_sx") == 0)
140 * Stack unwinders may be called from probe context on some
144 if (strcmp(name, "unwind_frame") == 0)
149 * When DTrace is built into the kernel we need to exclude
150 * the FBT functions from instrumentation.
153 if (strncmp(name, "fbt_", 4) == 0)
166 for (i = 0; i < fbt_probetab_size; i++) {
167 fbt = fbt_probetab[i];
169 for (; fbt != NULL; fbt = fbt->fbtp_probenext)
170 fbt_patch_tracepoint(fbt, fbt->fbtp_savedval);
175 fbt_provide_module(void *arg, modctl_t *lf)
177 char modname[MAXPATHLEN];
181 strlcpy(modname, lf->filename, sizeof(modname));
182 len = strlen(modname);
183 if (len > 3 && strcmp(modname + len - 3, ".ko") == 0)
184 modname[len - 3] = '\0';
187 * Employees of dtrace and their families are ineligible. Void
190 if (strcmp(modname, "dtrace") == 0)
194 * To register with DTrace, a module must list 'dtrace' as a
195 * dependency in order for the kernel linker to resolve
196 * symbols like dtrace_register(). All modules with such a
197 * dependency are ineligible for FBT tracing.
199 for (i = 0; i < lf->ndeps; i++)
200 if (strncmp(lf->deps[i]->filename, "dtrace", 6) == 0)
203 if (lf->fbt_nentries) {
205 * This module has some FBT entries allocated; we're afraid
212 * List the functions in the module and the symbol values.
214 (void) linker_file_function_listall(lf, fbt_provide_module_function, modname);
218 fbt_destroy_one(fbt_probe_t *fbt)
220 fbt_probe_t *hash, *hashprev, *next;
223 ndx = FBT_ADDR2NDX(fbt->fbtp_patchpoint);
224 for (hash = fbt_probetab[ndx], hashprev = NULL; hash != NULL;
225 hashprev = hash, hash = hash->fbtp_hashnext) {
227 if ((next = fbt->fbtp_tracenext) != NULL)
228 next->fbtp_hashnext = hash->fbtp_hashnext;
230 next = hash->fbtp_hashnext;
231 if (hashprev != NULL)
232 hashprev->fbtp_hashnext = next;
234 fbt_probetab[ndx] = next;
236 } else if (hash->fbtp_patchpoint == fbt->fbtp_patchpoint) {
237 for (next = hash; next->fbtp_tracenext != NULL;
238 next = next->fbtp_tracenext) {
239 if (fbt == next->fbtp_tracenext) {
240 next->fbtp_tracenext =
247 panic("probe %p not found in hash table", fbt);
253 fbt_destroy(void *arg, dtrace_id_t id, void *parg)
255 fbt_probe_t *fbt = parg, *next;
262 next = fbt->fbtp_probenext;
263 fbt_destroy_one(fbt);
265 } while (fbt != NULL);
269 fbt_enable(void *arg, dtrace_id_t id, void *parg)
271 fbt_probe_t *fbt = parg;
272 modctl_t *ctl = fbt->fbtp_ctl;
277 * Now check that our modctl has the expected load count. If it
278 * doesn't, this module must have been unloaded and reloaded -- and
279 * we're not going to touch it.
281 if (ctl->loadcnt != fbt->fbtp_loadcnt) {
283 printf("fbt is failing for probe %s "
284 "(module %s reloaded)",
285 fbt->fbtp_name, ctl->filename);
291 for (; fbt != NULL; fbt = fbt->fbtp_probenext) {
292 fbt_patch_tracepoint(fbt, fbt->fbtp_patchval);
298 fbt_disable(void *arg, dtrace_id_t id, void *parg)
300 fbt_probe_t *fbt = parg, *hash;
301 modctl_t *ctl = fbt->fbtp_ctl;
303 ASSERT(ctl->nenabled > 0);
306 if ((ctl->loadcnt != fbt->fbtp_loadcnt))
309 for (; fbt != NULL; fbt = fbt->fbtp_probenext) {
312 for (hash = fbt_probetab[FBT_ADDR2NDX(fbt->fbtp_patchpoint)];
313 hash != NULL; hash = hash->fbtp_hashnext) {
314 if (hash->fbtp_patchpoint == fbt->fbtp_patchpoint) {
315 for (; hash != NULL; hash = hash->fbtp_tracenext)
316 if (hash->fbtp_enabled > 0)
322 fbt_patch_tracepoint(fbt, fbt->fbtp_savedval);
327 fbt_suspend(void *arg, dtrace_id_t id, void *parg)
329 fbt_probe_t *fbt = parg;
330 modctl_t *ctl = fbt->fbtp_ctl;
332 ASSERT(ctl->nenabled > 0);
334 if ((ctl->loadcnt != fbt->fbtp_loadcnt))
337 for (; fbt != NULL; fbt = fbt->fbtp_probenext)
338 fbt_patch_tracepoint(fbt, fbt->fbtp_savedval);
342 fbt_resume(void *arg, dtrace_id_t id, void *parg)
344 fbt_probe_t *fbt = parg;
345 modctl_t *ctl = fbt->fbtp_ctl;
347 ASSERT(ctl->nenabled > 0);
349 if ((ctl->loadcnt != fbt->fbtp_loadcnt))
352 for (; fbt != NULL; fbt = fbt->fbtp_probenext)
353 fbt_patch_tracepoint(fbt, fbt->fbtp_patchval);
357 fbt_ctfoff_init(modctl_t *lf, linker_ctf_t *lc)
359 const Elf_Sym *symp = lc->symtab;;
360 const ctf_header_t *hp = (const ctf_header_t *) lc->ctftab;
361 const uint8_t *ctfdata = lc->ctftab + sizeof(ctf_header_t);
364 uint32_t objtoff = hp->cth_objtoff;
365 uint32_t funcoff = hp->cth_funcoff;
370 if (hp->cth_magic != CTF_MAGIC) {
371 printf("Bad magic value in CTF data of '%s'\n",lf->pathname);
375 if (lc->symtab == NULL) {
376 printf("No symbol table in '%s'\n",lf->pathname);
380 ctfoff = malloc(sizeof(uint32_t) * lc->nsym, M_LINKER, M_WAITOK);
381 *lc->ctfoffp = ctfoff;
383 for (i = 0; i < lc->nsym; i++, ctfoff++, symp++) {
384 if (symp->st_name == 0 || symp->st_shndx == SHN_UNDEF) {
385 *ctfoff = 0xffffffff;
389 switch (ELF_ST_TYPE(symp->st_info)) {
391 if (objtoff >= hp->cth_funcoff ||
392 (symp->st_shndx == SHN_ABS && symp->st_value == 0)) {
393 *ctfoff = 0xffffffff;
398 objtoff += sizeof (ushort_t);
402 if (funcoff >= hp->cth_typeoff) {
403 *ctfoff = 0xffffffff;
409 info = *((const ushort_t *)(ctfdata + funcoff));
410 vlen = CTF_INFO_VLEN(info);
413 * If we encounter a zero pad at the end, just skip it.
414 * Otherwise skip over the function and its return type
415 * (+2) and the argument list (vlen).
417 if (CTF_INFO_KIND(info) == CTF_K_UNKNOWN && vlen == 0)
418 funcoff += sizeof (ushort_t); /* skip pad */
420 funcoff += sizeof (ushort_t) * (vlen + 2);
424 *ctfoff = 0xffffffff;
433 fbt_get_ctt_size(uint8_t version, const ctf_type_t *tp, ssize_t *sizep,
436 ssize_t size, increment;
438 if (version > CTF_VERSION_1 &&
439 tp->ctt_size == CTF_LSIZE_SENT) {
440 size = CTF_TYPE_LSIZE(tp);
441 increment = sizeof (ctf_type_t);
444 increment = sizeof (ctf_stype_t);
450 *incrementp = increment;
456 fbt_typoff_init(linker_ctf_t *lc)
458 const ctf_header_t *hp = (const ctf_header_t *) lc->ctftab;
459 const ctf_type_t *tbuf;
460 const ctf_type_t *tend;
461 const ctf_type_t *tp;
462 const uint8_t *ctfdata = lc->ctftab + sizeof(ctf_header_t);
465 ulong_t pop[CTF_K_MAX + 1] = { 0 };
469 if (hp->cth_magic != CTF_MAGIC)
472 tbuf = (const ctf_type_t *) (ctfdata + hp->cth_typeoff);
473 tend = (const ctf_type_t *) (ctfdata + hp->cth_stroff);
475 int child = hp->cth_parname != 0;
478 * We make two passes through the entire type section. In this first
479 * pass, we count the number of each type and the total number of types.
481 for (tp = tbuf; tp < tend; ctf_typemax++) {
482 ushort_t kind = CTF_INFO_KIND(tp->ctt_info);
483 ulong_t vlen = CTF_INFO_VLEN(tp->ctt_info);
484 ssize_t size, increment;
489 (void) fbt_get_ctt_size(hp->cth_version, tp, &size, &increment);
494 vbytes = sizeof (uint_t);
497 vbytes = sizeof (ctf_array_t);
500 vbytes = sizeof (ushort_t) * (vlen + (vlen & 1));
504 if (size < CTF_LSTRUCT_THRESH) {
505 ctf_member_t *mp = (ctf_member_t *)
506 ((uintptr_t)tp + increment);
508 vbytes = sizeof (ctf_member_t) * vlen;
509 for (n = vlen; n != 0; n--, mp++)
510 child |= CTF_TYPE_ISCHILD(mp->ctm_type);
512 ctf_lmember_t *lmp = (ctf_lmember_t *)
513 ((uintptr_t)tp + increment);
515 vbytes = sizeof (ctf_lmember_t) * vlen;
516 for (n = vlen; n != 0; n--, lmp++)
518 CTF_TYPE_ISCHILD(lmp->ctlm_type);
522 vbytes = sizeof (ctf_enum_t) * vlen;
526 * For forward declarations, ctt_type is the CTF_K_*
527 * kind for the tag, so bump that population count too.
528 * If ctt_type is unknown, treat the tag as a struct.
530 if (tp->ctt_type == CTF_K_UNKNOWN ||
531 tp->ctt_type >= CTF_K_MAX)
544 child |= CTF_TYPE_ISCHILD(tp->ctt_type);
548 printf("%s(%d): detected invalid CTF kind -- %u\n", __func__, __LINE__, kind);
551 tp = (ctf_type_t *)((uintptr_t)tp + increment + vbytes);
555 /* account for a sentinel value below */
557 *lc->typlenp = ctf_typemax;
559 xp = malloc(sizeof(uint32_t) * ctf_typemax, M_LINKER,
564 /* type id 0 is used as a sentinel value */
568 * In the second pass, fill in the type offset.
570 for (tp = tbuf; tp < tend; xp++) {
571 ushort_t kind = CTF_INFO_KIND(tp->ctt_info);
572 ulong_t vlen = CTF_INFO_VLEN(tp->ctt_info);
573 ssize_t size, increment;
578 (void) fbt_get_ctt_size(hp->cth_version, tp, &size, &increment);
583 vbytes = sizeof (uint_t);
586 vbytes = sizeof (ctf_array_t);
589 vbytes = sizeof (ushort_t) * (vlen + (vlen & 1));
593 if (size < CTF_LSTRUCT_THRESH) {
594 ctf_member_t *mp = (ctf_member_t *)
595 ((uintptr_t)tp + increment);
597 vbytes = sizeof (ctf_member_t) * vlen;
598 for (n = vlen; n != 0; n--, mp++)
599 child |= CTF_TYPE_ISCHILD(mp->ctm_type);
601 ctf_lmember_t *lmp = (ctf_lmember_t *)
602 ((uintptr_t)tp + increment);
604 vbytes = sizeof (ctf_lmember_t) * vlen;
605 for (n = vlen; n != 0; n--, lmp++)
607 CTF_TYPE_ISCHILD(lmp->ctlm_type);
611 vbytes = sizeof (ctf_enum_t) * vlen;
625 printf("%s(%d): detected invalid CTF kind -- %u\n", __func__, __LINE__, kind);
628 *xp = (uint32_t)((uintptr_t) tp - (uintptr_t) ctfdata);
629 tp = (ctf_type_t *)((uintptr_t)tp + increment + vbytes);
636 * CTF Declaration Stack
638 * In order to implement ctf_type_name(), we must convert a type graph back
639 * into a C type declaration. Unfortunately, a type graph represents a storage
640 * class ordering of the type whereas a type declaration must obey the C rules
641 * for operator precedence, and the two orderings are frequently in conflict.
642 * For example, consider these CTF type graphs and their C declarations:
644 * CTF_K_POINTER -> CTF_K_FUNCTION -> CTF_K_INTEGER : int (*)()
645 * CTF_K_POINTER -> CTF_K_ARRAY -> CTF_K_INTEGER : int (*)[]
647 * In each case, parentheses are used to raise operator * to higher lexical
648 * precedence, so the string form of the C declaration cannot be constructed by
649 * walking the type graph links and forming the string from left to right.
651 * The functions in this file build a set of stacks from the type graph nodes
652 * corresponding to the C operator precedence levels in the appropriate order.
653 * The code in ctf_type_name() can then iterate over the levels and nodes in
654 * lexical precedence order and construct the final C declaration string.
656 typedef struct ctf_list {
657 struct ctf_list *l_prev; /* previous pointer or tail pointer */
658 struct ctf_list *l_next; /* next pointer or head pointer */
661 #define ctf_list_prev(elem) ((void *)(((ctf_list_t *)(elem))->l_prev))
662 #define ctf_list_next(elem) ((void *)(((ctf_list_t *)(elem))->l_next))
672 typedef struct ctf_decl_node {
673 ctf_list_t cd_list; /* linked list pointers */
674 ctf_id_t cd_type; /* type identifier */
675 uint_t cd_kind; /* type kind */
676 uint_t cd_n; /* type dimension if array */
679 typedef struct ctf_decl {
680 ctf_list_t cd_nodes[CTF_PREC_MAX]; /* declaration node stacks */
681 int cd_order[CTF_PREC_MAX]; /* storage order of decls */
682 ctf_decl_prec_t cd_qualp; /* qualifier precision */
683 ctf_decl_prec_t cd_ordp; /* ordered precision */
684 char *cd_buf; /* buffer for output */
685 char *cd_ptr; /* buffer location */
686 char *cd_end; /* buffer limit */
687 size_t cd_len; /* buffer space required */
688 int cd_err; /* saved error value */
692 * Simple doubly-linked list append routine. This implementation assumes that
693 * each list element contains an embedded ctf_list_t as the first member.
694 * An additional ctf_list_t is used to store the head (l_next) and tail
695 * (l_prev) pointers. The current head and tail list elements have their
696 * previous and next pointers set to NULL, respectively.
699 ctf_list_append(ctf_list_t *lp, void *new)
701 ctf_list_t *p = lp->l_prev; /* p = tail list element */
702 ctf_list_t *q = new; /* q = new list element */
715 * Prepend the specified existing element to the given ctf_list_t. The
716 * existing pointer should be pointing at a struct with embedded ctf_list_t.
719 ctf_list_prepend(ctf_list_t *lp, void *new)
721 ctf_list_t *p = new; /* p = new list element */
722 ctf_list_t *q = lp->l_next; /* q = head list element */
735 ctf_decl_init(ctf_decl_t *cd, char *buf, size_t len)
739 bzero(cd, sizeof (ctf_decl_t));
741 for (i = CTF_PREC_BASE; i < CTF_PREC_MAX; i++)
742 cd->cd_order[i] = CTF_PREC_BASE - 1;
744 cd->cd_qualp = CTF_PREC_BASE;
745 cd->cd_ordp = CTF_PREC_BASE;
749 cd->cd_end = buf + len;
753 ctf_decl_fini(ctf_decl_t *cd)
755 ctf_decl_node_t *cdp, *ndp;
758 for (i = CTF_PREC_BASE; i < CTF_PREC_MAX; i++) {
759 for (cdp = ctf_list_next(&cd->cd_nodes[i]);
760 cdp != NULL; cdp = ndp) {
761 ndp = ctf_list_next(cdp);
767 static const ctf_type_t *
768 ctf_lookup_by_id(linker_ctf_t *lc, ctf_id_t type)
770 const ctf_type_t *tp;
772 uint32_t *typoff = *lc->typoffp;
774 if (type >= *lc->typlenp) {
775 printf("%s(%d): type %d exceeds max %ld\n",__func__,__LINE__,(int) type,*lc->typlenp);
779 /* Check if the type isn't cross-referenced. */
780 if ((offset = typoff[type]) == 0) {
781 printf("%s(%d): type %d isn't cross referenced\n",__func__,__LINE__, (int) type);
785 tp = (const ctf_type_t *)(lc->ctftab + offset + sizeof(ctf_header_t));
791 fbt_array_info(linker_ctf_t *lc, ctf_id_t type, ctf_arinfo_t *arp)
793 const ctf_header_t *hp = (const ctf_header_t *) lc->ctftab;
794 const ctf_type_t *tp;
795 const ctf_array_t *ap;
798 bzero(arp, sizeof(*arp));
800 if ((tp = ctf_lookup_by_id(lc, type)) == NULL)
803 if (CTF_INFO_KIND(tp->ctt_info) != CTF_K_ARRAY)
806 (void) fbt_get_ctt_size(hp->cth_version, tp, NULL, &increment);
808 ap = (const ctf_array_t *)((uintptr_t)tp + increment);
809 arp->ctr_contents = ap->cta_contents;
810 arp->ctr_index = ap->cta_index;
811 arp->ctr_nelems = ap->cta_nelems;
815 ctf_strptr(linker_ctf_t *lc, int name)
817 const ctf_header_t *hp = (const ctf_header_t *) lc->ctftab;;
818 const char *strp = "";
820 if (name < 0 || name >= hp->cth_strlen)
823 strp = (const char *)(lc->ctftab + hp->cth_stroff + name + sizeof(ctf_header_t));
829 ctf_decl_push(ctf_decl_t *cd, linker_ctf_t *lc, ctf_id_t type)
831 ctf_decl_node_t *cdp;
832 ctf_decl_prec_t prec;
836 const ctf_type_t *tp;
839 if ((tp = ctf_lookup_by_id(lc, type)) == NULL) {
844 switch (kind = CTF_INFO_KIND(tp->ctt_info)) {
846 fbt_array_info(lc, type, &ar);
847 ctf_decl_push(cd, lc, ar.ctr_contents);
849 prec = CTF_PREC_ARRAY;
853 if (ctf_strptr(lc, tp->ctt_name)[0] == '\0') {
854 ctf_decl_push(cd, lc, tp->ctt_type);
857 prec = CTF_PREC_BASE;
861 ctf_decl_push(cd, lc, tp->ctt_type);
862 prec = CTF_PREC_FUNCTION;
866 ctf_decl_push(cd, lc, tp->ctt_type);
867 prec = CTF_PREC_POINTER;
873 ctf_decl_push(cd, lc, tp->ctt_type);
879 prec = CTF_PREC_BASE;
882 cdp = malloc(sizeof(*cdp), M_FBT, M_WAITOK);
887 if (ctf_list_next(&cd->cd_nodes[prec]) == NULL)
888 cd->cd_order[prec] = cd->cd_ordp++;
891 * Reset cd_qualp to the highest precedence level that we've seen so
892 * far that can be qualified (CTF_PREC_BASE or CTF_PREC_POINTER).
894 if (prec > cd->cd_qualp && prec < CTF_PREC_ARRAY)
898 * C array declarators are ordered inside out so prepend them. Also by
899 * convention qualifiers of base types precede the type specifier (e.g.
900 * const int vs. int const) even though the two forms are equivalent.
902 if (kind == CTF_K_ARRAY || (is_qual && prec == CTF_PREC_BASE))
903 ctf_list_prepend(&cd->cd_nodes[prec], cdp);
905 ctf_list_append(&cd->cd_nodes[prec], cdp);
909 ctf_decl_sprintf(ctf_decl_t *cd, const char *format, ...)
911 size_t len = (size_t)(cd->cd_end - cd->cd_ptr);
915 va_start(ap, format);
916 n = vsnprintf(cd->cd_ptr, len, format, ap);
919 cd->cd_ptr += MIN(n, len);
924 fbt_type_name(linker_ctf_t *lc, ctf_id_t type, char *buf, size_t len)
927 ctf_decl_node_t *cdp;
928 ctf_decl_prec_t prec, lp, rp;
932 if (lc == NULL && type == CTF_ERR)
933 return (-1); /* simplify caller code by permitting CTF_ERR */
935 ctf_decl_init(&cd, buf, len);
936 ctf_decl_push(&cd, lc, type);
938 if (cd.cd_err != 0) {
944 * If the type graph's order conflicts with lexical precedence order
945 * for pointers or arrays, then we need to surround the declarations at
946 * the corresponding lexical precedence with parentheses. This can
947 * result in either a parenthesized pointer (*) as in int (*)() or
948 * int (*)[], or in a parenthesized pointer and array as in int (*[])().
950 ptr = cd.cd_order[CTF_PREC_POINTER] > CTF_PREC_POINTER;
951 arr = cd.cd_order[CTF_PREC_ARRAY] > CTF_PREC_ARRAY;
953 rp = arr ? CTF_PREC_ARRAY : ptr ? CTF_PREC_POINTER : -1;
954 lp = ptr ? CTF_PREC_POINTER : arr ? CTF_PREC_ARRAY : -1;
956 k = CTF_K_POINTER; /* avoid leading whitespace (see below) */
958 for (prec = CTF_PREC_BASE; prec < CTF_PREC_MAX; prec++) {
959 for (cdp = ctf_list_next(&cd.cd_nodes[prec]);
960 cdp != NULL; cdp = ctf_list_next(cdp)) {
962 const ctf_type_t *tp =
963 ctf_lookup_by_id(lc, cdp->cd_type);
964 const char *name = ctf_strptr(lc, tp->ctt_name);
966 if (k != CTF_K_POINTER && k != CTF_K_ARRAY)
967 ctf_decl_sprintf(&cd, " ");
970 ctf_decl_sprintf(&cd, "(");
974 switch (cdp->cd_kind) {
978 ctf_decl_sprintf(&cd, "%s", name);
981 ctf_decl_sprintf(&cd, "*");
984 ctf_decl_sprintf(&cd, "[%u]", cdp->cd_n);
987 ctf_decl_sprintf(&cd, "()");
991 ctf_decl_sprintf(&cd, "struct %s", name);
994 ctf_decl_sprintf(&cd, "union %s", name);
997 ctf_decl_sprintf(&cd, "enum %s", name);
1000 ctf_decl_sprintf(&cd, "volatile");
1003 ctf_decl_sprintf(&cd, "const");
1005 case CTF_K_RESTRICT:
1006 ctf_decl_sprintf(&cd, "restrict");
1014 ctf_decl_sprintf(&cd, ")");
1022 fbt_getargdesc(void *arg __unused, dtrace_id_t id __unused, void *parg, dtrace_argdesc_t *desc)
1025 fbt_probe_t *fbt = parg;
1027 modctl_t *ctl = fbt->fbtp_ctl;
1028 int ndx = desc->dtargd_ndx;
1029 int symindx = fbt->fbtp_symindx;
1032 ushort_t info, kind, n;
1034 if (fbt->fbtp_roffset != 0 && desc->dtargd_ndx == 0) {
1035 (void) strcpy(desc->dtargd_native, "int");
1039 desc->dtargd_ndx = DTRACE_ARGNONE;
1041 /* Get a pointer to the CTF data and it's length. */
1042 if (linker_ctf_get(ctl, &lc) != 0)
1043 /* No CTF data? Something wrong? *shrug* */
1046 /* Check if this module hasn't been initialised yet. */
1047 if (*lc.ctfoffp == NULL) {
1049 * Initialise the CTF object and function symindx to
1050 * byte offset array.
1052 if (fbt_ctfoff_init(ctl, &lc) != 0)
1055 /* Initialise the CTF type to byte offset array. */
1056 if (fbt_typoff_init(&lc) != 0)
1060 ctfoff = *lc.ctfoffp;
1062 if (ctfoff == NULL || *lc.typoffp == NULL)
1065 /* Check if the symbol index is out of range. */
1066 if (symindx >= lc.nsym)
1069 /* Check if the symbol isn't cross-referenced. */
1070 if ((offset = ctfoff[symindx]) == 0xffffffff)
1073 dp = (const ushort_t *)(lc.ctftab + offset + sizeof(ctf_header_t));
1076 kind = CTF_INFO_KIND(info);
1077 n = CTF_INFO_VLEN(info);
1079 if (kind == CTF_K_UNKNOWN && n == 0) {
1080 printf("%s(%d): Unknown function!\n",__func__,__LINE__);
1084 if (kind != CTF_K_FUNCTION) {
1085 printf("%s(%d): Expected a function!\n",__func__,__LINE__);
1089 if (fbt->fbtp_roffset != 0) {
1090 /* Only return type is available for args[1] in return probe. */
1095 /* Check if the requested argument doesn't exist. */
1099 /* Skip the return type and arguments up to the one requested. */
1103 if (fbt_type_name(&lc, *dp, desc->dtargd_native, sizeof(desc->dtargd_native)) > 0)
1104 desc->dtargd_ndx = ndx;
1110 fbt_linker_file_cb(linker_file_t lf, void *arg)
1113 fbt_provide_module(arg, lf);
1119 fbt_load(void *dummy)
1121 /* Create the /dev/dtrace/fbt entry. */
1122 fbt_cdev = make_dev(&fbt_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600,
1125 /* Default the probe table size if not specified. */
1126 if (fbt_probetab_size == 0)
1127 fbt_probetab_size = FBT_PROBETAB_SIZE;
1129 /* Choose the hash mask for the probe table. */
1130 fbt_probetab_mask = fbt_probetab_size - 1;
1132 /* Allocate memory for the probe table. */
1134 malloc(fbt_probetab_size * sizeof (fbt_probe_t *), M_FBT, M_WAITOK | M_ZERO);
1136 dtrace_doubletrap_func = fbt_doubletrap;
1137 dtrace_invop_add(fbt_invop);
1139 if (dtrace_register("fbt", &fbt_attr, DTRACE_PRIV_USER,
1140 NULL, &fbt_pops, NULL, &fbt_id) != 0)
1143 /* Create probes for the kernel and already-loaded modules. */
1144 linker_file_foreach(fbt_linker_file_cb, NULL);
1152 /* De-register the invalid opcode handler. */
1153 dtrace_invop_remove(fbt_invop);
1155 dtrace_doubletrap_func = NULL;
1157 /* De-register this DTrace provider. */
1158 if ((error = dtrace_unregister(fbt_id)) != 0)
1161 /* Free the probe table. */
1162 free(fbt_probetab, M_FBT);
1163 fbt_probetab = NULL;
1164 fbt_probetab_mask = 0;
1166 destroy_dev(fbt_cdev);
1172 fbt_modevent(module_t mod __unused, int type, void *data __unused)
1196 fbt_open(struct cdev *dev __unused, int oflags __unused, int devtype __unused, struct thread *td __unused)
1201 SYSINIT(fbt_load, SI_SUB_DTRACE_PROVIDER, SI_ORDER_ANY, fbt_load, NULL);
1202 SYSUNINIT(fbt_unload, SI_SUB_DTRACE_PROVIDER, SI_ORDER_ANY, fbt_unload, NULL);
1204 DEV_MODULE(fbt, fbt_modevent, NULL);
1205 MODULE_VERSION(fbt, 1);
1206 MODULE_DEPEND(fbt, dtrace, 1, 1, 1);
1207 MODULE_DEPEND(fbt, opensolaris, 1, 1, 1);