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