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