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.
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.
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]
21 * Portions Copyright 2006-2008 John Birrell jb@freebsd.org
28 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
29 * Use is subject to license terms.
32 #include <sys/cdefs.h>
33 #include <sys/param.h>
34 #include <sys/systm.h>
36 #include <sys/cpuvar.h>
37 #include <sys/fcntl.h>
38 #include <sys/filio.h>
40 #include <sys/kernel.h>
42 #include <sys/kthread.h>
43 #include <sys/limits.h>
44 #include <sys/linker.h>
46 #include <sys/malloc.h>
47 #include <sys/module.h>
48 #include <sys/mutex.h>
52 #include <sys/selinfo.h>
54 #include <sys/syscall.h>
55 #include <sys/sysent.h>
56 #include <sys/sysproto.h>
58 #include <sys/unistd.h>
59 #include <machine/stdarg.h>
61 #include <sys/dtrace.h>
62 #include <sys/dtrace_bsd.h>
64 static MALLOC_DEFINE(M_FBT, "fbt", "Function Boundary Tracing");
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
73 #define FBT_POPL_EBP 0x5d
75 #define FBT_RET_IMM16 0xc2
76 #define FBT_LEAVE 0xc9
79 #define FBT_PATCHVAL 0xcc
81 #define FBT_PATCHVAL 0xf0
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 *);
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 */
100 static struct cdevsw fbt_cdevsw = {
101 .d_version = D_VERSION,
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 },
114 static dtrace_pops_t fbt_pops = {
127 typedef struct fbt_probe {
128 struct fbt_probe *fbtp_hashnext;
129 uint8_t *fbtp_patchpoint;
131 uint8_t fbtp_patchval;
132 uint8_t fbtp_savedval;
133 uintptr_t fbtp_roffset;
135 const char *fbtp_name;
141 struct fbt_probe *fbtp_next;
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;
157 for (i = 0; i < fbt_probetab_size; i++) {
158 fbt = fbt_probetab[i];
160 for (; fbt != NULL; fbt = fbt->fbtp_next)
161 *fbt->fbtp_patchpoint = fbt->fbtp_savedval;
166 fbt_invop(uintptr_t addr, uintptr_t *stack, uintptr_t rval)
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)];
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) {
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
184 DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);
185 cpu->cpu_dtrace_caller = stack[i++];
191 DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT |
194 dtrace_probe(fbt->fbtp_id, stack0, stack1,
195 stack2, stack3, stack4);
197 cpu->cpu_dtrace_caller = 0;
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()
206 DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);
207 cpu->cpu_dtrace_caller = stack[0];
208 DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT |
212 dtrace_probe(fbt->fbtp_id, fbt->fbtp_roffset,
214 cpu->cpu_dtrace_caller = 0;
217 return (fbt->fbtp_rval);
225 fbt_provide_module_function(linker_file_t lf, int symindx,
226 linker_symval_t *symval, void *opaque)
228 char *modname = opaque;
229 const char *name = symval->name;
230 fbt_probe_t *fbt, *retfbt;
233 u_int8_t *instr, *limit;
235 if (strncmp(name, "dtrace_", 7) == 0 &&
236 strncmp(name, "dtrace_safe_", 12) != 0) {
238 * Anything beginning with "dtrace_" may be called
239 * from probe context unless it explicitly indicates
240 * that it won't be called from probe context by
241 * using the prefix "dtrace_safe_".
246 if (name[0] == '_' && name[1] == '_')
251 instr = (u_int8_t *) symval->value;
252 limit = (u_int8_t *) symval->value + symval->size;
255 while (instr < limit) {
256 if (*instr == FBT_PUSHL_EBP)
259 if ((size = dtrace_instr_size(instr)) <= 0)
265 if (instr >= limit || *instr != FBT_PUSHL_EBP) {
267 * We either don't save the frame pointer in this
268 * function, or we ran into some disassembly
269 * screw-up. Either way, we bail.
274 if (instr[0] != FBT_PUSHL_EBP)
277 if (!(instr[1] == FBT_MOVL_ESP_EBP0_V0 &&
278 instr[2] == FBT_MOVL_ESP_EBP1_V0) &&
279 !(instr[1] == FBT_MOVL_ESP_EBP0_V1 &&
280 instr[2] == FBT_MOVL_ESP_EBP1_V1))
284 fbt = malloc(sizeof (fbt_probe_t), M_FBT, M_WAITOK | M_ZERO);
285 fbt->fbtp_name = name;
286 fbt->fbtp_id = dtrace_probe_create(fbt_id, modname,
287 name, FBT_ENTRY, 3, fbt);
288 fbt->fbtp_patchpoint = instr;
290 fbt->fbtp_loadcnt = lf->loadcnt;
291 fbt->fbtp_rval = DTRACE_INVOP_PUSHL_EBP;
292 fbt->fbtp_savedval = *instr;
293 fbt->fbtp_patchval = FBT_PATCHVAL;
294 fbt->fbtp_symindx = symindx;
296 fbt->fbtp_hashnext = fbt_probetab[FBT_ADDR2NDX(instr)];
297 fbt_probetab[FBT_ADDR2NDX(instr)] = fbt;
307 * If this disassembly fails, then we've likely walked off into
308 * a jump table or some other unsuitable area. Bail out of the
311 if ((size = dtrace_instr_size(instr)) <= 0)
316 * We only instrument "ret" on amd64 -- we don't yet instrument
317 * ret imm16, largely because the compiler doesn't seem to
318 * (yet) emit them in the kernel...
320 if (*instr != FBT_RET) {
326 (*instr == FBT_POPL_EBP || *instr == FBT_LEAVE) &&
327 (*(instr + 1) == FBT_RET ||
328 *(instr + 1) == FBT_RET_IMM16))) {
335 * We (desperately) want to avoid erroneously instrumenting a
336 * jump table, especially given that our markers are pretty
337 * short: two bytes on x86, and just one byte on amd64. To
338 * determine if we're looking at a true instruction sequence
339 * or an inline jump table that happens to contain the same
340 * byte sequences, we resort to some heuristic sleeze: we
341 * treat this instruction as being contained within a pointer,
342 * and see if that pointer points to within the body of the
343 * function. If it does, we refuse to instrument it.
345 for (j = 0; j < sizeof (uintptr_t); j++) {
346 caddr_t check = (caddr_t) instr - j;
349 if (check < symval->value)
352 if (check + sizeof (caddr_t) > (caddr_t)limit)
355 ptr = *(uint8_t **)check;
357 if (ptr >= (uint8_t *) symval->value && ptr < limit) {
366 fbt = malloc(sizeof (fbt_probe_t), M_FBT, M_WAITOK | M_ZERO);
367 fbt->fbtp_name = name;
369 if (retfbt == NULL) {
370 fbt->fbtp_id = dtrace_probe_create(fbt_id, modname,
371 name, FBT_RETURN, 3, fbt);
373 retfbt->fbtp_next = fbt;
374 fbt->fbtp_id = retfbt->fbtp_id;
378 fbt->fbtp_patchpoint = instr;
380 fbt->fbtp_loadcnt = lf->loadcnt;
381 fbt->fbtp_symindx = symindx;
384 if (*instr == FBT_POPL_EBP) {
385 fbt->fbtp_rval = DTRACE_INVOP_POPL_EBP;
387 ASSERT(*instr == FBT_LEAVE);
388 fbt->fbtp_rval = DTRACE_INVOP_LEAVE;
391 (uintptr_t)(instr - (uint8_t *) symval->value) + 1;
394 ASSERT(*instr == FBT_RET);
395 fbt->fbtp_rval = DTRACE_INVOP_RET;
397 (uintptr_t)(instr - (uint8_t *) symval->value);
400 fbt->fbtp_savedval = *instr;
401 fbt->fbtp_patchval = FBT_PATCHVAL;
402 fbt->fbtp_hashnext = fbt_probetab[FBT_ADDR2NDX(instr)];
403 fbt_probetab[FBT_ADDR2NDX(instr)] = fbt;
412 fbt_provide_module(void *arg, modctl_t *lf)
414 char modname[MAXPATHLEN];
418 strlcpy(modname, lf->filename, sizeof(modname));
419 len = strlen(modname);
420 if (len > 3 && strcmp(modname + len - 3, ".ko") == 0)
421 modname[len - 3] = '\0';
424 * Employees of dtrace and their families are ineligible. Void
427 if (strcmp(modname, "dtrace") == 0)
431 * The cyclic timer subsystem can be built as a module and DTrace
432 * depends on that, so it is ineligible too.
434 if (strcmp(modname, "cyclic") == 0)
438 * To register with DTrace, a module must list 'dtrace' as a
439 * dependency in order for the kernel linker to resolve
440 * symbols like dtrace_register(). All modules with such a
441 * dependency are ineligible for FBT tracing.
443 for (i = 0; i < lf->ndeps; i++)
444 if (strncmp(lf->deps[i]->filename, "dtrace", 6) == 0)
447 if (lf->fbt_nentries) {
449 * This module has some FBT entries allocated; we're afraid
456 * List the functions in the module and the symbol values.
458 (void) linker_file_function_listall(lf, fbt_provide_module_function, modname);
462 fbt_destroy(void *arg, dtrace_id_t id, void *parg)
464 fbt_probe_t *fbt = parg, *next, *hash, *last;
474 * Now we need to remove this probe from the fbt_probetab.
476 ndx = FBT_ADDR2NDX(fbt->fbtp_patchpoint);
478 hash = fbt_probetab[ndx];
480 while (hash != fbt) {
481 ASSERT(hash != NULL);
483 hash = hash->fbtp_hashnext;
487 last->fbtp_hashnext = fbt->fbtp_hashnext;
489 fbt_probetab[ndx] = fbt->fbtp_hashnext;
492 next = fbt->fbtp_next;
496 } while (fbt != NULL);
500 fbt_enable(void *arg, dtrace_id_t id, void *parg)
502 fbt_probe_t *fbt = parg;
503 modctl_t *ctl = fbt->fbtp_ctl;
508 * Now check that our modctl has the expected load count. If it
509 * doesn't, this module must have been unloaded and reloaded -- and
510 * we're not going to touch it.
512 if (ctl->loadcnt != fbt->fbtp_loadcnt) {
514 printf("fbt is failing for probe %s "
515 "(module %s reloaded)",
516 fbt->fbtp_name, ctl->filename);
522 for (; fbt != NULL; fbt = fbt->fbtp_next) {
523 *fbt->fbtp_patchpoint = fbt->fbtp_patchval;
528 fbt_disable(void *arg, dtrace_id_t id, void *parg)
530 fbt_probe_t *fbt = parg;
531 modctl_t *ctl = fbt->fbtp_ctl;
533 ASSERT(ctl->nenabled > 0);
536 if ((ctl->loadcnt != fbt->fbtp_loadcnt))
539 for (; fbt != NULL; fbt = fbt->fbtp_next)
540 *fbt->fbtp_patchpoint = fbt->fbtp_savedval;
544 fbt_suspend(void *arg, dtrace_id_t id, void *parg)
546 fbt_probe_t *fbt = parg;
547 modctl_t *ctl = fbt->fbtp_ctl;
549 ASSERT(ctl->nenabled > 0);
551 if ((ctl->loadcnt != fbt->fbtp_loadcnt))
554 for (; fbt != NULL; fbt = fbt->fbtp_next)
555 *fbt->fbtp_patchpoint = fbt->fbtp_savedval;
559 fbt_resume(void *arg, dtrace_id_t id, void *parg)
561 fbt_probe_t *fbt = parg;
562 modctl_t *ctl = fbt->fbtp_ctl;
564 ASSERT(ctl->nenabled > 0);
566 if ((ctl->loadcnt != fbt->fbtp_loadcnt))
569 for (; fbt != NULL; fbt = fbt->fbtp_next)
570 *fbt->fbtp_patchpoint = fbt->fbtp_patchval;
574 fbt_ctfoff_init(modctl_t *lf, linker_ctf_t *lc)
576 const Elf_Sym *symp = lc->symtab;;
577 const ctf_header_t *hp = (const ctf_header_t *) lc->ctftab;
578 const uint8_t *ctfdata = lc->ctftab + sizeof(ctf_header_t);
581 uint32_t objtoff = hp->cth_objtoff;
582 uint32_t funcoff = hp->cth_funcoff;
587 if (hp->cth_magic != CTF_MAGIC) {
588 printf("Bad magic value in CTF data of '%s'\n",lf->pathname);
592 if (lc->symtab == NULL) {
593 printf("No symbol table in '%s'\n",lf->pathname);
597 if ((ctfoff = malloc(sizeof(uint32_t) * lc->nsym, M_LINKER, M_WAITOK)) == NULL)
600 *lc->ctfoffp = ctfoff;
602 for (i = 0; i < lc->nsym; i++, ctfoff++, symp++) {
603 if (symp->st_name == 0 || symp->st_shndx == SHN_UNDEF) {
604 *ctfoff = 0xffffffff;
608 switch (ELF_ST_TYPE(symp->st_info)) {
610 if (objtoff >= hp->cth_funcoff ||
611 (symp->st_shndx == SHN_ABS && symp->st_value == 0)) {
612 *ctfoff = 0xffffffff;
617 objtoff += sizeof (ushort_t);
621 if (funcoff >= hp->cth_typeoff) {
622 *ctfoff = 0xffffffff;
628 info = *((const ushort_t *)(ctfdata + funcoff));
629 vlen = CTF_INFO_VLEN(info);
632 * If we encounter a zero pad at the end, just skip it.
633 * Otherwise skip over the function and its return type
634 * (+2) and the argument list (vlen).
636 if (CTF_INFO_KIND(info) == CTF_K_UNKNOWN && vlen == 0)
637 funcoff += sizeof (ushort_t); /* skip pad */
639 funcoff += sizeof (ushort_t) * (vlen + 2);
643 *ctfoff = 0xffffffff;
652 fbt_get_ctt_size(uint8_t version, const ctf_type_t *tp, ssize_t *sizep,
655 ssize_t size, increment;
657 if (version > CTF_VERSION_1 &&
658 tp->ctt_size == CTF_LSIZE_SENT) {
659 size = CTF_TYPE_LSIZE(tp);
660 increment = sizeof (ctf_type_t);
663 increment = sizeof (ctf_stype_t);
669 *incrementp = increment;
675 fbt_typoff_init(linker_ctf_t *lc)
677 const ctf_header_t *hp = (const ctf_header_t *) lc->ctftab;
678 const ctf_type_t *tbuf;
679 const ctf_type_t *tend;
680 const ctf_type_t *tp;
681 const uint8_t *ctfdata = lc->ctftab + sizeof(ctf_header_t);
684 ulong_t pop[CTF_K_MAX + 1] = { 0 };
688 if (hp->cth_magic != CTF_MAGIC)
691 tbuf = (const ctf_type_t *) (ctfdata + hp->cth_typeoff);
692 tend = (const ctf_type_t *) (ctfdata + hp->cth_stroff);
694 int child = hp->cth_parname != 0;
697 * We make two passes through the entire type section. In this first
698 * pass, we count the number of each type and the total number of types.
700 for (tp = tbuf; tp < tend; ctf_typemax++) {
701 ushort_t kind = CTF_INFO_KIND(tp->ctt_info);
702 ulong_t vlen = CTF_INFO_VLEN(tp->ctt_info);
703 ssize_t size, increment;
708 (void) fbt_get_ctt_size(hp->cth_version, tp, &size, &increment);
713 vbytes = sizeof (uint_t);
716 vbytes = sizeof (ctf_array_t);
719 vbytes = sizeof (ushort_t) * (vlen + (vlen & 1));
723 if (size < CTF_LSTRUCT_THRESH) {
724 ctf_member_t *mp = (ctf_member_t *)
725 ((uintptr_t)tp + increment);
727 vbytes = sizeof (ctf_member_t) * vlen;
728 for (n = vlen; n != 0; n--, mp++)
729 child |= CTF_TYPE_ISCHILD(mp->ctm_type);
731 ctf_lmember_t *lmp = (ctf_lmember_t *)
732 ((uintptr_t)tp + increment);
734 vbytes = sizeof (ctf_lmember_t) * vlen;
735 for (n = vlen; n != 0; n--, lmp++)
737 CTF_TYPE_ISCHILD(lmp->ctlm_type);
741 vbytes = sizeof (ctf_enum_t) * vlen;
745 * For forward declarations, ctt_type is the CTF_K_*
746 * kind for the tag, so bump that population count too.
747 * If ctt_type is unknown, treat the tag as a struct.
749 if (tp->ctt_type == CTF_K_UNKNOWN ||
750 tp->ctt_type >= CTF_K_MAX)
763 child |= CTF_TYPE_ISCHILD(tp->ctt_type);
767 printf("%s(%d): detected invalid CTF kind -- %u\n", __func__, __LINE__, kind);
770 tp = (ctf_type_t *)((uintptr_t)tp + increment + vbytes);
774 /* account for a sentinel value below */
776 *lc->typlenp = ctf_typemax;
778 if ((xp = malloc(sizeof(uint32_t) * ctf_typemax, M_LINKER, M_ZERO | M_WAITOK)) == NULL)
783 /* type id 0 is used as a sentinel value */
787 * In the second pass, fill in the type offset.
789 for (tp = tbuf; tp < tend; xp++) {
790 ushort_t kind = CTF_INFO_KIND(tp->ctt_info);
791 ulong_t vlen = CTF_INFO_VLEN(tp->ctt_info);
792 ssize_t size, increment;
797 (void) fbt_get_ctt_size(hp->cth_version, tp, &size, &increment);
802 vbytes = sizeof (uint_t);
805 vbytes = sizeof (ctf_array_t);
808 vbytes = sizeof (ushort_t) * (vlen + (vlen & 1));
812 if (size < CTF_LSTRUCT_THRESH) {
813 ctf_member_t *mp = (ctf_member_t *)
814 ((uintptr_t)tp + increment);
816 vbytes = sizeof (ctf_member_t) * vlen;
817 for (n = vlen; n != 0; n--, mp++)
818 child |= CTF_TYPE_ISCHILD(mp->ctm_type);
820 ctf_lmember_t *lmp = (ctf_lmember_t *)
821 ((uintptr_t)tp + increment);
823 vbytes = sizeof (ctf_lmember_t) * vlen;
824 for (n = vlen; n != 0; n--, lmp++)
826 CTF_TYPE_ISCHILD(lmp->ctlm_type);
830 vbytes = sizeof (ctf_enum_t) * vlen;
844 printf("%s(%d): detected invalid CTF kind -- %u\n", __func__, __LINE__, kind);
847 *xp = (uint32_t)((uintptr_t) tp - (uintptr_t) ctfdata);
848 tp = (ctf_type_t *)((uintptr_t)tp + increment + vbytes);
855 * CTF Declaration Stack
857 * In order to implement ctf_type_name(), we must convert a type graph back
858 * into a C type declaration. Unfortunately, a type graph represents a storage
859 * class ordering of the type whereas a type declaration must obey the C rules
860 * for operator precedence, and the two orderings are frequently in conflict.
861 * For example, consider these CTF type graphs and their C declarations:
863 * CTF_K_POINTER -> CTF_K_FUNCTION -> CTF_K_INTEGER : int (*)()
864 * CTF_K_POINTER -> CTF_K_ARRAY -> CTF_K_INTEGER : int (*)[]
866 * In each case, parentheses are used to raise operator * to higher lexical
867 * precedence, so the string form of the C declaration cannot be constructed by
868 * walking the type graph links and forming the string from left to right.
870 * The functions in this file build a set of stacks from the type graph nodes
871 * corresponding to the C operator precedence levels in the appropriate order.
872 * The code in ctf_type_name() can then iterate over the levels and nodes in
873 * lexical precedence order and construct the final C declaration string.
875 typedef struct ctf_list {
876 struct ctf_list *l_prev; /* previous pointer or tail pointer */
877 struct ctf_list *l_next; /* next pointer or head pointer */
880 #define ctf_list_prev(elem) ((void *)(((ctf_list_t *)(elem))->l_prev))
881 #define ctf_list_next(elem) ((void *)(((ctf_list_t *)(elem))->l_next))
891 typedef struct ctf_decl_node {
892 ctf_list_t cd_list; /* linked list pointers */
893 ctf_id_t cd_type; /* type identifier */
894 uint_t cd_kind; /* type kind */
895 uint_t cd_n; /* type dimension if array */
898 typedef struct ctf_decl {
899 ctf_list_t cd_nodes[CTF_PREC_MAX]; /* declaration node stacks */
900 int cd_order[CTF_PREC_MAX]; /* storage order of decls */
901 ctf_decl_prec_t cd_qualp; /* qualifier precision */
902 ctf_decl_prec_t cd_ordp; /* ordered precision */
903 char *cd_buf; /* buffer for output */
904 char *cd_ptr; /* buffer location */
905 char *cd_end; /* buffer limit */
906 size_t cd_len; /* buffer space required */
907 int cd_err; /* saved error value */
911 * Simple doubly-linked list append routine. This implementation assumes that
912 * each list element contains an embedded ctf_list_t as the first member.
913 * An additional ctf_list_t is used to store the head (l_next) and tail
914 * (l_prev) pointers. The current head and tail list elements have their
915 * previous and next pointers set to NULL, respectively.
918 ctf_list_append(ctf_list_t *lp, void *new)
920 ctf_list_t *p = lp->l_prev; /* p = tail list element */
921 ctf_list_t *q = new; /* q = new list element */
934 * Prepend the specified existing element to the given ctf_list_t. The
935 * existing pointer should be pointing at a struct with embedded ctf_list_t.
938 ctf_list_prepend(ctf_list_t *lp, void *new)
940 ctf_list_t *p = new; /* p = new list element */
941 ctf_list_t *q = lp->l_next; /* q = head list element */
954 ctf_decl_init(ctf_decl_t *cd, char *buf, size_t len)
958 bzero(cd, sizeof (ctf_decl_t));
960 for (i = CTF_PREC_BASE; i < CTF_PREC_MAX; i++)
961 cd->cd_order[i] = CTF_PREC_BASE - 1;
963 cd->cd_qualp = CTF_PREC_BASE;
964 cd->cd_ordp = CTF_PREC_BASE;
968 cd->cd_end = buf + len;
972 ctf_decl_fini(ctf_decl_t *cd)
974 ctf_decl_node_t *cdp, *ndp;
977 for (i = CTF_PREC_BASE; i < CTF_PREC_MAX; i++) {
978 for (cdp = ctf_list_next(&cd->cd_nodes[i]);
979 cdp != NULL; cdp = ndp) {
980 ndp = ctf_list_next(cdp);
986 static const ctf_type_t *
987 ctf_lookup_by_id(linker_ctf_t *lc, ctf_id_t type)
989 const ctf_type_t *tp;
991 uint32_t *typoff = *lc->typoffp;
993 if (type >= *lc->typlenp) {
994 printf("%s(%d): type %d exceeds max %ld\n",__func__,__LINE__,(int) type,*lc->typlenp);
998 /* Check if the type isn't cross-referenced. */
999 if ((offset = typoff[type]) == 0) {
1000 printf("%s(%d): type %d isn't cross referenced\n",__func__,__LINE__, (int) type);
1004 tp = (const ctf_type_t *)(lc->ctftab + offset + sizeof(ctf_header_t));
1010 fbt_array_info(linker_ctf_t *lc, ctf_id_t type, ctf_arinfo_t *arp)
1012 const ctf_header_t *hp = (const ctf_header_t *) lc->ctftab;
1013 const ctf_type_t *tp;
1014 const ctf_array_t *ap;
1017 bzero(arp, sizeof(*arp));
1019 if ((tp = ctf_lookup_by_id(lc, type)) == NULL)
1022 if (CTF_INFO_KIND(tp->ctt_info) != CTF_K_ARRAY)
1025 (void) fbt_get_ctt_size(hp->cth_version, tp, NULL, &increment);
1027 ap = (const ctf_array_t *)((uintptr_t)tp + increment);
1028 arp->ctr_contents = ap->cta_contents;
1029 arp->ctr_index = ap->cta_index;
1030 arp->ctr_nelems = ap->cta_nelems;
1034 ctf_strptr(linker_ctf_t *lc, int name)
1036 const ctf_header_t *hp = (const ctf_header_t *) lc->ctftab;;
1037 const char *strp = "";
1039 if (name < 0 || name >= hp->cth_strlen)
1042 strp = (const char *)(lc->ctftab + hp->cth_stroff + name + sizeof(ctf_header_t));
1048 ctf_decl_push(ctf_decl_t *cd, linker_ctf_t *lc, ctf_id_t type)
1050 ctf_decl_node_t *cdp;
1051 ctf_decl_prec_t prec;
1055 const ctf_type_t *tp;
1058 if ((tp = ctf_lookup_by_id(lc, type)) == NULL) {
1059 cd->cd_err = ENOENT;
1063 switch (kind = CTF_INFO_KIND(tp->ctt_info)) {
1065 fbt_array_info(lc, type, &ar);
1066 ctf_decl_push(cd, lc, ar.ctr_contents);
1068 prec = CTF_PREC_ARRAY;
1072 if (ctf_strptr(lc, tp->ctt_name)[0] == '\0') {
1073 ctf_decl_push(cd, lc, tp->ctt_type);
1076 prec = CTF_PREC_BASE;
1079 case CTF_K_FUNCTION:
1080 ctf_decl_push(cd, lc, tp->ctt_type);
1081 prec = CTF_PREC_FUNCTION;
1085 ctf_decl_push(cd, lc, tp->ctt_type);
1086 prec = CTF_PREC_POINTER;
1089 case CTF_K_VOLATILE:
1091 case CTF_K_RESTRICT:
1092 ctf_decl_push(cd, lc, tp->ctt_type);
1093 prec = cd->cd_qualp;
1098 prec = CTF_PREC_BASE;
1101 if ((cdp = malloc(sizeof (ctf_decl_node_t), M_FBT, M_WAITOK)) == NULL) {
1102 cd->cd_err = EAGAIN;
1106 cdp->cd_type = type;
1107 cdp->cd_kind = kind;
1110 if (ctf_list_next(&cd->cd_nodes[prec]) == NULL)
1111 cd->cd_order[prec] = cd->cd_ordp++;
1114 * Reset cd_qualp to the highest precedence level that we've seen so
1115 * far that can be qualified (CTF_PREC_BASE or CTF_PREC_POINTER).
1117 if (prec > cd->cd_qualp && prec < CTF_PREC_ARRAY)
1118 cd->cd_qualp = prec;
1121 * C array declarators are ordered inside out so prepend them. Also by
1122 * convention qualifiers of base types precede the type specifier (e.g.
1123 * const int vs. int const) even though the two forms are equivalent.
1125 if (kind == CTF_K_ARRAY || (is_qual && prec == CTF_PREC_BASE))
1126 ctf_list_prepend(&cd->cd_nodes[prec], cdp);
1128 ctf_list_append(&cd->cd_nodes[prec], cdp);
1132 ctf_decl_sprintf(ctf_decl_t *cd, const char *format, ...)
1134 size_t len = (size_t)(cd->cd_end - cd->cd_ptr);
1138 va_start(ap, format);
1139 n = vsnprintf(cd->cd_ptr, len, format, ap);
1142 cd->cd_ptr += MIN(n, len);
1147 fbt_type_name(linker_ctf_t *lc, ctf_id_t type, char *buf, size_t len)
1150 ctf_decl_node_t *cdp;
1151 ctf_decl_prec_t prec, lp, rp;
1155 if (lc == NULL && type == CTF_ERR)
1156 return (-1); /* simplify caller code by permitting CTF_ERR */
1158 ctf_decl_init(&cd, buf, len);
1159 ctf_decl_push(&cd, lc, type);
1161 if (cd.cd_err != 0) {
1167 * If the type graph's order conflicts with lexical precedence order
1168 * for pointers or arrays, then we need to surround the declarations at
1169 * the corresponding lexical precedence with parentheses. This can
1170 * result in either a parenthesized pointer (*) as in int (*)() or
1171 * int (*)[], or in a parenthesized pointer and array as in int (*[])().
1173 ptr = cd.cd_order[CTF_PREC_POINTER] > CTF_PREC_POINTER;
1174 arr = cd.cd_order[CTF_PREC_ARRAY] > CTF_PREC_ARRAY;
1176 rp = arr ? CTF_PREC_ARRAY : ptr ? CTF_PREC_POINTER : -1;
1177 lp = ptr ? CTF_PREC_POINTER : arr ? CTF_PREC_ARRAY : -1;
1179 k = CTF_K_POINTER; /* avoid leading whitespace (see below) */
1181 for (prec = CTF_PREC_BASE; prec < CTF_PREC_MAX; prec++) {
1182 for (cdp = ctf_list_next(&cd.cd_nodes[prec]);
1183 cdp != NULL; cdp = ctf_list_next(cdp)) {
1185 const ctf_type_t *tp =
1186 ctf_lookup_by_id(lc, cdp->cd_type);
1187 const char *name = ctf_strptr(lc, tp->ctt_name);
1189 if (k != CTF_K_POINTER && k != CTF_K_ARRAY)
1190 ctf_decl_sprintf(&cd, " ");
1193 ctf_decl_sprintf(&cd, "(");
1197 switch (cdp->cd_kind) {
1201 ctf_decl_sprintf(&cd, "%s", name);
1204 ctf_decl_sprintf(&cd, "*");
1207 ctf_decl_sprintf(&cd, "[%u]", cdp->cd_n);
1209 case CTF_K_FUNCTION:
1210 ctf_decl_sprintf(&cd, "()");
1214 ctf_decl_sprintf(&cd, "struct %s", name);
1217 ctf_decl_sprintf(&cd, "union %s", name);
1220 ctf_decl_sprintf(&cd, "enum %s", name);
1222 case CTF_K_VOLATILE:
1223 ctf_decl_sprintf(&cd, "volatile");
1226 ctf_decl_sprintf(&cd, "const");
1228 case CTF_K_RESTRICT:
1229 ctf_decl_sprintf(&cd, "restrict");
1237 ctf_decl_sprintf(&cd, ")");
1245 fbt_getargdesc(void *arg __unused, dtrace_id_t id __unused, void *parg, dtrace_argdesc_t *desc)
1248 fbt_probe_t *fbt = parg;
1250 modctl_t *ctl = fbt->fbtp_ctl;
1251 int ndx = desc->dtargd_ndx;
1252 int symindx = fbt->fbtp_symindx;
1255 ushort_t info, kind, n;
1257 if (fbt->fbtp_roffset != 0 && desc->dtargd_ndx == 0) {
1258 (void) strcpy(desc->dtargd_native, "int");
1262 desc->dtargd_ndx = DTRACE_ARGNONE;
1264 /* Get a pointer to the CTF data and it's length. */
1265 if (linker_ctf_get(ctl, &lc) != 0)
1266 /* No CTF data? Something wrong? *shrug* */
1269 /* Check if this module hasn't been initialised yet. */
1270 if (*lc.ctfoffp == NULL) {
1272 * Initialise the CTF object and function symindx to
1273 * byte offset array.
1275 if (fbt_ctfoff_init(ctl, &lc) != 0)
1278 /* Initialise the CTF type to byte offset array. */
1279 if (fbt_typoff_init(&lc) != 0)
1283 ctfoff = *lc.ctfoffp;
1285 if (ctfoff == NULL || *lc.typoffp == NULL)
1288 /* Check if the symbol index is out of range. */
1289 if (symindx >= lc.nsym)
1292 /* Check if the symbol isn't cross-referenced. */
1293 if ((offset = ctfoff[symindx]) == 0xffffffff)
1296 dp = (const ushort_t *)(lc.ctftab + offset + sizeof(ctf_header_t));
1299 kind = CTF_INFO_KIND(info);
1300 n = CTF_INFO_VLEN(info);
1302 if (kind == CTF_K_UNKNOWN && n == 0) {
1303 printf("%s(%d): Unknown function!\n",__func__,__LINE__);
1307 if (kind != CTF_K_FUNCTION) {
1308 printf("%s(%d): Expected a function!\n",__func__,__LINE__);
1312 if (fbt->fbtp_roffset != 0) {
1313 /* Only return type is available for args[1] in return probe. */
1318 /* Check if the requested argument doesn't exist. */
1322 /* Skip the return type and arguments up to the one requested. */
1326 if (fbt_type_name(&lc, *dp, desc->dtargd_native, sizeof(desc->dtargd_native)) > 0)
1327 desc->dtargd_ndx = ndx;
1333 fbt_linker_file_cb(linker_file_t lf, void *arg)
1336 fbt_provide_module(arg, lf);
1342 fbt_load(void *dummy)
1344 /* Create the /dev/dtrace/fbt entry. */
1345 fbt_cdev = make_dev(&fbt_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600,
1348 /* Default the probe table size if not specified. */
1349 if (fbt_probetab_size == 0)
1350 fbt_probetab_size = FBT_PROBETAB_SIZE;
1352 /* Choose the hash mask for the probe table. */
1353 fbt_probetab_mask = fbt_probetab_size - 1;
1355 /* Allocate memory for the probe table. */
1357 malloc(fbt_probetab_size * sizeof (fbt_probe_t *), M_FBT, M_WAITOK | M_ZERO);
1359 dtrace_doubletrap_func = fbt_doubletrap;
1360 dtrace_invop_add(fbt_invop);
1362 if (dtrace_register("fbt", &fbt_attr, DTRACE_PRIV_USER,
1363 NULL, &fbt_pops, NULL, &fbt_id) != 0)
1366 /* Create probes for the kernel and already-loaded modules. */
1367 linker_file_foreach(fbt_linker_file_cb, NULL);
1375 /* De-register the invalid opcode handler. */
1376 dtrace_invop_remove(fbt_invop);
1378 dtrace_doubletrap_func = NULL;
1380 /* De-register this DTrace provider. */
1381 if ((error = dtrace_unregister(fbt_id)) != 0)
1384 /* Free the probe table. */
1385 free(fbt_probetab, M_FBT);
1386 fbt_probetab = NULL;
1387 fbt_probetab_mask = 0;
1389 destroy_dev(fbt_cdev);
1395 fbt_modevent(module_t mod __unused, int type, void *data __unused)
1419 fbt_open(struct cdev *dev __unused, int oflags __unused, int devtype __unused, struct thread *td __unused)
1424 SYSINIT(fbt_load, SI_SUB_DTRACE_PROVIDER, SI_ORDER_ANY, fbt_load, NULL);
1425 SYSUNINIT(fbt_unload, SI_SUB_DTRACE_PROVIDER, SI_ORDER_ANY, fbt_unload, NULL);
1427 DEV_MODULE(fbt, fbt_modevent, NULL);
1428 MODULE_VERSION(fbt, 1);
1429 MODULE_DEPEND(fbt, dtrace, 1, 1, 1);
1430 MODULE_DEPEND(fbt, opensolaris, 1, 1, 1);