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