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