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