xref: /freebsd/sys/cddl/dev/fbt/fbt.c (revision 5dae51da3da0cc94d17bd67b308fad304ebec7e0)
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$
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 
66 MALLOC_DEFINE(M_FBT, "fbt", "Function Boundary Tracing");
67 
68 dtrace_provider_id_t	fbt_id;
69 fbt_probe_t		**fbt_probetab;
70 int			fbt_probetab_mask;
71 
72 static d_open_t	fbt_open;
73 static int	fbt_unload(void);
74 static void	fbt_getargdesc(void *, dtrace_id_t, void *, dtrace_argdesc_t *);
75 static void	fbt_provide_module(void *, modctl_t *);
76 static void	fbt_destroy(void *, dtrace_id_t, void *);
77 static void	fbt_enable(void *, dtrace_id_t, void *);
78 static void	fbt_disable(void *, dtrace_id_t, void *);
79 static void	fbt_load(void *);
80 static void	fbt_suspend(void *, dtrace_id_t, void *);
81 static void	fbt_resume(void *, dtrace_id_t, void *);
82 
83 static struct cdevsw fbt_cdevsw = {
84 	.d_version	= D_VERSION,
85 	.d_open		= fbt_open,
86 	.d_name		= "fbt",
87 };
88 
89 static dtrace_pattr_t fbt_attr = {
90 { DTRACE_STABILITY_EVOLVING, DTRACE_STABILITY_EVOLVING, DTRACE_CLASS_COMMON },
91 { DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_UNKNOWN },
92 { DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_ISA },
93 { DTRACE_STABILITY_EVOLVING, DTRACE_STABILITY_EVOLVING, DTRACE_CLASS_COMMON },
94 { DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_ISA },
95 };
96 
97 static dtrace_pops_t fbt_pops = {
98 	NULL,
99 	fbt_provide_module,
100 	fbt_enable,
101 	fbt_disable,
102 	fbt_suspend,
103 	fbt_resume,
104 	fbt_getargdesc,
105 	NULL,
106 	NULL,
107 	fbt_destroy
108 };
109 
110 static struct cdev		*fbt_cdev;
111 static int			fbt_probetab_size;
112 static int			fbt_verbose = 0;
113 
114 int
115 fbt_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 
141 static void
142 fbt_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 
155 static void
156 fbt_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 
198 static void
199 fbt_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 
236 static void
237 fbt_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 
263 static void
264 fbt_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 
279 static void
280 fbt_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 
294 static void
295 fbt_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 
309 static int
310 fbt_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 
385 static ssize_t
386 fbt_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 
408 static int
409 fbt_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  */
609 typedef 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 
617 typedef 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 
625 typedef 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 
632 typedef 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  */
651 static void
652 ctf_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  */
671 static void
672 ctf_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 
687 static void
688 ctf_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 
705 static void
706 ctf_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 
720 static const ctf_type_t *
721 ctf_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 
743 static void
744 fbt_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 
767 static const char *
768 ctf_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 
781 static void
782 ctf_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 
861 static void
862 ctf_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 
876 static ssize_t
877 fbt_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 
974 static void
975 fbt_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 
1062 static int
1063 fbt_linker_file_cb(linker_file_t lf, void *arg)
1064 {
1065 
1066 	fbt_provide_module(arg, lf);
1067 
1068 	return (0);
1069 }
1070 
1071 static void
1072 fbt_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 
1100 static int
1101 fbt_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 
1124 static int
1125 fbt_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 
1148 static int
1149 fbt_open(struct cdev *dev __unused, int oflags __unused, int devtype __unused, struct thread *td __unused)
1150 {
1151 	return (0);
1152 }
1153 
1154 SYSINIT(fbt_load, SI_SUB_DTRACE_PROVIDER, SI_ORDER_ANY, fbt_load, NULL);
1155 SYSUNINIT(fbt_unload, SI_SUB_DTRACE_PROVIDER, SI_ORDER_ANY, fbt_unload, NULL);
1156 
1157 DEV_MODULE(fbt, fbt_modevent, NULL);
1158 MODULE_VERSION(fbt, 1);
1159 MODULE_DEPEND(fbt, dtrace, 1, 1, 1);
1160 MODULE_DEPEND(fbt, opensolaris, 1, 1, 1);
1161