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