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