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