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