]> CyberLeo.Net >> Repos - FreeBSD/releng/7.2.git/blob - sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c
Create releng/7.2 from stable/7 in preparation for 7.2-RELEASE.
[FreeBSD/releng/7.2.git] / sys / cddl / contrib / opensolaris / uts / common / dtrace / dtrace.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  * $FreeBSD: src/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c,v 1.6 2008/08/19 21:28:58 jb Exp $
22  */
23
24 /*
25  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
26  * Use is subject to license terms.
27  */
28
29 #pragma ident   "%Z%%M% %I%     %E% SMI"
30
31 /*
32  * DTrace - Dynamic Tracing for Solaris
33  *
34  * This is the implementation of the Solaris Dynamic Tracing framework
35  * (DTrace).  The user-visible interface to DTrace is described at length in
36  * the "Solaris Dynamic Tracing Guide".  The interfaces between the libdtrace
37  * library, the in-kernel DTrace framework, and the DTrace providers are
38  * described in the block comments in the <sys/dtrace.h> header file.  The
39  * internal architecture of DTrace is described in the block comments in the
40  * <sys/dtrace_impl.h> header file.  The comments contained within the DTrace
41  * implementation very much assume mastery of all of these sources; if one has
42  * an unanswered question about the implementation, one should consult them
43  * first.
44  *
45  * The functions here are ordered roughly as follows:
46  *
47  *   - Probe context functions
48  *   - Probe hashing functions
49  *   - Non-probe context utility functions
50  *   - Matching functions
51  *   - Provider-to-Framework API functions
52  *   - Probe management functions
53  *   - DIF object functions
54  *   - Format functions
55  *   - Predicate functions
56  *   - ECB functions
57  *   - Buffer functions
58  *   - Enabling functions
59  *   - DOF functions
60  *   - Anonymous enabling functions
61  *   - Consumer state functions
62  *   - Helper functions
63  *   - Hook functions
64  *   - Driver cookbook functions
65  *
66  * Each group of functions begins with a block comment labelled the "DTrace
67  * [Group] Functions", allowing one to find each block by searching forward
68  * on capital-f functions.
69  */
70 #include <sys/errno.h>
71 #if !defined(sun)
72 #include <sys/time.h>
73 #endif
74 #include <sys/stat.h>
75 #include <sys/modctl.h>
76 #include <sys/conf.h>
77 #include <sys/systm.h>
78 #if defined(sun)
79 #include <sys/ddi.h>
80 #include <sys/sunddi.h>
81 #endif
82 #include <sys/cpuvar.h>
83 #include <sys/kmem.h>
84 #if defined(sun)
85 #include <sys/strsubr.h>
86 #endif
87 #include <sys/sysmacros.h>
88 #include <sys/dtrace_impl.h>
89 #include <sys/atomic.h>
90 #include <sys/cmn_err.h>
91 #if defined(sun)
92 #include <sys/mutex_impl.h>
93 #include <sys/rwlock_impl.h>
94 #endif
95 #include <sys/ctf_api.h>
96 #if defined(sun)
97 #include <sys/panic.h>
98 #include <sys/priv_impl.h>
99 #endif
100 #include <sys/policy.h>
101 #if defined(sun)
102 #include <sys/cred_impl.h>
103 #include <sys/procfs_isa.h>
104 #endif
105 #include <sys/taskq.h>
106 #if defined(sun)
107 #include <sys/mkdev.h>
108 #include <sys/kdi.h>
109 #endif
110 #include <sys/zone.h>
111 #include <sys/socket.h>
112 #include <netinet/in.h>
113
114 /* FreeBSD includes: */
115 #if !defined(sun)
116 #include <sys/callout.h>
117 #include <sys/ctype.h>
118 #include <sys/limits.h>
119 #include <sys/kdb.h>
120 #include <sys/kernel.h>
121 #include <sys/malloc.h>
122 #include <sys/sysctl.h>
123 #include <sys/lock.h>
124 #include <sys/mutex.h>
125 #include <sys/sx.h>
126 #include <sys/dtrace_bsd.h>
127 #include <netinet/in.h>
128 #include "dtrace_cddl.h"
129 #include "dtrace_debug.c"
130 #endif
131
132 /*
133  * DTrace Tunable Variables
134  *
135  * The following variables may be tuned by adding a line to /etc/system that
136  * includes both the name of the DTrace module ("dtrace") and the name of the
137  * variable.  For example:
138  *
139  *   set dtrace:dtrace_destructive_disallow = 1
140  *
141  * In general, the only variables that one should be tuning this way are those
142  * that affect system-wide DTrace behavior, and for which the default behavior
143  * is undesirable.  Most of these variables are tunable on a per-consumer
144  * basis using DTrace options, and need not be tuned on a system-wide basis.
145  * When tuning these variables, avoid pathological values; while some attempt
146  * is made to verify the integrity of these variables, they are not considered
147  * part of the supported interface to DTrace, and they are therefore not
148  * checked comprehensively.  Further, these variables should not be tuned
149  * dynamically via "mdb -kw" or other means; they should only be tuned via
150  * /etc/system.
151  */
152 int             dtrace_destructive_disallow = 0;
153 dtrace_optval_t dtrace_nonroot_maxsize = (16 * 1024 * 1024);
154 size_t          dtrace_difo_maxsize = (256 * 1024);
155 dtrace_optval_t dtrace_dof_maxsize = (256 * 1024);
156 size_t          dtrace_global_maxsize = (16 * 1024);
157 size_t          dtrace_actions_max = (16 * 1024);
158 size_t          dtrace_retain_max = 1024;
159 dtrace_optval_t dtrace_helper_actions_max = 32;
160 dtrace_optval_t dtrace_helper_providers_max = 32;
161 dtrace_optval_t dtrace_dstate_defsize = (1 * 1024 * 1024);
162 size_t          dtrace_strsize_default = 256;
163 dtrace_optval_t dtrace_cleanrate_default = 9900990;             /* 101 hz */
164 dtrace_optval_t dtrace_cleanrate_min = 200000;                  /* 5000 hz */
165 dtrace_optval_t dtrace_cleanrate_max = (uint64_t)60 * NANOSEC;  /* 1/minute */
166 dtrace_optval_t dtrace_aggrate_default = NANOSEC;               /* 1 hz */
167 dtrace_optval_t dtrace_statusrate_default = NANOSEC;            /* 1 hz */
168 dtrace_optval_t dtrace_statusrate_max = (hrtime_t)10 * NANOSEC;  /* 6/minute */
169 dtrace_optval_t dtrace_switchrate_default = NANOSEC;            /* 1 hz */
170 dtrace_optval_t dtrace_nspec_default = 1;
171 dtrace_optval_t dtrace_specsize_default = 32 * 1024;
172 dtrace_optval_t dtrace_stackframes_default = 20;
173 dtrace_optval_t dtrace_ustackframes_default = 20;
174 dtrace_optval_t dtrace_jstackframes_default = 50;
175 dtrace_optval_t dtrace_jstackstrsize_default = 512;
176 int             dtrace_msgdsize_max = 128;
177 hrtime_t        dtrace_chill_max = 500 * (NANOSEC / MILLISEC);  /* 500 ms */
178 hrtime_t        dtrace_chill_interval = NANOSEC;                /* 1000 ms */
179 int             dtrace_devdepth_max = 32;
180 int             dtrace_err_verbose;
181 hrtime_t        dtrace_deadman_interval = NANOSEC;
182 hrtime_t        dtrace_deadman_timeout = (hrtime_t)10 * NANOSEC;
183 hrtime_t        dtrace_deadman_user = (hrtime_t)30 * NANOSEC;
184
185 /*
186  * DTrace External Variables
187  *
188  * As dtrace(7D) is a kernel module, any DTrace variables are obviously
189  * available to DTrace consumers via the backtick (`) syntax.  One of these,
190  * dtrace_zero, is made deliberately so:  it is provided as a source of
191  * well-known, zero-filled memory.  While this variable is not documented,
192  * it is used by some translators as an implementation detail.
193  */
194 const char      dtrace_zero[256] = { 0 };       /* zero-filled memory */
195
196 /*
197  * DTrace Internal Variables
198  */
199 #if defined(sun)
200 static dev_info_t       *dtrace_devi;           /* device info */
201 #endif
202 #if defined(sun)
203 static vmem_t           *dtrace_arena;          /* probe ID arena */
204 static vmem_t           *dtrace_minor;          /* minor number arena */
205 static taskq_t          *dtrace_taskq;          /* task queue */
206 #else
207 static struct unrhdr    *dtrace_arena;          /* Probe ID number.     */
208 #endif
209 static dtrace_probe_t   **dtrace_probes;        /* array of all probes */
210 static int              dtrace_nprobes;         /* number of probes */
211 static dtrace_provider_t *dtrace_provider;      /* provider list */
212 static dtrace_meta_t    *dtrace_meta_pid;       /* user-land meta provider */
213 static int              dtrace_opens;           /* number of opens */
214 static int              dtrace_helpers;         /* number of helpers */
215 #if defined(sun)
216 static void             *dtrace_softstate;      /* softstate pointer */
217 #endif
218 static dtrace_hash_t    *dtrace_bymod;          /* probes hashed by module */
219 static dtrace_hash_t    *dtrace_byfunc;         /* probes hashed by function */
220 static dtrace_hash_t    *dtrace_byname;         /* probes hashed by name */
221 static dtrace_toxrange_t *dtrace_toxrange;      /* toxic range array */
222 static int              dtrace_toxranges;       /* number of toxic ranges */
223 static int              dtrace_toxranges_max;   /* size of toxic range array */
224 static dtrace_anon_t    dtrace_anon;            /* anonymous enabling */
225 static kmem_cache_t     *dtrace_state_cache;    /* cache for dynamic state */
226 static uint64_t         dtrace_vtime_references; /* number of vtimestamp refs */
227 static kthread_t        *dtrace_panicked;       /* panicking thread */
228 static dtrace_ecb_t     *dtrace_ecb_create_cache; /* cached created ECB */
229 static dtrace_genid_t   dtrace_probegen;        /* current probe generation */
230 static dtrace_helpers_t *dtrace_deferred_pid;   /* deferred helper list */
231 static dtrace_enabling_t *dtrace_retained;      /* list of retained enablings */
232 static dtrace_dynvar_t  dtrace_dynhash_sink;    /* end of dynamic hash chains */
233 #if !defined(sun)
234 static struct mtx       dtrace_unr_mtx;
235 MTX_SYSINIT(dtrace_unr_mtx, &dtrace_unr_mtx, "Unique resource identifier", MTX_DEF);
236 int             dtrace_in_probe;        /* non-zero if executing a probe */
237 #if defined(__i386__) || defined(__amd64__)
238 uintptr_t       dtrace_in_probe_addr;   /* Address of invop when already in probe */
239 #endif
240 #endif
241
242 /*
243  * DTrace Locking
244  * DTrace is protected by three (relatively coarse-grained) locks:
245  *
246  * (1) dtrace_lock is required to manipulate essentially any DTrace state,
247  *     including enabling state, probes, ECBs, consumer state, helper state,
248  *     etc.  Importantly, dtrace_lock is _not_ required when in probe context;
249  *     probe context is lock-free -- synchronization is handled via the
250  *     dtrace_sync() cross call mechanism.
251  *
252  * (2) dtrace_provider_lock is required when manipulating provider state, or
253  *     when provider state must be held constant.
254  *
255  * (3) dtrace_meta_lock is required when manipulating meta provider state, or
256  *     when meta provider state must be held constant.
257  *
258  * The lock ordering between these three locks is dtrace_meta_lock before
259  * dtrace_provider_lock before dtrace_lock.  (In particular, there are
260  * several places where dtrace_provider_lock is held by the framework as it
261  * calls into the providers -- which then call back into the framework,
262  * grabbing dtrace_lock.)
263  *
264  * There are two other locks in the mix:  mod_lock and cpu_lock.  With respect
265  * to dtrace_provider_lock and dtrace_lock, cpu_lock continues its historical
266  * role as a coarse-grained lock; it is acquired before both of these locks.
267  * With respect to dtrace_meta_lock, its behavior is stranger:  cpu_lock must
268  * be acquired _between_ dtrace_meta_lock and any other DTrace locks.
269  * mod_lock is similar with respect to dtrace_provider_lock in that it must be
270  * acquired _between_ dtrace_provider_lock and dtrace_lock.
271  */
272 static kmutex_t         dtrace_lock;            /* probe state lock */
273 static kmutex_t         dtrace_provider_lock;   /* provider state lock */
274 static kmutex_t         dtrace_meta_lock;       /* meta-provider state lock */
275
276 #if !defined(sun)
277 /* XXX FreeBSD hacks. */
278 static kmutex_t         mod_lock;
279
280 #define cr_suid         cr_svuid
281 #define cr_sgid         cr_svgid
282 #define ipaddr_t        in_addr_t
283 #define mod_modname     pathname
284 #define vuprintf        vprintf
285 #define ttoproc(_a)     ((_a)->td_proc)
286 #define crgetzoneid(_a) 0
287 #define NCPU            MAXCPU
288 #define SNOCD           0
289 #define CPU_ON_INTR(_a) 0
290
291 #define PRIV_EFFECTIVE          (1 << 0)
292 #define PRIV_DTRACE_KERNEL      (1 << 1)
293 #define PRIV_DTRACE_PROC        (1 << 2)
294 #define PRIV_DTRACE_USER        (1 << 3)
295 #define PRIV_PROC_OWNER         (1 << 4)
296 #define PRIV_PROC_ZONE          (1 << 5)
297 #define PRIV_ALL                ~0
298
299 SYSCTL_NODE(_debug, OID_AUTO, dtrace, CTLFLAG_RD, 0, "DTrace Information");
300 #endif
301
302 #if defined(sun)
303 #define curcpu  CPU->cpu_id
304 #endif
305
306
307 /*
308  * DTrace Provider Variables
309  *
310  * These are the variables relating to DTrace as a provider (that is, the
311  * provider of the BEGIN, END, and ERROR probes).
312  */
313 static dtrace_pattr_t   dtrace_provider_attr = {
314 { DTRACE_STABILITY_STABLE, DTRACE_STABILITY_STABLE, DTRACE_CLASS_COMMON },
315 { DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_UNKNOWN },
316 { DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_UNKNOWN },
317 { DTRACE_STABILITY_STABLE, DTRACE_STABILITY_STABLE, DTRACE_CLASS_COMMON },
318 { DTRACE_STABILITY_STABLE, DTRACE_STABILITY_STABLE, DTRACE_CLASS_COMMON },
319 };
320
321 static void
322 dtrace_nullop(void)
323 {}
324
325 static dtrace_pops_t    dtrace_provider_ops = {
326         (void (*)(void *, dtrace_probedesc_t *))dtrace_nullop,
327         (void (*)(void *, modctl_t *))dtrace_nullop,
328         (void (*)(void *, dtrace_id_t, void *))dtrace_nullop,
329         (void (*)(void *, dtrace_id_t, void *))dtrace_nullop,
330         (void (*)(void *, dtrace_id_t, void *))dtrace_nullop,
331         (void (*)(void *, dtrace_id_t, void *))dtrace_nullop,
332         NULL,
333         NULL,
334         NULL,
335         (void (*)(void *, dtrace_id_t, void *))dtrace_nullop
336 };
337
338 static dtrace_id_t      dtrace_probeid_begin;   /* special BEGIN probe */
339 static dtrace_id_t      dtrace_probeid_end;     /* special END probe */
340 dtrace_id_t             dtrace_probeid_error;   /* special ERROR probe */
341
342 /*
343  * DTrace Helper Tracing Variables
344  */
345 uint32_t dtrace_helptrace_next = 0;
346 uint32_t dtrace_helptrace_nlocals;
347 char    *dtrace_helptrace_buffer;
348 int     dtrace_helptrace_bufsize = 512 * 1024;
349
350 #ifdef DEBUG
351 int     dtrace_helptrace_enabled = 1;
352 #else
353 int     dtrace_helptrace_enabled = 0;
354 #endif
355
356 /*
357  * DTrace Error Hashing
358  *
359  * On DEBUG kernels, DTrace will track the errors that has seen in a hash
360  * table.  This is very useful for checking coverage of tests that are
361  * expected to induce DIF or DOF processing errors, and may be useful for
362  * debugging problems in the DIF code generator or in DOF generation .  The
363  * error hash may be examined with the ::dtrace_errhash MDB dcmd.
364  */
365 #ifdef DEBUG
366 static dtrace_errhash_t dtrace_errhash[DTRACE_ERRHASHSZ];
367 static const char *dtrace_errlast;
368 static kthread_t *dtrace_errthread;
369 static kmutex_t dtrace_errlock;
370 #endif
371
372 /*
373  * DTrace Macros and Constants
374  *
375  * These are various macros that are useful in various spots in the
376  * implementation, along with a few random constants that have no meaning
377  * outside of the implementation.  There is no real structure to this cpp
378  * mishmash -- but is there ever?
379  */
380 #define DTRACE_HASHSTR(hash, probe)     \
381         dtrace_hash_str(*((char **)((uintptr_t)(probe) + (hash)->dth_stroffs)))
382
383 #define DTRACE_HASHNEXT(hash, probe)    \
384         (dtrace_probe_t **)((uintptr_t)(probe) + (hash)->dth_nextoffs)
385
386 #define DTRACE_HASHPREV(hash, probe)    \
387         (dtrace_probe_t **)((uintptr_t)(probe) + (hash)->dth_prevoffs)
388
389 #define DTRACE_HASHEQ(hash, lhs, rhs)   \
390         (strcmp(*((char **)((uintptr_t)(lhs) + (hash)->dth_stroffs)), \
391             *((char **)((uintptr_t)(rhs) + (hash)->dth_stroffs))) == 0)
392
393 #define DTRACE_AGGHASHSIZE_SLEW         17
394
395 #define DTRACE_V4MAPPED_OFFSET          (sizeof (uint32_t) * 3)
396
397 /*
398  * The key for a thread-local variable consists of the lower 61 bits of the
399  * t_did, plus the 3 bits of the highest active interrupt above LOCK_LEVEL.
400  * We add DIF_VARIABLE_MAX to t_did to assure that the thread key is never
401  * equal to a variable identifier.  This is necessary (but not sufficient) to
402  * assure that global associative arrays never collide with thread-local
403  * variables.  To guarantee that they cannot collide, we must also define the
404  * order for keying dynamic variables.  That order is:
405  *
406  *   [ key0 ] ... [ keyn ] [ variable-key ] [ tls-key ]
407  *
408  * Because the variable-key and the tls-key are in orthogonal spaces, there is
409  * no way for a global variable key signature to match a thread-local key
410  * signature.
411  */
412 #if defined(sun)
413 #define DTRACE_TLS_THRKEY(where) { \
414         uint_t intr = 0; \
415         uint_t actv = CPU->cpu_intr_actv >> (LOCK_LEVEL + 1); \
416         for (; actv; actv >>= 1) \
417                 intr++; \
418         ASSERT(intr < (1 << 3)); \
419         (where) = ((curthread->t_did + DIF_VARIABLE_MAX) & \
420             (((uint64_t)1 << 61) - 1)) | ((uint64_t)intr << 61); \
421 }
422 #else
423 #define DTRACE_TLS_THRKEY(where) { \
424         solaris_cpu_t *_c = &solaris_cpu[curcpu]; \
425         uint_t intr = 0; \
426         uint_t actv = _c->cpu_intr_actv; \
427         for (; actv; actv >>= 1) \
428                 intr++; \
429         ASSERT(intr < (1 << 3)); \
430         (where) = ((curthread->td_tid + DIF_VARIABLE_MAX) & \
431             (((uint64_t)1 << 61) - 1)) | ((uint64_t)intr << 61); \
432 }
433 #endif
434
435 #define DT_BSWAP_8(x)   ((x) & 0xff)
436 #define DT_BSWAP_16(x)  ((DT_BSWAP_8(x) << 8) | DT_BSWAP_8((x) >> 8))
437 #define DT_BSWAP_32(x)  ((DT_BSWAP_16(x) << 16) | DT_BSWAP_16((x) >> 16))
438 #define DT_BSWAP_64(x)  ((DT_BSWAP_32(x) << 32) | DT_BSWAP_32((x) >> 32))
439
440 #define DT_MASK_LO 0x00000000FFFFFFFFULL
441
442 #define DTRACE_STORE(type, tomax, offset, what) \
443         *((type *)((uintptr_t)(tomax) + (uintptr_t)offset)) = (type)(what);
444
445 #ifndef __i386
446 #define DTRACE_ALIGNCHECK(addr, size, flags)                            \
447         if (addr & (size - 1)) {                                        \
448                 *flags |= CPU_DTRACE_BADALIGN;                          \
449                 cpu_core[curcpu].cpuc_dtrace_illval = addr;     \
450                 return (0);                                             \
451         }
452 #else
453 #define DTRACE_ALIGNCHECK(addr, size, flags)
454 #endif
455
456 /*
457  * Test whether a range of memory starting at testaddr of size testsz falls
458  * within the range of memory described by addr, sz.  We take care to avoid
459  * problems with overflow and underflow of the unsigned quantities, and
460  * disallow all negative sizes.  Ranges of size 0 are allowed.
461  */
462 #define DTRACE_INRANGE(testaddr, testsz, baseaddr, basesz) \
463         ((testaddr) - (baseaddr) < (basesz) && \
464         (testaddr) + (testsz) - (baseaddr) <= (basesz) && \
465         (testaddr) + (testsz) >= (testaddr))
466
467 /*
468  * Test whether alloc_sz bytes will fit in the scratch region.  We isolate
469  * alloc_sz on the righthand side of the comparison in order to avoid overflow
470  * or underflow in the comparison with it.  This is simpler than the INRANGE
471  * check above, because we know that the dtms_scratch_ptr is valid in the
472  * range.  Allocations of size zero are allowed.
473  */
474 #define DTRACE_INSCRATCH(mstate, alloc_sz) \
475         ((mstate)->dtms_scratch_base + (mstate)->dtms_scratch_size - \
476         (mstate)->dtms_scratch_ptr >= (alloc_sz))
477
478 #define DTRACE_LOADFUNC(bits)                                           \
479 /*CSTYLED*/                                                             \
480 uint##bits##_t                                                          \
481 dtrace_load##bits(uintptr_t addr)                                       \
482 {                                                                       \
483         size_t size = bits / NBBY;                                      \
484         /*CSTYLED*/                                                     \
485         uint##bits##_t rval;                                            \
486         int i;                                                          \
487         volatile uint16_t *flags = (volatile uint16_t *)                \
488             &cpu_core[curcpu].cpuc_dtrace_flags;                        \
489                                                                         \
490         DTRACE_ALIGNCHECK(addr, size, flags);                           \
491                                                                         \
492         for (i = 0; i < dtrace_toxranges; i++) {                        \
493                 if (addr >= dtrace_toxrange[i].dtt_limit)               \
494                         continue;                                       \
495                                                                         \
496                 if (addr + size <= dtrace_toxrange[i].dtt_base)         \
497                         continue;                                       \
498                                                                         \
499                 /*                                                      \
500                  * This address falls within a toxic region; return 0.  \
501                  */                                                     \
502                 *flags |= CPU_DTRACE_BADADDR;                           \
503                 cpu_core[curcpu].cpuc_dtrace_illval = addr;             \
504                 return (0);                                             \
505         }                                                               \
506                                                                         \
507         *flags |= CPU_DTRACE_NOFAULT;                                   \
508         /*CSTYLED*/                                                     \
509         rval = *((volatile uint##bits##_t *)addr);                      \
510         *flags &= ~CPU_DTRACE_NOFAULT;                                  \
511                                                                         \
512         return (!(*flags & CPU_DTRACE_FAULT) ? rval : 0);               \
513 }
514
515 #ifdef _LP64
516 #define dtrace_loadptr  dtrace_load64
517 #else
518 #define dtrace_loadptr  dtrace_load32
519 #endif
520
521 #define DTRACE_DYNHASH_FREE     0
522 #define DTRACE_DYNHASH_SINK     1
523 #define DTRACE_DYNHASH_VALID    2
524
525 #define DTRACE_MATCH_NEXT       0
526 #define DTRACE_MATCH_DONE       1
527 #define DTRACE_ANCHORED(probe)  ((probe)->dtpr_func[0] != '\0')
528 #define DTRACE_STATE_ALIGN      64
529
530 #define DTRACE_FLAGS2FLT(flags)                                         \
531         (((flags) & CPU_DTRACE_BADADDR) ? DTRACEFLT_BADADDR :           \
532         ((flags) & CPU_DTRACE_ILLOP) ? DTRACEFLT_ILLOP :                \
533         ((flags) & CPU_DTRACE_DIVZERO) ? DTRACEFLT_DIVZERO :            \
534         ((flags) & CPU_DTRACE_KPRIV) ? DTRACEFLT_KPRIV :                \
535         ((flags) & CPU_DTRACE_UPRIV) ? DTRACEFLT_UPRIV :                \
536         ((flags) & CPU_DTRACE_TUPOFLOW) ?  DTRACEFLT_TUPOFLOW :         \
537         ((flags) & CPU_DTRACE_BADALIGN) ?  DTRACEFLT_BADALIGN :         \
538         ((flags) & CPU_DTRACE_NOSCRATCH) ?  DTRACEFLT_NOSCRATCH :       \
539         ((flags) & CPU_DTRACE_BADSTACK) ?  DTRACEFLT_BADSTACK :         \
540         DTRACEFLT_UNKNOWN)
541
542 #define DTRACEACT_ISSTRING(act)                                         \
543         ((act)->dta_kind == DTRACEACT_DIFEXPR &&                        \
544         (act)->dta_difo->dtdo_rtype.dtdt_kind == DIF_TYPE_STRING)
545
546 /* Function prototype definitions: */
547 static size_t dtrace_strlen(const char *, size_t);
548 static dtrace_probe_t *dtrace_probe_lookup_id(dtrace_id_t id);
549 static void dtrace_enabling_provide(dtrace_provider_t *);
550 static int dtrace_enabling_match(dtrace_enabling_t *, int *);
551 static void dtrace_enabling_matchall(void);
552 static dtrace_state_t *dtrace_anon_grab(void);
553 #if defined(sun)
554 static uint64_t dtrace_helper(int, dtrace_mstate_t *,
555     dtrace_state_t *, uint64_t, uint64_t);
556 static dtrace_helpers_t *dtrace_helpers_create(proc_t *);
557 #endif
558 static void dtrace_buffer_drop(dtrace_buffer_t *);
559 static intptr_t dtrace_buffer_reserve(dtrace_buffer_t *, size_t, size_t,
560     dtrace_state_t *, dtrace_mstate_t *);
561 static int dtrace_state_option(dtrace_state_t *, dtrace_optid_t,
562     dtrace_optval_t);
563 static int dtrace_ecb_create_enable(dtrace_probe_t *, void *);
564 #if defined(sun)
565 static void dtrace_helper_provider_destroy(dtrace_helper_provider_t *);
566 #endif
567 uint16_t dtrace_load16(uintptr_t);
568 uint32_t dtrace_load32(uintptr_t);
569 uint64_t dtrace_load64(uintptr_t);
570 uint8_t dtrace_load8(uintptr_t);
571 void dtrace_dynvar_clean(dtrace_dstate_t *);
572 dtrace_dynvar_t *dtrace_dynvar(dtrace_dstate_t *, uint_t, dtrace_key_t *,
573     size_t, dtrace_dynvar_op_t, dtrace_mstate_t *, dtrace_vstate_t *);
574 uintptr_t dtrace_dif_varstr(uintptr_t, dtrace_state_t *, dtrace_mstate_t *);
575
576 /*
577  * DTrace Probe Context Functions
578  *
579  * These functions are called from probe context.  Because probe context is
580  * any context in which C may be called, arbitrarily locks may be held,
581  * interrupts may be disabled, we may be in arbitrary dispatched state, etc.
582  * As a result, functions called from probe context may only call other DTrace
583  * support functions -- they may not interact at all with the system at large.
584  * (Note that the ASSERT macro is made probe-context safe by redefining it in
585  * terms of dtrace_assfail(), a probe-context safe function.) If arbitrary
586  * loads are to be performed from probe context, they _must_ be in terms of
587  * the safe dtrace_load*() variants.
588  *
589  * Some functions in this block are not actually called from probe context;
590  * for these functions, there will be a comment above the function reading
591  * "Note:  not called from probe context."
592  */
593 void
594 dtrace_panic(const char *format, ...)
595 {
596         va_list alist;
597
598         va_start(alist, format);
599         dtrace_vpanic(format, alist);
600         va_end(alist);
601 }
602
603 int
604 dtrace_assfail(const char *a, const char *f, int l)
605 {
606         dtrace_panic("assertion failed: %s, file: %s, line: %d", a, f, l);
607
608         /*
609          * We just need something here that even the most clever compiler
610          * cannot optimize away.
611          */
612         return (a[(uintptr_t)f]);
613 }
614
615 /*
616  * Atomically increment a specified error counter from probe context.
617  */
618 static void
619 dtrace_error(uint32_t *counter)
620 {
621         /*
622          * Most counters stored to in probe context are per-CPU counters.
623          * However, there are some error conditions that are sufficiently
624          * arcane that they don't merit per-CPU storage.  If these counters
625          * are incremented concurrently on different CPUs, scalability will be
626          * adversely affected -- but we don't expect them to be white-hot in a
627          * correctly constructed enabling...
628          */
629         uint32_t oval, nval;
630
631         do {
632                 oval = *counter;
633
634                 if ((nval = oval + 1) == 0) {
635                         /*
636                          * If the counter would wrap, set it to 1 -- assuring
637                          * that the counter is never zero when we have seen
638                          * errors.  (The counter must be 32-bits because we
639                          * aren't guaranteed a 64-bit compare&swap operation.)
640                          * To save this code both the infamy of being fingered
641                          * by a priggish news story and the indignity of being
642                          * the target of a neo-puritan witch trial, we're
643                          * carefully avoiding any colorful description of the
644                          * likelihood of this condition -- but suffice it to
645                          * say that it is only slightly more likely than the
646                          * overflow of predicate cache IDs, as discussed in
647                          * dtrace_predicate_create().
648                          */
649                         nval = 1;
650                 }
651         } while (dtrace_cas32(counter, oval, nval) != oval);
652 }
653
654 /*
655  * Use the DTRACE_LOADFUNC macro to define functions for each of loading a
656  * uint8_t, a uint16_t, a uint32_t and a uint64_t.
657  */
658 DTRACE_LOADFUNC(8)
659 DTRACE_LOADFUNC(16)
660 DTRACE_LOADFUNC(32)
661 DTRACE_LOADFUNC(64)
662
663 static int
664 dtrace_inscratch(uintptr_t dest, size_t size, dtrace_mstate_t *mstate)
665 {
666         if (dest < mstate->dtms_scratch_base)
667                 return (0);
668
669         if (dest + size < dest)
670                 return (0);
671
672         if (dest + size > mstate->dtms_scratch_ptr)
673                 return (0);
674
675         return (1);
676 }
677
678 static int
679 dtrace_canstore_statvar(uint64_t addr, size_t sz,
680     dtrace_statvar_t **svars, int nsvars)
681 {
682         int i;
683
684         for (i = 0; i < nsvars; i++) {
685                 dtrace_statvar_t *svar = svars[i];
686
687                 if (svar == NULL || svar->dtsv_size == 0)
688                         continue;
689
690                 if (DTRACE_INRANGE(addr, sz, svar->dtsv_data, svar->dtsv_size))
691                         return (1);
692         }
693
694         return (0);
695 }
696
697 /*
698  * Check to see if the address is within a memory region to which a store may
699  * be issued.  This includes the DTrace scratch areas, and any DTrace variable
700  * region.  The caller of dtrace_canstore() is responsible for performing any
701  * alignment checks that are needed before stores are actually executed.
702  */
703 static int
704 dtrace_canstore(uint64_t addr, size_t sz, dtrace_mstate_t *mstate,
705     dtrace_vstate_t *vstate)
706 {
707         /*
708          * First, check to see if the address is in scratch space...
709          */
710         if (DTRACE_INRANGE(addr, sz, mstate->dtms_scratch_base,
711             mstate->dtms_scratch_size))
712                 return (1);
713
714         /*
715          * Now check to see if it's a dynamic variable.  This check will pick
716          * up both thread-local variables and any global dynamically-allocated
717          * variables.
718          */
719         if (DTRACE_INRANGE(addr, sz, (uintptr_t)vstate->dtvs_dynvars.dtds_base,
720             vstate->dtvs_dynvars.dtds_size)) {
721                 dtrace_dstate_t *dstate = &vstate->dtvs_dynvars;
722                 uintptr_t base = (uintptr_t)dstate->dtds_base +
723                     (dstate->dtds_hashsize * sizeof (dtrace_dynhash_t));
724                 uintptr_t chunkoffs;
725
726                 /*
727                  * Before we assume that we can store here, we need to make
728                  * sure that it isn't in our metadata -- storing to our
729                  * dynamic variable metadata would corrupt our state.  For
730                  * the range to not include any dynamic variable metadata,
731                  * it must:
732                  *
733                  *      (1) Start above the hash table that is at the base of
734                  *      the dynamic variable space
735                  *
736                  *      (2) Have a starting chunk offset that is beyond the
737                  *      dtrace_dynvar_t that is at the base of every chunk
738                  *
739                  *      (3) Not span a chunk boundary
740                  *
741                  */
742                 if (addr < base)
743                         return (0);
744
745                 chunkoffs = (addr - base) % dstate->dtds_chunksize;
746
747                 if (chunkoffs < sizeof (dtrace_dynvar_t))
748                         return (0);
749
750                 if (chunkoffs + sz > dstate->dtds_chunksize)
751                         return (0);
752
753                 return (1);
754         }
755
756         /*
757          * Finally, check the static local and global variables.  These checks
758          * take the longest, so we perform them last.
759          */
760         if (dtrace_canstore_statvar(addr, sz,
761             vstate->dtvs_locals, vstate->dtvs_nlocals))
762                 return (1);
763
764         if (dtrace_canstore_statvar(addr, sz,
765             vstate->dtvs_globals, vstate->dtvs_nglobals))
766                 return (1);
767
768         return (0);
769 }
770
771
772 /*
773  * Convenience routine to check to see if the address is within a memory
774  * region in which a load may be issued given the user's privilege level;
775  * if not, it sets the appropriate error flags and loads 'addr' into the
776  * illegal value slot.
777  *
778  * DTrace subroutines (DIF_SUBR_*) should use this helper to implement
779  * appropriate memory access protection.
780  */
781 static int
782 dtrace_canload(uint64_t addr, size_t sz, dtrace_mstate_t *mstate,
783     dtrace_vstate_t *vstate)
784 {
785         volatile uintptr_t *illval = &cpu_core[curcpu].cpuc_dtrace_illval;
786
787         /*
788          * If we hold the privilege to read from kernel memory, then
789          * everything is readable.
790          */
791         if ((mstate->dtms_access & DTRACE_ACCESS_KERNEL) != 0)
792                 return (1);
793
794         /*
795          * You can obviously read that which you can store.
796          */
797         if (dtrace_canstore(addr, sz, mstate, vstate))
798                 return (1);
799
800         /*
801          * We're allowed to read from our own string table.
802          */
803         if (DTRACE_INRANGE(addr, sz, (uintptr_t)mstate->dtms_difo->dtdo_strtab,
804             mstate->dtms_difo->dtdo_strlen))
805                 return (1);
806
807         DTRACE_CPUFLAG_SET(CPU_DTRACE_KPRIV);
808         *illval = addr;
809         return (0);
810 }
811
812 /*
813  * Convenience routine to check to see if a given string is within a memory
814  * region in which a load may be issued given the user's privilege level;
815  * this exists so that we don't need to issue unnecessary dtrace_strlen()
816  * calls in the event that the user has all privileges.
817  */
818 static int
819 dtrace_strcanload(uint64_t addr, size_t sz, dtrace_mstate_t *mstate,
820     dtrace_vstate_t *vstate)
821 {
822         size_t strsz;
823
824         /*
825          * If we hold the privilege to read from kernel memory, then
826          * everything is readable.
827          */
828         if ((mstate->dtms_access & DTRACE_ACCESS_KERNEL) != 0)
829                 return (1);
830
831         strsz = 1 + dtrace_strlen((char *)(uintptr_t)addr, sz);
832         if (dtrace_canload(addr, strsz, mstate, vstate))
833                 return (1);
834
835         return (0);
836 }
837
838 /*
839  * Convenience routine to check to see if a given variable is within a memory
840  * region in which a load may be issued given the user's privilege level.
841  */
842 static int
843 dtrace_vcanload(void *src, dtrace_diftype_t *type, dtrace_mstate_t *mstate,
844     dtrace_vstate_t *vstate)
845 {
846         size_t sz;
847         ASSERT(type->dtdt_flags & DIF_TF_BYREF);
848
849         /*
850          * If we hold the privilege to read from kernel memory, then
851          * everything is readable.
852          */
853         if ((mstate->dtms_access & DTRACE_ACCESS_KERNEL) != 0)
854                 return (1);
855
856         if (type->dtdt_kind == DIF_TYPE_STRING)
857                 sz = dtrace_strlen(src,
858                     vstate->dtvs_state->dts_options[DTRACEOPT_STRSIZE]) + 1;
859         else
860                 sz = type->dtdt_size;
861
862         return (dtrace_canload((uintptr_t)src, sz, mstate, vstate));
863 }
864
865 /*
866  * Compare two strings using safe loads.
867  */
868 static int
869 dtrace_strncmp(char *s1, char *s2, size_t limit)
870 {
871         uint8_t c1, c2;
872         volatile uint16_t *flags;
873
874         if (s1 == s2 || limit == 0)
875                 return (0);
876
877         flags = (volatile uint16_t *)&cpu_core[curcpu].cpuc_dtrace_flags;
878
879         do {
880                 if (s1 == NULL) {
881                         c1 = '\0';
882                 } else {
883                         c1 = dtrace_load8((uintptr_t)s1++);
884                 }
885
886                 if (s2 == NULL) {
887                         c2 = '\0';
888                 } else {
889                         c2 = dtrace_load8((uintptr_t)s2++);
890                 }
891
892                 if (c1 != c2)
893                         return (c1 - c2);
894         } while (--limit && c1 != '\0' && !(*flags & CPU_DTRACE_FAULT));
895
896         return (0);
897 }
898
899 /*
900  * Compute strlen(s) for a string using safe memory accesses.  The additional
901  * len parameter is used to specify a maximum length to ensure completion.
902  */
903 static size_t
904 dtrace_strlen(const char *s, size_t lim)
905 {
906         uint_t len;
907
908         for (len = 0; len != lim; len++) {
909                 if (dtrace_load8((uintptr_t)s++) == '\0')
910                         break;
911         }
912
913         return (len);
914 }
915
916 /*
917  * Check if an address falls within a toxic region.
918  */
919 static int
920 dtrace_istoxic(uintptr_t kaddr, size_t size)
921 {
922         uintptr_t taddr, tsize;
923         int i;
924
925         for (i = 0; i < dtrace_toxranges; i++) {
926                 taddr = dtrace_toxrange[i].dtt_base;
927                 tsize = dtrace_toxrange[i].dtt_limit - taddr;
928
929                 if (kaddr - taddr < tsize) {
930                         DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
931                         cpu_core[curcpu].cpuc_dtrace_illval = kaddr;
932                         return (1);
933                 }
934
935                 if (taddr - kaddr < size) {
936                         DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
937                         cpu_core[curcpu].cpuc_dtrace_illval = taddr;
938                         return (1);
939                 }
940         }
941
942         return (0);
943 }
944
945 /*
946  * Copy src to dst using safe memory accesses.  The src is assumed to be unsafe
947  * memory specified by the DIF program.  The dst is assumed to be safe memory
948  * that we can store to directly because it is managed by DTrace.  As with
949  * standard bcopy, overlapping copies are handled properly.
950  */
951 static void
952 dtrace_bcopy(const void *src, void *dst, size_t len)
953 {
954         if (len != 0) {
955                 uint8_t *s1 = dst;
956                 const uint8_t *s2 = src;
957
958                 if (s1 <= s2) {
959                         do {
960                                 *s1++ = dtrace_load8((uintptr_t)s2++);
961                         } while (--len != 0);
962                 } else {
963                         s2 += len;
964                         s1 += len;
965
966                         do {
967                                 *--s1 = dtrace_load8((uintptr_t)--s2);
968                         } while (--len != 0);
969                 }
970         }
971 }
972
973 /*
974  * Copy src to dst using safe memory accesses, up to either the specified
975  * length, or the point that a nul byte is encountered.  The src is assumed to
976  * be unsafe memory specified by the DIF program.  The dst is assumed to be
977  * safe memory that we can store to directly because it is managed by DTrace.
978  * Unlike dtrace_bcopy(), overlapping regions are not handled.
979  */
980 static void
981 dtrace_strcpy(const void *src, void *dst, size_t len)
982 {
983         if (len != 0) {
984                 uint8_t *s1 = dst, c;
985                 const uint8_t *s2 = src;
986
987                 do {
988                         *s1++ = c = dtrace_load8((uintptr_t)s2++);
989                 } while (--len != 0 && c != '\0');
990         }
991 }
992
993 /*
994  * Copy src to dst, deriving the size and type from the specified (BYREF)
995  * variable type.  The src is assumed to be unsafe memory specified by the DIF
996  * program.  The dst is assumed to be DTrace variable memory that is of the
997  * specified type; we assume that we can store to directly.
998  */
999 static void
1000 dtrace_vcopy(void *src, void *dst, dtrace_diftype_t *type)
1001 {
1002         ASSERT(type->dtdt_flags & DIF_TF_BYREF);
1003
1004         if (type->dtdt_kind == DIF_TYPE_STRING) {
1005                 dtrace_strcpy(src, dst, type->dtdt_size);
1006         } else {
1007                 dtrace_bcopy(src, dst, type->dtdt_size);
1008         }
1009 }
1010
1011 /*
1012  * Compare s1 to s2 using safe memory accesses.  The s1 data is assumed to be
1013  * unsafe memory specified by the DIF program.  The s2 data is assumed to be
1014  * safe memory that we can access directly because it is managed by DTrace.
1015  */
1016 static int
1017 dtrace_bcmp(const void *s1, const void *s2, size_t len)
1018 {
1019         volatile uint16_t *flags;
1020
1021         flags = (volatile uint16_t *)&cpu_core[curcpu].cpuc_dtrace_flags;
1022
1023         if (s1 == s2)
1024                 return (0);
1025
1026         if (s1 == NULL || s2 == NULL)
1027                 return (1);
1028
1029         if (s1 != s2 && len != 0) {
1030                 const uint8_t *ps1 = s1;
1031                 const uint8_t *ps2 = s2;
1032
1033                 do {
1034                         if (dtrace_load8((uintptr_t)ps1++) != *ps2++)
1035                                 return (1);
1036                 } while (--len != 0 && !(*flags & CPU_DTRACE_FAULT));
1037         }
1038         return (0);
1039 }
1040
1041 /*
1042  * Zero the specified region using a simple byte-by-byte loop.  Note that this
1043  * is for safe DTrace-managed memory only.
1044  */
1045 static void
1046 dtrace_bzero(void *dst, size_t len)
1047 {
1048         uchar_t *cp;
1049
1050         for (cp = dst; len != 0; len--)
1051                 *cp++ = 0;
1052 }
1053
1054 static void
1055 dtrace_add_128(uint64_t *addend1, uint64_t *addend2, uint64_t *sum)
1056 {
1057         uint64_t result[2];
1058
1059         result[0] = addend1[0] + addend2[0];
1060         result[1] = addend1[1] + addend2[1] +
1061             (result[0] < addend1[0] || result[0] < addend2[0] ? 1 : 0);
1062
1063         sum[0] = result[0];
1064         sum[1] = result[1];
1065 }
1066
1067 /*
1068  * Shift the 128-bit value in a by b. If b is positive, shift left.
1069  * If b is negative, shift right.
1070  */
1071 static void
1072 dtrace_shift_128(uint64_t *a, int b)
1073 {
1074         uint64_t mask;
1075
1076         if (b == 0)
1077                 return;
1078
1079         if (b < 0) {
1080                 b = -b;
1081                 if (b >= 64) {
1082                         a[0] = a[1] >> (b - 64);
1083                         a[1] = 0;
1084                 } else {
1085                         a[0] >>= b;
1086                         mask = 1LL << (64 - b);
1087                         mask -= 1;
1088                         a[0] |= ((a[1] & mask) << (64 - b));
1089                         a[1] >>= b;
1090                 }
1091         } else {
1092                 if (b >= 64) {
1093                         a[1] = a[0] << (b - 64);
1094                         a[0] = 0;
1095                 } else {
1096                         a[1] <<= b;
1097                         mask = a[0] >> (64 - b);
1098                         a[1] |= mask;
1099                         a[0] <<= b;
1100                 }
1101         }
1102 }
1103
1104 /*
1105  * The basic idea is to break the 2 64-bit values into 4 32-bit values,
1106  * use native multiplication on those, and then re-combine into the
1107  * resulting 128-bit value.
1108  *
1109  * (hi1 << 32 + lo1) * (hi2 << 32 + lo2) =
1110  *     hi1 * hi2 << 64 +
1111  *     hi1 * lo2 << 32 +
1112  *     hi2 * lo1 << 32 +
1113  *     lo1 * lo2
1114  */
1115 static void
1116 dtrace_multiply_128(uint64_t factor1, uint64_t factor2, uint64_t *product)
1117 {
1118         uint64_t hi1, hi2, lo1, lo2;
1119         uint64_t tmp[2];
1120
1121         hi1 = factor1 >> 32;
1122         hi2 = factor2 >> 32;
1123
1124         lo1 = factor1 & DT_MASK_LO;
1125         lo2 = factor2 & DT_MASK_LO;
1126
1127         product[0] = lo1 * lo2;
1128         product[1] = hi1 * hi2;
1129
1130         tmp[0] = hi1 * lo2;
1131         tmp[1] = 0;
1132         dtrace_shift_128(tmp, 32);
1133         dtrace_add_128(product, tmp, product);
1134
1135         tmp[0] = hi2 * lo1;
1136         tmp[1] = 0;
1137         dtrace_shift_128(tmp, 32);
1138         dtrace_add_128(product, tmp, product);
1139 }
1140
1141 /*
1142  * This privilege check should be used by actions and subroutines to
1143  * verify that the user credentials of the process that enabled the
1144  * invoking ECB match the target credentials
1145  */
1146 static int
1147 dtrace_priv_proc_common_user(dtrace_state_t *state)
1148 {
1149         cred_t *cr, *s_cr = state->dts_cred.dcr_cred;
1150
1151         /*
1152          * We should always have a non-NULL state cred here, since if cred
1153          * is null (anonymous tracing), we fast-path bypass this routine.
1154          */
1155         ASSERT(s_cr != NULL);
1156
1157         if ((cr = CRED()) != NULL &&
1158             s_cr->cr_uid == cr->cr_uid &&
1159             s_cr->cr_uid == cr->cr_ruid &&
1160             s_cr->cr_uid == cr->cr_suid &&
1161             s_cr->cr_gid == cr->cr_gid &&
1162             s_cr->cr_gid == cr->cr_rgid &&
1163             s_cr->cr_gid == cr->cr_sgid)
1164                 return (1);
1165
1166         return (0);
1167 }
1168
1169 /*
1170  * This privilege check should be used by actions and subroutines to
1171  * verify that the zone of the process that enabled the invoking ECB
1172  * matches the target credentials
1173  */
1174 static int
1175 dtrace_priv_proc_common_zone(dtrace_state_t *state)
1176 {
1177 #if defined(sun)
1178         cred_t *cr, *s_cr = state->dts_cred.dcr_cred;
1179
1180         /*
1181          * We should always have a non-NULL state cred here, since if cred
1182          * is null (anonymous tracing), we fast-path bypass this routine.
1183          */
1184         ASSERT(s_cr != NULL);
1185
1186         if ((cr = CRED()) != NULL &&
1187             s_cr->cr_zone == cr->cr_zone)
1188                 return (1);
1189
1190         return (0);
1191 #else
1192         return (1);
1193 #endif
1194 }
1195
1196 /*
1197  * This privilege check should be used by actions and subroutines to
1198  * verify that the process has not setuid or changed credentials.
1199  */
1200 static int
1201 dtrace_priv_proc_common_nocd(void)
1202 {
1203         proc_t *proc;
1204
1205         if ((proc = ttoproc(curthread)) != NULL &&
1206             !(proc->p_flag & SNOCD))
1207                 return (1);
1208
1209         return (0);
1210 }
1211
1212 static int
1213 dtrace_priv_proc_destructive(dtrace_state_t *state)
1214 {
1215         int action = state->dts_cred.dcr_action;
1216
1217         if (((action & DTRACE_CRA_PROC_DESTRUCTIVE_ALLZONE) == 0) &&
1218             dtrace_priv_proc_common_zone(state) == 0)
1219                 goto bad;
1220
1221         if (((action & DTRACE_CRA_PROC_DESTRUCTIVE_ALLUSER) == 0) &&
1222             dtrace_priv_proc_common_user(state) == 0)
1223                 goto bad;
1224
1225         if (((action & DTRACE_CRA_PROC_DESTRUCTIVE_CREDCHG) == 0) &&
1226             dtrace_priv_proc_common_nocd() == 0)
1227                 goto bad;
1228
1229         return (1);
1230
1231 bad:
1232         cpu_core[curcpu].cpuc_dtrace_flags |= CPU_DTRACE_UPRIV;
1233
1234         return (0);
1235 }
1236
1237 static int
1238 dtrace_priv_proc_control(dtrace_state_t *state)
1239 {
1240         if (state->dts_cred.dcr_action & DTRACE_CRA_PROC_CONTROL)
1241                 return (1);
1242
1243         if (dtrace_priv_proc_common_zone(state) &&
1244             dtrace_priv_proc_common_user(state) &&
1245             dtrace_priv_proc_common_nocd())
1246                 return (1);
1247
1248         cpu_core[curcpu].cpuc_dtrace_flags |= CPU_DTRACE_UPRIV;
1249
1250         return (0);
1251 }
1252
1253 static int
1254 dtrace_priv_proc(dtrace_state_t *state)
1255 {
1256         if (state->dts_cred.dcr_action & DTRACE_CRA_PROC)
1257                 return (1);
1258
1259         cpu_core[curcpu].cpuc_dtrace_flags |= CPU_DTRACE_UPRIV;
1260
1261         return (0);
1262 }
1263
1264 static int
1265 dtrace_priv_kernel(dtrace_state_t *state)
1266 {
1267         if (state->dts_cred.dcr_action & DTRACE_CRA_KERNEL)
1268                 return (1);
1269
1270         cpu_core[curcpu].cpuc_dtrace_flags |= CPU_DTRACE_KPRIV;
1271
1272         return (0);
1273 }
1274
1275 static int
1276 dtrace_priv_kernel_destructive(dtrace_state_t *state)
1277 {
1278         if (state->dts_cred.dcr_action & DTRACE_CRA_KERNEL_DESTRUCTIVE)
1279                 return (1);
1280
1281         cpu_core[curcpu].cpuc_dtrace_flags |= CPU_DTRACE_KPRIV;
1282
1283         return (0);
1284 }
1285
1286 /*
1287  * Note:  not called from probe context.  This function is called
1288  * asynchronously (and at a regular interval) from outside of probe context to
1289  * clean the dirty dynamic variable lists on all CPUs.  Dynamic variable
1290  * cleaning is explained in detail in <sys/dtrace_impl.h>.
1291  */
1292 void
1293 dtrace_dynvar_clean(dtrace_dstate_t *dstate)
1294 {
1295         dtrace_dynvar_t *dirty;
1296         dtrace_dstate_percpu_t *dcpu;
1297         int i, work = 0;
1298
1299         for (i = 0; i < NCPU; i++) {
1300                 dcpu = &dstate->dtds_percpu[i];
1301
1302                 ASSERT(dcpu->dtdsc_rinsing == NULL);
1303
1304                 /*
1305                  * If the dirty list is NULL, there is no dirty work to do.
1306                  */
1307                 if (dcpu->dtdsc_dirty == NULL)
1308                         continue;
1309
1310                 /*
1311                  * If the clean list is non-NULL, then we're not going to do
1312                  * any work for this CPU -- it means that there has not been
1313                  * a dtrace_dynvar() allocation on this CPU (or from this CPU)
1314                  * since the last time we cleaned house.
1315                  */
1316                 if (dcpu->dtdsc_clean != NULL)
1317                         continue;
1318
1319                 work = 1;
1320
1321                 /*
1322                  * Atomically move the dirty list aside.
1323                  */
1324                 do {
1325                         dirty = dcpu->dtdsc_dirty;
1326
1327                         /*
1328                          * Before we zap the dirty list, set the rinsing list.
1329                          * (This allows for a potential assertion in
1330                          * dtrace_dynvar():  if a free dynamic variable appears
1331                          * on a hash chain, either the dirty list or the
1332                          * rinsing list for some CPU must be non-NULL.)
1333                          */
1334                         dcpu->dtdsc_rinsing = dirty;
1335                         dtrace_membar_producer();
1336                 } while (dtrace_casptr(&dcpu->dtdsc_dirty,
1337                     dirty, NULL) != dirty);
1338         }
1339
1340         if (!work) {
1341                 /*
1342                  * We have no work to do; we can simply return.
1343                  */
1344                 return;
1345         }
1346
1347         dtrace_sync();
1348
1349         for (i = 0; i < NCPU; i++) {
1350                 dcpu = &dstate->dtds_percpu[i];
1351
1352                 if (dcpu->dtdsc_rinsing == NULL)
1353                         continue;
1354
1355                 /*
1356                  * We are now guaranteed that no hash chain contains a pointer
1357                  * into this dirty list; we can make it clean.
1358                  */
1359                 ASSERT(dcpu->dtdsc_clean == NULL);
1360                 dcpu->dtdsc_clean = dcpu->dtdsc_rinsing;
1361                 dcpu->dtdsc_rinsing = NULL;
1362         }
1363
1364         /*
1365          * Before we actually set the state to be DTRACE_DSTATE_CLEAN, make
1366          * sure that all CPUs have seen all of the dtdsc_clean pointers.
1367          * This prevents a race whereby a CPU incorrectly decides that
1368          * the state should be something other than DTRACE_DSTATE_CLEAN
1369          * after dtrace_dynvar_clean() has completed.
1370          */
1371         dtrace_sync();
1372
1373         dstate->dtds_state = DTRACE_DSTATE_CLEAN;
1374 }
1375
1376 /*
1377  * Depending on the value of the op parameter, this function looks-up,
1378  * allocates or deallocates an arbitrarily-keyed dynamic variable.  If an
1379  * allocation is requested, this function will return a pointer to a
1380  * dtrace_dynvar_t corresponding to the allocated variable -- or NULL if no
1381  * variable can be allocated.  If NULL is returned, the appropriate counter
1382  * will be incremented.
1383  */
1384 dtrace_dynvar_t *
1385 dtrace_dynvar(dtrace_dstate_t *dstate, uint_t nkeys,
1386     dtrace_key_t *key, size_t dsize, dtrace_dynvar_op_t op,
1387     dtrace_mstate_t *mstate, dtrace_vstate_t *vstate)
1388 {
1389         uint64_t hashval = DTRACE_DYNHASH_VALID;
1390         dtrace_dynhash_t *hash = dstate->dtds_hash;
1391         dtrace_dynvar_t *free, *new_free, *next, *dvar, *start, *prev = NULL;
1392         processorid_t me = curcpu, cpu = me;
1393         dtrace_dstate_percpu_t *dcpu = &dstate->dtds_percpu[me];
1394         size_t bucket, ksize;
1395         size_t chunksize = dstate->dtds_chunksize;
1396         uintptr_t kdata, lock, nstate;
1397         uint_t i;
1398
1399         ASSERT(nkeys != 0);
1400
1401         /*
1402          * Hash the key.  As with aggregations, we use Jenkins' "One-at-a-time"
1403          * algorithm.  For the by-value portions, we perform the algorithm in
1404          * 16-bit chunks (as opposed to 8-bit chunks).  This speeds things up a
1405          * bit, and seems to have only a minute effect on distribution.  For
1406          * the by-reference data, we perform "One-at-a-time" iterating (safely)
1407          * over each referenced byte.  It's painful to do this, but it's much
1408          * better than pathological hash distribution.  The efficacy of the
1409          * hashing algorithm (and a comparison with other algorithms) may be
1410          * found by running the ::dtrace_dynstat MDB dcmd.
1411          */
1412         for (i = 0; i < nkeys; i++) {
1413                 if (key[i].dttk_size == 0) {
1414                         uint64_t val = key[i].dttk_value;
1415
1416                         hashval += (val >> 48) & 0xffff;
1417                         hashval += (hashval << 10);
1418                         hashval ^= (hashval >> 6);
1419
1420                         hashval += (val >> 32) & 0xffff;
1421                         hashval += (hashval << 10);
1422                         hashval ^= (hashval >> 6);
1423
1424                         hashval += (val >> 16) & 0xffff;
1425                         hashval += (hashval << 10);
1426                         hashval ^= (hashval >> 6);
1427
1428                         hashval += val & 0xffff;
1429                         hashval += (hashval << 10);
1430                         hashval ^= (hashval >> 6);
1431                 } else {
1432                         /*
1433                          * This is incredibly painful, but it beats the hell
1434                          * out of the alternative.
1435                          */
1436                         uint64_t j, size = key[i].dttk_size;
1437                         uintptr_t base = (uintptr_t)key[i].dttk_value;
1438
1439                         if (!dtrace_canload(base, size, mstate, vstate))
1440                                 break;
1441
1442                         for (j = 0; j < size; j++) {
1443                                 hashval += dtrace_load8(base + j);
1444                                 hashval += (hashval << 10);
1445                                 hashval ^= (hashval >> 6);
1446                         }
1447                 }
1448         }
1449
1450         if (DTRACE_CPUFLAG_ISSET(CPU_DTRACE_FAULT))
1451                 return (NULL);
1452
1453         hashval += (hashval << 3);
1454         hashval ^= (hashval >> 11);
1455         hashval += (hashval << 15);
1456
1457         /*
1458          * There is a remote chance (ideally, 1 in 2^31) that our hashval
1459          * comes out to be one of our two sentinel hash values.  If this
1460          * actually happens, we set the hashval to be a value known to be a
1461          * non-sentinel value.
1462          */
1463         if (hashval == DTRACE_DYNHASH_FREE || hashval == DTRACE_DYNHASH_SINK)
1464                 hashval = DTRACE_DYNHASH_VALID;
1465
1466         /*
1467          * Yes, it's painful to do a divide here.  If the cycle count becomes
1468          * important here, tricks can be pulled to reduce it.  (However, it's
1469          * critical that hash collisions be kept to an absolute minimum;
1470          * they're much more painful than a divide.)  It's better to have a
1471          * solution that generates few collisions and still keeps things
1472          * relatively simple.
1473          */
1474         bucket = hashval % dstate->dtds_hashsize;
1475
1476         if (op == DTRACE_DYNVAR_DEALLOC) {
1477                 volatile uintptr_t *lockp = &hash[bucket].dtdh_lock;
1478
1479                 for (;;) {
1480                         while ((lock = *lockp) & 1)
1481                                 continue;
1482
1483                         if (dtrace_casptr((volatile void *)lockp,
1484                             (volatile void *)lock, (volatile void *)(lock + 1)) == (void *)lock)
1485                                 break;
1486                 }
1487
1488                 dtrace_membar_producer();
1489         }
1490
1491 top:
1492         prev = NULL;
1493         lock = hash[bucket].dtdh_lock;
1494
1495         dtrace_membar_consumer();
1496
1497         start = hash[bucket].dtdh_chain;
1498         ASSERT(start != NULL && (start->dtdv_hashval == DTRACE_DYNHASH_SINK ||
1499             start->dtdv_hashval != DTRACE_DYNHASH_FREE ||
1500             op != DTRACE_DYNVAR_DEALLOC));
1501
1502         for (dvar = start; dvar != NULL; dvar = dvar->dtdv_next) {
1503                 dtrace_tuple_t *dtuple = &dvar->dtdv_tuple;
1504                 dtrace_key_t *dkey = &dtuple->dtt_key[0];
1505
1506                 if (dvar->dtdv_hashval != hashval) {
1507                         if (dvar->dtdv_hashval == DTRACE_DYNHASH_SINK) {
1508                                 /*
1509                                  * We've reached the sink, and therefore the
1510                                  * end of the hash chain; we can kick out of
1511                                  * the loop knowing that we have seen a valid
1512                                  * snapshot of state.
1513                                  */
1514                                 ASSERT(dvar->dtdv_next == NULL);
1515                                 ASSERT(dvar == &dtrace_dynhash_sink);
1516                                 break;
1517                         }
1518
1519                         if (dvar->dtdv_hashval == DTRACE_DYNHASH_FREE) {
1520                                 /*
1521                                  * We've gone off the rails:  somewhere along
1522                                  * the line, one of the members of this hash
1523                                  * chain was deleted.  Note that we could also
1524                                  * detect this by simply letting this loop run
1525                                  * to completion, as we would eventually hit
1526                                  * the end of the dirty list.  However, we
1527                                  * want to avoid running the length of the
1528                                  * dirty list unnecessarily (it might be quite
1529                                  * long), so we catch this as early as
1530                                  * possible by detecting the hash marker.  In
1531                                  * this case, we simply set dvar to NULL and
1532                                  * break; the conditional after the loop will
1533                                  * send us back to top.
1534                                  */
1535                                 dvar = NULL;
1536                                 break;
1537                         }
1538
1539                         goto next;
1540                 }
1541
1542                 if (dtuple->dtt_nkeys != nkeys)
1543                         goto next;
1544
1545                 for (i = 0; i < nkeys; i++, dkey++) {
1546                         if (dkey->dttk_size != key[i].dttk_size)
1547                                 goto next; /* size or type mismatch */
1548
1549                         if (dkey->dttk_size != 0) {
1550                                 if (dtrace_bcmp(
1551                                     (void *)(uintptr_t)key[i].dttk_value,
1552                                     (void *)(uintptr_t)dkey->dttk_value,
1553                                     dkey->dttk_size))
1554                                         goto next;
1555                         } else {
1556                                 if (dkey->dttk_value != key[i].dttk_value)
1557                                         goto next;
1558                         }
1559                 }
1560
1561                 if (op != DTRACE_DYNVAR_DEALLOC)
1562                         return (dvar);
1563
1564                 ASSERT(dvar->dtdv_next == NULL ||
1565                     dvar->dtdv_next->dtdv_hashval != DTRACE_DYNHASH_FREE);
1566
1567                 if (prev != NULL) {
1568                         ASSERT(hash[bucket].dtdh_chain != dvar);
1569                         ASSERT(start != dvar);
1570                         ASSERT(prev->dtdv_next == dvar);
1571                         prev->dtdv_next = dvar->dtdv_next;
1572                 } else {
1573                         if (dtrace_casptr(&hash[bucket].dtdh_chain,
1574                             start, dvar->dtdv_next) != start) {
1575                                 /*
1576                                  * We have failed to atomically swing the
1577                                  * hash table head pointer, presumably because
1578                                  * of a conflicting allocation on another CPU.
1579                                  * We need to reread the hash chain and try
1580                                  * again.
1581                                  */
1582                                 goto top;
1583                         }
1584                 }
1585
1586                 dtrace_membar_producer();
1587
1588                 /*
1589                  * Now set the hash value to indicate that it's free.
1590                  */
1591                 ASSERT(hash[bucket].dtdh_chain != dvar);
1592                 dvar->dtdv_hashval = DTRACE_DYNHASH_FREE;
1593
1594                 dtrace_membar_producer();
1595
1596                 /*
1597                  * Set the next pointer to point at the dirty list, and
1598                  * atomically swing the dirty pointer to the newly freed dvar.
1599                  */
1600                 do {
1601                         next = dcpu->dtdsc_dirty;
1602                         dvar->dtdv_next = next;
1603                 } while (dtrace_casptr(&dcpu->dtdsc_dirty, next, dvar) != next);
1604
1605                 /*
1606                  * Finally, unlock this hash bucket.
1607                  */
1608                 ASSERT(hash[bucket].dtdh_lock == lock);
1609                 ASSERT(lock & 1);
1610                 hash[bucket].dtdh_lock++;
1611
1612                 return (NULL);
1613 next:
1614                 prev = dvar;
1615                 continue;
1616         }
1617
1618         if (dvar == NULL) {
1619                 /*
1620                  * If dvar is NULL, it is because we went off the rails:
1621                  * one of the elements that we traversed in the hash chain
1622                  * was deleted while we were traversing it.  In this case,
1623                  * we assert that we aren't doing a dealloc (deallocs lock
1624                  * the hash bucket to prevent themselves from racing with
1625                  * one another), and retry the hash chain traversal.
1626                  */
1627                 ASSERT(op != DTRACE_DYNVAR_DEALLOC);
1628                 goto top;
1629         }
1630
1631         if (op != DTRACE_DYNVAR_ALLOC) {
1632                 /*
1633                  * If we are not to allocate a new variable, we want to
1634                  * return NULL now.  Before we return, check that the value
1635                  * of the lock word hasn't changed.  If it has, we may have
1636                  * seen an inconsistent snapshot.
1637                  */
1638                 if (op == DTRACE_DYNVAR_NOALLOC) {
1639                         if (hash[bucket].dtdh_lock != lock)
1640                                 goto top;
1641                 } else {
1642                         ASSERT(op == DTRACE_DYNVAR_DEALLOC);
1643                         ASSERT(hash[bucket].dtdh_lock == lock);
1644                         ASSERT(lock & 1);
1645                         hash[bucket].dtdh_lock++;
1646                 }
1647
1648                 return (NULL);
1649         }
1650
1651         /*
1652          * We need to allocate a new dynamic variable.  The size we need is the
1653          * size of dtrace_dynvar plus the size of nkeys dtrace_key_t's plus the
1654          * size of any auxiliary key data (rounded up to 8-byte alignment) plus
1655          * the size of any referred-to data (dsize).  We then round the final
1656          * size up to the chunksize for allocation.
1657          */
1658         for (ksize = 0, i = 0; i < nkeys; i++)
1659                 ksize += P2ROUNDUP(key[i].dttk_size, sizeof (uint64_t));
1660
1661         /*
1662          * This should be pretty much impossible, but could happen if, say,
1663          * strange DIF specified the tuple.  Ideally, this should be an
1664          * assertion and not an error condition -- but that requires that the
1665          * chunksize calculation in dtrace_difo_chunksize() be absolutely
1666          * bullet-proof.  (That is, it must not be able to be fooled by
1667          * malicious DIF.)  Given the lack of backwards branches in DIF,
1668          * solving this would presumably not amount to solving the Halting
1669          * Problem -- but it still seems awfully hard.
1670          */
1671         if (sizeof (dtrace_dynvar_t) + sizeof (dtrace_key_t) * (nkeys - 1) +
1672             ksize + dsize > chunksize) {
1673                 dcpu->dtdsc_drops++;
1674                 return (NULL);
1675         }
1676
1677         nstate = DTRACE_DSTATE_EMPTY;
1678
1679         do {
1680 retry:
1681                 free = dcpu->dtdsc_free;
1682
1683                 if (free == NULL) {
1684                         dtrace_dynvar_t *clean = dcpu->dtdsc_clean;
1685                         void *rval;
1686
1687                         if (clean == NULL) {
1688                                 /*
1689                                  * We're out of dynamic variable space on
1690                                  * this CPU.  Unless we have tried all CPUs,
1691                                  * we'll try to allocate from a different
1692                                  * CPU.
1693                                  */
1694                                 switch (dstate->dtds_state) {
1695                                 case DTRACE_DSTATE_CLEAN: {
1696                                         void *sp = &dstate->dtds_state;
1697
1698                                         if (++cpu >= NCPU)
1699                                                 cpu = 0;
1700
1701                                         if (dcpu->dtdsc_dirty != NULL &&
1702                                             nstate == DTRACE_DSTATE_EMPTY)
1703                                                 nstate = DTRACE_DSTATE_DIRTY;
1704
1705                                         if (dcpu->dtdsc_rinsing != NULL)
1706                                                 nstate = DTRACE_DSTATE_RINSING;
1707
1708                                         dcpu = &dstate->dtds_percpu[cpu];
1709
1710                                         if (cpu != me)
1711                                                 goto retry;
1712
1713                                         (void) dtrace_cas32(sp,
1714                                             DTRACE_DSTATE_CLEAN, nstate);
1715
1716                                         /*
1717                                          * To increment the correct bean
1718                                          * counter, take another lap.
1719                                          */
1720                                         goto retry;
1721                                 }
1722
1723                                 case DTRACE_DSTATE_DIRTY:
1724                                         dcpu->dtdsc_dirty_drops++;
1725                                         break;
1726
1727                                 case DTRACE_DSTATE_RINSING:
1728                                         dcpu->dtdsc_rinsing_drops++;
1729                                         break;
1730
1731                                 case DTRACE_DSTATE_EMPTY:
1732                                         dcpu->dtdsc_drops++;
1733                                         break;
1734                                 }
1735
1736                                 DTRACE_CPUFLAG_SET(CPU_DTRACE_DROP);
1737                                 return (NULL);
1738                         }
1739
1740                         /*
1741                          * The clean list appears to be non-empty.  We want to
1742                          * move the clean list to the free list; we start by
1743                          * moving the clean pointer aside.
1744                          */
1745                         if (dtrace_casptr(&dcpu->dtdsc_clean,
1746                             clean, NULL) != clean) {
1747                                 /*
1748                                  * We are in one of two situations:
1749                                  *
1750                                  *  (a) The clean list was switched to the
1751                                  *      free list by another CPU.
1752                                  *
1753                                  *  (b) The clean list was added to by the
1754                                  *      cleansing cyclic.
1755                                  *
1756                                  * In either of these situations, we can
1757                                  * just reattempt the free list allocation.
1758                                  */
1759                                 goto retry;
1760                         }
1761
1762                         ASSERT(clean->dtdv_hashval == DTRACE_DYNHASH_FREE);
1763
1764                         /*
1765                          * Now we'll move the clean list to the free list.
1766                          * It's impossible for this to fail:  the only way
1767                          * the free list can be updated is through this
1768                          * code path, and only one CPU can own the clean list.
1769                          * Thus, it would only be possible for this to fail if
1770                          * this code were racing with dtrace_dynvar_clean().
1771                          * (That is, if dtrace_dynvar_clean() updated the clean
1772                          * list, and we ended up racing to update the free
1773                          * list.)  This race is prevented by the dtrace_sync()
1774                          * in dtrace_dynvar_clean() -- which flushes the
1775                          * owners of the clean lists out before resetting
1776                          * the clean lists.
1777                          */
1778                         rval = dtrace_casptr(&dcpu->dtdsc_free, NULL, clean);
1779                         ASSERT(rval == NULL);
1780                         goto retry;
1781                 }
1782
1783                 dvar = free;
1784                 new_free = dvar->dtdv_next;
1785         } while (dtrace_casptr(&dcpu->dtdsc_free, free, new_free) != free);
1786
1787         /*
1788          * We have now allocated a new chunk.  We copy the tuple keys into the
1789          * tuple array and copy any referenced key data into the data space
1790          * following the tuple array.  As we do this, we relocate dttk_value
1791          * in the final tuple to point to the key data address in the chunk.
1792          */
1793         kdata = (uintptr_t)&dvar->dtdv_tuple.dtt_key[nkeys];
1794         dvar->dtdv_data = (void *)(kdata + ksize);
1795         dvar->dtdv_tuple.dtt_nkeys = nkeys;
1796
1797         for (i = 0; i < nkeys; i++) {
1798                 dtrace_key_t *dkey = &dvar->dtdv_tuple.dtt_key[i];
1799                 size_t kesize = key[i].dttk_size;
1800
1801                 if (kesize != 0) {
1802                         dtrace_bcopy(
1803                             (const void *)(uintptr_t)key[i].dttk_value,
1804                             (void *)kdata, kesize);
1805                         dkey->dttk_value = kdata;
1806                         kdata += P2ROUNDUP(kesize, sizeof (uint64_t));
1807                 } else {
1808                         dkey->dttk_value = key[i].dttk_value;
1809                 }
1810
1811                 dkey->dttk_size = kesize;
1812         }
1813
1814         ASSERT(dvar->dtdv_hashval == DTRACE_DYNHASH_FREE);
1815         dvar->dtdv_hashval = hashval;
1816         dvar->dtdv_next = start;
1817
1818         if (dtrace_casptr(&hash[bucket].dtdh_chain, start, dvar) == start)
1819                 return (dvar);
1820
1821         /*
1822          * The cas has failed.  Either another CPU is adding an element to
1823          * this hash chain, or another CPU is deleting an element from this
1824          * hash chain.  The simplest way to deal with both of these cases
1825          * (though not necessarily the most efficient) is to free our
1826          * allocated block and tail-call ourselves.  Note that the free is
1827          * to the dirty list and _not_ to the free list.  This is to prevent
1828          * races with allocators, above.
1829          */
1830         dvar->dtdv_hashval = DTRACE_DYNHASH_FREE;
1831
1832         dtrace_membar_producer();
1833
1834         do {
1835                 free = dcpu->dtdsc_dirty;
1836                 dvar->dtdv_next = free;
1837         } while (dtrace_casptr(&dcpu->dtdsc_dirty, free, dvar) != free);
1838
1839         return (dtrace_dynvar(dstate, nkeys, key, dsize, op, mstate, vstate));
1840 }
1841
1842 /*ARGSUSED*/
1843 static void
1844 dtrace_aggregate_min(uint64_t *oval, uint64_t nval, uint64_t arg)
1845 {
1846         if ((int64_t)nval < (int64_t)*oval)
1847                 *oval = nval;
1848 }
1849
1850 /*ARGSUSED*/
1851 static void
1852 dtrace_aggregate_max(uint64_t *oval, uint64_t nval, uint64_t arg)
1853 {
1854         if ((int64_t)nval > (int64_t)*oval)
1855                 *oval = nval;
1856 }
1857
1858 static void
1859 dtrace_aggregate_quantize(uint64_t *quanta, uint64_t nval, uint64_t incr)
1860 {
1861         int i, zero = DTRACE_QUANTIZE_ZEROBUCKET;
1862         int64_t val = (int64_t)nval;
1863
1864         if (val < 0) {
1865                 for (i = 0; i < zero; i++) {
1866                         if (val <= DTRACE_QUANTIZE_BUCKETVAL(i)) {
1867                                 quanta[i] += incr;
1868                                 return;
1869                         }
1870                 }
1871         } else {
1872                 for (i = zero + 1; i < DTRACE_QUANTIZE_NBUCKETS; i++) {
1873                         if (val < DTRACE_QUANTIZE_BUCKETVAL(i)) {
1874                                 quanta[i - 1] += incr;
1875                                 return;
1876                         }
1877                 }
1878
1879                 quanta[DTRACE_QUANTIZE_NBUCKETS - 1] += incr;
1880                 return;
1881         }
1882
1883         ASSERT(0);
1884 }
1885
1886 static void
1887 dtrace_aggregate_lquantize(uint64_t *lquanta, uint64_t nval, uint64_t incr)
1888 {
1889         uint64_t arg = *lquanta++;
1890         int32_t base = DTRACE_LQUANTIZE_BASE(arg);
1891         uint16_t step = DTRACE_LQUANTIZE_STEP(arg);
1892         uint16_t levels = DTRACE_LQUANTIZE_LEVELS(arg);
1893         int32_t val = (int32_t)nval, level;
1894
1895         ASSERT(step != 0);
1896         ASSERT(levels != 0);
1897
1898         if (val < base) {
1899                 /*
1900                  * This is an underflow.
1901                  */
1902                 lquanta[0] += incr;
1903                 return;
1904         }
1905
1906         level = (val - base) / step;
1907
1908         if (level < levels) {
1909                 lquanta[level + 1] += incr;
1910                 return;
1911         }
1912
1913         /*
1914          * This is an overflow.
1915          */
1916         lquanta[levels + 1] += incr;
1917 }
1918
1919 /*ARGSUSED*/
1920 static void
1921 dtrace_aggregate_avg(uint64_t *data, uint64_t nval, uint64_t arg)
1922 {
1923         data[0]++;
1924         data[1] += nval;
1925 }
1926
1927 /*ARGSUSED*/
1928 static void
1929 dtrace_aggregate_stddev(uint64_t *data, uint64_t nval, uint64_t arg)
1930 {
1931         int64_t snval = (int64_t)nval;
1932         uint64_t tmp[2];
1933
1934         data[0]++;
1935         data[1] += nval;
1936
1937         /*
1938          * What we want to say here is:
1939          *
1940          * data[2] += nval * nval;
1941          *
1942          * But given that nval is 64-bit, we could easily overflow, so
1943          * we do this as 128-bit arithmetic.
1944          */
1945         if (snval < 0)
1946                 snval = -snval;
1947
1948         dtrace_multiply_128((uint64_t)snval, (uint64_t)snval, tmp);
1949         dtrace_add_128(data + 2, tmp, data + 2);
1950 }
1951
1952 /*ARGSUSED*/
1953 static void
1954 dtrace_aggregate_count(uint64_t *oval, uint64_t nval, uint64_t arg)
1955 {
1956         *oval = *oval + 1;
1957 }
1958
1959 /*ARGSUSED*/
1960 static void
1961 dtrace_aggregate_sum(uint64_t *oval, uint64_t nval, uint64_t arg)
1962 {
1963         *oval += nval;
1964 }
1965
1966 /*
1967  * Aggregate given the tuple in the principal data buffer, and the aggregating
1968  * action denoted by the specified dtrace_aggregation_t.  The aggregation
1969  * buffer is specified as the buf parameter.  This routine does not return
1970  * failure; if there is no space in the aggregation buffer, the data will be
1971  * dropped, and a corresponding counter incremented.
1972  */
1973 static void
1974 dtrace_aggregate(dtrace_aggregation_t *agg, dtrace_buffer_t *dbuf,
1975     intptr_t offset, dtrace_buffer_t *buf, uint64_t expr, uint64_t arg)
1976 {
1977         dtrace_recdesc_t *rec = &agg->dtag_action.dta_rec;
1978         uint32_t i, ndx, size, fsize;
1979         uint32_t align = sizeof (uint64_t) - 1;
1980         dtrace_aggbuffer_t *agb;
1981         dtrace_aggkey_t *key;
1982         uint32_t hashval = 0, limit, isstr;
1983         caddr_t tomax, data, kdata;
1984         dtrace_actkind_t action;
1985         dtrace_action_t *act;
1986         uintptr_t offs;
1987
1988         if (buf == NULL)
1989                 return;
1990
1991         if (!agg->dtag_hasarg) {
1992                 /*
1993                  * Currently, only quantize() and lquantize() take additional
1994                  * arguments, and they have the same semantics:  an increment
1995                  * value that defaults to 1 when not present.  If additional
1996                  * aggregating actions take arguments, the setting of the
1997                  * default argument value will presumably have to become more
1998                  * sophisticated...
1999                  */
2000                 arg = 1;
2001         }
2002
2003         action = agg->dtag_action.dta_kind - DTRACEACT_AGGREGATION;
2004         size = rec->dtrd_offset - agg->dtag_base;
2005         fsize = size + rec->dtrd_size;
2006
2007         ASSERT(dbuf->dtb_tomax != NULL);
2008         data = dbuf->dtb_tomax + offset + agg->dtag_base;
2009
2010         if ((tomax = buf->dtb_tomax) == NULL) {
2011                 dtrace_buffer_drop(buf);
2012                 return;
2013         }
2014
2015         /*
2016          * The metastructure is always at the bottom of the buffer.
2017          */
2018         agb = (dtrace_aggbuffer_t *)(tomax + buf->dtb_size -
2019             sizeof (dtrace_aggbuffer_t));
2020
2021         if (buf->dtb_offset == 0) {
2022                 /*
2023                  * We just kludge up approximately 1/8th of the size to be
2024                  * buckets.  If this guess ends up being routinely
2025                  * off-the-mark, we may need to dynamically readjust this
2026                  * based on past performance.
2027                  */
2028                 uintptr_t hashsize = (buf->dtb_size >> 3) / sizeof (uintptr_t);
2029
2030                 if ((uintptr_t)agb - hashsize * sizeof (dtrace_aggkey_t *) <
2031                     (uintptr_t)tomax || hashsize == 0) {
2032                         /*
2033                          * We've been given a ludicrously small buffer;
2034                          * increment our drop count and leave.
2035                          */
2036                         dtrace_buffer_drop(buf);
2037                         return;
2038                 }
2039
2040                 /*
2041                  * And now, a pathetic attempt to try to get a an odd (or
2042                  * perchance, a prime) hash size for better hash distribution.
2043                  */
2044                 if (hashsize > (DTRACE_AGGHASHSIZE_SLEW << 3))
2045                         hashsize -= DTRACE_AGGHASHSIZE_SLEW;
2046
2047                 agb->dtagb_hashsize = hashsize;
2048                 agb->dtagb_hash = (dtrace_aggkey_t **)((uintptr_t)agb -
2049                     agb->dtagb_hashsize * sizeof (dtrace_aggkey_t *));
2050                 agb->dtagb_free = (uintptr_t)agb->dtagb_hash;
2051
2052                 for (i = 0; i < agb->dtagb_hashsize; i++)
2053                         agb->dtagb_hash[i] = NULL;
2054         }
2055
2056         ASSERT(agg->dtag_first != NULL);
2057         ASSERT(agg->dtag_first->dta_intuple);
2058
2059         /*
2060          * Calculate the hash value based on the key.  Note that we _don't_
2061          * include the aggid in the hashing (but we will store it as part of
2062          * the key).  The hashing algorithm is Bob Jenkins' "One-at-a-time"
2063          * algorithm: a simple, quick algorithm that has no known funnels, and
2064          * gets good distribution in practice.  The efficacy of the hashing
2065          * algorithm (and a comparison with other algorithms) may be found by
2066          * running the ::dtrace_aggstat MDB dcmd.
2067          */
2068         for (act = agg->dtag_first; act->dta_intuple; act = act->dta_next) {
2069                 i = act->dta_rec.dtrd_offset - agg->dtag_base;
2070                 limit = i + act->dta_rec.dtrd_size;
2071                 ASSERT(limit <= size);
2072                 isstr = DTRACEACT_ISSTRING(act);
2073
2074                 for (; i < limit; i++) {
2075                         hashval += data[i];
2076                         hashval += (hashval << 10);
2077                         hashval ^= (hashval >> 6);
2078
2079                         if (isstr && data[i] == '\0')
2080                                 break;
2081                 }
2082         }
2083
2084         hashval += (hashval << 3);
2085         hashval ^= (hashval >> 11);
2086         hashval += (hashval << 15);
2087
2088         /*
2089          * Yes, the divide here is expensive -- but it's generally the least
2090          * of the performance issues given the amount of data that we iterate
2091          * over to compute hash values, compare data, etc.
2092          */
2093         ndx = hashval % agb->dtagb_hashsize;
2094
2095         for (key = agb->dtagb_hash[ndx]; key != NULL; key = key->dtak_next) {
2096                 ASSERT((caddr_t)key >= tomax);
2097                 ASSERT((caddr_t)key < tomax + buf->dtb_size);
2098
2099                 if (hashval != key->dtak_hashval || key->dtak_size != size)
2100                         continue;
2101
2102                 kdata = key->dtak_data;
2103                 ASSERT(kdata >= tomax && kdata < tomax + buf->dtb_size);
2104
2105                 for (act = agg->dtag_first; act->dta_intuple;
2106                     act = act->dta_next) {
2107                         i = act->dta_rec.dtrd_offset - agg->dtag_base;
2108                         limit = i + act->dta_rec.dtrd_size;
2109                         ASSERT(limit <= size);
2110                         isstr = DTRACEACT_ISSTRING(act);
2111
2112                         for (; i < limit; i++) {
2113                                 if (kdata[i] != data[i])
2114                                         goto next;
2115
2116                                 if (isstr && data[i] == '\0')
2117                                         break;
2118                         }
2119                 }
2120
2121                 if (action != key->dtak_action) {
2122                         /*
2123                          * We are aggregating on the same value in the same
2124                          * aggregation with two different aggregating actions.
2125                          * (This should have been picked up in the compiler,
2126                          * so we may be dealing with errant or devious DIF.)
2127                          * This is an error condition; we indicate as much,
2128                          * and return.
2129                          */
2130                         DTRACE_CPUFLAG_SET(CPU_DTRACE_ILLOP);
2131                         return;
2132                 }
2133
2134                 /*
2135                  * This is a hit:  we need to apply the aggregator to
2136                  * the value at this key.
2137                  */
2138                 agg->dtag_aggregate((uint64_t *)(kdata + size), expr, arg);
2139                 return;
2140 next:
2141                 continue;
2142         }
2143
2144         /*
2145          * We didn't find it.  We need to allocate some zero-filled space,
2146          * link it into the hash table appropriately, and apply the aggregator
2147          * to the (zero-filled) value.
2148          */
2149         offs = buf->dtb_offset;
2150         while (offs & (align - 1))
2151                 offs += sizeof (uint32_t);
2152
2153         /*
2154          * If we don't have enough room to both allocate a new key _and_
2155          * its associated data, increment the drop count and return.
2156          */
2157         if ((uintptr_t)tomax + offs + fsize >
2158             agb->dtagb_free - sizeof (dtrace_aggkey_t)) {
2159                 dtrace_buffer_drop(buf);
2160                 return;
2161         }
2162
2163         /*CONSTCOND*/
2164         ASSERT(!(sizeof (dtrace_aggkey_t) & (sizeof (uintptr_t) - 1)));
2165         key = (dtrace_aggkey_t *)(agb->dtagb_free - sizeof (dtrace_aggkey_t));
2166         agb->dtagb_free -= sizeof (dtrace_aggkey_t);
2167
2168         key->dtak_data = kdata = tomax + offs;
2169         buf->dtb_offset = offs + fsize;
2170
2171         /*
2172          * Now copy the data across.
2173          */
2174         *((dtrace_aggid_t *)kdata) = agg->dtag_id;
2175
2176         for (i = sizeof (dtrace_aggid_t); i < size; i++)
2177                 kdata[i] = data[i];
2178
2179         /*
2180          * Because strings are not zeroed out by default, we need to iterate
2181          * looking for actions that store strings, and we need to explicitly
2182          * pad these strings out with zeroes.
2183          */
2184         for (act = agg->dtag_first; act->dta_intuple; act = act->dta_next) {
2185                 int nul;
2186
2187                 if (!DTRACEACT_ISSTRING(act))
2188                         continue;
2189
2190                 i = act->dta_rec.dtrd_offset - agg->dtag_base;
2191                 limit = i + act->dta_rec.dtrd_size;
2192                 ASSERT(limit <= size);
2193
2194                 for (nul = 0; i < limit; i++) {
2195                         if (nul) {
2196                                 kdata[i] = '\0';
2197                                 continue;
2198                         }
2199
2200                         if (data[i] != '\0')
2201                                 continue;
2202
2203                         nul = 1;
2204                 }
2205         }
2206
2207         for (i = size; i < fsize; i++)
2208                 kdata[i] = 0;
2209
2210         key->dtak_hashval = hashval;
2211         key->dtak_size = size;
2212         key->dtak_action = action;
2213         key->dtak_next = agb->dtagb_hash[ndx];
2214         agb->dtagb_hash[ndx] = key;
2215
2216         /*
2217          * Finally, apply the aggregator.
2218          */
2219         *((uint64_t *)(key->dtak_data + size)) = agg->dtag_initial;
2220         agg->dtag_aggregate((uint64_t *)(key->dtak_data + size), expr, arg);
2221 }
2222
2223 /*
2224  * Given consumer state, this routine finds a speculation in the INACTIVE
2225  * state and transitions it into the ACTIVE state.  If there is no speculation
2226  * in the INACTIVE state, 0 is returned.  In this case, no error counter is
2227  * incremented -- it is up to the caller to take appropriate action.
2228  */
2229 static int
2230 dtrace_speculation(dtrace_state_t *state)
2231 {
2232         int i = 0;
2233         dtrace_speculation_state_t current;
2234         uint32_t *stat = &state->dts_speculations_unavail, count;
2235
2236         while (i < state->dts_nspeculations) {
2237                 dtrace_speculation_t *spec = &state->dts_speculations[i];
2238
2239                 current = spec->dtsp_state;
2240
2241                 if (current != DTRACESPEC_INACTIVE) {
2242                         if (current == DTRACESPEC_COMMITTINGMANY ||
2243                             current == DTRACESPEC_COMMITTING ||
2244                             current == DTRACESPEC_DISCARDING)
2245                                 stat = &state->dts_speculations_busy;
2246                         i++;
2247                         continue;
2248                 }
2249
2250                 if (dtrace_cas32((uint32_t *)&spec->dtsp_state,
2251                     current, DTRACESPEC_ACTIVE) == current)
2252                         return (i + 1);
2253         }
2254
2255         /*
2256          * We couldn't find a speculation.  If we found as much as a single
2257          * busy speculation buffer, we'll attribute this failure as "busy"
2258          * instead of "unavail".
2259          */
2260         do {
2261                 count = *stat;
2262         } while (dtrace_cas32(stat, count, count + 1) != count);
2263
2264         return (0);
2265 }
2266
2267 /*
2268  * This routine commits an active speculation.  If the specified speculation
2269  * is not in a valid state to perform a commit(), this routine will silently do
2270  * nothing.  The state of the specified speculation is transitioned according
2271  * to the state transition diagram outlined in <sys/dtrace_impl.h>
2272  */
2273 static void
2274 dtrace_speculation_commit(dtrace_state_t *state, processorid_t cpu,
2275     dtrace_specid_t which)
2276 {
2277         dtrace_speculation_t *spec;
2278         dtrace_buffer_t *src, *dest;
2279         uintptr_t daddr, saddr, dlimit;
2280         dtrace_speculation_state_t current, new = 0;
2281         intptr_t offs;
2282
2283         if (which == 0)
2284                 return;
2285
2286         if (which > state->dts_nspeculations) {
2287                 cpu_core[cpu].cpuc_dtrace_flags |= CPU_DTRACE_ILLOP;
2288                 return;
2289         }
2290
2291         spec = &state->dts_speculations[which - 1];
2292         src = &spec->dtsp_buffer[cpu];
2293         dest = &state->dts_buffer[cpu];
2294
2295         do {
2296                 current = spec->dtsp_state;
2297
2298                 if (current == DTRACESPEC_COMMITTINGMANY)
2299                         break;
2300
2301                 switch (current) {
2302                 case DTRACESPEC_INACTIVE:
2303                 case DTRACESPEC_DISCARDING:
2304                         return;
2305
2306                 case DTRACESPEC_COMMITTING:
2307                         /*
2308                          * This is only possible if we are (a) commit()'ing
2309                          * without having done a prior speculate() on this CPU
2310                          * and (b) racing with another commit() on a different
2311                          * CPU.  There's nothing to do -- we just assert that
2312                          * our offset is 0.
2313                          */
2314                         ASSERT(src->dtb_offset == 0);
2315                         return;
2316
2317                 case DTRACESPEC_ACTIVE:
2318                         new = DTRACESPEC_COMMITTING;
2319                         break;
2320
2321                 case DTRACESPEC_ACTIVEONE:
2322                         /*
2323                          * This speculation is active on one CPU.  If our
2324                          * buffer offset is non-zero, we know that the one CPU
2325                          * must be us.  Otherwise, we are committing on a
2326                          * different CPU from the speculate(), and we must
2327                          * rely on being asynchronously cleaned.
2328                          */
2329                         if (src->dtb_offset != 0) {
2330                                 new = DTRACESPEC_COMMITTING;
2331                                 break;
2332                         }
2333                         /*FALLTHROUGH*/
2334
2335                 case DTRACESPEC_ACTIVEMANY:
2336                         new = DTRACESPEC_COMMITTINGMANY;
2337                         break;
2338
2339                 default:
2340                         ASSERT(0);
2341                 }
2342         } while (dtrace_cas32((uint32_t *)&spec->dtsp_state,
2343             current, new) != current);
2344
2345         /*
2346          * We have set the state to indicate that we are committing this
2347          * speculation.  Now reserve the necessary space in the destination
2348          * buffer.
2349          */
2350         if ((offs = dtrace_buffer_reserve(dest, src->dtb_offset,
2351             sizeof (uint64_t), state, NULL)) < 0) {
2352                 dtrace_buffer_drop(dest);
2353                 goto out;
2354         }
2355
2356         /*
2357          * We have the space; copy the buffer across.  (Note that this is a
2358          * highly subobtimal bcopy(); in the unlikely event that this becomes
2359          * a serious performance issue, a high-performance DTrace-specific
2360          * bcopy() should obviously be invented.)
2361          */
2362         daddr = (uintptr_t)dest->dtb_tomax + offs;
2363         dlimit = daddr + src->dtb_offset;
2364         saddr = (uintptr_t)src->dtb_tomax;
2365
2366         /*
2367          * First, the aligned portion.
2368          */
2369         while (dlimit - daddr >= sizeof (uint64_t)) {
2370                 *((uint64_t *)daddr) = *((uint64_t *)saddr);
2371
2372                 daddr += sizeof (uint64_t);
2373                 saddr += sizeof (uint64_t);
2374         }
2375
2376         /*
2377          * Now any left-over bit...
2378          */
2379         while (dlimit - daddr)
2380                 *((uint8_t *)daddr++) = *((uint8_t *)saddr++);
2381
2382         /*
2383          * Finally, commit the reserved space in the destination buffer.
2384          */
2385         dest->dtb_offset = offs + src->dtb_offset;
2386
2387 out:
2388         /*
2389          * If we're lucky enough to be the only active CPU on this speculation
2390          * buffer, we can just set the state back to DTRACESPEC_INACTIVE.
2391          */
2392         if (current == DTRACESPEC_ACTIVE ||
2393             (current == DTRACESPEC_ACTIVEONE && new == DTRACESPEC_COMMITTING)) {
2394                 uint32_t rval = dtrace_cas32((uint32_t *)&spec->dtsp_state,
2395                     DTRACESPEC_COMMITTING, DTRACESPEC_INACTIVE);
2396
2397                 ASSERT(rval == DTRACESPEC_COMMITTING);
2398         }
2399
2400         src->dtb_offset = 0;
2401         src->dtb_xamot_drops += src->dtb_drops;
2402         src->dtb_drops = 0;
2403 }
2404
2405 /*
2406  * This routine discards an active speculation.  If the specified speculation
2407  * is not in a valid state to perform a discard(), this routine will silently
2408  * do nothing.  The state of the specified speculation is transitioned
2409  * according to the state transition diagram outlined in <sys/dtrace_impl.h>
2410  */
2411 static void
2412 dtrace_speculation_discard(dtrace_state_t *state, processorid_t cpu,
2413     dtrace_specid_t which)
2414 {
2415         dtrace_speculation_t *spec;
2416         dtrace_speculation_state_t current, new = 0;
2417         dtrace_buffer_t *buf;
2418
2419         if (which == 0)
2420                 return;
2421
2422         if (which > state->dts_nspeculations) {
2423                 cpu_core[cpu].cpuc_dtrace_flags |= CPU_DTRACE_ILLOP;
2424                 return;
2425         }
2426
2427         spec = &state->dts_speculations[which - 1];
2428         buf = &spec->dtsp_buffer[cpu];
2429
2430         do {
2431                 current = spec->dtsp_state;
2432
2433                 switch (current) {
2434                 case DTRACESPEC_INACTIVE:
2435                 case DTRACESPEC_COMMITTINGMANY:
2436                 case DTRACESPEC_COMMITTING:
2437                 case DTRACESPEC_DISCARDING:
2438                         return;
2439
2440                 case DTRACESPEC_ACTIVE:
2441                 case DTRACESPEC_ACTIVEMANY:
2442                         new = DTRACESPEC_DISCARDING;
2443                         break;
2444
2445                 case DTRACESPEC_ACTIVEONE:
2446                         if (buf->dtb_offset != 0) {
2447                                 new = DTRACESPEC_INACTIVE;
2448                         } else {
2449                                 new = DTRACESPEC_DISCARDING;
2450                         }
2451                         break;
2452
2453                 default:
2454                         ASSERT(0);
2455                 }
2456         } while (dtrace_cas32((uint32_t *)&spec->dtsp_state,
2457             current, new) != current);
2458
2459         buf->dtb_offset = 0;
2460         buf->dtb_drops = 0;
2461 }
2462
2463 /*
2464  * Note:  not called from probe context.  This function is called
2465  * asynchronously from cross call context to clean any speculations that are
2466  * in the COMMITTINGMANY or DISCARDING states.  These speculations may not be
2467  * transitioned back to the INACTIVE state until all CPUs have cleaned the
2468  * speculation.
2469  */
2470 static void
2471 dtrace_speculation_clean_here(dtrace_state_t *state)
2472 {
2473         dtrace_icookie_t cookie;
2474         processorid_t cpu = curcpu;
2475         dtrace_buffer_t *dest = &state->dts_buffer[cpu];
2476         dtrace_specid_t i;
2477
2478         cookie = dtrace_interrupt_disable();
2479
2480         if (dest->dtb_tomax == NULL) {
2481                 dtrace_interrupt_enable(cookie);
2482                 return;
2483         }
2484
2485         for (i = 0; i < state->dts_nspeculations; i++) {
2486                 dtrace_speculation_t *spec = &state->dts_speculations[i];
2487                 dtrace_buffer_t *src = &spec->dtsp_buffer[cpu];
2488
2489                 if (src->dtb_tomax == NULL)
2490                         continue;
2491
2492                 if (spec->dtsp_state == DTRACESPEC_DISCARDING) {
2493                         src->dtb_offset = 0;
2494                         continue;
2495                 }
2496
2497                 if (spec->dtsp_state != DTRACESPEC_COMMITTINGMANY)
2498                         continue;
2499
2500                 if (src->dtb_offset == 0)
2501                         continue;
2502
2503                 dtrace_speculation_commit(state, cpu, i + 1);
2504         }
2505
2506         dtrace_interrupt_enable(cookie);
2507 }
2508
2509 /*
2510  * Note:  not called from probe context.  This function is called
2511  * asynchronously (and at a regular interval) to clean any speculations that
2512  * are in the COMMITTINGMANY or DISCARDING states.  If it discovers that there
2513  * is work to be done, it cross calls all CPUs to perform that work;
2514  * COMMITMANY and DISCARDING speculations may not be transitioned back to the
2515  * INACTIVE state until they have been cleaned by all CPUs.
2516  */
2517 static void
2518 dtrace_speculation_clean(dtrace_state_t *state)
2519 {
2520         int work = 0, rv;
2521         dtrace_specid_t i;
2522
2523         for (i = 0; i < state->dts_nspeculations; i++) {
2524                 dtrace_speculation_t *spec = &state->dts_speculations[i];
2525
2526                 ASSERT(!spec->dtsp_cleaning);
2527
2528                 if (spec->dtsp_state != DTRACESPEC_DISCARDING &&
2529                     spec->dtsp_state != DTRACESPEC_COMMITTINGMANY)
2530                         continue;
2531
2532                 work++;
2533                 spec->dtsp_cleaning = 1;
2534         }
2535
2536         if (!work)
2537                 return;
2538
2539         dtrace_xcall(DTRACE_CPUALL,
2540             (dtrace_xcall_t)dtrace_speculation_clean_here, state);
2541
2542         /*
2543          * We now know that all CPUs have committed or discarded their
2544          * speculation buffers, as appropriate.  We can now set the state
2545          * to inactive.
2546          */
2547         for (i = 0; i < state->dts_nspeculations; i++) {
2548                 dtrace_speculation_t *spec = &state->dts_speculations[i];
2549                 dtrace_speculation_state_t current, new;
2550
2551                 if (!spec->dtsp_cleaning)
2552                         continue;
2553
2554                 current = spec->dtsp_state;
2555                 ASSERT(current == DTRACESPEC_DISCARDING ||
2556                     current == DTRACESPEC_COMMITTINGMANY);
2557
2558                 new = DTRACESPEC_INACTIVE;
2559
2560                 rv = dtrace_cas32((uint32_t *)&spec->dtsp_state, current, new);
2561                 ASSERT(rv == current);
2562                 spec->dtsp_cleaning = 0;
2563         }
2564 }
2565
2566 /*
2567  * Called as part of a speculate() to get the speculative buffer associated
2568  * with a given speculation.  Returns NULL if the specified speculation is not
2569  * in an ACTIVE state.  If the speculation is in the ACTIVEONE state -- and
2570  * the active CPU is not the specified CPU -- the speculation will be
2571  * atomically transitioned into the ACTIVEMANY state.
2572  */
2573 static dtrace_buffer_t *
2574 dtrace_speculation_buffer(dtrace_state_t *state, processorid_t cpuid,
2575     dtrace_specid_t which)
2576 {
2577         dtrace_speculation_t *spec;
2578         dtrace_speculation_state_t current, new = 0;
2579         dtrace_buffer_t *buf;
2580
2581         if (which == 0)
2582                 return (NULL);
2583
2584         if (which > state->dts_nspeculations) {
2585                 cpu_core[cpuid].cpuc_dtrace_flags |= CPU_DTRACE_ILLOP;
2586                 return (NULL);
2587         }
2588
2589         spec = &state->dts_speculations[which - 1];
2590         buf = &spec->dtsp_buffer[cpuid];
2591
2592         do {
2593                 current = spec->dtsp_state;
2594
2595                 switch (current) {
2596                 case DTRACESPEC_INACTIVE:
2597                 case DTRACESPEC_COMMITTINGMANY:
2598                 case DTRACESPEC_DISCARDING:
2599                         return (NULL);
2600
2601                 case DTRACESPEC_COMMITTING:
2602                         ASSERT(buf->dtb_offset == 0);
2603                         return (NULL);
2604
2605                 case DTRACESPEC_ACTIVEONE:
2606                         /*
2607                          * This speculation is currently active on one CPU.
2608                          * Check the offset in the buffer; if it's non-zero,
2609                          * that CPU must be us (and we leave the state alone).
2610                          * If it's zero, assume that we're starting on a new
2611                          * CPU -- and change the state to indicate that the
2612                          * speculation is active on more than one CPU.
2613                          */
2614                         if (buf->dtb_offset != 0)
2615                                 return (buf);
2616
2617                         new = DTRACESPEC_ACTIVEMANY;
2618                         break;
2619
2620                 case DTRACESPEC_ACTIVEMANY:
2621                         return (buf);
2622
2623                 case DTRACESPEC_ACTIVE:
2624                         new = DTRACESPEC_ACTIVEONE;
2625                         break;
2626
2627                 default:
2628                         ASSERT(0);
2629                 }
2630         } while (dtrace_cas32((uint32_t *)&spec->dtsp_state,
2631             current, new) != current);
2632
2633         ASSERT(new == DTRACESPEC_ACTIVEONE || new == DTRACESPEC_ACTIVEMANY);
2634         return (buf);
2635 }
2636
2637 /*
2638  * Return a string.  In the event that the user lacks the privilege to access
2639  * arbitrary kernel memory, we copy the string out to scratch memory so that we
2640  * don't fail access checking.
2641  *
2642  * dtrace_dif_variable() uses this routine as a helper for various
2643  * builtin values such as 'execname' and 'probefunc.'
2644  */
2645 uintptr_t
2646 dtrace_dif_varstr(uintptr_t addr, dtrace_state_t *state,
2647     dtrace_mstate_t *mstate)
2648 {
2649         uint64_t size = state->dts_options[DTRACEOPT_STRSIZE];
2650         uintptr_t ret;
2651         size_t strsz;
2652
2653         /*
2654          * The easy case: this probe is allowed to read all of memory, so
2655          * we can just return this as a vanilla pointer.
2656          */
2657         if ((mstate->dtms_access & DTRACE_ACCESS_KERNEL) != 0)
2658                 return (addr);
2659
2660         /*
2661          * This is the tougher case: we copy the string in question from
2662          * kernel memory into scratch memory and return it that way: this
2663          * ensures that we won't trip up when access checking tests the
2664          * BYREF return value.
2665          */
2666         strsz = dtrace_strlen((char *)addr, size) + 1;
2667
2668         if (mstate->dtms_scratch_ptr + strsz >
2669             mstate->dtms_scratch_base + mstate->dtms_scratch_size) {
2670                 DTRACE_CPUFLAG_SET(CPU_DTRACE_NOSCRATCH);
2671                 return (0);
2672         }
2673
2674         dtrace_strcpy((const void *)addr, (void *)mstate->dtms_scratch_ptr,
2675             strsz);
2676         ret = mstate->dtms_scratch_ptr;
2677         mstate->dtms_scratch_ptr += strsz;
2678         return (ret);
2679 }
2680
2681 /*
2682  * Return a string from a memoy address which is known to have one or
2683  * more concatenated, individually zero terminated, sub-strings.
2684  * In the event that the user lacks the privilege to access
2685  * arbitrary kernel memory, we copy the string out to scratch memory so that we
2686  * don't fail access checking.
2687  *
2688  * dtrace_dif_variable() uses this routine as a helper for various
2689  * builtin values such as 'execargs'.
2690  */
2691 static uintptr_t
2692 dtrace_dif_varstrz(uintptr_t addr, size_t strsz, dtrace_state_t *state,
2693     dtrace_mstate_t *mstate)
2694 {
2695         char *p;
2696         size_t i;
2697         uintptr_t ret;
2698
2699         if (mstate->dtms_scratch_ptr + strsz >
2700             mstate->dtms_scratch_base + mstate->dtms_scratch_size) {
2701                 DTRACE_CPUFLAG_SET(CPU_DTRACE_NOSCRATCH);
2702                 return (0);
2703         }
2704
2705         dtrace_bcopy((const void *)addr, (void *)mstate->dtms_scratch_ptr,
2706             strsz);
2707
2708         /* Replace sub-string termination characters with a space. */
2709         for (p = (char *) mstate->dtms_scratch_ptr, i = 0; i < strsz - 1;
2710             p++, i++)
2711                 if (*p == '\0')
2712                         *p = ' ';
2713
2714         ret = mstate->dtms_scratch_ptr;
2715         mstate->dtms_scratch_ptr += strsz;
2716         return (ret);
2717 }
2718
2719 /*
2720  * This function implements the DIF emulator's variable lookups.  The emulator
2721  * passes a reserved variable identifier and optional built-in array index.
2722  */
2723 static uint64_t
2724 dtrace_dif_variable(dtrace_mstate_t *mstate, dtrace_state_t *state, uint64_t v,
2725     uint64_t ndx)
2726 {
2727         /*
2728          * If we're accessing one of the uncached arguments, we'll turn this
2729          * into a reference in the args array.
2730          */
2731         if (v >= DIF_VAR_ARG0 && v <= DIF_VAR_ARG9) {
2732                 ndx = v - DIF_VAR_ARG0;
2733                 v = DIF_VAR_ARGS;
2734         }
2735
2736         switch (v) {
2737         case DIF_VAR_ARGS:
2738                 ASSERT(mstate->dtms_present & DTRACE_MSTATE_ARGS);
2739                 if (ndx >= sizeof (mstate->dtms_arg) /
2740                     sizeof (mstate->dtms_arg[0])) {
2741                         int aframes = mstate->dtms_probe->dtpr_aframes + 2;
2742                         dtrace_provider_t *pv;
2743                         uint64_t val;
2744
2745                         pv = mstate->dtms_probe->dtpr_provider;
2746                         if (pv->dtpv_pops.dtps_getargval != NULL)
2747                                 val = pv->dtpv_pops.dtps_getargval(pv->dtpv_arg,
2748                                     mstate->dtms_probe->dtpr_id,
2749                                     mstate->dtms_probe->dtpr_arg, ndx, aframes);
2750                         else
2751                                 val = dtrace_getarg(ndx, aframes);
2752
2753                         /*
2754                          * This is regrettably required to keep the compiler
2755                          * from tail-optimizing the call to dtrace_getarg().
2756                          * The condition always evaluates to true, but the
2757                          * compiler has no way of figuring that out a priori.
2758                          * (None of this would be necessary if the compiler
2759                          * could be relied upon to _always_ tail-optimize
2760                          * the call to dtrace_getarg() -- but it can't.)
2761                          */
2762                         if (mstate->dtms_probe != NULL)
2763                                 return (val);
2764
2765                         ASSERT(0);
2766                 }
2767
2768                 return (mstate->dtms_arg[ndx]);
2769
2770 #if defined(sun)
2771         case DIF_VAR_UREGS: {
2772                 klwp_t *lwp;
2773
2774                 if (!dtrace_priv_proc(state))
2775                         return (0);
2776
2777                 if ((lwp = curthread->t_lwp) == NULL) {
2778                         DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
2779                         cpu_core[curcpu].cpuc_dtrace_illval = NULL;
2780                         return (0);
2781                 }
2782
2783                 return (dtrace_getreg(lwp->lwp_regs, ndx));
2784                 return (0);
2785         }
2786 #endif
2787
2788         case DIF_VAR_CURTHREAD:
2789                 if (!dtrace_priv_kernel(state))
2790                         return (0);
2791                 return ((uint64_t)(uintptr_t)curthread);
2792
2793         case DIF_VAR_TIMESTAMP:
2794                 if (!(mstate->dtms_present & DTRACE_MSTATE_TIMESTAMP)) {
2795                         mstate->dtms_timestamp = dtrace_gethrtime();
2796                         mstate->dtms_present |= DTRACE_MSTATE_TIMESTAMP;
2797                 }
2798                 return (mstate->dtms_timestamp);
2799
2800         case DIF_VAR_VTIMESTAMP:
2801                 ASSERT(dtrace_vtime_references != 0);
2802                 return (curthread->t_dtrace_vtime);
2803
2804         case DIF_VAR_WALLTIMESTAMP:
2805                 if (!(mstate->dtms_present & DTRACE_MSTATE_WALLTIMESTAMP)) {
2806                         mstate->dtms_walltimestamp = dtrace_gethrestime();
2807                         mstate->dtms_present |= DTRACE_MSTATE_WALLTIMESTAMP;
2808                 }
2809                 return (mstate->dtms_walltimestamp);
2810
2811 #if defined(sun)
2812         case DIF_VAR_IPL:
2813                 if (!dtrace_priv_kernel(state))
2814                         return (0);
2815                 if (!(mstate->dtms_present & DTRACE_MSTATE_IPL)) {
2816                         mstate->dtms_ipl = dtrace_getipl();
2817                         mstate->dtms_present |= DTRACE_MSTATE_IPL;
2818                 }
2819                 return (mstate->dtms_ipl);
2820 #endif
2821
2822         case DIF_VAR_EPID:
2823                 ASSERT(mstate->dtms_present & DTRACE_MSTATE_EPID);
2824                 return (mstate->dtms_epid);
2825
2826         case DIF_VAR_ID:
2827                 ASSERT(mstate->dtms_present & DTRACE_MSTATE_PROBE);
2828                 return (mstate->dtms_probe->dtpr_id);
2829
2830         case DIF_VAR_STACKDEPTH:
2831                 if (!dtrace_priv_kernel(state))
2832                         return (0);
2833                 if (!(mstate->dtms_present & DTRACE_MSTATE_STACKDEPTH)) {
2834                         int aframes = mstate->dtms_probe->dtpr_aframes + 2;
2835
2836                         mstate->dtms_stackdepth = dtrace_getstackdepth(aframes);
2837                         mstate->dtms_present |= DTRACE_MSTATE_STACKDEPTH;
2838                 }
2839                 return (mstate->dtms_stackdepth);
2840
2841 #if defined(sun)
2842         case DIF_VAR_USTACKDEPTH:
2843                 if (!dtrace_priv_proc(state))
2844                         return (0);
2845                 if (!(mstate->dtms_present & DTRACE_MSTATE_USTACKDEPTH)) {
2846                         /*
2847                          * See comment in DIF_VAR_PID.
2848                          */
2849                         if (DTRACE_ANCHORED(mstate->dtms_probe) &&
2850                             CPU_ON_INTR(CPU)) {
2851                                 mstate->dtms_ustackdepth = 0;
2852                         } else {
2853                                 DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);
2854                                 mstate->dtms_ustackdepth =
2855                                     dtrace_getustackdepth();
2856                                 DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT);
2857                         }
2858                         mstate->dtms_present |= DTRACE_MSTATE_USTACKDEPTH;
2859                 }
2860                 return (mstate->dtms_ustackdepth);
2861 #endif
2862
2863         case DIF_VAR_CALLER:
2864                 if (!dtrace_priv_kernel(state))
2865                         return (0);
2866                 if (!(mstate->dtms_present & DTRACE_MSTATE_CALLER)) {
2867                         int aframes = mstate->dtms_probe->dtpr_aframes + 2;
2868
2869                         if (!DTRACE_ANCHORED(mstate->dtms_probe)) {
2870                                 /*
2871                                  * If this is an unanchored probe, we are
2872                                  * required to go through the slow path:
2873                                  * dtrace_caller() only guarantees correct
2874                                  * results for anchored probes.
2875                                  */
2876                                 pc_t caller[2] = {0, 0};
2877
2878                                 dtrace_getpcstack(caller, 2, aframes,
2879                                     (uint32_t *)(uintptr_t)mstate->dtms_arg[0]);
2880                                 mstate->dtms_caller = caller[1];
2881                         } else if ((mstate->dtms_caller =
2882                             dtrace_caller(aframes)) == -1) {
2883                                 /*
2884                                  * We have failed to do this the quick way;
2885                                  * we must resort to the slower approach of
2886                                  * calling dtrace_getpcstack().
2887                                  */
2888                                 pc_t caller = 0;
2889
2890                                 dtrace_getpcstack(&caller, 1, aframes, NULL);
2891                                 mstate->dtms_caller = caller;
2892                         }
2893
2894                         mstate->dtms_present |= DTRACE_MSTATE_CALLER;
2895                 }
2896                 return (mstate->dtms_caller);
2897
2898 #if defined(sun)
2899         case DIF_VAR_UCALLER:
2900                 if (!dtrace_priv_proc(state))
2901                         return (0);
2902
2903                 if (!(mstate->dtms_present & DTRACE_MSTATE_UCALLER)) {
2904                         uint64_t ustack[3];
2905
2906                         /*
2907                          * dtrace_getupcstack() fills in the first uint64_t
2908                          * with the current PID.  The second uint64_t will
2909                          * be the program counter at user-level.  The third
2910                          * uint64_t will contain the caller, which is what
2911                          * we're after.
2912                          */
2913                         ustack[2] = 0;
2914                         DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);
2915                         dtrace_getupcstack(ustack, 3);
2916                         DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT);
2917                         mstate->dtms_ucaller = ustack[2];
2918                         mstate->dtms_present |= DTRACE_MSTATE_UCALLER;
2919                 }
2920
2921                 return (mstate->dtms_ucaller);
2922 #endif
2923
2924         case DIF_VAR_PROBEPROV:
2925                 ASSERT(mstate->dtms_present & DTRACE_MSTATE_PROBE);
2926                 return (dtrace_dif_varstr(
2927                     (uintptr_t)mstate->dtms_probe->dtpr_provider->dtpv_name,
2928                     state, mstate));
2929
2930         case DIF_VAR_PROBEMOD:
2931                 ASSERT(mstate->dtms_present & DTRACE_MSTATE_PROBE);
2932                 return (dtrace_dif_varstr(
2933                     (uintptr_t)mstate->dtms_probe->dtpr_mod,
2934                     state, mstate));
2935
2936         case DIF_VAR_PROBEFUNC:
2937                 ASSERT(mstate->dtms_present & DTRACE_MSTATE_PROBE);
2938                 return (dtrace_dif_varstr(
2939                     (uintptr_t)mstate->dtms_probe->dtpr_func,
2940                     state, mstate));
2941
2942         case DIF_VAR_PROBENAME:
2943                 ASSERT(mstate->dtms_present & DTRACE_MSTATE_PROBE);
2944                 return (dtrace_dif_varstr(
2945                     (uintptr_t)mstate->dtms_probe->dtpr_name,
2946                     state, mstate));
2947
2948         case DIF_VAR_PID:
2949                 if (!dtrace_priv_proc(state))
2950                         return (0);
2951
2952 #if defined(sun)
2953                 /*
2954                  * Note that we are assuming that an unanchored probe is
2955                  * always due to a high-level interrupt.  (And we're assuming
2956                  * that there is only a single high level interrupt.)
2957                  */
2958                 if (DTRACE_ANCHORED(mstate->dtms_probe) && CPU_ON_INTR(CPU))
2959                         return (pid0.pid_id);
2960
2961                 /*
2962                  * It is always safe to dereference one's own t_procp pointer:
2963                  * it always points to a valid, allocated proc structure.
2964                  * Further, it is always safe to dereference the p_pidp member
2965                  * of one's own proc structure.  (These are truisms becuase
2966                  * threads and processes don't clean up their own state --
2967                  * they leave that task to whomever reaps them.)
2968                  */
2969                 return ((uint64_t)curthread->t_procp->p_pidp->pid_id);
2970 #else
2971                 return ((uint64_t)curproc->p_pid);
2972 #endif
2973
2974         case DIF_VAR_PPID:
2975                 if (!dtrace_priv_proc(state))
2976                         return (0);
2977
2978 #if defined(sun)
2979                 /*
2980                  * See comment in DIF_VAR_PID.
2981                  */
2982                 if (DTRACE_ANCHORED(mstate->dtms_probe) && CPU_ON_INTR(CPU))
2983                         return (pid0.pid_id);
2984
2985                 /*
2986                  * It is always safe to dereference one's own t_procp pointer:
2987                  * it always points to a valid, allocated proc structure.
2988                  * (This is true because threads don't clean up their own
2989                  * state -- they leave that task to whomever reaps them.)
2990                  */
2991                 return ((uint64_t)curthread->t_procp->p_ppid);
2992 #else
2993                 return ((uint64_t)curproc->p_pptr->p_pid);
2994 #endif
2995
2996         case DIF_VAR_TID:
2997 #if defined(sun)
2998                 /*
2999                  * See comment in DIF_VAR_PID.
3000                  */
3001                 if (DTRACE_ANCHORED(mstate->dtms_probe) && CPU_ON_INTR(CPU))
3002                         return (0);
3003 #endif
3004
3005                 return ((uint64_t)curthread->t_tid);
3006
3007         case DIF_VAR_EXECARGS: {
3008                 struct pargs *p_args = curthread->td_proc->p_args;
3009
3010                 if (p_args == NULL)
3011                         return(0);
3012
3013                 return (dtrace_dif_varstrz(
3014                     (uintptr_t) p_args->ar_args, p_args->ar_length, state, mstate));
3015         }
3016
3017         case DIF_VAR_EXECNAME:
3018 #if defined(sun)
3019                 if (!dtrace_priv_proc(state))
3020                         return (0);
3021
3022                 /*
3023                  * See comment in DIF_VAR_PID.
3024                  */
3025                 if (DTRACE_ANCHORED(mstate->dtms_probe) && CPU_ON_INTR(CPU))
3026                         return ((uint64_t)(uintptr_t)p0.p_user.u_comm);
3027
3028                 /*
3029                  * It is always safe to dereference one's own t_procp pointer:
3030                  * it always points to a valid, allocated proc structure.
3031                  * (This is true because threads don't clean up their own
3032                  * state -- they leave that task to whomever reaps them.)
3033                  */
3034                 return (dtrace_dif_varstr(
3035                     (uintptr_t)curthread->t_procp->p_user.u_comm,
3036                     state, mstate));
3037 #else
3038                 return (dtrace_dif_varstr(
3039                     (uintptr_t) curthread->td_proc->p_comm, state, mstate));
3040 #endif
3041
3042         case DIF_VAR_ZONENAME:
3043 #if defined(sun)
3044                 if (!dtrace_priv_proc(state))
3045                         return (0);
3046
3047                 /*
3048                  * See comment in DIF_VAR_PID.
3049                  */
3050                 if (DTRACE_ANCHORED(mstate->dtms_probe) && CPU_ON_INTR(CPU))
3051                         return ((uint64_t)(uintptr_t)p0.p_zone->zone_name);
3052
3053                 /*
3054                  * It is always safe to dereference one's own t_procp pointer:
3055                  * it always points to a valid, allocated proc structure.
3056                  * (This is true because threads don't clean up their own
3057                  * state -- they leave that task to whomever reaps them.)
3058                  */
3059                 return (dtrace_dif_varstr(
3060                     (uintptr_t)curthread->t_procp->p_zone->zone_name,
3061                     state, mstate));
3062 #else
3063                 return (0);
3064 #endif
3065
3066         case DIF_VAR_UID:
3067                 if (!dtrace_priv_proc(state))
3068                         return (0);
3069
3070 #if defined(sun)
3071                 /*
3072                  * See comment in DIF_VAR_PID.
3073                  */
3074                 if (DTRACE_ANCHORED(mstate->dtms_probe) && CPU_ON_INTR(CPU))
3075                         return ((uint64_t)p0.p_cred->cr_uid);
3076 #endif
3077
3078                 /*
3079                  * It is always safe to dereference one's own t_procp pointer:
3080                  * it always points to a valid, allocated proc structure.
3081                  * (This is true because threads don't clean up their own
3082                  * state -- they leave that task to whomever reaps them.)
3083                  *
3084                  * Additionally, it is safe to dereference one's own process
3085                  * credential, since this is never NULL after process birth.
3086                  */
3087                 return ((uint64_t)curthread->t_procp->p_cred->cr_uid);
3088
3089         case DIF_VAR_GID:
3090                 if (!dtrace_priv_proc(state))
3091                         return (0);
3092
3093 #if defined(sun)
3094                 /*
3095                  * See comment in DIF_VAR_PID.
3096                  */
3097                 if (DTRACE_ANCHORED(mstate->dtms_probe) && CPU_ON_INTR(CPU))
3098                         return ((uint64_t)p0.p_cred->cr_gid);
3099 #endif
3100
3101                 /*
3102                  * It is always safe to dereference one's own t_procp pointer:
3103                  * it always points to a valid, allocated proc structure.
3104                  * (This is true because threads don't clean up their own
3105                  * state -- they leave that task to whomever reaps them.)
3106                  *
3107                  * Additionally, it is safe to dereference one's own process
3108                  * credential, since this is never NULL after process birth.
3109                  */
3110                 return ((uint64_t)curthread->t_procp->p_cred->cr_gid);
3111
3112         case DIF_VAR_ERRNO: {
3113 #if defined(sun)
3114                 klwp_t *lwp;
3115                 if (!dtrace_priv_proc(state))
3116                         return (0);
3117
3118                 /*
3119                  * See comment in DIF_VAR_PID.
3120                  */
3121                 if (DTRACE_ANCHORED(mstate->dtms_probe) && CPU_ON_INTR(CPU))
3122                         return (0);
3123
3124                 /*
3125                  * It is always safe to dereference one's own t_lwp pointer in
3126                  * the event that this pointer is non-NULL.  (This is true
3127                  * because threads and lwps don't clean up their own state --
3128                  * they leave that task to whomever reaps them.)
3129                  */
3130                 if ((lwp = curthread->t_lwp) == NULL)
3131                         return (0);
3132
3133                 return ((uint64_t)lwp->lwp_errno);
3134 #else
3135                 return (curthread->td_errno);
3136 #endif
3137         }
3138         default:
3139                 DTRACE_CPUFLAG_SET(CPU_DTRACE_ILLOP);
3140                 return (0);
3141         }
3142 }
3143
3144 /*
3145  * Emulate the execution of DTrace ID subroutines invoked by the call opcode.
3146  * Notice that we don't bother validating the proper number of arguments or
3147  * their types in the tuple stack.  This isn't needed because all argument
3148  * interpretation is safe because of our load safety -- the worst that can
3149  * happen is that a bogus program can obtain bogus results.
3150  */
3151 static void
3152 dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs,
3153     dtrace_key_t *tupregs, int nargs,
3154     dtrace_mstate_t *mstate, dtrace_state_t *state)
3155 {
3156         volatile uint16_t *flags = &cpu_core[curcpu].cpuc_dtrace_flags;
3157         volatile uintptr_t *illval = &cpu_core[curcpu].cpuc_dtrace_illval;
3158         dtrace_vstate_t *vstate = &state->dts_vstate;
3159
3160 #if defined(sun)
3161         union {
3162                 mutex_impl_t mi;
3163                 uint64_t mx;
3164         } m;
3165
3166         union {
3167                 krwlock_t ri;
3168                 uintptr_t rw;
3169         } r;
3170 #else
3171         union {
3172                 struct mtx *mi;
3173                 uintptr_t mx;
3174         } m;
3175         union {
3176                 struct sx *si;
3177                 uintptr_t sx;
3178         } s;
3179 #endif
3180
3181         switch (subr) {
3182         case DIF_SUBR_RAND:
3183                 regs[rd] = (dtrace_gethrtime() * 2416 + 374441) % 1771875;
3184                 break;
3185
3186 #if defined(sun)
3187         case DIF_SUBR_MUTEX_OWNED:
3188                 if (!dtrace_canload(tupregs[0].dttk_value, sizeof (kmutex_t),
3189                     mstate, vstate)) {
3190                         regs[rd] = 0;
3191                         break;
3192                 }
3193
3194                 m.mx = dtrace_load64(tupregs[0].dttk_value);
3195                 if (MUTEX_TYPE_ADAPTIVE(&m.mi))
3196                         regs[rd] = MUTEX_OWNER(&m.mi) != MUTEX_NO_OWNER;
3197                 else
3198                         regs[rd] = LOCK_HELD(&m.mi.m_spin.m_spinlock);
3199                 break;
3200
3201         case DIF_SUBR_MUTEX_OWNER:
3202                 if (!dtrace_canload(tupregs[0].dttk_value, sizeof (kmutex_t),
3203                     mstate, vstate)) {
3204                         regs[rd] = 0;
3205                         break;
3206                 }
3207
3208                 m.mx = dtrace_load64(tupregs[0].dttk_value);
3209                 if (MUTEX_TYPE_ADAPTIVE(&m.mi) &&
3210                     MUTEX_OWNER(&m.mi) != MUTEX_NO_OWNER)
3211                         regs[rd] = (uintptr_t)MUTEX_OWNER(&m.mi);
3212                 else
3213                         regs[rd] = 0;
3214                 break;
3215
3216         case DIF_SUBR_MUTEX_TYPE_ADAPTIVE:
3217                 if (!dtrace_canload(tupregs[0].dttk_value, sizeof (kmutex_t),
3218                     mstate, vstate)) {
3219                         regs[rd] = 0;
3220                         break;
3221                 }
3222
3223                 m.mx = dtrace_load64(tupregs[0].dttk_value);
3224                 regs[rd] = MUTEX_TYPE_ADAPTIVE(&m.mi);
3225                 break;
3226
3227         case DIF_SUBR_MUTEX_TYPE_SPIN:
3228                 if (!dtrace_canload(tupregs[0].dttk_value, sizeof (kmutex_t),
3229                     mstate, vstate)) {
3230                         regs[rd] = 0;
3231                         break;
3232                 }
3233
3234                 m.mx = dtrace_load64(tupregs[0].dttk_value);
3235                 regs[rd] = MUTEX_TYPE_SPIN(&m.mi);
3236                 break;
3237
3238         case DIF_SUBR_RW_READ_HELD: {
3239                 uintptr_t tmp;
3240
3241                 if (!dtrace_canload(tupregs[0].dttk_value, sizeof (uintptr_t),
3242                     mstate, vstate)) {
3243                         regs[rd] = 0;
3244                         break;
3245                 }
3246
3247                 r.rw = dtrace_loadptr(tupregs[0].dttk_value);
3248                 regs[rd] = _RW_READ_HELD(&r.ri, tmp);
3249                 break;
3250         }
3251
3252         case DIF_SUBR_RW_WRITE_HELD:
3253                 if (!dtrace_canload(tupregs[0].dttk_value, sizeof (krwlock_t),
3254                     mstate, vstate)) {
3255                         regs[rd] = 0;
3256                         break;
3257                 }
3258
3259                 r.rw = dtrace_loadptr(tupregs[0].dttk_value);
3260                 regs[rd] = _RW_WRITE_HELD(&r.ri);
3261                 break;
3262
3263         case DIF_SUBR_RW_ISWRITER:
3264                 if (!dtrace_canload(tupregs[0].dttk_value, sizeof (krwlock_t),
3265                     mstate, vstate)) {
3266                         regs[rd] = 0;
3267                         break;
3268                 }
3269
3270                 r.rw = dtrace_loadptr(tupregs[0].dttk_value);
3271                 regs[rd] = _RW_ISWRITER(&r.ri);
3272                 break;
3273
3274 #else
3275         /* 
3276          * XXX - The following code works because mutex, rwlocks, & sxlocks
3277          *       all have similar data structures in FreeBSD.  This may not be
3278          *       good if someone changes one of the lock data structures.
3279          *       Ideally, it would be nice if all these shared a common lock 
3280          *       object.
3281          */
3282         case DIF_SUBR_MUTEX_OWNED:
3283                 /* XXX - need to use dtrace_canload() and dtrace_loadptr() */ 
3284                 m.mx = tupregs[0].dttk_value;
3285
3286 #ifdef DOODAD
3287                 if (LO_CLASSINDEX(&(m.mi->lock_object)) < 2) { 
3288                         regs[rd] = !(m.mi->mtx_lock & MTX_UNOWNED);
3289                 } else {        
3290                         regs[rd] = !(m.mi->mtx_lock & SX_UNLOCKED);
3291                 }
3292 #endif
3293                 break;
3294
3295         case DIF_SUBR_MUTEX_OWNER:
3296                 /* XXX - need to use dtrace_canload() and dtrace_loadptr() */ 
3297                 m.mx = tupregs[0].dttk_value;
3298
3299                 if (LO_CLASSINDEX(&(m.mi->lock_object)) < 2) { 
3300                         regs[rd] = m.mi->mtx_lock & ~MTX_FLAGMASK;
3301                 } else {
3302                         if (!(m.mi->mtx_lock & SX_LOCK_SHARED)) 
3303                                 regs[rd] = SX_OWNER(m.mi->mtx_lock);
3304                         else
3305                                 regs[rd] = 0;
3306                 }
3307                 break;
3308
3309         case DIF_SUBR_MUTEX_TYPE_ADAPTIVE:
3310                 /* XXX - need to use dtrace_canload() and dtrace_loadptr() */ 
3311                 m.mx = tupregs[0].dttk_value;
3312
3313                 regs[rd] = (LO_CLASSINDEX(&(m.mi->lock_object)) != 0);
3314                 break;
3315
3316         case DIF_SUBR_MUTEX_TYPE_SPIN:
3317                 /* XXX - need to use dtrace_canload() and dtrace_loadptr() */ 
3318                 m.mx = tupregs[0].dttk_value;
3319
3320                 regs[rd] = (LO_CLASSINDEX(&(m.mi->lock_object)) == 0);
3321                 break;
3322
3323         case DIF_SUBR_RW_READ_HELD: 
3324         case DIF_SUBR_SX_SHARED_HELD: 
3325                 /* XXX - need to use dtrace_canload() and dtrace_loadptr() */ 
3326                 s.sx = tupregs[0].dttk_value;
3327                 regs[rd] = ((s.si->sx_lock & SX_LOCK_SHARED)  && 
3328                             (SX_OWNER(s.si->sx_lock) >> SX_SHARERS_SHIFT) != 0);
3329                 break;
3330
3331         case DIF_SUBR_RW_WRITE_HELD:
3332         case DIF_SUBR_SX_EXCLUSIVE_HELD:
3333                 /* XXX - need to use dtrace_canload() and dtrace_loadptr() */ 
3334                 s.sx = tupregs[0].dttk_value;
3335                 regs[rd] = (SX_OWNER(s.si->sx_lock) == (uintptr_t) curthread); 
3336                 break;
3337
3338         case DIF_SUBR_RW_ISWRITER:
3339         case DIF_SUBR_SX_ISEXCLUSIVE:
3340                 /* XXX - need to use dtrace_canload() and dtrace_loadptr() */ 
3341                 s.sx = tupregs[0].dttk_value;
3342                 regs[rd] = ((s.si->sx_lock & SX_LOCK_EXCLUSIVE_WAITERS) ||
3343                             !(s.si->sx_lock & SX_LOCK_SHARED));
3344                 break;
3345 #endif /* ! defined(sun) */
3346
3347         case DIF_SUBR_BCOPY: {
3348                 /*
3349                  * We need to be sure that the destination is in the scratch
3350                  * region -- no other region is allowed.
3351                  */
3352                 uintptr_t src = tupregs[0].dttk_value;
3353                 uintptr_t dest = tupregs[1].dttk_value;
3354                 size_t size = tupregs[2].dttk_value;
3355
3356                 if (!dtrace_inscratch(dest, size, mstate)) {
3357                         *flags |= CPU_DTRACE_BADADDR;
3358                         *illval = regs[rd];
3359                         break;
3360                 }
3361
3362                 if (!dtrace_canload(src, size, mstate, vstate)) {
3363                         regs[rd] = 0;
3364                         break;
3365                 }
3366
3367                 dtrace_bcopy((void *)src, (void *)dest, size);
3368                 break;
3369         }
3370
3371         case DIF_SUBR_ALLOCA:
3372         case DIF_SUBR_COPYIN: {
3373                 uintptr_t dest = P2ROUNDUP(mstate->dtms_scratch_ptr, 8);
3374                 uint64_t size =
3375                     tupregs[subr == DIF_SUBR_ALLOCA ? 0 : 1].dttk_value;
3376                 size_t scratch_size = (dest - mstate->dtms_scratch_ptr) + size;
3377
3378                 /*
3379                  * This action doesn't require any credential checks since
3380                  * probes will not activate in user contexts to which the
3381                  * enabling user does not have permissions.
3382                  */
3383
3384                 /*
3385                  * Rounding up the user allocation size could have overflowed
3386                  * a large, bogus allocation (like -1ULL) to 0.
3387                  */
3388                 if (scratch_size < size ||
3389                     !DTRACE_INSCRATCH(mstate, scratch_size)) {
3390                         DTRACE_CPUFLAG_SET(CPU_DTRACE_NOSCRATCH);
3391                         regs[rd] = 0;
3392                         break;
3393                 }
3394
3395                 if (subr == DIF_SUBR_COPYIN) {
3396                         DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);
3397                         dtrace_copyin(tupregs[0].dttk_value, dest, size, flags);
3398                         DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT);
3399                 }
3400
3401                 mstate->dtms_scratch_ptr += scratch_size;
3402                 regs[rd] = dest;
3403                 break;
3404         }
3405
3406         case DIF_SUBR_COPYINTO: {
3407                 uint64_t size = tupregs[1].dttk_value;
3408                 uintptr_t dest = tupregs[2].dttk_value;
3409
3410                 /*
3411                  * This action doesn't require any credential checks since
3412                  * probes will not activate in user contexts to which the
3413                  * enabling user does not have permissions.
3414                  */
3415                 if (!dtrace_inscratch(dest, size, mstate)) {
3416                         *flags |= CPU_DTRACE_BADADDR;
3417                         *illval = regs[rd];
3418                         break;
3419                 }
3420
3421                 DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);
3422                 dtrace_copyin(tupregs[0].dttk_value, dest, size, flags);
3423                 DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT);
3424                 break;
3425         }
3426
3427         case DIF_SUBR_COPYINSTR: {
3428                 uintptr_t dest = mstate->dtms_scratch_ptr;
3429                 uint64_t size = state->dts_options[DTRACEOPT_STRSIZE];
3430
3431                 if (nargs > 1 && tupregs[1].dttk_value < size)
3432                         size = tupregs[1].dttk_value + 1;
3433
3434                 /*
3435                  * This action doesn't require any credential checks since
3436                  * probes will not activate in user contexts to which the
3437                  * enabling user does not have permissions.
3438                  */
3439                 if (!DTRACE_INSCRATCH(mstate, size)) {
3440                         DTRACE_CPUFLAG_SET(CPU_DTRACE_NOSCRATCH);
3441                         regs[rd] = 0;
3442                         break;
3443                 }
3444
3445                 DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);
3446                 dtrace_copyinstr(tupregs[0].dttk_value, dest, size, flags);
3447                 DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT);
3448
3449                 ((char *)dest)[size - 1] = '\0';
3450                 mstate->dtms_scratch_ptr += size;
3451                 regs[rd] = dest;
3452                 break;
3453         }
3454
3455 #if defined(sun)
3456         case DIF_SUBR_MSGSIZE:
3457         case DIF_SUBR_MSGDSIZE: {
3458                 uintptr_t baddr = tupregs[0].dttk_value, daddr;
3459                 uintptr_t wptr, rptr;
3460                 size_t count = 0;
3461                 int cont = 0;
3462
3463                 while (baddr != 0 && !(*flags & CPU_DTRACE_FAULT)) {
3464
3465                         if (!dtrace_canload(baddr, sizeof (mblk_t), mstate,
3466                             vstate)) {
3467                                 regs[rd] = 0;
3468                                 break;
3469                         }
3470
3471                         wptr = dtrace_loadptr(baddr +
3472                             offsetof(mblk_t, b_wptr));
3473
3474                         rptr = dtrace_loadptr(baddr +
3475                             offsetof(mblk_t, b_rptr));
3476
3477                         if (wptr < rptr) {
3478                                 *flags |= CPU_DTRACE_BADADDR;
3479                                 *illval = tupregs[0].dttk_value;
3480                                 break;
3481                         }
3482
3483                         daddr = dtrace_loadptr(baddr +
3484                             offsetof(mblk_t, b_datap));
3485
3486                         baddr = dtrace_loadptr(baddr +
3487                             offsetof(mblk_t, b_cont));
3488
3489                         /*
3490                          * We want to prevent against denial-of-service here,
3491                          * so we're only going to search the list for
3492                          * dtrace_msgdsize_max mblks.
3493                          */
3494                         if (cont++ > dtrace_msgdsize_max) {
3495                                 *flags |= CPU_DTRACE_ILLOP;
3496                                 break;
3497                         }
3498
3499                         if (subr == DIF_SUBR_MSGDSIZE) {
3500                                 if (dtrace_load8(daddr +
3501                                     offsetof(dblk_t, db_type)) != M_DATA)
3502                                         continue;
3503                         }
3504
3505                         count += wptr - rptr;
3506                 }
3507
3508                 if (!(*flags & CPU_DTRACE_FAULT))
3509                         regs[rd] = count;
3510
3511                 break;
3512         }
3513 #endif
3514
3515         case DIF_SUBR_PROGENYOF: {
3516                 pid_t pid = tupregs[0].dttk_value;
3517                 proc_t *p;
3518                 int rval = 0;
3519
3520                 DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);
3521
3522                 for (p = curthread->t_procp; p != NULL; p = p->p_parent) {
3523 #if defined(sun)
3524                         if (p->p_pidp->pid_id == pid) {
3525 #else
3526                         if (p->p_pid == pid) {
3527 #endif
3528                                 rval = 1;
3529                                 break;
3530                         }
3531                 }
3532
3533                 DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT);
3534
3535                 regs[rd] = rval;
3536                 break;
3537         }
3538
3539         case DIF_SUBR_SPECULATION:
3540                 regs[rd] = dtrace_speculation(state);
3541                 break;
3542
3543         case DIF_SUBR_COPYOUT: {
3544                 uintptr_t kaddr = tupregs[0].dttk_value;
3545                 uintptr_t uaddr = tupregs[1].dttk_value;
3546                 uint64_t size = tupregs[2].dttk_value;
3547
3548                 if (!dtrace_destructive_disallow &&
3549                     dtrace_priv_proc_control(state) &&
3550                     !dtrace_istoxic(kaddr, size)) {
3551                         DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);
3552                         dtrace_copyout(kaddr, uaddr, size, flags);
3553                         DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT);
3554                 }
3555                 break;
3556         }
3557
3558         case DIF_SUBR_COPYOUTSTR: {
3559                 uintptr_t kaddr = tupregs[0].dttk_value;
3560                 uintptr_t uaddr = tupregs[1].dttk_value;
3561                 uint64_t size = tupregs[2].dttk_value;
3562
3563                 if (!dtrace_destructive_disallow &&
3564                     dtrace_priv_proc_control(state) &&
3565                     !dtrace_istoxic(kaddr, size)) {
3566                         DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);
3567                         dtrace_copyoutstr(kaddr, uaddr, size, flags);
3568                         DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT);
3569                 }
3570                 break;
3571         }
3572
3573         case DIF_SUBR_STRLEN: {
3574                 size_t sz;
3575                 uintptr_t addr = (uintptr_t)tupregs[0].dttk_value;
3576                 sz = dtrace_strlen((char *)addr,
3577                     state->dts_options[DTRACEOPT_STRSIZE]);
3578
3579                 if (!dtrace_canload(addr, sz + 1, mstate, vstate)) {
3580                         regs[rd] = 0;
3581                         break;
3582                 }
3583
3584                 regs[rd] = sz;
3585
3586                 break;
3587         }
3588
3589         case DIF_SUBR_STRCHR:
3590         case DIF_SUBR_STRRCHR: {
3591                 /*
3592                  * We're going to iterate over the string looking for the
3593                  * specified character.  We will iterate until we have reached
3594                  * the string length or we have found the character.  If this
3595                  * is DIF_SUBR_STRRCHR, we will look for the last occurrence
3596                  * of the specified character instead of the first.
3597                  */
3598                 uintptr_t saddr = tupregs[0].dttk_value;
3599                 uintptr_t addr = tupregs[0].dttk_value;
3600                 uintptr_t limit = addr + state->dts_options[DTRACEOPT_STRSIZE];
3601                 char c, target = (char)tupregs[1].dttk_value;
3602
3603                 for (regs[rd] = 0; addr < limit; addr++) {
3604                         if ((c = dtrace_load8(addr)) == target) {
3605                                 regs[rd] = addr;
3606
3607                                 if (subr == DIF_SUBR_STRCHR)
3608                                         break;
3609                         }
3610
3611                         if (c == '\0')
3612                                 break;
3613                 }
3614
3615                 if (!dtrace_canload(saddr, addr - saddr, mstate, vstate)) {
3616                         regs[rd] = 0;
3617                         break;
3618                 }
3619
3620                 break;
3621         }
3622
3623         case DIF_SUBR_STRSTR:
3624         case DIF_SUBR_INDEX:
3625         case DIF_SUBR_RINDEX: {
3626                 /*
3627                  * We're going to iterate over the string looking for the
3628                  * specified string.  We will iterate until we have reached
3629                  * the string length or we have found the string.  (Yes, this
3630                  * is done in the most naive way possible -- but considering
3631                  * that the string we're searching for is likely to be
3632                  * relatively short, the complexity of Rabin-Karp or similar
3633                  * hardly seems merited.)
3634                  */
3635                 char *addr = (char *)(uintptr_t)tupregs[0].dttk_value;
3636                 char *substr = (char *)(uintptr_t)tupregs[1].dttk_value;
3637                 uint64_t size = state->dts_options[DTRACEOPT_STRSIZE];
3638                 size_t len = dtrace_strlen(addr, size);
3639                 size_t sublen = dtrace_strlen(substr, size);
3640                 char *limit = addr + len, *orig = addr;
3641                 int notfound = subr == DIF_SUBR_STRSTR ? 0 : -1;
3642                 int inc = 1;
3643
3644                 regs[rd] = notfound;
3645
3646                 if (!dtrace_canload((uintptr_t)addr, len + 1, mstate, vstate)) {
3647                         regs[rd] = 0;
3648                         break;
3649                 }
3650
3651                 if (!dtrace_canload((uintptr_t)substr, sublen + 1, mstate,
3652                     vstate)) {
3653                         regs[rd] = 0;
3654                         break;
3655                 }
3656
3657                 /*
3658                  * strstr() and index()/rindex() have similar semantics if
3659                  * both strings are the empty string: strstr() returns a
3660                  * pointer to the (empty) string, and index() and rindex()
3661                  * both return index 0 (regardless of any position argument).
3662                  */
3663                 if (sublen == 0 && len == 0) {
3664                         if (subr == DIF_SUBR_STRSTR)
3665                                 regs[rd] = (uintptr_t)addr;
3666                         else
3667                                 regs[rd] = 0;
3668                         break;
3669                 }
3670
3671                 if (subr != DIF_SUBR_STRSTR) {
3672                         if (subr == DIF_SUBR_RINDEX) {
3673                                 limit = orig - 1;
3674                                 addr += len;
3675                                 inc = -1;
3676                         }
3677
3678                         /*
3679                          * Both index() and rindex() take an optional position
3680                          * argument that denotes the starting position.
3681                          */
3682                         if (nargs == 3) {
3683                                 int64_t pos = (int64_t)tupregs[2].dttk_value;
3684
3685                                 /*
3686                                  * If the position argument to index() is
3687                                  * negative, Perl implicitly clamps it at
3688                                  * zero.  This semantic is a little surprising
3689                                  * given the special meaning of negative
3690                                  * positions to similar Perl functions like
3691                                  * substr(), but it appears to reflect a
3692                                  * notion that index() can start from a
3693                                  * negative index and increment its way up to
3694                                  * the string.  Given this notion, Perl's
3695                                  * rindex() is at least self-consistent in
3696                                  * that it implicitly clamps positions greater
3697                                  * than the string length to be the string
3698                                  * length.  Where Perl completely loses
3699                                  * coherence, however, is when the specified
3700                                  * substring is the empty string ("").  In
3701                                  * this case, even if the position is
3702                                  * negative, rindex() returns 0 -- and even if
3703                                  * the position is greater than the length,
3704                                  * index() returns the string length.  These
3705                                  * semantics violate the notion that index()
3706                                  * should never return a value less than the
3707                                  * specified position and that rindex() should
3708                                  * never return a value greater than the
3709                                  * specified position.  (One assumes that
3710                                  * these semantics are artifacts of Perl's
3711                                  * implementation and not the results of
3712                                  * deliberate design -- it beggars belief that
3713                                  * even Larry Wall could desire such oddness.)
3714                                  * While in the abstract one would wish for
3715                                  * consistent position semantics across
3716                                  * substr(), index() and rindex() -- or at the
3717                                  * very least self-consistent position
3718                                  * semantics for index() and rindex() -- we
3719                                  * instead opt to keep with the extant Perl
3720                                  * semantics, in all their broken glory.  (Do
3721                                  * we have more desire to maintain Perl's
3722                                  * semantics than Perl does?  Probably.)
3723                                  */
3724                                 if (subr == DIF_SUBR_RINDEX) {
3725                                         if (pos < 0) {
3726                                                 if (sublen == 0)
3727                                                         regs[rd] = 0;
3728                                                 break;
3729                                         }
3730
3731                                         if (pos > len)
3732                                                 pos = len;
3733                                 } else {
3734                                         if (pos < 0)
3735                                                 pos = 0;
3736
3737                                         if (pos >= len) {
3738                                                 if (sublen == 0)
3739                                                         regs[rd] = len;
3740                                                 break;
3741                                         }
3742                                 }
3743
3744                                 addr = orig + pos;
3745                         }
3746                 }
3747
3748                 for (regs[rd] = notfound; addr != limit; addr += inc) {
3749                         if (dtrace_strncmp(addr, substr, sublen) == 0) {
3750                                 if (subr != DIF_SUBR_STRSTR) {
3751                                         /*
3752                                          * As D index() and rindex() are
3753                                          * modeled on Perl (and not on awk),
3754                                          * we return a zero-based (and not a
3755                                          * one-based) index.  (For you Perl
3756                                          * weenies: no, we're not going to add
3757                                          * $[ -- and shouldn't you be at a con
3758                                          * or something?)
3759                                          */
3760                                         regs[rd] = (uintptr_t)(addr - orig);
3761                                         break;
3762                                 }
3763
3764                                 ASSERT(subr == DIF_SUBR_STRSTR);
3765                                 regs[rd] = (uintptr_t)addr;
3766                                 break;
3767                         }
3768                 }
3769
3770                 break;
3771         }
3772
3773         case DIF_SUBR_STRTOK: {
3774                 uintptr_t addr = tupregs[0].dttk_value;
3775                 uintptr_t tokaddr = tupregs[1].dttk_value;
3776                 uint64_t size = state->dts_options[DTRACEOPT_STRSIZE];
3777                 uintptr_t limit, toklimit = tokaddr + size;
3778                 uint8_t c = 0, tokmap[32];       /* 256 / 8 */
3779                 char *dest = (char *)mstate->dtms_scratch_ptr;
3780                 int i;
3781
3782                 /*
3783                  * Check both the token buffer and (later) the input buffer,
3784                  * since both could be non-scratch addresses.
3785                  */
3786                 if (!dtrace_strcanload(tokaddr, size, mstate, vstate)) {
3787                         regs[rd] = 0;
3788                         break;
3789                 }
3790
3791                 if (!DTRACE_INSCRATCH(mstate, size)) {
3792                         DTRACE_CPUFLAG_SET(CPU_DTRACE_NOSCRATCH);
3793                         regs[rd] = 0;
3794                         break;
3795                 }
3796
3797                 if (addr == 0) {
3798                         /*
3799                          * If the address specified is NULL, we use our saved
3800                          * strtok pointer from the mstate.  Note that this
3801                          * means that the saved strtok pointer is _only_
3802                          * valid within multiple enablings of the same probe --
3803                          * it behaves like an implicit clause-local variable.
3804                          */
3805                         addr = mstate->dtms_strtok;
3806                 } else {
3807                         /*
3808                          * If the user-specified address is non-NULL we must
3809                          * access check it.  This is the only time we have
3810                          * a chance to do so, since this address may reside
3811                          * in the string table of this clause-- future calls
3812                          * (when we fetch addr from mstate->dtms_strtok)
3813                          * would fail this access check.
3814                          */
3815                         if (!dtrace_strcanload(addr, size, mstate, vstate)) {
3816                                 regs[rd] = 0;
3817                                 break;
3818                         }
3819                 }
3820
3821                 /*
3822                  * First, zero the token map, and then process the token
3823                  * string -- setting a bit in the map for every character
3824                  * found in the token string.
3825                  */
3826                 for (i = 0; i < sizeof (tokmap); i++)
3827                         tokmap[i] = 0;
3828
3829                 for (; tokaddr < toklimit; tokaddr++) {
3830                         if ((c = dtrace_load8(tokaddr)) == '\0')
3831                                 break;
3832
3833                         ASSERT((c >> 3) < sizeof (tokmap));
3834                         tokmap[c >> 3] |= (1 << (c & 0x7));
3835                 }
3836
3837                 for (limit = addr + size; addr < limit; addr++) {
3838                         /*
3839                          * We're looking for a character that is _not_ contained
3840                          * in the token string.
3841                          */
3842                         if ((c = dtrace_load8(addr)) == '\0')
3843                                 break;
3844
3845                         if (!(tokmap[c >> 3] & (1 << (c & 0x7))))
3846                                 break;
3847                 }
3848
3849                 if (c == '\0') {
3850                         /*
3851                          * We reached the end of the string without finding
3852                          * any character that was not in the token string.
3853                          * We return NULL in this case, and we set the saved
3854                          * address to NULL as well.
3855                          */
3856                         regs[rd] = 0;
3857                         mstate->dtms_strtok = 0;
3858                         break;
3859                 }
3860
3861                 /*
3862                  * From here on, we're copying into the destination string.
3863                  */
3864                 for (i = 0; addr < limit && i < size - 1; addr++) {
3865                         if ((c = dtrace_load8(addr)) == '\0')
3866                                 break;
3867
3868                         if (tokmap[c >> 3] & (1 << (c & 0x7)))
3869                                 break;
3870
3871                         ASSERT(i < size);
3872                         dest[i++] = c;
3873                 }
3874
3875                 ASSERT(i < size);
3876                 dest[i] = '\0';
3877                 regs[rd] = (uintptr_t)dest;
3878                 mstate->dtms_scratch_ptr += size;
3879                 mstate->dtms_strtok = addr;
3880                 break;
3881         }
3882
3883         case DIF_SUBR_SUBSTR: {
3884                 uintptr_t s = tupregs[0].dttk_value;
3885                 uint64_t size = state->dts_options[DTRACEOPT_STRSIZE];
3886                 char *d = (char *)mstate->dtms_scratch_ptr;
3887                 int64_t index = (int64_t)tupregs[1].dttk_value;
3888                 int64_t remaining = (int64_t)tupregs[2].dttk_value;
3889                 size_t len = dtrace_strlen((char *)s, size);
3890                 int64_t i = 0;
3891
3892                 if (!dtrace_canload(s, len + 1, mstate, vstate)) {
3893                         regs[rd] = 0;
3894                         break;
3895                 }
3896
3897                 if (!DTRACE_INSCRATCH(mstate, size)) {
3898                         DTRACE_CPUFLAG_SET(CPU_DTRACE_NOSCRATCH);
3899                         regs[rd] = 0;
3900                         break;
3901                 }
3902
3903                 if (nargs <= 2)
3904                         remaining = (int64_t)size;
3905
3906                 if (index < 0) {
3907                         index += len;
3908
3909                         if (index < 0 && index + remaining > 0) {
3910                                 remaining += index;
3911                                 index = 0;
3912                         }
3913                 }
3914
3915                 if (index >= len || index < 0) {
3916                         remaining = 0;
3917                 } else if (remaining < 0) {
3918                         remaining += len - index;
3919                 } else if (index + remaining > size) {
3920                         remaining = size - index;
3921                 }
3922
3923                 for (i = 0; i < remaining; i++) {
3924                         if ((d[i] = dtrace_load8(s + index + i)) == '\0')
3925                                 break;
3926                 }
3927
3928                 d[i] = '\0';
3929
3930                 mstate->dtms_scratch_ptr += size;
3931                 regs[rd] = (uintptr_t)d;
3932                 break;
3933         }
3934
3935 #if defined(sun)
3936         case DIF_SUBR_GETMAJOR:
3937 #ifdef _LP64
3938                 regs[rd] = (tupregs[0].dttk_value >> NBITSMINOR64) & MAXMAJ64;
3939 #else
3940                 regs[rd] = (tupregs[0].dttk_value >> NBITSMINOR) & MAXMAJ;
3941 #endif
3942                 break;
3943
3944         case DIF_SUBR_GETMINOR:
3945 #ifdef _LP64
3946                 regs[rd] = tupregs[0].dttk_value & MAXMIN64;
3947 #else
3948                 regs[rd] = tupregs[0].dttk_value & MAXMIN;
3949 #endif
3950                 break;
3951
3952         case DIF_SUBR_DDI_PATHNAME: {
3953                 /*
3954                  * This one is a galactic mess.  We are going to roughly
3955                  * emulate ddi_pathname(), but it's made more complicated
3956                  * by the fact that we (a) want to include the minor name and
3957                  * (b) must proceed iteratively instead of recursively.
3958                  */
3959                 uintptr_t dest = mstate->dtms_scratch_ptr;
3960                 uint64_t size = state->dts_options[DTRACEOPT_STRSIZE];
3961                 char *start = (char *)dest, *end = start + size - 1;
3962                 uintptr_t daddr = tupregs[0].dttk_value;
3963                 int64_t minor = (int64_t)tupregs[1].dttk_value;
3964                 char *s;
3965                 int i, len, depth = 0;
3966
3967                 /*
3968                  * Due to all the pointer jumping we do and context we must
3969                  * rely upon, we just mandate that the user must have kernel
3970                  * read privileges to use this routine.
3971                  */
3972                 if ((mstate->dtms_access & DTRACE_ACCESS_KERNEL) == 0) {
3973                         *flags |= CPU_DTRACE_KPRIV;
3974                         *illval = daddr;
3975                         regs[rd] = 0;
3976                 }
3977
3978                 if (!DTRACE_INSCRATCH(mstate, size)) {
3979                         DTRACE_CPUFLAG_SET(CPU_DTRACE_NOSCRATCH);
3980                         regs[rd] = 0;
3981                         break;
3982                 }
3983
3984                 *end = '\0';
3985
3986                 /*
3987                  * We want to have a name for the minor.  In order to do this,
3988                  * we need to walk the minor list from the devinfo.  We want
3989                  * to be sure that we don't infinitely walk a circular list,
3990                  * so we check for circularity by sending a scout pointer
3991                  * ahead two elements for every element that we iterate over;
3992                  * if the list is circular, these will ultimately point to the
3993                  * same element.  You may recognize this little trick as the
3994                  * answer to a stupid interview question -- one that always
3995                  * seems to be asked by those who had to have it laboriously
3996                  * explained to them, and who can't even concisely describe
3997                  * the conditions under which one would be forced to resort to
3998                  * this technique.  Needless to say, those conditions are
3999                  * found here -- and probably only here.  Is this the only use
4000                  * of this infamous trick in shipping, production code?  If it
4001                  * isn't, it probably should be...
4002                  */
4003                 if (minor != -1) {
4004                         uintptr_t maddr = dtrace_loadptr(daddr +
4005                             offsetof(struct dev_info, devi_minor));
4006
4007                         uintptr_t next = offsetof(struct ddi_minor_data, next);
4008                         uintptr_t name = offsetof(struct ddi_minor_data,
4009                             d_minor) + offsetof(struct ddi_minor, name);
4010                         uintptr_t dev = offsetof(struct ddi_minor_data,
4011                             d_minor) + offsetof(struct ddi_minor, dev);
4012                         uintptr_t scout;
4013
4014                         if (maddr != NULL)
4015                                 scout = dtrace_loadptr(maddr + next);
4016
4017                         while (maddr != NULL && !(*flags & CPU_DTRACE_FAULT)) {
4018                                 uint64_t m;
4019 #ifdef _LP64
4020                                 m = dtrace_load64(maddr + dev) & MAXMIN64;
4021 #else
4022                                 m = dtrace_load32(maddr + dev) & MAXMIN;
4023 #endif
4024                                 if (m != minor) {
4025                                         maddr = dtrace_loadptr(maddr + next);
4026
4027                                         if (scout == NULL)
4028                                                 continue;
4029
4030                                         scout = dtrace_loadptr(scout + next);
4031
4032                                         if (scout == NULL)
4033                                                 continue;
4034
4035                                         scout = dtrace_loadptr(scout + next);
4036
4037                                         if (scout == NULL)
4038                                                 continue;
4039
4040                                         if (scout == maddr) {
4041                                                 *flags |= CPU_DTRACE_ILLOP;
4042                                                 break;
4043                                         }
4044
4045                                         continue;
4046                                 }
4047
4048                                 /*
4049                                  * We have the minor data.  Now we need to
4050                                  * copy the minor's name into the end of the
4051                                  * pathname.
4052                                  */
4053                                 s = (char *)dtrace_loadptr(maddr + name);
4054                                 len = dtrace_strlen(s, size);
4055
4056                                 if (*flags & CPU_DTRACE_FAULT)
4057                                         break;
4058
4059                                 if (len != 0) {
4060                                         if ((end -= (len + 1)) < start)
4061                                                 break;
4062
4063                                         *end = ':';
4064                                 }
4065
4066                                 for (i = 1; i <= len; i++)
4067                                         end[i] = dtrace_load8((uintptr_t)s++);
4068                                 break;
4069                         }
4070                 }
4071
4072                 while (daddr != NULL && !(*flags & CPU_DTRACE_FAULT)) {
4073                         ddi_node_state_t devi_state;
4074
4075                         devi_state = dtrace_load32(daddr +
4076                             offsetof(struct dev_info, devi_node_state));
4077
4078                         if (*flags & CPU_DTRACE_FAULT)
4079                                 break;
4080
4081                         if (devi_state >= DS_INITIALIZED) {
4082                                 s = (char *)dtrace_loadptr(daddr +
4083                                     offsetof(struct dev_info, devi_addr));
4084                                 len = dtrace_strlen(s, size);
4085
4086                                 if (*flags & CPU_DTRACE_FAULT)
4087                                         break;
4088
4089                                 if (len != 0) {
4090                                         if ((end -= (len + 1)) < start)
4091                                                 break;
4092
4093                                         *end = '@';
4094                                 }
4095
4096                                 for (i = 1; i <= len; i++)
4097                                         end[i] = dtrace_load8((uintptr_t)s++);
4098                         }
4099
4100                         /*
4101                          * Now for the node name...
4102                          */
4103                         s = (char *)dtrace_loadptr(daddr +
4104                             offsetof(struct dev_info, devi_node_name));
4105
4106                         daddr = dtrace_loadptr(daddr +
4107                             offsetof(struct dev_info, devi_parent));
4108
4109                         /*
4110                          * If our parent is NULL (that is, if we're the root
4111                          * node), we're going to use the special path
4112                          * "devices".
4113                          */
4114                         if (daddr == 0)
4115                                 s = "devices";
4116
4117                         len = dtrace_strlen(s, size);
4118                         if (*flags & CPU_DTRACE_FAULT)
4119                                 break;
4120
4121                         if ((end -= (len + 1)) < start)
4122                                 break;
4123
4124                         for (i = 1; i <= len; i++)
4125                                 end[i] = dtrace_load8((uintptr_t)s++);
4126                         *end = '/';
4127
4128                         if (depth++ > dtrace_devdepth_max) {
4129                                 *flags |= CPU_DTRACE_ILLOP;
4130                                 break;
4131                         }
4132                 }
4133
4134                 if (end < start)
4135                         DTRACE_CPUFLAG_SET(CPU_DTRACE_NOSCRATCH);
4136
4137                 if (daddr == 0) {
4138                         regs[rd] = (uintptr_t)end;
4139                         mstate->dtms_scratch_ptr += size;
4140                 }
4141
4142                 break;
4143         }
4144 #endif
4145
4146         case DIF_SUBR_STRJOIN: {
4147                 char *d = (char *)mstate->dtms_scratch_ptr;
4148                 uint64_t size = state->dts_options[DTRACEOPT_STRSIZE];
4149                 uintptr_t s1 = tupregs[0].dttk_value;
4150                 uintptr_t s2 = tupregs[1].dttk_value;
4151                 int i = 0;
4152
4153                 if (!dtrace_strcanload(s1, size, mstate, vstate) ||
4154                     !dtrace_strcanload(s2, size, mstate, vstate)) {
4155                         regs[rd] = 0;
4156                         break;
4157                 }
4158
4159                 if (!DTRACE_INSCRATCH(mstate, size)) {
4160                         DTRACE_CPUFLAG_SET(CPU_DTRACE_NOSCRATCH);
4161                         regs[rd] = 0;
4162                         break;
4163                 }
4164
4165                 for (;;) {
4166                         if (i >= size) {
4167                                 DTRACE_CPUFLAG_SET(CPU_DTRACE_NOSCRATCH);
4168                                 regs[rd] = 0;
4169                                 break;
4170                         }
4171
4172                         if ((d[i++] = dtrace_load8(s1++)) == '\0') {
4173                                 i--;
4174                                 break;
4175                         }
4176                 }
4177
4178                 for (;;) {
4179                         if (i >= size) {
4180                                 DTRACE_CPUFLAG_SET(CPU_DTRACE_NOSCRATCH);
4181                                 regs[rd] = 0;
4182                                 break;
4183                         }
4184
4185                         if ((d[i++] = dtrace_load8(s2++)) == '\0')
4186                                 break;
4187                 }
4188
4189                 if (i < size) {
4190                         mstate->dtms_scratch_ptr += i;
4191                         regs[rd] = (uintptr_t)d;
4192                 }
4193
4194                 break;
4195         }
4196
4197         case DIF_SUBR_LLTOSTR: {
4198                 int64_t i = (int64_t)tupregs[0].dttk_value;
4199                 int64_t val = i < 0 ? i * -1 : i;
4200                 uint64_t size = 22;     /* enough room for 2^64 in decimal */
4201                 char *end = (char *)mstate->dtms_scratch_ptr + size - 1;
4202
4203                 if (!DTRACE_INSCRATCH(mstate, size)) {
4204                         DTRACE_CPUFLAG_SET(CPU_DTRACE_NOSCRATCH);
4205                         regs[rd] = 0;
4206                         break;
4207                 }
4208
4209                 for (*end-- = '\0'; val; val /= 10)
4210                         *end-- = '0' + (val % 10);
4211
4212                 if (i == 0)
4213                         *end-- = '0';
4214
4215                 if (i < 0)
4216                         *end-- = '-';
4217
4218                 regs[rd] = (uintptr_t)end + 1;
4219                 mstate->dtms_scratch_ptr += size;
4220                 break;
4221         }
4222
4223         case DIF_SUBR_HTONS:
4224         case DIF_SUBR_NTOHS:
4225 #if BYTE_ORDER == BIG_ENDIAN
4226                 regs[rd] = (uint16_t)tupregs[0].dttk_value;
4227 #else
4228                 regs[rd] = DT_BSWAP_16((uint16_t)tupregs[0].dttk_value);
4229 #endif
4230                 break;
4231
4232
4233         case DIF_SUBR_HTONL:
4234         case DIF_SUBR_NTOHL:
4235 #if BYTE_ORDER == BIG_ENDIAN
4236                 regs[rd] = (uint32_t)tupregs[0].dttk_value;
4237 #else
4238                 regs[rd] = DT_BSWAP_32((uint32_t)tupregs[0].dttk_value);
4239 #endif
4240                 break;
4241
4242
4243         case DIF_SUBR_HTONLL:
4244         case DIF_SUBR_NTOHLL:
4245 #if BYTE_ORDER == BIG_ENDIAN
4246                 regs[rd] = (uint64_t)tupregs[0].dttk_value;
4247 #else
4248                 regs[rd] = DT_BSWAP_64((uint64_t)tupregs[0].dttk_value);
4249 #endif
4250                 break;
4251
4252
4253         case DIF_SUBR_DIRNAME:
4254         case DIF_SUBR_BASENAME: {
4255                 char *dest = (char *)mstate->dtms_scratch_ptr;
4256                 uint64_t size = state->dts_options[DTRACEOPT_STRSIZE];
4257                 uintptr_t src = tupregs[0].dttk_value;
4258                 int i, j, len = dtrace_strlen((char *)src, size);
4259                 int lastbase = -1, firstbase = -1, lastdir = -1;
4260                 int start, end;
4261
4262                 if (!dtrace_canload(src, len + 1, mstate, vstate)) {
4263                         regs[rd] = 0;
4264                         break;
4265                 }
4266
4267                 if (!DTRACE_INSCRATCH(mstate, size)) {
4268                         DTRACE_CPUFLAG_SET(CPU_DTRACE_NOSCRATCH);
4269                         regs[rd] = 0;
4270                         break;
4271                 }
4272
4273                 /*
4274                  * The basename and dirname for a zero-length string is
4275                  * defined to be "."
4276                  */
4277                 if (len == 0) {
4278                         len = 1;
4279                         src = (uintptr_t)".";
4280                 }
4281
4282                 /*
4283                  * Start from the back of the string, moving back toward the
4284                  * front until we see a character that isn't a slash.  That
4285                  * character is the last character in the basename.
4286                  */
4287                 for (i = len - 1; i >= 0; i--) {
4288                         if (dtrace_load8(src + i) != '/')
4289                                 break;
4290                 }
4291
4292                 if (i >= 0)
4293                         lastbase = i;
4294
4295                 /*
4296                  * Starting from the last character in the basename, move
4297                  * towards the front until we find a slash.  The character
4298                  * that we processed immediately before that is the first
4299                  * character in the basename.
4300                  */
4301                 for (; i >= 0; i--) {
4302                         if (dtrace_load8(src + i) == '/')
4303                                 break;
4304                 }
4305
4306                 if (i >= 0)
4307                         firstbase = i + 1;
4308
4309                 /*
4310                  * Now keep going until we find a non-slash character.  That
4311                  * character is the last character in the dirname.
4312                  */
4313                 for (; i >= 0; i--) {
4314                         if (dtrace_load8(src + i) != '/')
4315                                 break;
4316                 }
4317
4318                 if (i >= 0)
4319                         lastdir = i;
4320
4321                 ASSERT(!(lastbase == -1 && firstbase != -1));
4322                 ASSERT(!(firstbase == -1 && lastdir != -1));
4323
4324                 if (lastbase == -1) {
4325                         /*
4326                          * We didn't find a non-slash character.  We know that
4327                          * the length is non-zero, so the whole string must be
4328                          * slashes.  In either the dirname or the basename
4329                          * case, we return '/'.
4330                          */
4331                         ASSERT(firstbase == -1);
4332                         firstbase = lastbase = lastdir = 0;
4333                 }
4334
4335                 if (firstbase == -1) {
4336                         /*
4337                          * The entire string consists only of a basename
4338                          * component.  If we're looking for dirname, we need
4339                          * to change our string to be just "."; if we're
4340                          * looking for a basename, we'll just set the first
4341                          * character of the basename to be 0.
4342                          */
4343                         if (subr == DIF_SUBR_DIRNAME) {
4344                                 ASSERT(lastdir == -1);
4345                                 src = (uintptr_t)".";
4346                                 lastdir = 0;
4347                         } else {
4348                                 firstbase = 0;
4349                         }
4350                 }
4351
4352                 if (subr == DIF_SUBR_DIRNAME) {
4353                         if (lastdir == -1) {
4354                                 /*
4355                                  * We know that we have a slash in the name --
4356                                  * or lastdir would be set to 0, above.  And
4357                                  * because lastdir is -1, we know that this
4358                                  * slash must be the first character.  (That
4359                                  * is, the full string must be of the form
4360                                  * "/basename".)  In this case, the last
4361                                  * character of the directory name is 0.
4362                                  */
4363                                 lastdir = 0;
4364                         }
4365
4366                         start = 0;
4367                         end = lastdir;
4368                 } else {
4369                         ASSERT(subr == DIF_SUBR_BASENAME);
4370                         ASSERT(firstbase != -1 && lastbase != -1);
4371                         start = firstbase;
4372                         end = lastbase;
4373                 }
4374
4375                 for (i = start, j = 0; i <= end && j < size - 1; i++, j++)
4376                         dest[j] = dtrace_load8(src + i);
4377
4378                 dest[j] = '\0';
4379                 regs[rd] = (uintptr_t)dest;
4380                 mstate->dtms_scratch_ptr += size;
4381                 break;
4382         }
4383
4384         case DIF_SUBR_CLEANPATH: {
4385                 char *dest = (char *)mstate->dtms_scratch_ptr, c;
4386                 uint64_t size = state->dts_options[DTRACEOPT_STRSIZE];
4387                 uintptr_t src = tupregs[0].dttk_value;
4388                 int i = 0, j = 0;
4389
4390                 if (!dtrace_strcanload(src, size, mstate, vstate)) {
4391                         regs[rd] = 0;
4392                         break;
4393                 }
4394
4395                 if (!DTRACE_INSCRATCH(mstate, size)) {
4396                         DTRACE_CPUFLAG_SET(CPU_DTRACE_NOSCRATCH);
4397                         regs[rd] = 0;
4398                         break;
4399                 }
4400
4401                 /*
4402                  * Move forward, loading each character.
4403                  */
4404                 do {
4405                         c = dtrace_load8(src + i++);
4406 next:
4407                         if (j + 5 >= size)      /* 5 = strlen("/..c\0") */
4408                                 break;
4409
4410                         if (c != '/') {
4411                                 dest[j++] = c;
4412                                 continue;
4413                         }
4414
4415                         c = dtrace_load8(src + i++);
4416
4417                         if (c == '/') {
4418                                 /*
4419                                  * We have two slashes -- we can just advance
4420                                  * to the next character.
4421                                  */
4422                                 goto next;
4423                         }
4424
4425                         if (c != '.') {
4426                                 /*
4427                                  * This is not "." and it's not ".." -- we can
4428                                  * just store the "/" and this character and
4429                                  * drive on.
4430                                  */
4431                                 dest[j++] = '/';
4432                                 dest[j++] = c;
4433                                 continue;
4434                         }
4435
4436                         c = dtrace_load8(src + i++);
4437
4438                         if (c == '/') {
4439                                 /*
4440                                  * This is a "/./" component.  We're not going
4441                                  * to store anything in the destination buffer;
4442                                  * we're just going to go to the next component.
4443                                  */
4444                                 goto next;
4445                         }
4446
4447                         if (c != '.') {
4448                                 /*
4449                                  * This is not ".." -- we can just store the
4450                                  * "/." and this character and continue
4451                                  * processing.
4452                                  */
4453                                 dest[j++] = '/';
4454                                 dest[j++] = '.';
4455                                 dest[j++] = c;
4456                                 continue;
4457                         }
4458
4459                         c = dtrace_load8(src + i++);
4460
4461                         if (c != '/' && c != '\0') {
4462                                 /*
4463                                  * This is not ".." -- it's "..[mumble]".
4464                                  * We'll store the "/.." and this character
4465                                  * and continue processing.
4466                                  */
4467                                 dest[j++] = '/';
4468                                 dest[j++] = '.';
4469                                 dest[j++] = '.';
4470                                 dest[j++] = c;
4471                                 continue;
4472                         }
4473
4474                         /*
4475                          * This is "/../" or "/..\0".  We need to back up
4476                          * our destination pointer until we find a "/".
4477                          */
4478                         i--;
4479                         while (j != 0 && dest[--j] != '/')
4480                                 continue;
4481
4482                         if (c == '\0')
4483                                 dest[++j] = '/';
4484                 } while (c != '\0');
4485
4486                 dest[j] = '\0';
4487                 regs[rd] = (uintptr_t)dest;
4488                 mstate->dtms_scratch_ptr += size;
4489                 break;
4490         }
4491
4492         case DIF_SUBR_INET_NTOA:
4493         case DIF_SUBR_INET_NTOA6:
4494         case DIF_SUBR_INET_NTOP: {
4495                 size_t size;
4496                 int af, argi, i;
4497                 char *base, *end;
4498
4499                 if (subr == DIF_SUBR_INET_NTOP) {
4500                         af = (int)tupregs[0].dttk_value;
4501                         argi = 1;
4502                 } else {
4503                         af = subr == DIF_SUBR_INET_NTOA ? AF_INET: AF_INET6;
4504                         argi = 0;
4505                 }
4506
4507                 if (af == AF_INET) {
4508                         ipaddr_t ip4;
4509                         uint8_t *ptr8, val;
4510
4511                         /*
4512                          * Safely load the IPv4 address.
4513                          */
4514                         ip4 = dtrace_load32(tupregs[argi].dttk_value);
4515
4516                         /*
4517                          * Check an IPv4 string will fit in scratch.
4518                          */
4519                         size = INET_ADDRSTRLEN;
4520                         if (!DTRACE_INSCRATCH(mstate, size)) {
4521                                 DTRACE_CPUFLAG_SET(CPU_DTRACE_NOSCRATCH);
4522                                 regs[rd] = 0;
4523                                 break;
4524                         }
4525                         base = (char *)mstate->dtms_scratch_ptr;
4526                         end = (char *)mstate->dtms_scratch_ptr + size - 1;
4527
4528                         /*
4529                          * Stringify as a dotted decimal quad.
4530                          */
4531                         *end-- = '\0';
4532                         ptr8 = (uint8_t *)&ip4;
4533                         for (i = 3; i >= 0; i--) {
4534                                 val = ptr8[i];
4535
4536                                 if (val == 0) {
4537                                         *end-- = '0';
4538                                 } else {
4539                                         for (; val; val /= 10) {
4540                                                 *end-- = '0' + (val % 10);
4541                                         }
4542                                 }
4543
4544                                 if (i > 0)
4545                                         *end-- = '.';
4546                         }
4547                         ASSERT(end + 1 >= base);
4548
4549                 } else if (af == AF_INET6) {
4550                         struct in6_addr ip6;
4551                         int firstzero, tryzero, numzero, v6end;
4552                         uint16_t val;
4553                         const char digits[] = "0123456789abcdef";
4554
4555                         /*
4556                          * Stringify using RFC 1884 convention 2 - 16 bit
4557                          * hexadecimal values with a zero-run compression.
4558                          * Lower case hexadecimal digits are used.
4559                          *      eg, fe80::214:4fff:fe0b:76c8.
4560                          * The IPv4 embedded form is returned for inet_ntop,
4561                          * just the IPv4 string is returned for inet_ntoa6.
4562                          */
4563
4564                         /*
4565                          * Safely load the IPv6 address.
4566                          */
4567                         dtrace_bcopy(
4568                             (void *)(uintptr_t)tupregs[argi].dttk_value,
4569                             (void *)(uintptr_t)&ip6, sizeof (struct in6_addr));
4570
4571                         /*
4572                          * Check an IPv6 string will fit in scratch.
4573                          */
4574                         size = INET6_ADDRSTRLEN;
4575                         if (!DTRACE_INSCRATCH(mstate, size)) {
4576                                 DTRACE_CPUFLAG_SET(CPU_DTRACE_NOSCRATCH);
4577                                 regs[rd] = 0;
4578                                 break;
4579                         }
4580                         base = (char *)mstate->dtms_scratch_ptr;
4581                         end = (char *)mstate->dtms_scratch_ptr + size - 1;
4582                         *end-- = '\0';
4583
4584                         /*
4585                          * Find the longest run of 16 bit zero values
4586                          * for the single allowed zero compression - "::".
4587                          */
4588                         firstzero = -1;
4589                         tryzero = -1;
4590                         numzero = 1;
4591                         for (i = 0; i < sizeof (struct in6_addr); i++) {
4592 #if defined(sun)
4593                                 if (ip6._S6_un._S6_u8[i] == 0 &&
4594 #else
4595                                 if (ip6.__u6_addr.__u6_addr8[i] == 0 &&
4596 #endif
4597                                     tryzero == -1 && i % 2 == 0) {
4598                                         tryzero = i;
4599                                         continue;
4600                                 }
4601
4602                                 if (tryzero != -1 &&
4603 #if defined(sun)
4604                                     (ip6._S6_un._S6_u8[i] != 0 ||
4605 #else
4606                                     (ip6.__u6_addr.__u6_addr8[i] != 0 ||
4607 #endif
4608                                     i == sizeof (struct in6_addr) - 1)) {
4609
4610                                         if (i - tryzero <= numzero) {
4611                                                 tryzero = -1;
4612                                                 continue;
4613                                         }
4614
4615                                         firstzero = tryzero;
4616                                         numzero = i - i % 2 - tryzero;
4617                                         tryzero = -1;
4618
4619 #if defined(sun)
4620                                         if (ip6._S6_un._S6_u8[i] == 0 &&
4621 #else
4622                                         if (ip6.__u6_addr.__u6_addr8[i] == 0 &&
4623 #endif
4624                                             i == sizeof (struct in6_addr) - 1)
4625                                                 numzero += 2;
4626                                 }
4627                         }
4628                         ASSERT(firstzero + numzero <= sizeof (struct in6_addr));
4629
4630                         /*
4631                          * Check for an IPv4 embedded address.
4632                          */
4633                         v6end = sizeof (struct in6_addr) - 2;
4634                         if (IN6_IS_ADDR_V4MAPPED(&ip6) ||
4635                             IN6_IS_ADDR_V4COMPAT(&ip6)) {
4636                                 for (i = sizeof (struct in6_addr) - 1;
4637                                     i >= DTRACE_V4MAPPED_OFFSET; i--) {
4638                                         ASSERT(end >= base);
4639
4640 #if defined(sun)
4641                                         val = ip6._S6_un._S6_u8[i];
4642 #else
4643                                         val = ip6.__u6_addr.__u6_addr8[i];
4644 #endif
4645
4646                                         if (val == 0) {
4647                                                 *end-- = '0';
4648                                         } else {
4649                                                 for (; val; val /= 10) {
4650                                                         *end-- = '0' + val % 10;
4651                                                 }
4652                                         }
4653
4654                                         if (i > DTRACE_V4MAPPED_OFFSET)
4655                                                 *end-- = '.';
4656                                 }
4657
4658                                 if (subr == DIF_SUBR_INET_NTOA6)
4659                                         goto inetout;
4660
4661                                 /*
4662                                  * Set v6end to skip the IPv4 address that
4663                                  * we have already stringified.
4664                                  */
4665                                 v6end = 10;
4666                         }
4667
4668                         /*
4669                          * Build the IPv6 string by working through the
4670                          * address in reverse.
4671                          */
4672                         for (i = v6end; i >= 0; i -= 2) {
4673                                 ASSERT(end >= base);
4674
4675                                 if (i == firstzero + numzero - 2) {
4676                                         *end-- = ':';
4677                                         *end-- = ':';
4678                                         i -= numzero - 2;
4679                                         continue;
4680                                 }
4681
4682                                 if (i < 14 && i != firstzero - 2)
4683                                         *end-- = ':';
4684
4685 #if defined(sun)
4686                                 val = (ip6._S6_un._S6_u8[i] << 8) +
4687                                     ip6._S6_un._S6_u8[i + 1];
4688 #else
4689                                 val = (ip6.__u6_addr.__u6_addr8[i] << 8) +
4690                                     ip6.__u6_addr.__u6_addr8[i + 1];
4691 #endif
4692
4693                                 if (val == 0) {
4694                                         *end-- = '0';
4695                                 } else {
4696                                         for (; val; val /= 16) {
4697                                                 *end-- = digits[val % 16];
4698                                         }
4699                                 }
4700                         }
4701                         ASSERT(end + 1 >= base);
4702
4703                 } else {
4704                         /*
4705                          * The user didn't use AH_INET or AH_INET6.
4706                          */
4707                         DTRACE_CPUFLAG_SET(CPU_DTRACE_ILLOP);
4708                         regs[rd] = 0;
4709                         break;
4710                 }
4711
4712 inetout:        regs[rd] = (uintptr_t)end + 1;
4713                 mstate->dtms_scratch_ptr += size;
4714                 break;
4715         }
4716
4717         case DIF_SUBR_MEMREF: {
4718                 uintptr_t size = 2 * sizeof(uintptr_t);
4719                 uintptr_t *memref = (uintptr_t *) P2ROUNDUP(mstate->dtms_scratch_ptr, sizeof(uintptr_t));
4720                 size_t scratch_size = ((uintptr_t) memref - mstate->dtms_scratch_ptr) + size;
4721
4722                 /* address and length */
4723                 memref[0] = tupregs[0].dttk_value;
4724                 memref[1] = tupregs[1].dttk_value;
4725
4726                 regs[rd] = (uintptr_t) memref;
4727                 mstate->dtms_scratch_ptr += scratch_size;
4728                 break;
4729         }
4730
4731         case DIF_SUBR_TYPEREF: {
4732                 uintptr_t size = 4 * sizeof(uintptr_t);
4733                 uintptr_t *typeref = (uintptr_t *) P2ROUNDUP(mstate->dtms_scratch_ptr, sizeof(uintptr_t));
4734                 size_t scratch_size = ((uintptr_t) typeref - mstate->dtms_scratch_ptr) + size;
4735
4736                 /* address, num_elements, type_str, type_len */
4737                 typeref[0] = tupregs[0].dttk_value;
4738                 typeref[1] = tupregs[1].dttk_value;
4739                 typeref[2] = tupregs[2].dttk_value;
4740                 typeref[3] = tupregs[3].dttk_value;
4741
4742                 regs[rd] = (uintptr_t) typeref;
4743                 mstate->dtms_scratch_ptr += scratch_size;
4744                 break;
4745         }
4746         }
4747 }
4748
4749 /*
4750  * Emulate the execution of DTrace IR instructions specified by the given
4751  * DIF object.  This function is deliberately void of assertions as all of
4752  * the necessary checks are handled by a call to dtrace_difo_validate().
4753  */
4754 static uint64_t
4755 dtrace_dif_emulate(dtrace_difo_t *difo, dtrace_mstate_t *mstate,
4756     dtrace_vstate_t *vstate, dtrace_state_t *state)
4757 {
4758         const dif_instr_t *text = difo->dtdo_buf;
4759         const uint_t textlen = difo->dtdo_len;
4760         const char *strtab = difo->dtdo_strtab;
4761         const uint64_t *inttab = difo->dtdo_inttab;
4762
4763         uint64_t rval = 0;
4764         dtrace_statvar_t *svar;
4765         dtrace_dstate_t *dstate = &vstate->dtvs_dynvars;
4766         dtrace_difv_t *v;
4767         volatile uint16_t *flags = &cpu_core[curcpu].cpuc_dtrace_flags;
4768         volatile uintptr_t *illval = &cpu_core[curcpu].cpuc_dtrace_illval;
4769
4770         dtrace_key_t tupregs[DIF_DTR_NREGS + 2]; /* +2 for thread and id */
4771         uint64_t regs[DIF_DIR_NREGS];
4772         uint64_t *tmp;
4773
4774         uint8_t cc_n = 0, cc_z = 0, cc_v = 0, cc_c = 0;
4775         int64_t cc_r;
4776         uint_t pc = 0, id, opc = 0;
4777         uint8_t ttop = 0;
4778         dif_instr_t instr;
4779         uint_t r1, r2, rd;
4780
4781         /*
4782          * We stash the current DIF object into the machine state: we need it
4783          * for subsequent access checking.
4784          */
4785         mstate->dtms_difo = difo;
4786
4787         regs[DIF_REG_R0] = 0;           /* %r0 is fixed at zero */
4788
4789         while (pc < textlen && !(*flags & CPU_DTRACE_FAULT)) {
4790                 opc = pc;
4791
4792                 instr = text[pc++];
4793                 r1 = DIF_INSTR_R1(instr);
4794                 r2 = DIF_INSTR_R2(instr);
4795                 rd = DIF_INSTR_RD(instr);
4796
4797                 switch (DIF_INSTR_OP(instr)) {
4798                 case DIF_OP_OR:
4799                         regs[rd] = regs[r1] | regs[r2];
4800                         break;
4801                 case DIF_OP_XOR:
4802                         regs[rd] = regs[r1] ^ regs[r2];
4803                         break;
4804                 case DIF_OP_AND:
4805                         regs[rd] = regs[r1] & regs[r2];
4806                         break;
4807                 case DIF_OP_SLL:
4808                         regs[rd] = regs[r1] << regs[r2];
4809                         break;
4810                 case DIF_OP_SRL:
4811                         regs[rd] = regs[r1] >> regs[r2];
4812                         break;
4813                 case DIF_OP_SUB:
4814                         regs[rd] = regs[r1] - regs[r2];
4815                         break;
4816                 case DIF_OP_ADD:
4817                         regs[rd] = regs[r1] + regs[r2];
4818                         break;
4819                 case DIF_OP_MUL:
4820                         regs[rd] = regs[r1] * regs[r2];
4821                         break;
4822                 case DIF_OP_SDIV:
4823                         if (regs[r2] == 0) {
4824                                 regs[rd] = 0;
4825                                 *flags |= CPU_DTRACE_DIVZERO;
4826                         } else {
4827                                 regs[rd] = (int64_t)regs[r1] /
4828                                     (int64_t)regs[r2];
4829                         }
4830                         break;
4831
4832                 case DIF_OP_UDIV:
4833                         if (regs[r2] == 0) {
4834                                 regs[rd] = 0;
4835                                 *flags |= CPU_DTRACE_DIVZERO;
4836                         } else {
4837                                 regs[rd] = regs[r1] / regs[r2];
4838                         }
4839                         break;
4840
4841                 case DIF_OP_SREM:
4842                         if (regs[r2] == 0) {
4843                                 regs[rd] = 0;
4844                                 *flags |= CPU_DTRACE_DIVZERO;
4845                         } else {
4846                                 regs[rd] = (int64_t)regs[r1] %
4847                                     (int64_t)regs[r2];
4848                         }
4849                         break;
4850
4851                 case DIF_OP_UREM:
4852                         if (regs[r2] == 0) {
4853                                 regs[rd] = 0;
4854                                 *flags |= CPU_DTRACE_DIVZERO;
4855                         } else {
4856                                 regs[rd] = regs[r1] % regs[r2];
4857                         }
4858                         break;
4859
4860                 case DIF_OP_NOT:
4861                         regs[rd] = ~regs[r1];
4862                         break;
4863                 case DIF_OP_MOV:
4864                         regs[rd] = regs[r1];
4865                         break;
4866                 case DIF_OP_CMP:
4867                         cc_r = regs[r1] - regs[r2];
4868                         cc_n = cc_r < 0;
4869                         cc_z = cc_r == 0;
4870                         cc_v = 0;
4871                         cc_c = regs[r1] < regs[r2];
4872                         break;
4873                 case DIF_OP_TST:
4874                         cc_n = cc_v = cc_c = 0;
4875                         cc_z = regs[r1] == 0;
4876                         break;
4877                 case DIF_OP_BA:
4878                         pc = DIF_INSTR_LABEL(instr);
4879                         break;
4880                 case DIF_OP_BE:
4881                         if (cc_z)
4882                                 pc = DIF_INSTR_LABEL(instr);
4883                         break;
4884                 case DIF_OP_BNE:
4885                         if (cc_z == 0)
4886                                 pc = DIF_INSTR_LABEL(instr);
4887                         break;
4888                 case DIF_OP_BG:
4889                         if ((cc_z | (cc_n ^ cc_v)) == 0)
4890                                 pc = DIF_INSTR_LABEL(instr);
4891                         break;
4892                 case DIF_OP_BGU:
4893                         if ((cc_c | cc_z) == 0)
4894                                 pc = DIF_INSTR_LABEL(instr);
4895                         break;
4896                 case DIF_OP_BGE:
4897                         if ((cc_n ^ cc_v) == 0)
4898                                 pc = DIF_INSTR_LABEL(instr);
4899                         break;
4900                 case DIF_OP_BGEU:
4901                         if (cc_c == 0)
4902                                 pc = DIF_INSTR_LABEL(instr);
4903                         break;
4904                 case DIF_OP_BL:
4905                         if (cc_n ^ cc_v)
4906                                 pc = DIF_INSTR_LABEL(instr);
4907                         break;
4908                 case DIF_OP_BLU:
4909                         if (cc_c)
4910                                 pc = DIF_INSTR_LABEL(instr);
4911                         break;
4912                 case DIF_OP_BLE:
4913                         if (cc_z | (cc_n ^ cc_v))
4914                                 pc = DIF_INSTR_LABEL(instr);
4915                         break;
4916                 case DIF_OP_BLEU:
4917                         if (cc_c | cc_z)
4918                                 pc = DIF_INSTR_LABEL(instr);
4919                         break;
4920                 case DIF_OP_RLDSB:
4921                         if (!dtrace_canstore(regs[r1], 1, mstate, vstate)) {
4922                                 *flags |= CPU_DTRACE_KPRIV;
4923                                 *illval = regs[r1];
4924                                 break;
4925                         }
4926                         /*FALLTHROUGH*/
4927                 case DIF_OP_LDSB:
4928                         regs[rd] = (int8_t)dtrace_load8(regs[r1]);
4929                         break;
4930                 case DIF_OP_RLDSH:
4931                         if (!dtrace_canstore(regs[r1], 2, mstate, vstate)) {
4932                                 *flags |= CPU_DTRACE_KPRIV;
4933                                 *illval = regs[r1];
4934                                 break;
4935                         }
4936                         /*FALLTHROUGH*/
4937                 case DIF_OP_LDSH:
4938                         regs[rd] = (int16_t)dtrace_load16(regs[r1]);
4939                         break;
4940                 case DIF_OP_RLDSW:
4941                         if (!dtrace_canstore(regs[r1], 4, mstate, vstate)) {
4942                                 *flags |= CPU_DTRACE_KPRIV;
4943                                 *illval = regs[r1];
4944                                 break;
4945                         }
4946                         /*FALLTHROUGH*/
4947                 case DIF_OP_LDSW:
4948                         regs[rd] = (int32_t)dtrace_load32(regs[r1]);
4949                         break;
4950                 case DIF_OP_RLDUB:
4951                         if (!dtrace_canstore(regs[r1], 1, mstate, vstate)) {
4952                                 *flags |= CPU_DTRACE_KPRIV;
4953                                 *illval = regs[r1];
4954                                 break;
4955                         }
4956                         /*FALLTHROUGH*/
4957                 case DIF_OP_LDUB:
4958                         regs[rd] = dtrace_load8(regs[r1]);
4959                         break;
4960                 case DIF_OP_RLDUH:
4961                         if (!dtrace_canstore(regs[r1], 2, mstate, vstate)) {
4962                                 *flags |= CPU_DTRACE_KPRIV;
4963                                 *illval = regs[r1];
4964                                 break;
4965                         }
4966                         /*FALLTHROUGH*/
4967                 case DIF_OP_LDUH:
4968                         regs[rd] = dtrace_load16(regs[r1]);
4969                         break;
4970                 case DIF_OP_RLDUW:
4971                         if (!dtrace_canstore(regs[r1], 4, mstate, vstate)) {
4972                                 *flags |= CPU_DTRACE_KPRIV;
4973                                 *illval = regs[r1];
4974                                 break;
4975                         }
4976                         /*FALLTHROUGH*/
4977                 case DIF_OP_LDUW:
4978                         regs[rd] = dtrace_load32(regs[r1]);
4979                         break;
4980                 case DIF_OP_RLDX:
4981                         if (!dtrace_canstore(regs[r1], 8, mstate, vstate)) {
4982                                 *flags |= CPU_DTRACE_KPRIV;
4983                                 *illval = regs[r1];
4984                                 break;
4985                         }
4986                         /*FALLTHROUGH*/
4987                 case DIF_OP_LDX:
4988                         regs[rd] = dtrace_load64(regs[r1]);
4989                         break;
4990                 case DIF_OP_ULDSB:
4991                         regs[rd] = (int8_t)
4992                             dtrace_fuword8((void *)(uintptr_t)regs[r1]);
4993                         break;
4994                 case DIF_OP_ULDSH:
4995                         regs[rd] = (int16_t)
4996                             dtrace_fuword16((void *)(uintptr_t)regs[r1]);
4997                         break;
4998                 case DIF_OP_ULDSW:
4999                         regs[rd] = (int32_t)
5000                             dtrace_fuword32((void *)(uintptr_t)regs[r1]);
5001                         break;
5002                 case DIF_OP_ULDUB:
5003                         regs[rd] =
5004                             dtrace_fuword8((void *)(uintptr_t)regs[r1]);
5005                         break;
5006                 case DIF_OP_ULDUH:
5007                         regs[rd] =
5008                             dtrace_fuword16((void *)(uintptr_t)regs[r1]);
5009                         break;
5010                 case DIF_OP_ULDUW:
5011                         regs[rd] =
5012                             dtrace_fuword32((void *)(uintptr_t)regs[r1]);
5013                         break;
5014                 case DIF_OP_ULDX:
5015                         regs[rd] =
5016                             dtrace_fuword64((void *)(uintptr_t)regs[r1]);
5017                         break;
5018                 case DIF_OP_RET:
5019                         rval = regs[rd];
5020                         pc = textlen;
5021                         break;
5022                 case DIF_OP_NOP:
5023                         break;
5024                 case DIF_OP_SETX:
5025                         regs[rd] = inttab[DIF_INSTR_INTEGER(instr)];
5026                         break;
5027                 case DIF_OP_SETS:
5028                         regs[rd] = (uint64_t)(uintptr_t)
5029                             (strtab + DIF_INSTR_STRING(instr));
5030                         break;
5031                 case DIF_OP_SCMP: {
5032                         size_t sz = state->dts_options[DTRACEOPT_STRSIZE];
5033                         uintptr_t s1 = regs[r1];
5034                         uintptr_t s2 = regs[r2];
5035
5036                         if (s1 != 0 &&
5037                             !dtrace_strcanload(s1, sz, mstate, vstate))
5038                                 break;
5039                         if (s2 != 0 &&
5040                             !dtrace_strcanload(s2, sz, mstate, vstate))
5041                                 break;
5042
5043                         cc_r = dtrace_strncmp((char *)s1, (char *)s2, sz);
5044
5045                         cc_n = cc_r < 0;
5046                         cc_z = cc_r == 0;
5047                         cc_v = cc_c = 0;
5048                         break;
5049                 }
5050                 case DIF_OP_LDGA:
5051                         regs[rd] = dtrace_dif_variable(mstate, state,
5052                             r1, regs[r2]);
5053                         break;
5054                 case DIF_OP_LDGS:
5055                         id = DIF_INSTR_VAR(instr);
5056
5057                         if (id >= DIF_VAR_OTHER_UBASE) {
5058                                 uintptr_t a;
5059
5060                                 id -= DIF_VAR_OTHER_UBASE;
5061                                 svar = vstate->dtvs_globals[id];
5062                                 ASSERT(svar != NULL);
5063                                 v = &svar->dtsv_var;
5064
5065                                 if (!(v->dtdv_type.dtdt_flags & DIF_TF_BYREF)) {
5066                                         regs[rd] = svar->dtsv_data;
5067                                         break;
5068                                 }
5069
5070                                 a = (uintptr_t)svar->dtsv_data;
5071
5072                                 if (*(uint8_t *)a == UINT8_MAX) {
5073                                         /*
5074                                          * If the 0th byte is set to UINT8_MAX
5075                                          * then this is to be treated as a
5076                                          * reference to a NULL variable.
5077                                          */
5078                                         regs[rd] = 0;
5079                                 } else {
5080                                         regs[rd] = a + sizeof (uint64_t);
5081                                 }
5082
5083                                 break;
5084                         }
5085
5086                         regs[rd] = dtrace_dif_variable(mstate, state, id, 0);
5087                         break;
5088
5089                 case DIF_OP_STGS:
5090                         id = DIF_INSTR_VAR(instr);
5091
5092                         ASSERT(id >= DIF_VAR_OTHER_UBASE);
5093                         id -= DIF_VAR_OTHER_UBASE;
5094
5095                         svar = vstate->dtvs_globals[id];
5096                         ASSERT(svar != NULL);
5097                         v = &svar->dtsv_var;
5098
5099                         if (v->dtdv_type.dtdt_flags & DIF_TF_BYREF) {
5100                                 uintptr_t a = (uintptr_t)svar->dtsv_data;
5101
5102                                 ASSERT(a != 0);
5103                                 ASSERT(svar->dtsv_size != 0);
5104
5105                                 if (regs[rd] == 0) {
5106                                         *(uint8_t *)a = UINT8_MAX;
5107                                         break;
5108                                 } else {
5109                                         *(uint8_t *)a = 0;
5110                                         a += sizeof (uint64_t);
5111                                 }
5112                                 if (!dtrace_vcanload(
5113                                     (void *)(uintptr_t)regs[rd], &v->dtdv_type,
5114                                     mstate, vstate))
5115                                         break;
5116
5117                                 dtrace_vcopy((void *)(uintptr_t)regs[rd],
5118                                     (void *)a, &v->dtdv_type);
5119                                 break;
5120                         }
5121
5122                         svar->dtsv_data = regs[rd];
5123                         break;
5124
5125                 case DIF_OP_LDTA:
5126                         /*
5127                          * There are no DTrace built-in thread-local arrays at
5128                          * present.  This opcode is saved for future work.
5129                          */
5130                         *flags |= CPU_DTRACE_ILLOP;
5131                         regs[rd] = 0;
5132                         break;
5133
5134                 case DIF_OP_LDLS:
5135                         id = DIF_INSTR_VAR(instr);
5136
5137                         if (id < DIF_VAR_OTHER_UBASE) {
5138                                 /*
5139                                  * For now, this has no meaning.
5140                                  */
5141                                 regs[rd] = 0;
5142                                 break;
5143                         }
5144
5145                         id -= DIF_VAR_OTHER_UBASE;
5146
5147                         ASSERT(id < vstate->dtvs_nlocals);
5148                         ASSERT(vstate->dtvs_locals != NULL);
5149
5150                         svar = vstate->dtvs_locals[id];
5151                         ASSERT(svar != NULL);
5152                         v = &svar->dtsv_var;
5153
5154                         if (v->dtdv_type.dtdt_flags & DIF_TF_BYREF) {
5155                                 uintptr_t a = (uintptr_t)svar->dtsv_data;
5156                                 size_t sz = v->dtdv_type.dtdt_size;
5157
5158                                 sz += sizeof (uint64_t);
5159                                 ASSERT(svar->dtsv_size == NCPU * sz);
5160                                 a += curcpu * sz;
5161
5162                                 if (*(uint8_t *)a == UINT8_MAX) {
5163                                         /*
5164                                          * If the 0th byte is set to UINT8_MAX
5165                                          * then this is to be treated as a
5166                                          * reference to a NULL variable.
5167                                          */
5168                                         regs[rd] = 0;
5169                                 } else {
5170                                         regs[rd] = a + sizeof (uint64_t);
5171                                 }
5172
5173                                 break;
5174                         }
5175
5176                         ASSERT(svar->dtsv_size == NCPU * sizeof (uint64_t));
5177                         tmp = (uint64_t *)(uintptr_t)svar->dtsv_data;
5178                         regs[rd] = tmp[curcpu];
5179                         break;
5180
5181                 case DIF_OP_STLS:
5182                         id = DIF_INSTR_VAR(instr);
5183
5184                         ASSERT(id >= DIF_VAR_OTHER_UBASE);
5185                         id -= DIF_VAR_OTHER_UBASE;
5186                         ASSERT(id < vstate->dtvs_nlocals);
5187
5188                         ASSERT(vstate->dtvs_locals != NULL);
5189                         svar = vstate->dtvs_locals[id];
5190                         ASSERT(svar != NULL);
5191                         v = &svar->dtsv_var;
5192
5193                         if (v->dtdv_type.dtdt_flags & DIF_TF_BYREF) {
5194                                 uintptr_t a = (uintptr_t)svar->dtsv_data;
5195                                 size_t sz = v->dtdv_type.dtdt_size;
5196
5197                                 sz += sizeof (uint64_t);
5198                                 ASSERT(svar->dtsv_size == NCPU * sz);
5199                                 a += curcpu * sz;
5200
5201                                 if (regs[rd] == 0) {
5202                                         *(uint8_t *)a = UINT8_MAX;
5203                                         break;
5204                                 } else {
5205                                         *(uint8_t *)a = 0;
5206                                         a += sizeof (uint64_t);
5207                                 }
5208
5209                                 if (!dtrace_vcanload(
5210                                     (void *)(uintptr_t)regs[rd], &v->dtdv_type,
5211                                     mstate, vstate))
5212                                         break;
5213
5214                                 dtrace_vcopy((void *)(uintptr_t)regs[rd],
5215                                     (void *)a, &v->dtdv_type);
5216                                 break;
5217                         }
5218
5219                         ASSERT(svar->dtsv_size == NCPU * sizeof (uint64_t));
5220                         tmp = (uint64_t *)(uintptr_t)svar->dtsv_data;
5221                         tmp[curcpu] = regs[rd];
5222                         break;
5223
5224                 case DIF_OP_LDTS: {
5225                         dtrace_dynvar_t *dvar;
5226                         dtrace_key_t *key;
5227
5228                         id = DIF_INSTR_VAR(instr);
5229                         ASSERT(id >= DIF_VAR_OTHER_UBASE);
5230                         id -= DIF_VAR_OTHER_UBASE;
5231                         v = &vstate->dtvs_tlocals[id];
5232
5233                         key = &tupregs[DIF_DTR_NREGS];
5234                         key[0].dttk_value = (uint64_t)id;
5235                         key[0].dttk_size = 0;
5236                         DTRACE_TLS_THRKEY(key[1].dttk_value);
5237                         key[1].dttk_size = 0;
5238
5239                         dvar = dtrace_dynvar(dstate, 2, key,
5240                             sizeof (uint64_t), DTRACE_DYNVAR_NOALLOC,
5241                             mstate, vstate);
5242
5243                         if (dvar == NULL) {
5244                                 regs[rd] = 0;
5245                                 break;
5246                         }
5247
5248                         if (v->dtdv_type.dtdt_flags & DIF_TF_BYREF) {
5249                                 regs[rd] = (uint64_t)(uintptr_t)dvar->dtdv_data;
5250                         } else {
5251                                 regs[rd] = *((uint64_t *)dvar->dtdv_data);
5252                         }
5253
5254                         break;
5255                 }
5256
5257                 case DIF_OP_STTS: {
5258                         dtrace_dynvar_t *dvar;
5259                         dtrace_key_t *key;
5260
5261                         id = DIF_INSTR_VAR(instr);
5262                         ASSERT(id >= DIF_VAR_OTHER_UBASE);
5263                         id -= DIF_VAR_OTHER_UBASE;
5264
5265                         key = &tupregs[DIF_DTR_NREGS];
5266                         key[0].dttk_value = (uint64_t)id;
5267                         key[0].dttk_size = 0;
5268                         DTRACE_TLS_THRKEY(key[1].dttk_value);
5269                         key[1].dttk_size = 0;
5270                         v = &vstate->dtvs_tlocals[id];
5271
5272                         dvar = dtrace_dynvar(dstate, 2, key,
5273                             v->dtdv_type.dtdt_size > sizeof (uint64_t) ?
5274                             v->dtdv_type.dtdt_size : sizeof (uint64_t),
5275                             regs[rd] ? DTRACE_DYNVAR_ALLOC :
5276                             DTRACE_DYNVAR_DEALLOC, mstate, vstate);
5277
5278                         /*
5279                          * Given that we're storing to thread-local data,
5280                          * we need to flush our predicate cache.
5281                          */
5282                         curthread->t_predcache = 0;
5283
5284                         if (dvar == NULL)
5285                                 break;
5286
5287                         if (v->dtdv_type.dtdt_flags & DIF_TF_BYREF) {
5288                                 if (!dtrace_vcanload(
5289                                     (void *)(uintptr_t)regs[rd],
5290                                     &v->dtdv_type, mstate, vstate))
5291                                         break;
5292
5293                                 dtrace_vcopy((void *)(uintptr_t)regs[rd],
5294                                     dvar->dtdv_data, &v->dtdv_type);
5295                         } else {
5296                                 *((uint64_t *)dvar->dtdv_data) = regs[rd];
5297                         }
5298
5299                         break;
5300                 }
5301
5302                 case DIF_OP_SRA:
5303                         regs[rd] = (int64_t)regs[r1] >> regs[r2];
5304                         break;
5305
5306                 case DIF_OP_CALL:
5307                         dtrace_dif_subr(DIF_INSTR_SUBR(instr), rd,
5308                             regs, tupregs, ttop, mstate, state);
5309                         break;
5310
5311                 case DIF_OP_PUSHTR:
5312                         if (ttop == DIF_DTR_NREGS) {
5313                                 *flags |= CPU_DTRACE_TUPOFLOW;
5314                                 break;
5315                         }
5316
5317                         if (r1 == DIF_TYPE_STRING) {
5318                                 /*
5319                                  * If this is a string type and the size is 0,
5320                                  * we'll use the system-wide default string
5321                                  * size.  Note that we are _not_ looking at
5322                                  * the value of the DTRACEOPT_STRSIZE option;
5323                                  * had this been set, we would expect to have
5324                                  * a non-zero size value in the "pushtr".
5325                                  */
5326                                 tupregs[ttop].dttk_size =
5327                                     dtrace_strlen((char *)(uintptr_t)regs[rd],
5328                                     regs[r2] ? regs[r2] :
5329                                     dtrace_strsize_default) + 1;
5330                         } else {
5331                                 tupregs[ttop].dttk_size = regs[r2];
5332                         }
5333
5334                         tupregs[ttop++].dttk_value = regs[rd];
5335                         break;
5336
5337                 case DIF_OP_PUSHTV:
5338                         if (ttop == DIF_DTR_NREGS) {
5339                                 *flags |= CPU_DTRACE_TUPOFLOW;
5340                                 break;
5341                         }
5342
5343                         tupregs[ttop].dttk_value = regs[rd];
5344                         tupregs[ttop++].dttk_size = 0;
5345                         break;
5346
5347                 case DIF_OP_POPTS:
5348                         if (ttop != 0)
5349                                 ttop--;
5350                         break;
5351
5352                 case DIF_OP_FLUSHTS:
5353                         ttop = 0;
5354                         break;
5355
5356                 case DIF_OP_LDGAA:
5357                 case DIF_OP_LDTAA: {
5358                         dtrace_dynvar_t *dvar;
5359                         dtrace_key_t *key = tupregs;
5360                         uint_t nkeys = ttop;
5361
5362                         id = DIF_INSTR_VAR(instr);
5363                         ASSERT(id >= DIF_VAR_OTHER_UBASE);
5364                         id -= DIF_VAR_OTHER_UBASE;
5365
5366                         key[nkeys].dttk_value = (uint64_t)id;
5367                         key[nkeys++].dttk_size = 0;
5368
5369                         if (DIF_INSTR_OP(instr) == DIF_OP_LDTAA) {
5370                                 DTRACE_TLS_THRKEY(key[nkeys].dttk_value);
5371                                 key[nkeys++].dttk_size = 0;
5372                                 v = &vstate->dtvs_tlocals[id];
5373                         } else {
5374                                 v = &vstate->dtvs_globals[id]->dtsv_var;
5375                         }
5376
5377                         dvar = dtrace_dynvar(dstate, nkeys, key,
5378                             v->dtdv_type.dtdt_size > sizeof (uint64_t) ?
5379                             v->dtdv_type.dtdt_size : sizeof (uint64_t),
5380                             DTRACE_DYNVAR_NOALLOC, mstate, vstate);
5381
5382                         if (dvar == NULL) {
5383                                 regs[rd] = 0;
5384                                 break;
5385                         }
5386
5387                         if (v->dtdv_type.dtdt_flags & DIF_TF_BYREF) {
5388                                 regs[rd] = (uint64_t)(uintptr_t)dvar->dtdv_data;
5389                         } else {
5390                                 regs[rd] = *((uint64_t *)dvar->dtdv_data);
5391                         }
5392
5393                         break;
5394                 }
5395
5396                 case DIF_OP_STGAA:
5397                 case DIF_OP_STTAA: {
5398                         dtrace_dynvar_t *dvar;
5399                         dtrace_key_t *key = tupregs;
5400                         uint_t nkeys = ttop;
5401
5402                         id = DIF_INSTR_VAR(instr);
5403                         ASSERT(id >= DIF_VAR_OTHER_UBASE);
5404                         id -= DIF_VAR_OTHER_UBASE;
5405
5406                         key[nkeys].dttk_value = (uint64_t)id;
5407                         key[nkeys++].dttk_size = 0;
5408
5409                         if (DIF_INSTR_OP(instr) == DIF_OP_STTAA) {
5410                                 DTRACE_TLS_THRKEY(key[nkeys].dttk_value);
5411                                 key[nkeys++].dttk_size = 0;
5412                                 v = &vstate->dtvs_tlocals[id];
5413                         } else {
5414                                 v = &vstate->dtvs_globals[id]->dtsv_var;
5415                         }
5416
5417                         dvar = dtrace_dynvar(dstate, nkeys, key,
5418                             v->dtdv_type.dtdt_size > sizeof (uint64_t) ?
5419                             v->dtdv_type.dtdt_size : sizeof (uint64_t),
5420                             regs[rd] ? DTRACE_DYNVAR_ALLOC :
5421                             DTRACE_DYNVAR_DEALLOC, mstate, vstate);
5422
5423                         if (dvar == NULL)
5424                                 break;
5425
5426                         if (v->dtdv_type.dtdt_flags & DIF_TF_BYREF) {
5427                                 if (!dtrace_vcanload(
5428                                     (void *)(uintptr_t)regs[rd], &v->dtdv_type,
5429                                     mstate, vstate))
5430                                         break;
5431
5432                                 dtrace_vcopy((void *)(uintptr_t)regs[rd],
5433                                     dvar->dtdv_data, &v->dtdv_type);
5434                         } else {
5435                                 *((uint64_t *)dvar->dtdv_data) = regs[rd];
5436                         }
5437
5438                         break;
5439                 }
5440
5441                 case DIF_OP_ALLOCS: {
5442                         uintptr_t ptr = P2ROUNDUP(mstate->dtms_scratch_ptr, 8);
5443                         size_t size = ptr - mstate->dtms_scratch_ptr + regs[r1];
5444
5445                         /*
5446                          * Rounding up the user allocation size could have
5447                          * overflowed large, bogus allocations (like -1ULL) to
5448                          * 0.
5449                          */
5450                         if (size < regs[r1] ||
5451                             !DTRACE_INSCRATCH(mstate, size)) {
5452                                 DTRACE_CPUFLAG_SET(CPU_DTRACE_NOSCRATCH);
5453                                 regs[rd] = 0;
5454                                 break;
5455                         }
5456
5457                         dtrace_bzero((void *) mstate->dtms_scratch_ptr, size);
5458                         mstate->dtms_scratch_ptr += size;
5459                         regs[rd] = ptr;
5460                         break;
5461                 }
5462
5463                 case DIF_OP_COPYS:
5464                         if (!dtrace_canstore(regs[rd], regs[r2],
5465                             mstate, vstate)) {
5466                                 *flags |= CPU_DTRACE_BADADDR;
5467                                 *illval = regs[rd];
5468                                 break;
5469                         }
5470
5471                         if (!dtrace_canload(regs[r1], regs[r2], mstate, vstate))
5472                                 break;
5473
5474                         dtrace_bcopy((void *)(uintptr_t)regs[r1],
5475                             (void *)(uintptr_t)regs[rd], (size_t)regs[r2]);
5476                         break;
5477
5478                 case DIF_OP_STB:
5479                         if (!dtrace_canstore(regs[rd], 1, mstate, vstate)) {
5480                                 *flags |= CPU_DTRACE_BADADDR;
5481                                 *illval = regs[rd];
5482                                 break;
5483                         }
5484                         *((uint8_t *)(uintptr_t)regs[rd]) = (uint8_t)regs[r1];
5485                         break;
5486
5487                 case DIF_OP_STH:
5488                         if (!dtrace_canstore(regs[rd], 2, mstate, vstate)) {
5489                                 *flags |= CPU_DTRACE_BADADDR;
5490                                 *illval = regs[rd];
5491                                 break;
5492                         }
5493                         if (regs[rd] & 1) {
5494                                 *flags |= CPU_DTRACE_BADALIGN;
5495                                 *illval = regs[rd];
5496                                 break;
5497                         }
5498                         *((uint16_t *)(uintptr_t)regs[rd]) = (uint16_t)regs[r1];
5499                         break;
5500
5501                 case DIF_OP_STW:
5502                         if (!dtrace_canstore(regs[rd], 4, mstate, vstate)) {
5503                                 *flags |= CPU_DTRACE_BADADDR;
5504                                 *illval = regs[rd];
5505                                 break;
5506                         }
5507                         if (regs[rd] & 3) {
5508                                 *flags |= CPU_DTRACE_BADALIGN;
5509                                 *illval = regs[rd];
5510                                 break;
5511                         }
5512                         *((uint32_t *)(uintptr_t)regs[rd]) = (uint32_t)regs[r1];
5513                         break;
5514
5515                 case DIF_OP_STX:
5516                         if (!dtrace_canstore(regs[rd], 8, mstate, vstate)) {
5517                                 *flags |= CPU_DTRACE_BADADDR;
5518                                 *illval = regs[rd];
5519                                 break;
5520                         }
5521                         if (regs[rd] & 7) {
5522                                 *flags |= CPU_DTRACE_BADALIGN;
5523                                 *illval = regs[rd];
5524                                 break;
5525                         }
5526                         *((uint64_t *)(uintptr_t)regs[rd]) = regs[r1];
5527                         break;
5528                 }
5529         }
5530
5531         if (!(*flags & CPU_DTRACE_FAULT))
5532                 return (rval);
5533
5534         mstate->dtms_fltoffs = opc * sizeof (dif_instr_t);
5535         mstate->dtms_present |= DTRACE_MSTATE_FLTOFFS;
5536
5537         return (0);
5538 }
5539
5540 static void
5541 dtrace_action_breakpoint(dtrace_ecb_t *ecb)
5542 {
5543         dtrace_probe_t *probe = ecb->dte_probe;
5544         dtrace_provider_t *prov = probe->dtpr_provider;
5545         char c[DTRACE_FULLNAMELEN + 80], *str;
5546         char *msg = "dtrace: breakpoint action at probe ";
5547         char *ecbmsg = " (ecb ";
5548         uintptr_t mask = (0xf << (sizeof (uintptr_t) * NBBY / 4));
5549         uintptr_t val = (uintptr_t)ecb;
5550         int shift = (sizeof (uintptr_t) * NBBY) - 4, i = 0;
5551
5552         if (dtrace_destructive_disallow)
5553                 return;
5554
5555         /*
5556          * It's impossible to be taking action on the NULL probe.
5557          */
5558         ASSERT(probe != NULL);
5559
5560         /*
5561          * This is a poor man's (destitute man's?) sprintf():  we want to
5562          * print the provider name, module name, function name and name of
5563          * the probe, along with the hex address of the ECB with the breakpoint
5564          * action -- all of which we must place in the character buffer by
5565          * hand.
5566          */
5567         while (*msg != '\0')
5568                 c[i++] = *msg++;
5569
5570         for (str = prov->dtpv_name; *str != '\0'; str++)
5571                 c[i++] = *str;
5572         c[i++] = ':';
5573
5574         for (str = probe->dtpr_mod; *str != '\0'; str++)
5575                 c[i++] = *str;
5576         c[i++] = ':';
5577
5578         for (str = probe->dtpr_func; *str != '\0'; str++)
5579                 c[i++] = *str;
5580         c[i++] = ':';
5581
5582         for (str = probe->dtpr_name; *str != '\0'; str++)
5583                 c[i++] = *str;
5584
5585         while (*ecbmsg != '\0')
5586                 c[i++] = *ecbmsg++;
5587
5588         while (shift >= 0) {
5589                 mask = (uintptr_t)0xf << shift;
5590
5591                 if (val >= ((uintptr_t)1 << shift))
5592                         c[i++] = "0123456789abcdef"[(val & mask) >> shift];
5593                 shift -= 4;
5594         }
5595
5596         c[i++] = ')';
5597         c[i] = '\0';
5598
5599 #if defined(sun)
5600         debug_enter(c);
5601 #else
5602         kdb_enter_why(KDB_WHY_DTRACE, "breakpoint action");
5603 #endif
5604 }
5605
5606 static void
5607 dtrace_action_panic(dtrace_ecb_t *ecb)
5608 {
5609         dtrace_probe_t *probe = ecb->dte_probe;
5610
5611         /*
5612          * It's impossible to be taking action on the NULL probe.
5613          */
5614         ASSERT(probe != NULL);
5615
5616         if (dtrace_destructive_disallow)
5617                 return;
5618
5619         if (dtrace_panicked != NULL)
5620                 return;
5621
5622         if (dtrace_casptr(&dtrace_panicked, NULL, curthread) != NULL)
5623                 return;
5624
5625         /*
5626          * We won the right to panic.  (We want to be sure that only one
5627          * thread calls panic() from dtrace_probe(), and that panic() is
5628          * called exactly once.)
5629          */
5630         dtrace_panic("dtrace: panic action at probe %s:%s:%s:%s (ecb %p)",
5631             probe->dtpr_provider->dtpv_name, probe->dtpr_mod,
5632             probe->dtpr_func, probe->dtpr_name, (void *)ecb);
5633 }
5634
5635 static void
5636 dtrace_action_raise(uint64_t sig)
5637 {
5638         if (dtrace_destructive_disallow)
5639                 return;
5640
5641         if (sig >= NSIG) {
5642                 DTRACE_CPUFLAG_SET(CPU_DTRACE_ILLOP);
5643                 return;
5644         }
5645
5646 #if defined(sun)
5647         /*
5648          * raise() has a queue depth of 1 -- we ignore all subsequent
5649          * invocations of the raise() action.
5650          */
5651         if (curthread->t_dtrace_sig == 0)
5652                 curthread->t_dtrace_sig = (uint8_t)sig;
5653
5654         curthread->t_sig_check = 1;
5655         aston(curthread);
5656 #else
5657         struct proc *p = curproc;
5658         PROC_LOCK(p);
5659         psignal(p, sig);
5660         PROC_UNLOCK(p);
5661 #endif
5662 }
5663
5664 static void
5665 dtrace_action_stop(void)
5666 {
5667         if (dtrace_destructive_disallow)
5668                 return;
5669
5670 #if defined(sun)
5671         if (!curthread->t_dtrace_stop) {
5672                 curthread->t_dtrace_stop = 1;
5673                 curthread->t_sig_check = 1;
5674                 aston(curthread);
5675         }
5676 #else
5677         struct proc *p = curproc;
5678         PROC_LOCK(p);
5679         psignal(p, SIGSTOP);
5680         PROC_UNLOCK(p);
5681 #endif
5682 }
5683
5684 static void
5685 dtrace_action_chill(dtrace_mstate_t *mstate, hrtime_t val)
5686 {
5687         hrtime_t now;
5688         volatile uint16_t *flags;
5689 #if defined(sun)
5690         cpu_t *cpu = CPU;
5691 #else
5692         cpu_t *cpu = &solaris_cpu[curcpu];
5693 #endif
5694
5695         if (dtrace_destructive_disallow)
5696                 return;
5697
5698         flags = (volatile uint16_t *)&cpu_core[cpu->cpu_id].cpuc_dtrace_flags;
5699
5700         now = dtrace_gethrtime();
5701
5702         if (now - cpu->cpu_dtrace_chillmark > dtrace_chill_interval) {
5703                 /*
5704                  * We need to advance the mark to the current time.
5705                  */
5706                 cpu->cpu_dtrace_chillmark = now;
5707                 cpu->cpu_dtrace_chilled = 0;
5708         }
5709
5710         /*
5711          * Now check to see if the requested chill time would take us over
5712          * the maximum amount of time allowed in the chill interval.  (Or
5713          * worse, if the calculation itself induces overflow.)
5714          */
5715         if (cpu->cpu_dtrace_chilled + val > dtrace_chill_max ||
5716             cpu->cpu_dtrace_chilled + val < cpu->cpu_dtrace_chilled) {
5717                 *flags |= CPU_DTRACE_ILLOP;
5718                 return;
5719         }
5720
5721         while (dtrace_gethrtime() - now < val)
5722                 continue;
5723
5724         /*
5725          * Normally, we assure that the value of the variable "timestamp" does
5726          * not change within an ECB.  The presence of chill() represents an
5727          * exception to this rule, however.
5728          */
5729         mstate->dtms_present &= ~DTRACE_MSTATE_TIMESTAMP;
5730         cpu->cpu_dtrace_chilled += val;
5731 }
5732
5733 #if defined(sun)
5734 static void
5735 dtrace_action_ustack(dtrace_mstate_t *mstate, dtrace_state_t *state,
5736     uint64_t *buf, uint64_t arg)
5737 {
5738         int nframes = DTRACE_USTACK_NFRAMES(arg);
5739         int strsize = DTRACE_USTACK_STRSIZE(arg);
5740         uint64_t *pcs = &buf[1], *fps;
5741         char *str = (char *)&pcs[nframes];
5742         int size, offs = 0, i, j;
5743         uintptr_t old = mstate->dtms_scratch_ptr, saved;
5744         uint16_t *flags = &cpu_core[curcpu].cpuc_dtrace_flags;
5745         char *sym;
5746
5747         /*
5748          * Should be taking a faster path if string space has not been
5749          * allocated.
5750          */
5751         ASSERT(strsize != 0);
5752
5753         /*
5754          * We will first allocate some temporary space for the frame pointers.
5755          */
5756         fps = (uint64_t *)P2ROUNDUP(mstate->dtms_scratch_ptr, 8);
5757         size = (uintptr_t)fps - mstate->dtms_scratch_ptr +
5758             (nframes * sizeof (uint64_t));
5759
5760         if (!DTRACE_INSCRATCH(mstate, size)) {
5761                 /*
5762                  * Not enough room for our frame pointers -- need to indicate
5763                  * that we ran out of scratch space.
5764                  */
5765                 DTRACE_CPUFLAG_SET(CPU_DTRACE_NOSCRATCH);
5766                 return;
5767         }
5768
5769         mstate->dtms_scratch_ptr += size;
5770         saved = mstate->dtms_scratch_ptr;
5771
5772         /*
5773          * Now get a stack with both program counters and frame pointers.
5774          */
5775         DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);
5776         dtrace_getufpstack(buf, fps, nframes + 1);
5777         DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT);
5778
5779         /*
5780          * If that faulted, we're cooked.
5781          */
5782         if (*flags & CPU_DTRACE_FAULT)
5783                 goto out;
5784
5785         /*
5786          * Now we want to walk up the stack, calling the USTACK helper.  For
5787          * each iteration, we restore the scratch pointer.
5788          */
5789         for (i = 0; i < nframes; i++) {
5790                 mstate->dtms_scratch_ptr = saved;
5791
5792                 if (offs >= strsize)
5793                         break;
5794
5795                 sym = (char *)(uintptr_t)dtrace_helper(
5796                     DTRACE_HELPER_ACTION_USTACK,
5797                     mstate, state, pcs[i], fps[i]);
5798
5799                 /*
5800                  * If we faulted while running the helper, we're going to
5801                  * clear the fault and null out the corresponding string.
5802                  */
5803                 if (*flags & CPU_DTRACE_FAULT) {
5804                         *flags &= ~CPU_DTRACE_FAULT;
5805                         str[offs++] = '\0';
5806                         continue;
5807                 }
5808
5809                 if (sym == NULL) {
5810                         str[offs++] = '\0';
5811                         continue;
5812                 }
5813
5814                 DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);
5815
5816                 /*
5817                  * Now copy in the string that the helper returned to us.
5818                  */
5819                 for (j = 0; offs + j < strsize; j++) {
5820                         if ((str[offs + j] = sym[j]) == '\0')
5821                                 break;
5822                 }
5823
5824                 DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT);
5825
5826                 offs += j + 1;
5827         }
5828
5829         if (offs >= strsize) {
5830                 /*
5831                  * If we didn't have room for all of the strings, we don't
5832                  * abort processing -- this needn't be a fatal error -- but we
5833                  * still want to increment a counter (dts_stkstroverflows) to
5834                  * allow this condition to be warned about.  (If this is from
5835                  * a jstack() action, it is easily tuned via jstackstrsize.)
5836                  */
5837                 dtrace_error(&state->dts_stkstroverflows);
5838         }
5839
5840         while (offs < strsize)
5841                 str[offs++] = '\0';
5842
5843 out:
5844         mstate->dtms_scratch_ptr = old;
5845 }
5846 #endif
5847
5848 /*
5849  * If you're looking for the epicenter of DTrace, you just found it.  This
5850  * is the function called by the provider to fire a probe -- from which all
5851  * subsequent probe-context DTrace activity emanates.
5852  */
5853 void
5854 dtrace_probe(dtrace_id_t id, uintptr_t arg0, uintptr_t arg1,
5855     uintptr_t arg2, uintptr_t arg3, uintptr_t arg4)
5856 {
5857         processorid_t cpuid;
5858         dtrace_icookie_t cookie;
5859         dtrace_probe_t *probe;
5860         dtrace_mstate_t mstate;
5861         dtrace_ecb_t *ecb;
5862         dtrace_action_t *act;
5863         intptr_t offs;
5864         size_t size;
5865         int vtime, onintr;
5866         volatile uint16_t *flags;
5867         hrtime_t now;
5868
5869 #if defined(sun)
5870         /*
5871          * Kick out immediately if this CPU is still being born (in which case
5872          * curthread will be set to -1) or the current thread can't allow
5873          * probes in its current context.
5874          */
5875         if (((uintptr_t)curthread & 1) || (curthread->t_flag & T_DONTDTRACE))
5876                 return;
5877 #endif
5878
5879         cookie = dtrace_interrupt_disable();
5880         probe = dtrace_probes[id - 1];
5881         cpuid = curcpu;
5882         onintr = CPU_ON_INTR(CPU);
5883
5884         if (!onintr && probe->dtpr_predcache != DTRACE_CACHEIDNONE &&
5885             probe->dtpr_predcache == curthread->t_predcache) {
5886                 /*
5887                  * We have hit in the predicate cache; we know that
5888                  * this predicate would evaluate to be false.
5889                  */
5890                 dtrace_interrupt_enable(cookie);
5891                 return;
5892         }
5893
5894 #if defined(sun)
5895         if (panic_quiesce) {
5896 #else
5897         if (panicstr != NULL) {
5898 #endif
5899                 /*
5900                  * We don't trace anything if we're panicking.
5901                  */
5902                 dtrace_interrupt_enable(cookie);
5903                 return;
5904         }
5905
5906         now = dtrace_gethrtime();
5907         vtime = dtrace_vtime_references != 0;
5908
5909         if (vtime && curthread->t_dtrace_start)
5910                 curthread->t_dtrace_vtime += now - curthread->t_dtrace_start;
5911
5912         mstate.dtms_difo = NULL;
5913         mstate.dtms_probe = probe;
5914         mstate.dtms_strtok = 0;
5915         mstate.dtms_arg[0] = arg0;
5916         mstate.dtms_arg[1] = arg1;
5917         mstate.dtms_arg[2] = arg2;
5918         mstate.dtms_arg[3] = arg3;
5919         mstate.dtms_arg[4] = arg4;
5920
5921         flags = (volatile uint16_t *)&cpu_core[cpuid].cpuc_dtrace_flags;
5922
5923         for (ecb = probe->dtpr_ecb; ecb != NULL; ecb = ecb->dte_next) {
5924                 dtrace_predicate_t *pred = ecb->dte_predicate;
5925                 dtrace_state_t *state = ecb->dte_state;
5926                 dtrace_buffer_t *buf = &state->dts_buffer[cpuid];
5927                 dtrace_buffer_t *aggbuf = &state->dts_aggbuffer[cpuid];
5928                 dtrace_vstate_t *vstate = &state->dts_vstate;
5929                 dtrace_provider_t *prov = probe->dtpr_provider;
5930                 int committed = 0;
5931                 caddr_t tomax;
5932
5933                 /*
5934                  * A little subtlety with the following (seemingly innocuous)
5935                  * declaration of the automatic 'val':  by looking at the
5936                  * code, you might think that it could be declared in the
5937                  * action processing loop, below.  (That is, it's only used in
5938                  * the action processing loop.)  However, it must be declared
5939                  * out of that scope because in the case of DIF expression
5940                  * arguments to aggregating actions, one iteration of the
5941                  * action loop will use the last iteration's value.
5942                  */
5943                 uint64_t val = 0;
5944
5945                 mstate.dtms_present = DTRACE_MSTATE_ARGS | DTRACE_MSTATE_PROBE;
5946                 *flags &= ~CPU_DTRACE_ERROR;
5947
5948                 if (prov == dtrace_provider) {
5949                         /*
5950                          * If dtrace itself is the provider of this probe,
5951                          * we're only going to continue processing the ECB if
5952                          * arg0 (the dtrace_state_t) is equal to the ECB's
5953                          * creating state.  (This prevents disjoint consumers
5954                          * from seeing one another's metaprobes.)
5955                          */
5956                         if (arg0 != (uint64_t)(uintptr_t)state)
5957                                 continue;
5958                 }
5959
5960                 if (state->dts_activity != DTRACE_ACTIVITY_ACTIVE) {
5961                         /*
5962                          * We're not currently active.  If our provider isn't
5963                          * the dtrace pseudo provider, we're not interested.
5964                          */
5965                         if (prov != dtrace_provider)
5966                                 continue;
5967
5968                         /*
5969                          * Now we must further check if we are in the BEGIN
5970                          * probe.  If we are, we will only continue processing
5971                          * if we're still in WARMUP -- if one BEGIN enabling
5972                          * has invoked the exit() action, we don't want to
5973                          * evaluate subsequent BEGIN enablings.
5974                          */
5975                         if (probe->dtpr_id == dtrace_probeid_begin &&
5976                             state->dts_activity != DTRACE_ACTIVITY_WARMUP) {
5977                                 ASSERT(state->dts_activity ==
5978                                     DTRACE_ACTIVITY_DRAINING);
5979                                 continue;
5980                         }
5981                 }
5982
5983                 if (ecb->dte_cond) {
5984                         /*
5985                          * If the dte_cond bits indicate that this
5986                          * consumer is only allowed to see user-mode firings
5987                          * of this probe, call the provider's dtps_usermode()
5988                          * entry point to check that the probe was fired
5989                          * while in a user context. Skip this ECB if that's
5990                          * not the case.
5991                          */
5992                         if ((ecb->dte_cond & DTRACE_COND_USERMODE) &&
5993                             prov->dtpv_pops.dtps_usermode(prov->dtpv_arg,
5994                             probe->dtpr_id, probe->dtpr_arg) == 0)
5995                                 continue;
5996
5997 #if defined(sun)
5998                         /*
5999                          * This is more subtle than it looks. We have to be
6000                          * absolutely certain that CRED() isn't going to
6001                          * change out from under us so it's only legit to
6002                          * examine that structure if we're in constrained
6003                          * situations. Currently, the only times we'll this
6004                          * check is if a non-super-user has enabled the
6005                          * profile or syscall providers -- providers that
6006                          * allow visibility of all processes. For the
6007                          * profile case, the check above will ensure that
6008                          * we're examining a user context.
6009                          */
6010                         if (ecb->dte_cond & DTRACE_COND_OWNER) {
6011                                 cred_t *cr;
6012                                 cred_t *s_cr =
6013                                     ecb->dte_state->dts_cred.dcr_cred;
6014                                 proc_t *proc;
6015
6016                                 ASSERT(s_cr != NULL);
6017
6018                                 if ((cr = CRED()) == NULL ||
6019                                     s_cr->cr_uid != cr->cr_uid ||
6020                                     s_cr->cr_uid != cr->cr_ruid ||
6021                                     s_cr->cr_uid != cr->cr_suid ||
6022                                     s_cr->cr_gid != cr->cr_gid ||
6023                                     s_cr->cr_gid != cr->cr_rgid ||
6024                                     s_cr->cr_gid != cr->cr_sgid ||
6025                                     (proc = ttoproc(curthread)) == NULL ||
6026                                     (proc->p_flag & SNOCD))
6027                                         continue;
6028                         }
6029
6030                         if (ecb->dte_cond & DTRACE_COND_ZONEOWNER) {
6031                                 cred_t *cr;
6032                                 cred_t *s_cr =
6033                                     ecb->dte_state->dts_cred.dcr_cred;
6034
6035                                 ASSERT(s_cr != NULL);
6036
6037                                 if ((cr = CRED()) == NULL ||
6038                                     s_cr->cr_zone->zone_id !=
6039                                     cr->cr_zone->zone_id)
6040                                         continue;
6041                         }
6042 #endif
6043                 }
6044
6045                 if (now - state->dts_alive > dtrace_deadman_timeout) {
6046                         /*
6047                          * We seem to be dead.  Unless we (a) have kernel
6048                          * destructive permissions (b) have expicitly enabled
6049                          * destructive actions and (c) destructive actions have
6050                          * not been disabled, we're going to transition into
6051                          * the KILLED state, from which no further processing
6052                          * on this state will be performed.
6053                          */
6054                         if (!dtrace_priv_kernel_destructive(state) ||
6055                             !state->dts_cred.dcr_destructive ||
6056                             dtrace_destructive_disallow) {
6057                                 void *activity = &state->dts_activity;
6058                                 dtrace_activity_t current;
6059
6060                                 do {
6061                                         current = state->dts_activity;
6062                                 } while (dtrace_cas32(activity, current,
6063                                     DTRACE_ACTIVITY_KILLED) != current);
6064
6065                                 continue;
6066                         }
6067                 }
6068
6069                 if ((offs = dtrace_buffer_reserve(buf, ecb->dte_needed,
6070                     ecb->dte_alignment, state, &mstate)) < 0)
6071                         continue;
6072
6073                 tomax = buf->dtb_tomax;
6074                 ASSERT(tomax != NULL);
6075
6076                 if (ecb->dte_size != 0)
6077                         DTRACE_STORE(uint32_t, tomax, offs, ecb->dte_epid);
6078
6079                 mstate.dtms_epid = ecb->dte_epid;
6080                 mstate.dtms_present |= DTRACE_MSTATE_EPID;
6081
6082                 if (state->dts_cred.dcr_visible & DTRACE_CRV_KERNEL)
6083                         mstate.dtms_access = DTRACE_ACCESS_KERNEL;
6084                 else
6085                         mstate.dtms_access = 0;
6086
6087                 if (pred != NULL) {
6088                         dtrace_difo_t *dp = pred->dtp_difo;
6089                         int rval;
6090
6091                         rval = dtrace_dif_emulate(dp, &mstate, vstate, state);
6092
6093                         if (!(*flags & CPU_DTRACE_ERROR) && !rval) {
6094                                 dtrace_cacheid_t cid = probe->dtpr_predcache;
6095
6096                                 if (cid != DTRACE_CACHEIDNONE && !onintr) {
6097                                         /*
6098                                          * Update the predicate cache...
6099                                          */
6100                                         ASSERT(cid == pred->dtp_cacheid);
6101                                         curthread->t_predcache = cid;
6102                                 }
6103
6104                                 continue;
6105                         }
6106                 }
6107
6108                 for (act = ecb->dte_action; !(*flags & CPU_DTRACE_ERROR) &&
6109                     act != NULL; act = act->dta_next) {
6110                         size_t valoffs;
6111                         dtrace_difo_t *dp;
6112                         dtrace_recdesc_t *rec = &act->dta_rec;
6113
6114                         size = rec->dtrd_size;
6115                         valoffs = offs + rec->dtrd_offset;
6116
6117                         if (DTRACEACT_ISAGG(act->dta_kind)) {
6118                                 uint64_t v = 0xbad;
6119                                 dtrace_aggregation_t *agg;
6120
6121                                 agg = (dtrace_aggregation_t *)act;
6122
6123                                 if ((dp = act->dta_difo) != NULL)
6124                                         v = dtrace_dif_emulate(dp,
6125                                             &mstate, vstate, state);
6126
6127                                 if (*flags & CPU_DTRACE_ERROR)
6128                                         continue;
6129
6130                                 /*
6131                                  * Note that we always pass the expression
6132                                  * value from the previous iteration of the
6133                                  * action loop.  This value will only be used
6134                                  * if there is an expression argument to the
6135                                  * aggregating action, denoted by the
6136                                  * dtag_hasarg field.
6137                                  */
6138                                 dtrace_aggregate(agg, buf,
6139                                     offs, aggbuf, v, val);
6140                                 continue;
6141                         }
6142
6143                         switch (act->dta_kind) {
6144                         case DTRACEACT_STOP:
6145                                 if (dtrace_priv_proc_destructive(state))
6146                                         dtrace_action_stop();
6147                                 continue;
6148
6149                         case DTRACEACT_BREAKPOINT:
6150                                 if (dtrace_priv_kernel_destructive(state))
6151                                         dtrace_action_breakpoint(ecb);
6152                                 continue;
6153
6154                         case DTRACEACT_PANIC:
6155                                 if (dtrace_priv_kernel_destructive(state))
6156                                         dtrace_action_panic(ecb);
6157                                 continue;
6158
6159                         case DTRACEACT_STACK:
6160                                 if (!dtrace_priv_kernel(state))
6161                                         continue;
6162
6163                                 dtrace_getpcstack((pc_t *)(tomax + valoffs),
6164                                     size / sizeof (pc_t), probe->dtpr_aframes,
6165                                     DTRACE_ANCHORED(probe) ? NULL :
6166                                     (uint32_t *)arg0);
6167                                 continue;
6168
6169 #if defined(sun)
6170                         case DTRACEACT_JSTACK:
6171                         case DTRACEACT_USTACK:
6172                                 if (!dtrace_priv_proc(state))
6173                                         continue;
6174
6175                                 /*
6176                                  * See comment in DIF_VAR_PID.
6177                                  */
6178                                 if (DTRACE_ANCHORED(mstate.dtms_probe) &&
6179                                     CPU_ON_INTR(CPU)) {
6180                                         int depth = DTRACE_USTACK_NFRAMES(
6181                                             rec->dtrd_arg) + 1;
6182
6183                                         dtrace_bzero((void *)(tomax + valoffs),
6184                                             DTRACE_USTACK_STRSIZE(rec->dtrd_arg)
6185                                             + depth * sizeof (uint64_t));
6186
6187                                         continue;
6188                                 }
6189
6190                                 if (DTRACE_USTACK_STRSIZE(rec->dtrd_arg) != 0 &&
6191                                     curproc->p_dtrace_helpers != NULL) {
6192                                         /*
6193                                          * This is the slow path -- we have
6194                                          * allocated string space, and we're
6195                                          * getting the stack of a process that
6196                                          * has helpers.  Call into a separate
6197                                          * routine to perform this processing.
6198                                          */
6199                                         dtrace_action_ustack(&mstate, state,
6200                                             (uint64_t *)(tomax + valoffs),
6201                                             rec->dtrd_arg);
6202                                         continue;
6203                                 }
6204
6205                                 DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);
6206                                 dtrace_getupcstack((uint64_t *)
6207                                     (tomax + valoffs),
6208                                     DTRACE_USTACK_NFRAMES(rec->dtrd_arg) + 1);
6209                                 DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT);
6210                                 continue;
6211 #endif
6212
6213                         default:
6214                                 break;
6215                         }
6216
6217                         dp = act->dta_difo;
6218                         ASSERT(dp != NULL);
6219
6220                         val = dtrace_dif_emulate(dp, &mstate, vstate, state);
6221
6222                         if (*flags & CPU_DTRACE_ERROR)
6223                                 continue;
6224
6225                         switch (act->dta_kind) {
6226                         case DTRACEACT_SPECULATE:
6227                                 ASSERT(buf == &state->dts_buffer[cpuid]);
6228                                 buf = dtrace_speculation_buffer(state,
6229                                     cpuid, val);
6230
6231                                 if (buf == NULL) {
6232                                         *flags |= CPU_DTRACE_DROP;
6233                                         continue;
6234                                 }
6235
6236                                 offs = dtrace_buffer_reserve(buf,
6237                                     ecb->dte_needed, ecb->dte_alignment,
6238                                     state, NULL);
6239
6240                                 if (offs < 0) {
6241                                         *flags |= CPU_DTRACE_DROP;
6242                                         continue;
6243                                 }
6244
6245                                 tomax = buf->dtb_tomax;
6246                                 ASSERT(tomax != NULL);
6247
6248                                 if (ecb->dte_size != 0)
6249                                         DTRACE_STORE(uint32_t, tomax, offs,
6250                                             ecb->dte_epid);
6251                                 continue;
6252
6253                         case DTRACEACT_PRINTM: {
6254                                 /* The DIF returns a 'memref'. */
6255                                 uintptr_t *memref = (uintptr_t *)(uintptr_t) val;
6256
6257                                 /* Get the size from the memref. */
6258                                 size = memref[1];
6259
6260                                 /*
6261                                  * Check if the size exceeds the allocated
6262                                  * buffer size.
6263                                  */
6264                                 if (size + sizeof(uintptr_t) > dp->dtdo_rtype.dtdt_size) {
6265                                         /* Flag a drop! */
6266                                         *flags |= CPU_DTRACE_DROP;
6267                                         continue;
6268                                 }
6269
6270                                 /* Store the size in the buffer first. */
6271                                 DTRACE_STORE(uintptr_t, tomax,
6272                                     valoffs, size);
6273
6274                                 /*
6275                                  * Offset the buffer address to the start
6276                                  * of the data.
6277                                  */
6278                                 valoffs += sizeof(uintptr_t);
6279
6280                                 /*
6281                                  * Reset to the memory address rather than
6282                                  * the memref array, then let the BYREF
6283                                  * code below do the work to store the 
6284                                  * memory data in the buffer.
6285                                  */
6286                                 val = memref[0];
6287                                 break;
6288                         }
6289
6290                         case DTRACEACT_PRINTT: {
6291                                 /* The DIF returns a 'typeref'. */
6292                                 uintptr_t *typeref = (uintptr_t *)(uintptr_t) val;
6293                                 char c = '\0' + 1;
6294                                 size_t s;
6295
6296                                 /*
6297                                  * Get the type string length and round it
6298                                  * up so that the data that follows is
6299                                  * aligned for easy access.
6300                                  */
6301                                 size_t typs = strlen((char *) typeref[2]) + 1;
6302                                 typs = roundup(typs,  sizeof(uintptr_t));
6303
6304                                 /*
6305                                  *Get the size from the typeref using the
6306                                  * number of elements and the type size.
6307                                  */
6308                                 size = typeref[1] * typeref[3];
6309
6310                                 /*
6311                                  * Check if the size exceeds the allocated
6312                                  * buffer size.
6313                                  */
6314                                 if (size + typs + 2 * sizeof(uintptr_t) > dp->dtdo_rtype.dtdt_size) {
6315                                         /* Flag a drop! */
6316                                         *flags |= CPU_DTRACE_DROP;
6317                                 
6318                                 }
6319
6320                                 /* Store the size in the buffer first. */
6321                                 DTRACE_STORE(uintptr_t, tomax,
6322                                     valoffs, size);
6323                                 valoffs += sizeof(uintptr_t);
6324
6325                                 /* Store the type size in the buffer. */
6326                                 DTRACE_STORE(uintptr_t, tomax,
6327                                     valoffs, typeref[3]);
6328                                 valoffs += sizeof(uintptr_t);
6329
6330                                 val = typeref[2];
6331
6332                                 for (s = 0; s < typs; s++) {
6333                                         if (c != '\0')
6334                                                 c = dtrace_load8(val++);
6335
6336                                         DTRACE_STORE(uint8_t, tomax,
6337                                             valoffs++, c);
6338                                 }
6339
6340                                 /*
6341                                  * Reset to the memory address rather than
6342                                  * the typeref array, then let the BYREF
6343                                  * code below do the work to store the 
6344                                  * memory data in the buffer.
6345                                  */
6346                                 val = typeref[0];
6347                                 break;
6348                         }
6349
6350                         case DTRACEACT_CHILL:
6351                                 if (dtrace_priv_kernel_destructive(state))
6352                                         dtrace_action_chill(&mstate, val);
6353                                 continue;
6354
6355                         case DTRACEACT_RAISE:
6356                                 if (dtrace_priv_proc_destructive(state))
6357                                         dtrace_action_raise(val);
6358                                 continue;
6359
6360                         case DTRACEACT_COMMIT:
6361                                 ASSERT(!committed);
6362
6363                                 /*
6364                                  * We need to commit our buffer state.
6365                                  */
6366                                 if (ecb->dte_size)
6367                                         buf->dtb_offset = offs + ecb->dte_size;
6368                                 buf = &state->dts_buffer[cpuid];
6369                                 dtrace_speculation_commit(state, cpuid, val);
6370                                 committed = 1;
6371                                 continue;
6372
6373                         case DTRACEACT_DISCARD:
6374                                 dtrace_speculation_discard(state, cpuid, val);
6375                                 continue;
6376
6377                         case DTRACEACT_DIFEXPR:
6378                         case DTRACEACT_LIBACT:
6379                         case DTRACEACT_PRINTF:
6380                         case DTRACEACT_PRINTA:
6381                         case DTRACEACT_SYSTEM:
6382                         case DTRACEACT_FREOPEN:
6383                                 break;
6384
6385                         case DTRACEACT_SYM:
6386                         case DTRACEACT_MOD:
6387                                 if (!dtrace_priv_kernel(state))
6388                                         continue;
6389                                 break;
6390
6391                         case DTRACEACT_USYM:
6392                         case DTRACEACT_UMOD:
6393                         case DTRACEACT_UADDR: {
6394 #if defined(sun)
6395                                 struct pid *pid = curthread->t_procp->p_pidp;
6396 #endif
6397
6398                                 if (!dtrace_priv_proc(state))
6399                                         continue;
6400
6401                                 DTRACE_STORE(uint64_t, tomax,
6402 #if defined(sun)
6403                                     valoffs, (uint64_t)pid->pid_id);
6404 #else
6405                                     valoffs, (uint64_t) curproc->p_pid);
6406 #endif
6407                                 DTRACE_STORE(uint64_t, tomax,
6408                                     valoffs + sizeof (uint64_t), val);
6409
6410                                 continue;
6411                         }
6412
6413                         case DTRACEACT_EXIT: {
6414                                 /*
6415                                  * For the exit action, we are going to attempt
6416                                  * to atomically set our activity to be
6417                                  * draining.  If this fails (either because
6418                                  * another CPU has beat us to the exit action,
6419                                  * or because our current activity is something
6420                                  * other than ACTIVE or WARMUP), we will
6421                                  * continue.  This assures that the exit action
6422                                  * can be successfully recorded at most once
6423                                  * when we're in the ACTIVE state.  If we're
6424                                  * encountering the exit() action while in
6425                                  * COOLDOWN, however, we want to honor the new
6426                                  * status code.  (We know that we're the only
6427                                  * thread in COOLDOWN, so there is no race.)
6428                                  */
6429                                 void *activity = &state->dts_activity;
6430                                 dtrace_activity_t current = state->dts_activity;
6431
6432                                 if (current == DTRACE_ACTIVITY_COOLDOWN)
6433                                         break;
6434
6435                                 if (current != DTRACE_ACTIVITY_WARMUP)
6436                                         current = DTRACE_ACTIVITY_ACTIVE;
6437
6438                                 if (dtrace_cas32(activity, current,
6439                                     DTRACE_ACTIVITY_DRAINING) != current) {
6440                                         *flags |= CPU_DTRACE_DROP;
6441                                         continue;
6442                                 }
6443
6444                                 break;
6445                         }
6446
6447                         default:
6448                                 ASSERT(0);
6449                         }
6450
6451                         if (dp->dtdo_rtype.dtdt_flags & DIF_TF_BYREF) {
6452                                 uintptr_t end = valoffs + size;
6453
6454                                 if (!dtrace_vcanload((void *)(uintptr_t)val,
6455                                     &dp->dtdo_rtype, &mstate, vstate))
6456                                         continue;
6457
6458                                 /*
6459                                  * If this is a string, we're going to only
6460                                  * load until we find the zero byte -- after
6461                                  * which we'll store zero bytes.
6462                                  */
6463                                 if (dp->dtdo_rtype.dtdt_kind ==
6464                                     DIF_TYPE_STRING) {
6465                                         char c = '\0' + 1;
6466                                         int intuple = act->dta_intuple;
6467                                         size_t s;
6468
6469                                         for (s = 0; s < size; s++) {
6470                                                 if (c != '\0')
6471                                                         c = dtrace_load8(val++);
6472
6473                                                 DTRACE_STORE(uint8_t, tomax,
6474                                                     valoffs++, c);
6475
6476                                                 if (c == '\0' && intuple)
6477                                                         break;
6478                                         }
6479
6480                                         continue;
6481                                 }
6482
6483                                 while (valoffs < end) {
6484                                         DTRACE_STORE(uint8_t, tomax, valoffs++,
6485                                             dtrace_load8(val++));
6486                                 }
6487
6488                                 continue;
6489                         }
6490
6491                         switch (size) {
6492                         case 0:
6493                                 break;
6494
6495                         case sizeof (uint8_t):
6496                                 DTRACE_STORE(uint8_t, tomax, valoffs, val);
6497                                 break;
6498                         case sizeof (uint16_t):
6499                                 DTRACE_STORE(uint16_t, tomax, valoffs, val);
6500                                 break;
6501                         case sizeof (uint32_t):
6502                                 DTRACE_STORE(uint32_t, tomax, valoffs, val);
6503                                 break;
6504                         case sizeof (uint64_t):
6505                                 DTRACE_STORE(uint64_t, tomax, valoffs, val);
6506                                 break;
6507                         default:
6508                                 /*
6509                                  * Any other size should have been returned by
6510                                  * reference, not by value.
6511                                  */
6512                                 ASSERT(0);
6513                                 break;
6514                         }
6515                 }
6516
6517                 if (*flags & CPU_DTRACE_DROP)
6518                         continue;
6519
6520                 if (*flags & CPU_DTRACE_FAULT) {
6521                         int ndx;
6522                         dtrace_action_t *err;
6523
6524                         buf->dtb_errors++;
6525
6526                         if (probe->dtpr_id == dtrace_probeid_error) {
6527                                 /*
6528                                  * There's nothing we can do -- we had an
6529                                  * error on the error probe.  We bump an
6530                                  * error counter to at least indicate that
6531                                  * this condition happened.
6532                                  */
6533                                 dtrace_error(&state->dts_dblerrors);
6534                                 continue;
6535                         }
6536
6537                         if (vtime) {
6538                                 /*
6539                                  * Before recursing on dtrace_probe(), we
6540                                  * need to explicitly clear out our start
6541                                  * time to prevent it from being accumulated
6542                                  * into t_dtrace_vtime.
6543                                  */
6544                                 curthread->t_dtrace_start = 0;
6545                         }
6546
6547                         /*
6548                          * Iterate over the actions to figure out which action
6549                          * we were processing when we experienced the error.
6550                          * Note that act points _past_ the faulting action; if
6551                          * act is ecb->dte_action, the fault was in the
6552                          * predicate, if it's ecb->dte_action->dta_next it's
6553                          * in action #1, and so on.
6554                          */
6555                         for (err = ecb->dte_action, ndx = 0;
6556                             err != act; err = err->dta_next, ndx++)
6557                                 continue;
6558
6559                         dtrace_probe_error(state, ecb->dte_epid, ndx,
6560                             (mstate.dtms_present & DTRACE_MSTATE_FLTOFFS) ?
6561                             mstate.dtms_fltoffs : -1, DTRACE_FLAGS2FLT(*flags),
6562                             cpu_core[cpuid].cpuc_dtrace_illval);
6563
6564                         continue;
6565                 }
6566
6567                 if (!committed)
6568                         buf->dtb_offset = offs + ecb->dte_size;
6569         }
6570
6571         if (vtime)
6572                 curthread->t_dtrace_start = dtrace_gethrtime();
6573
6574         dtrace_interrupt_enable(cookie);
6575 }
6576
6577 /*
6578  * DTrace Probe Hashing Functions
6579  *
6580  * The functions in this section (and indeed, the functions in remaining
6581  * sections) are not _called_ from probe context.  (Any exceptions to this are
6582  * marked with a "Note:".)  Rather, they are called from elsewhere in the
6583  * DTrace framework to look-up probes in, add probes to and remove probes from
6584  * the DTrace probe hashes.  (Each probe is hashed by each element of the
6585  * probe tuple -- allowing for fast lookups, regardless of what was
6586  * specified.)
6587  */
6588 static uint_t
6589 dtrace_hash_str(const char *p)
6590 {
6591         unsigned int g;
6592         uint_t hval = 0;
6593
6594         while (*p) {
6595                 hval = (hval << 4) + *p++;
6596                 if ((g = (hval & 0xf0000000)) != 0)
6597                         hval ^= g >> 24;
6598                 hval &= ~g;
6599         }
6600         return (hval);
6601 }
6602
6603 static dtrace_hash_t *
6604 dtrace_hash_create(uintptr_t stroffs, uintptr_t nextoffs, uintptr_t prevoffs)
6605 {
6606         dtrace_hash_t *hash = kmem_zalloc(sizeof (dtrace_hash_t), KM_SLEEP);
6607
6608         hash->dth_stroffs = stroffs;
6609         hash->dth_nextoffs = nextoffs;
6610         hash->dth_prevoffs = prevoffs;
6611
6612         hash->dth_size = 1;
6613         hash->dth_mask = hash->dth_size - 1;
6614
6615         hash->dth_tab = kmem_zalloc(hash->dth_size *
6616             sizeof (dtrace_hashbucket_t *), KM_SLEEP);
6617
6618         return (hash);
6619 }
6620
6621 static void
6622 dtrace_hash_destroy(dtrace_hash_t *hash)
6623 {
6624 #ifdef DEBUG
6625         int i;
6626
6627         for (i = 0; i < hash->dth_size; i++)
6628                 ASSERT(hash->dth_tab[i] == NULL);
6629 #endif
6630
6631         kmem_free(hash->dth_tab,
6632             hash->dth_size * sizeof (dtrace_hashbucket_t *));
6633         kmem_free(hash, sizeof (dtrace_hash_t));
6634 }
6635
6636 static void
6637 dtrace_hash_resize(dtrace_hash_t *hash)
6638 {
6639         int size = hash->dth_size, i, ndx;
6640         int new_size = hash->dth_size << 1;
6641         int new_mask = new_size - 1;
6642         dtrace_hashbucket_t **new_tab, *bucket, *next;
6643
6644         ASSERT((new_size & new_mask) == 0);
6645
6646         new_tab = kmem_zalloc(new_size * sizeof (void *), KM_SLEEP);
6647
6648         for (i = 0; i < size; i++) {
6649                 for (bucket = hash->dth_tab[i]; bucket != NULL; bucket = next) {
6650                         dtrace_probe_t *probe = bucket->dthb_chain;
6651
6652                         ASSERT(probe != NULL);
6653                         ndx = DTRACE_HASHSTR(hash, probe) & new_mask;
6654
6655                         next = bucket->dthb_next;
6656                         bucket->dthb_next = new_tab[ndx];
6657                         new_tab[ndx] = bucket;
6658                 }
6659         }
6660
6661         kmem_free(hash->dth_tab, hash->dth_size * sizeof (void *));
6662         hash->dth_tab = new_tab;
6663         hash->dth_size = new_size;
6664         hash->dth_mask = new_mask;
6665 }
6666
6667 static void
6668 dtrace_hash_add(dtrace_hash_t *hash, dtrace_probe_t *new)
6669 {
6670         int hashval = DTRACE_HASHSTR(hash, new);
6671         int ndx = hashval & hash->dth_mask;
6672         dtrace_hashbucket_t *bucket = hash->dth_tab[ndx];
6673         dtrace_probe_t **nextp, **prevp;
6674
6675         for (; bucket != NULL; bucket = bucket->dthb_next) {
6676                 if (DTRACE_HASHEQ(hash, bucket->dthb_chain, new))
6677                         goto add;
6678         }
6679
6680         if ((hash->dth_nbuckets >> 1) > hash->dth_size) {
6681                 dtrace_hash_resize(hash);
6682                 dtrace_hash_add(hash, new);
6683                 return;
6684         }
6685
6686         bucket = kmem_zalloc(sizeof (dtrace_hashbucket_t), KM_SLEEP);
6687         bucket->dthb_next = hash->dth_tab[ndx];
6688         hash->dth_tab[ndx] = bucket;
6689         hash->dth_nbuckets++;
6690
6691 add:
6692         nextp = DTRACE_HASHNEXT(hash, new);
6693         ASSERT(*nextp == NULL && *(DTRACE_HASHPREV(hash, new)) == NULL);
6694         *nextp = bucket->dthb_chain;
6695
6696         if (bucket->dthb_chain != NULL) {
6697                 prevp = DTRACE_HASHPREV(hash, bucket->dthb_chain);
6698                 ASSERT(*prevp == NULL);
6699                 *prevp = new;
6700         }
6701
6702         bucket->dthb_chain = new;
6703         bucket->dthb_len++;
6704 }
6705
6706 static dtrace_probe_t *
6707 dtrace_hash_lookup(dtrace_hash_t *hash, dtrace_probe_t *template)
6708 {
6709         int hashval = DTRACE_HASHSTR(hash, template);
6710         int ndx = hashval & hash->dth_mask;
6711         dtrace_hashbucket_t *bucket = hash->dth_tab[ndx];
6712
6713         for (; bucket != NULL; bucket = bucket->dthb_next) {
6714                 if (DTRACE_HASHEQ(hash, bucket->dthb_chain, template))
6715                         return (bucket->dthb_chain);
6716         }
6717
6718         return (NULL);
6719 }
6720
6721 static int
6722 dtrace_hash_collisions(dtrace_hash_t *hash, dtrace_probe_t *template)
6723 {
6724         int hashval = DTRACE_HASHSTR(hash, template);
6725         int ndx = hashval & hash->dth_mask;
6726         dtrace_hashbucket_t *bucket = hash->dth_tab[ndx];
6727
6728         for (; bucket != NULL; bucket = bucket->dthb_next) {
6729                 if (DTRACE_HASHEQ(hash, bucket->dthb_chain, template))
6730                         return (bucket->dthb_len);
6731         }
6732
6733         return (0);
6734 }
6735
6736 static void
6737 dtrace_hash_remove(dtrace_hash_t *hash, dtrace_probe_t *probe)
6738 {
6739         int ndx = DTRACE_HASHSTR(hash, probe) & hash->dth_mask;
6740         dtrace_hashbucket_t *bucket = hash->dth_tab[ndx];
6741
6742         dtrace_probe_t **prevp = DTRACE_HASHPREV(hash, probe);
6743         dtrace_probe_t **nextp = DTRACE_HASHNEXT(hash, probe);
6744
6745         /*
6746          * Find the bucket that we're removing this probe from.
6747          */
6748         for (; bucket != NULL; bucket = bucket->dthb_next) {
6749                 if (DTRACE_HASHEQ(hash, bucket->dthb_chain, probe))
6750                         break;
6751         }
6752
6753         ASSERT(bucket != NULL);
6754
6755         if (*prevp == NULL) {
6756                 if (*nextp == NULL) {
6757                         /*
6758                          * The removed probe was the only probe on this
6759                          * bucket; we need to remove the bucket.
6760                          */
6761                         dtrace_hashbucket_t *b = hash->dth_tab[ndx];
6762
6763                         ASSERT(bucket->dthb_chain == probe);
6764                         ASSERT(b != NULL);
6765
6766                         if (b == bucket) {
6767                                 hash->dth_tab[ndx] = bucket->dthb_next;
6768                         } else {
6769                                 while (b->dthb_next != bucket)
6770                                         b = b->dthb_next;
6771                                 b->dthb_next = bucket->dthb_next;
6772                         }
6773
6774                         ASSERT(hash->dth_nbuckets > 0);
6775                         hash->dth_nbuckets--;
6776                         kmem_free(bucket, sizeof (dtrace_hashbucket_t));
6777                         return;
6778                 }
6779
6780                 bucket->dthb_chain = *nextp;
6781         } else {
6782                 *(DTRACE_HASHNEXT(hash, *prevp)) = *nextp;
6783         }
6784
6785         if (*nextp != NULL)
6786                 *(DTRACE_HASHPREV(hash, *nextp)) = *prevp;
6787 }
6788
6789 /*
6790  * DTrace Utility Functions
6791  *
6792  * These are random utility functions that are _not_ called from probe context.
6793  */
6794 static int
6795 dtrace_badattr(const dtrace_attribute_t *a)
6796 {
6797         return (a->dtat_name > DTRACE_STABILITY_MAX ||
6798             a->dtat_data > DTRACE_STABILITY_MAX ||
6799             a->dtat_class > DTRACE_CLASS_MAX);
6800 }
6801
6802 /*
6803  * Return a duplicate copy of a string.  If the specified string is NULL,
6804  * this function returns a zero-length string.
6805  */
6806 static char *
6807 dtrace_strdup(const char *str)
6808 {
6809         char *new = kmem_zalloc((str != NULL ? strlen(str) : 0) + 1, KM_SLEEP);
6810
6811         if (str != NULL)
6812                 (void) strcpy(new, str);
6813
6814         return (new);
6815 }
6816
6817 #define DTRACE_ISALPHA(c)       \
6818         (((c) >= 'a' && (c) <= 'z') || ((c) >= 'A' && (c) <= 'Z'))
6819
6820 static int
6821 dtrace_badname(const char *s)
6822 {
6823         char c;
6824
6825         if (s == NULL || (c = *s++) == '\0')
6826                 return (0);
6827
6828         if (!DTRACE_ISALPHA(c) && c != '-' && c != '_' && c != '.')
6829                 return (1);
6830
6831         while ((c = *s++) != '\0') {
6832                 if (!DTRACE_ISALPHA(c) && (c < '0' || c > '9') &&
6833                     c != '-' && c != '_' && c != '.' && c != '`')
6834                         return (1);
6835         }
6836
6837         return (0);
6838 }
6839
6840 static void
6841 dtrace_cred2priv(cred_t *cr, uint32_t *privp, uid_t *uidp, zoneid_t *zoneidp)
6842 {
6843         uint32_t priv;
6844
6845 #if defined(sun)
6846         if (cr == NULL || PRIV_POLICY_ONLY(cr, PRIV_ALL, B_FALSE)) {
6847                 /*
6848                  * For DTRACE_PRIV_ALL, the uid and zoneid don't matter.
6849                  */
6850                 priv = DTRACE_PRIV_ALL;
6851         } else {
6852                 *uidp = crgetuid(cr);
6853                 *zoneidp = crgetzoneid(cr);
6854
6855                 priv = 0;
6856                 if (PRIV_POLICY_ONLY(cr, PRIV_DTRACE_KERNEL, B_FALSE))
6857                         priv |= DTRACE_PRIV_KERNEL | DTRACE_PRIV_USER;
6858                 else if (PRIV_POLICY_ONLY(cr, PRIV_DTRACE_USER, B_FALSE))
6859                         priv |= DTRACE_PRIV_USER;
6860                 if (PRIV_POLICY_ONLY(cr, PRIV_DTRACE_PROC, B_FALSE))
6861                         priv |= DTRACE_PRIV_PROC;
6862                 if (PRIV_POLICY_ONLY(cr, PRIV_PROC_OWNER, B_FALSE))
6863                         priv |= DTRACE_PRIV_OWNER;
6864                 if (PRIV_POLICY_ONLY(cr, PRIV_PROC_ZONE, B_FALSE))
6865                         priv |= DTRACE_PRIV_ZONEOWNER;
6866         }
6867 #else
6868         priv = DTRACE_PRIV_ALL;
6869 #endif
6870
6871         *privp = priv;
6872 }
6873
6874 #ifdef DTRACE_ERRDEBUG
6875 static void
6876 dtrace_errdebug(const char *str)
6877 {
6878         int hval = dtrace_hash_str(str) % DTRACE_ERRHASHSZ;
6879         int occupied = 0;
6880
6881         mutex_enter(&dtrace_errlock);
6882         dtrace_errlast = str;
6883         dtrace_errthread = curthread;
6884
6885         while (occupied++ < DTRACE_ERRHASHSZ) {
6886                 if (dtrace_errhash[hval].dter_msg == str) {
6887                         dtrace_errhash[hval].dter_count++;
6888                         goto out;
6889                 }
6890
6891                 if (dtrace_errhash[hval].dter_msg != NULL) {
6892                         hval = (hval + 1) % DTRACE_ERRHASHSZ;
6893                         continue;
6894                 }
6895
6896                 dtrace_errhash[hval].dter_msg = str;
6897                 dtrace_errhash[hval].dter_count = 1;
6898                 goto out;
6899         }
6900
6901         panic("dtrace: undersized error hash");
6902 out:
6903         mutex_exit(&dtrace_errlock);
6904 }
6905 #endif
6906
6907 /*
6908  * DTrace Matching Functions
6909  *
6910  * These functions are used to match groups of probes, given some elements of
6911  * a probe tuple, or some globbed expressions for elements of a probe tuple.
6912  */
6913 static int
6914 dtrace_match_priv(const dtrace_probe_t *prp, uint32_t priv, uid_t uid,
6915     zoneid_t zoneid)
6916 {
6917         if (priv != DTRACE_PRIV_ALL) {
6918                 uint32_t ppriv = prp->dtpr_provider->dtpv_priv.dtpp_flags;
6919                 uint32_t match = priv & ppriv;
6920
6921                 /*
6922                  * No PRIV_DTRACE_* privileges...
6923                  */
6924                 if ((priv & (DTRACE_PRIV_PROC | DTRACE_PRIV_USER |
6925                     DTRACE_PRIV_KERNEL)) == 0)
6926                         return (0);
6927
6928                 /*
6929                  * No matching bits, but there were bits to match...
6930                  */
6931                 if (match == 0 && ppriv != 0)
6932                         return (0);
6933
6934                 /*
6935                  * Need to have permissions to the process, but don't...
6936                  */
6937                 if (((ppriv & ~match) & DTRACE_PRIV_OWNER) != 0 &&
6938                     uid != prp->dtpr_provider->dtpv_priv.dtpp_uid) {
6939                         return (0);
6940                 }
6941
6942                 /*
6943                  * Need to be in the same zone unless we possess the
6944                  * privilege to examine all zones.
6945                  */
6946                 if (((ppriv & ~match) & DTRACE_PRIV_ZONEOWNER) != 0 &&
6947                     zoneid != prp->dtpr_provider->dtpv_priv.dtpp_zoneid) {
6948                         return (0);
6949                 }
6950         }
6951
6952         return (1);
6953 }
6954
6955 /*
6956  * dtrace_match_probe compares a dtrace_probe_t to a pre-compiled key, which
6957  * consists of input pattern strings and an ops-vector to evaluate them.
6958  * This function returns >0 for match, 0 for no match, and <0 for error.
6959  */
6960 static int
6961 dtrace_match_probe(const dtrace_probe_t *prp, const dtrace_probekey_t *pkp,
6962     uint32_t priv, uid_t uid, zoneid_t zoneid)
6963 {
6964         dtrace_provider_t *pvp = prp->dtpr_provider;
6965         int rv;
6966
6967         if (pvp->dtpv_defunct)
6968                 return (0);
6969
6970         if ((rv = pkp->dtpk_pmatch(pvp->dtpv_name, pkp->dtpk_prov, 0)) <= 0)
6971                 return (rv);
6972
6973         if ((rv = pkp->dtpk_mmatch(prp->dtpr_mod, pkp->dtpk_mod, 0)) <= 0)
6974                 return (rv);
6975
6976         if ((rv = pkp->dtpk_fmatch(prp->dtpr_func, pkp->dtpk_func, 0)) <= 0)
6977                 return (rv);
6978
6979         if ((rv = pkp->dtpk_nmatch(prp->dtpr_name, pkp->dtpk_name, 0)) <= 0)
6980                 return (rv);
6981
6982         if (dtrace_match_priv(prp, priv, uid, zoneid) == 0)
6983                 return (0);
6984
6985         return (rv);
6986 }
6987
6988 /*
6989  * dtrace_match_glob() is a safe kernel implementation of the gmatch(3GEN)
6990  * interface for matching a glob pattern 'p' to an input string 's'.  Unlike
6991  * libc's version, the kernel version only applies to 8-bit ASCII strings.
6992  * In addition, all of the recursion cases except for '*' matching have been
6993  * unwound.  For '*', we still implement recursive evaluation, but a depth
6994  * counter is maintained and matching is aborted if we recurse too deep.
6995  * The function returns 0 if no match, >0 if match, and <0 if recursion error.
6996  */
6997 static int
6998 dtrace_match_glob(const char *s, const char *p, int depth)
6999 {
7000         const char *olds;
7001         char s1, c;
7002         int gs;
7003
7004         if (depth > DTRACE_PROBEKEY_MAXDEPTH)
7005                 return (-1);
7006
7007         if (s == NULL)
7008                 s = ""; /* treat NULL as empty string */
7009
7010 top:
7011         olds = s;
7012         s1 = *s++;
7013
7014         if (p == NULL)
7015                 return (0);
7016
7017         if ((c = *p++) == '\0')
7018                 return (s1 == '\0');
7019
7020         switch (c) {
7021         case '[': {
7022                 int ok = 0, notflag = 0;
7023                 char lc = '\0';
7024
7025                 if (s1 == '\0')
7026                         return (0);
7027
7028                 if (*p == '!') {
7029                         notflag = 1;
7030                         p++;
7031                 }
7032
7033                 if ((c = *p++) == '\0')
7034                         return (0);
7035
7036                 do {
7037                         if (c == '-' && lc != '\0' && *p != ']') {
7038                                 if ((c = *p++) == '\0')
7039                                         return (0);
7040                                 if (c == '\\' && (c = *p++) == '\0')
7041                                         return (0);
7042
7043                                 if (notflag) {
7044                                         if (s1 < lc || s1 > c)
7045                                                 ok++;
7046                                         else
7047                                                 return (0);
7048                                 } else if (lc <= s1 && s1 <= c)
7049                                         ok++;
7050
7051                         } else if (c == '\\' && (c = *p++) == '\0')
7052                                 return (0);
7053
7054                         lc = c; /* save left-hand 'c' for next iteration */
7055
7056                         if (notflag) {
7057                                 if (s1 != c)
7058                                         ok++;
7059                                 else
7060                                         return (0);
7061                         } else if (s1 == c)
7062                                 ok++;
7063
7064                         if ((c = *p++) == '\0')
7065                                 return (0);
7066
7067                 } while (c != ']');
7068
7069                 if (ok)
7070                         goto top;
7071
7072                 return (0);
7073         }
7074
7075         case '\\':
7076                 if ((c = *p++) == '\0')
7077                         return (0);
7078                 /*FALLTHRU*/
7079
7080         default:
7081                 if (c != s1)
7082                         return (0);
7083                 /*FALLTHRU*/
7084
7085         case '?':
7086                 if (s1 != '\0')
7087                         goto top;
7088                 return (0);
7089
7090         case '*':
7091                 while (*p == '*')
7092                         p++; /* consecutive *'s are identical to a single one */
7093
7094                 if (*p == '\0')
7095                         return (1);
7096
7097                 for (s = olds; *s != '\0'; s++) {
7098                         if ((gs = dtrace_match_glob(s, p, depth + 1)) != 0)
7099                                 return (gs);
7100                 }
7101
7102                 return (0);
7103         }
7104 }
7105
7106 /*ARGSUSED*/
7107 static int
7108 dtrace_match_string(const char *s, const char *p, int depth)
7109 {
7110         return (s != NULL && strcmp(s, p) == 0);
7111 }
7112
7113 /*ARGSUSED*/
7114 static int
7115 dtrace_match_nul(const char *s, const char *p, int depth)
7116 {
7117         return (1); /* always match the empty pattern */
7118 }
7119
7120 /*ARGSUSED*/
7121 static int
7122 dtrace_match_nonzero(const char *s, const char *p, int depth)
7123 {
7124         return (s != NULL && s[0] != '\0');
7125 }
7126
7127 static int
7128 dtrace_match(const dtrace_probekey_t *pkp, uint32_t priv, uid_t uid,
7129     zoneid_t zoneid, int (*matched)(dtrace_probe_t *, void *), void *arg)
7130 {
7131         dtrace_probe_t template, *probe;
7132         dtrace_hash_t *hash = NULL;
7133         int len, best = INT_MAX, nmatched = 0;
7134         dtrace_id_t i;
7135
7136         ASSERT(MUTEX_HELD(&dtrace_lock));
7137
7138         /*
7139          * If the probe ID is specified in the key, just lookup by ID and
7140          * invoke the match callback once if a matching probe is found.
7141          */
7142         if (pkp->dtpk_id != DTRACE_IDNONE) {
7143                 if ((probe = dtrace_probe_lookup_id(pkp->dtpk_id)) != NULL &&
7144                     dtrace_match_probe(probe, pkp, priv, uid, zoneid) > 0) {
7145                         (void) (*matched)(probe, arg);
7146                         nmatched++;
7147                 }
7148                 return (nmatched);
7149         }
7150
7151         template.dtpr_mod = (char *)pkp->dtpk_mod;
7152         template.dtpr_func = (char *)pkp->dtpk_func;
7153         template.dtpr_name = (char *)pkp->dtpk_name;
7154
7155         /*
7156          * We want to find the most distinct of the module name, function
7157          * name, and name.  So for each one that is not a glob pattern or
7158          * empty string, we perform a lookup in the corresponding hash and
7159          * use the hash table with the fewest collisions to do our search.
7160          */
7161         if (pkp->dtpk_mmatch == &dtrace_match_string &&
7162             (len = dtrace_hash_collisions(dtrace_bymod, &template)) < best) {
7163                 best = len;
7164                 hash = dtrace_bymod;
7165         }
7166
7167         if (pkp->dtpk_fmatch == &dtrace_match_string &&
7168             (len = dtrace_hash_collisions(dtrace_byfunc, &template)) < best) {
7169                 best = len;
7170                 hash = dtrace_byfunc;
7171         }
7172
7173         if (pkp->dtpk_nmatch == &dtrace_match_string &&
7174             (len = dtrace_hash_collisions(dtrace_byname, &template)) < best) {
7175                 best = len;
7176                 hash = dtrace_byname;
7177         }
7178
7179         /*
7180          * If we did not select a hash table, iterate over every probe and
7181          * invoke our callback for each one that matches our input probe key.
7182          */
7183         if (hash == NULL) {
7184                 for (i = 0; i < dtrace_nprobes; i++) {
7185                         if ((probe = dtrace_probes[i]) == NULL ||
7186                             dtrace_match_probe(probe, pkp, priv, uid,
7187                             zoneid) <= 0)
7188                                 continue;
7189
7190                         nmatched++;
7191
7192                         if ((*matched)(probe, arg) != DTRACE_MATCH_NEXT)
7193                                 break;
7194                 }
7195
7196                 return (nmatched);
7197         }
7198
7199         /*
7200          * If we selected a hash table, iterate over each probe of the same key
7201          * name and invoke the callback for every probe that matches the other
7202          * attributes of our input probe key.
7203          */
7204         for (probe = dtrace_hash_lookup(hash, &template); probe != NULL;
7205             probe = *(DTRACE_HASHNEXT(hash, probe))) {
7206
7207                 if (dtrace_match_probe(probe, pkp, priv, uid, zoneid) <= 0)
7208                         continue;
7209
7210                 nmatched++;
7211
7212                 if ((*matched)(probe, arg) != DTRACE_MATCH_NEXT)
7213                         break;
7214         }
7215
7216         return (nmatched);
7217 }
7218
7219 /*
7220  * Return the function pointer dtrace_probecmp() should use to compare the
7221  * specified pattern with a string.  For NULL or empty patterns, we select
7222  * dtrace_match_nul().  For glob pattern strings, we use dtrace_match_glob().
7223  * For non-empty non-glob strings, we use dtrace_match_string().
7224  */
7225 static dtrace_probekey_f *
7226 dtrace_probekey_func(const char *p)
7227 {
7228         char c;
7229
7230         if (p == NULL || *p == '\0')
7231                 return (&dtrace_match_nul);
7232
7233         while ((c = *p++) != '\0') {
7234                 if (c == '[' || c == '?' || c == '*' || c == '\\')
7235                         return (&dtrace_match_glob);
7236         }
7237
7238         return (&dtrace_match_string);
7239 }
7240
7241 /*
7242  * Build a probe comparison key for use with dtrace_match_probe() from the
7243  * given probe description.  By convention, a null key only matches anchored
7244  * probes: if each field is the empty string, reset dtpk_fmatch to
7245  * dtrace_match_nonzero().
7246  */
7247 static void
7248 dtrace_probekey(dtrace_probedesc_t *pdp, dtrace_probekey_t *pkp)
7249 {
7250         pkp->dtpk_prov = pdp->dtpd_provider;
7251         pkp->dtpk_pmatch = dtrace_probekey_func(pdp->dtpd_provider);
7252
7253         pkp->dtpk_mod = pdp->dtpd_mod;
7254         pkp->dtpk_mmatch = dtrace_probekey_func(pdp->dtpd_mod);
7255
7256         pkp->dtpk_func = pdp->dtpd_func;
7257         pkp->dtpk_fmatch = dtrace_probekey_func(pdp->dtpd_func);
7258
7259         pkp->dtpk_name = pdp->dtpd_name;
7260         pkp->dtpk_nmatch = dtrace_probekey_func(pdp->dtpd_name);
7261
7262         pkp->dtpk_id = pdp->dtpd_id;
7263
7264         if (pkp->dtpk_id == DTRACE_IDNONE &&
7265             pkp->dtpk_pmatch == &dtrace_match_nul &&
7266             pkp->dtpk_mmatch == &dtrace_match_nul &&
7267             pkp->dtpk_fmatch == &dtrace_match_nul &&
7268             pkp->dtpk_nmatch == &dtrace_match_nul)
7269                 pkp->dtpk_fmatch = &dtrace_match_nonzero;
7270 }
7271
7272 /*
7273  * DTrace Provider-to-Framework API Functions
7274  *
7275  * These functions implement much of the Provider-to-Framework API, as
7276  * described in <sys/dtrace.h>.  The parts of the API not in this section are
7277  * the functions in the API for probe management (found below), and
7278  * dtrace_probe() itself (found above).
7279  */
7280
7281 /*
7282  * Register the calling provider with the DTrace framework.  This should
7283  * generally be called by DTrace providers in their attach(9E) entry point.
7284  */
7285 int
7286 dtrace_register(const char *name, const dtrace_pattr_t *pap, uint32_t priv,
7287     cred_t *cr, const dtrace_pops_t *pops, void *arg, dtrace_provider_id_t *idp)
7288 {
7289         dtrace_provider_t *provider;
7290
7291         if (name == NULL || pap == NULL || pops == NULL || idp == NULL) {
7292                 cmn_err(CE_WARN, "failed to register provider '%s': invalid "
7293                     "arguments", name ? name : "<NULL>");
7294                 return (EINVAL);
7295         }
7296
7297         if (name[0] == '\0' || dtrace_badname(name)) {
7298                 cmn_err(CE_WARN, "failed to register provider '%s': invalid "
7299                     "provider name", name);
7300                 return (EINVAL);
7301         }
7302
7303         if ((pops->dtps_provide == NULL && pops->dtps_provide_module == NULL) ||
7304             pops->dtps_enable == NULL || pops->dtps_disable == NULL ||
7305             pops->dtps_destroy == NULL ||
7306             ((pops->dtps_resume == NULL) != (pops->dtps_suspend == NULL))) {
7307                 cmn_err(CE_WARN, "failed to register provider '%s': invalid "
7308                     "provider ops", name);
7309                 return (EINVAL);
7310         }
7311
7312         if (dtrace_badattr(&pap->dtpa_provider) ||
7313             dtrace_badattr(&pap->dtpa_mod) ||
7314             dtrace_badattr(&pap->dtpa_func) ||
7315             dtrace_badattr(&pap->dtpa_name) ||
7316             dtrace_badattr(&pap->dtpa_args)) {
7317                 cmn_err(CE_WARN, "failed to register provider '%s': invalid "
7318                     "provider attributes", name);
7319                 return (EINVAL);
7320         }
7321
7322         if (priv & ~DTRACE_PRIV_ALL) {
7323                 cmn_err(CE_WARN, "failed to register provider '%s': invalid "
7324                     "privilege attributes", name);
7325                 return (EINVAL);
7326         }
7327
7328         if ((priv & DTRACE_PRIV_KERNEL) &&
7329             (priv & (DTRACE_PRIV_USER | DTRACE_PRIV_OWNER)) &&
7330             pops->dtps_usermode == NULL) {
7331                 cmn_err(CE_WARN, "failed to register provider '%s': need "
7332                     "dtps_usermode() op for given privilege attributes", name);
7333                 return (EINVAL);
7334         }
7335
7336         provider = kmem_zalloc(sizeof (dtrace_provider_t), KM_SLEEP);
7337         provider->dtpv_name = kmem_alloc(strlen(name) + 1, KM_SLEEP);
7338         (void) strcpy(provider->dtpv_name, name);
7339
7340         provider->dtpv_attr = *pap;
7341         provider->dtpv_priv.dtpp_flags = priv;
7342         if (cr != NULL) {
7343                 provider->dtpv_priv.dtpp_uid = crgetuid(cr);
7344                 provider->dtpv_priv.dtpp_zoneid = crgetzoneid(cr);
7345         }
7346         provider->dtpv_pops = *pops;
7347
7348         if (pops->dtps_provide == NULL) {
7349                 ASSERT(pops->dtps_provide_module != NULL);
7350                 provider->dtpv_pops.dtps_provide =
7351                     (void (*)(void *, dtrace_probedesc_t *))dtrace_nullop;
7352         }
7353
7354         if (pops->dtps_provide_module == NULL) {
7355                 ASSERT(pops->dtps_provide != NULL);
7356                 provider->dtpv_pops.dtps_provide_module =
7357                     (void (*)(void *, modctl_t *))dtrace_nullop;
7358         }
7359
7360         if (pops->dtps_suspend == NULL) {
7361                 ASSERT(pops->dtps_resume == NULL);
7362                 provider->dtpv_pops.dtps_suspend =
7363                     (void (*)(void *, dtrace_id_t, void *))dtrace_nullop;
7364                 provider->dtpv_pops.dtps_resume =
7365                     (void (*)(void *, dtrace_id_t, void *))dtrace_nullop;
7366         }
7367
7368         provider->dtpv_arg = arg;
7369         *idp = (dtrace_provider_id_t)provider;
7370
7371         if (pops == &dtrace_provider_ops) {
7372                 ASSERT(MUTEX_HELD(&dtrace_provider_lock));
7373                 ASSERT(MUTEX_HELD(&dtrace_lock));
7374                 ASSERT(dtrace_anon.dta_enabling == NULL);
7375
7376                 /*
7377                  * We make sure that the DTrace provider is at the head of
7378                  * the provider chain.
7379                  */
7380                 provider->dtpv_next = dtrace_provider;
7381                 dtrace_provider = provider;
7382                 return (0);
7383         }
7384
7385         mutex_enter(&dtrace_provider_lock);
7386         mutex_enter(&dtrace_lock);
7387
7388         /*
7389          * If there is at least one provider registered, we'll add this
7390          * provider after the first provider.
7391          */
7392         if (dtrace_provider != NULL) {
7393                 provider->dtpv_next = dtrace_provider->dtpv_next;
7394                 dtrace_provider->dtpv_next = provider;
7395         } else {
7396                 dtrace_provider = provider;
7397         }
7398
7399         if (dtrace_retained != NULL) {
7400                 dtrace_enabling_provide(provider);
7401
7402                 /*
7403                  * Now we need to call dtrace_enabling_matchall() -- which
7404                  * will acquire cpu_lock and dtrace_lock.  We therefore need
7405                  * to drop all of our locks before calling into it...
7406                  */
7407                 mutex_exit(&dtrace_lock);
7408                 mutex_exit(&dtrace_provider_lock);
7409                 dtrace_enabling_matchall();
7410
7411                 return (0);
7412         }
7413
7414         mutex_exit(&dtrace_lock);
7415         mutex_exit(&dtrace_provider_lock);
7416
7417         return (0);
7418 }
7419
7420 /*
7421  * Unregister the specified provider from the DTrace framework.  This should
7422  * generally be called by DTrace providers in their detach(9E) entry point.
7423  */
7424 int
7425 dtrace_unregister(dtrace_provider_id_t id)
7426 {
7427         dtrace_provider_t *old = (dtrace_provider_t *)id;
7428         dtrace_provider_t *prev = NULL;
7429         int i, self = 0;
7430         dtrace_probe_t *probe, *first = NULL;
7431
7432         if (old->dtpv_pops.dtps_enable ==
7433             (void (*)(void *, dtrace_id_t, void *))dtrace_nullop) {
7434                 /*
7435                  * If DTrace itself is the provider, we're called with locks
7436                  * already held.
7437                  */
7438                 ASSERT(old == dtrace_provider);
7439 #if defined(sun)
7440                 ASSERT(dtrace_devi != NULL);
7441 #endif
7442                 ASSERT(MUTEX_HELD(&dtrace_provider_lock));
7443                 ASSERT(MUTEX_HELD(&dtrace_lock));
7444                 self = 1;
7445
7446                 if (dtrace_provider->dtpv_next != NULL) {
7447                         /*
7448                          * There's another provider here; return failure.
7449                          */
7450                         return (EBUSY);
7451                 }
7452         } else {
7453                 mutex_enter(&dtrace_provider_lock);
7454                 mutex_enter(&mod_lock);
7455                 mutex_enter(&dtrace_lock);
7456         }
7457
7458         /*
7459          * If anyone has /dev/dtrace open, or if there are anonymous enabled
7460          * probes, we refuse to let providers slither away, unless this
7461          * provider has already been explicitly invalidated.
7462          */
7463         if (!old->dtpv_defunct &&
7464             (dtrace_opens || (dtrace_anon.dta_state != NULL &&
7465             dtrace_anon.dta_state->dts_necbs > 0))) {
7466                 if (!self) {
7467                         mutex_exit(&dtrace_lock);
7468                         mutex_exit(&mod_lock);
7469                         mutex_exit(&dtrace_provider_lock);
7470                 }
7471                 return (EBUSY);
7472         }
7473
7474         /*
7475          * Attempt to destroy the probes associated with this provider.
7476          */
7477         for (i = 0; i < dtrace_nprobes; i++) {
7478                 if ((probe = dtrace_probes[i]) == NULL)
7479                         continue;
7480
7481                 if (probe->dtpr_provider != old)
7482                         continue;
7483
7484                 if (probe->dtpr_ecb == NULL)
7485                         continue;
7486
7487                 /*
7488                  * We have at least one ECB; we can't remove this provider.
7489                  */
7490                 if (!self) {
7491                         mutex_exit(&dtrace_lock);
7492                         mutex_exit(&mod_lock);
7493                         mutex_exit(&dtrace_provider_lock);
7494                 }
7495                 return (EBUSY);
7496         }
7497
7498         /*
7499          * All of the probes for this provider are disabled; we can safely
7500          * remove all of them from their hash chains and from the probe array.
7501          */
7502         for (i = 0; i < dtrace_nprobes; i++) {
7503                 if ((probe = dtrace_probes[i]) == NULL)
7504                         continue;
7505
7506                 if (probe->dtpr_provider != old)
7507                         continue;
7508
7509                 dtrace_probes[i] = NULL;
7510
7511                 dtrace_hash_remove(dtrace_bymod, probe);
7512                 dtrace_hash_remove(dtrace_byfunc, probe);
7513                 dtrace_hash_remove(dtrace_byname, probe);
7514
7515                 if (first == NULL) {
7516                         first = probe;
7517                         probe->dtpr_nextmod = NULL;
7518                 } else {
7519                         probe->dtpr_nextmod = first;
7520                         first = probe;
7521                 }
7522         }
7523
7524         /*
7525          * The provider's probes have been removed from the hash chains and
7526          * from the probe array.  Now issue a dtrace_sync() to be sure that
7527          * everyone has cleared out from any probe array processing.
7528          */
7529         dtrace_sync();
7530
7531         for (probe = first; probe != NULL; probe = first) {
7532                 first = probe->dtpr_nextmod;
7533
7534                 old->dtpv_pops.dtps_destroy(old->dtpv_arg, probe->dtpr_id,
7535                     probe->dtpr_arg);
7536                 kmem_free(probe->dtpr_mod, strlen(probe->dtpr_mod) + 1);
7537                 kmem_free(probe->dtpr_func, strlen(probe->dtpr_func) + 1);
7538                 kmem_free(probe->dtpr_name, strlen(probe->dtpr_name) + 1);
7539 #if defined(sun)
7540                 vmem_free(dtrace_arena, (void *)(uintptr_t)(probe->dtpr_id), 1);
7541 #else
7542                 free_unr(dtrace_arena, probe->dtpr_id);
7543 #endif
7544                 kmem_free(probe, sizeof (dtrace_probe_t));
7545         }
7546
7547         if ((prev = dtrace_provider) == old) {
7548 #if defined(sun)
7549                 ASSERT(self || dtrace_devi == NULL);
7550                 ASSERT(old->dtpv_next == NULL || dtrace_devi == NULL);
7551 #endif
7552                 dtrace_provider = old->dtpv_next;
7553         } else {
7554                 while (prev != NULL && prev->dtpv_next != old)
7555                         prev = prev->dtpv_next;
7556
7557                 if (prev == NULL) {
7558                         panic("attempt to unregister non-existent "
7559                             "dtrace provider %p\n", (void *)id);
7560                 }
7561
7562                 prev->dtpv_next = old->dtpv_next;
7563         }
7564
7565         if (!self) {
7566                 mutex_exit(&dtrace_lock);
7567                 mutex_exit(&mod_lock);
7568                 mutex_exit(&dtrace_provider_lock);
7569         }
7570
7571         kmem_free(old->dtpv_name, strlen(old->dtpv_name) + 1);
7572         kmem_free(old, sizeof (dtrace_provider_t));
7573
7574         return (0);
7575 }
7576
7577 /*
7578  * Invalidate the specified provider.  All subsequent probe lookups for the
7579  * specified provider will fail, but its probes will not be removed.
7580  */
7581 void
7582 dtrace_invalidate(dtrace_provider_id_t id)
7583 {
7584         dtrace_provider_t *pvp = (dtrace_provider_t *)id;
7585
7586         ASSERT(pvp->dtpv_pops.dtps_enable !=
7587             (void (*)(void *, dtrace_id_t, void *))dtrace_nullop);
7588
7589         mutex_enter(&dtrace_provider_lock);
7590         mutex_enter(&dtrace_lock);
7591
7592         pvp->dtpv_defunct = 1;
7593
7594         mutex_exit(&dtrace_lock);
7595         mutex_exit(&dtrace_provider_lock);
7596 }
7597
7598 /*
7599  * Indicate whether or not DTrace has attached.
7600  */
7601 int
7602 dtrace_attached(void)
7603 {
7604         /*
7605          * dtrace_provider will be non-NULL iff the DTrace driver has
7606          * attached.  (It's non-NULL because DTrace is always itself a
7607          * provider.)
7608          */
7609         return (dtrace_provider != NULL);
7610 }
7611
7612 /*
7613  * Remove all the unenabled probes for the given provider.  This function is
7614  * not unlike dtrace_unregister(), except that it doesn't remove the provider
7615  * -- just as many of its associated probes as it can.
7616  */
7617 int
7618 dtrace_condense(dtrace_provider_id_t id)
7619 {
7620         dtrace_provider_t *prov = (dtrace_provider_t *)id;
7621         int i;
7622         dtrace_probe_t *probe;
7623
7624         /*
7625          * Make sure this isn't the dtrace provider itself.
7626          */
7627         ASSERT(prov->dtpv_pops.dtps_enable !=
7628             (void (*)(void *, dtrace_id_t, void *))dtrace_nullop);
7629
7630         mutex_enter(&dtrace_provider_lock);
7631         mutex_enter(&dtrace_lock);
7632
7633         /*
7634          * Attempt to destroy the probes associated with this provider.
7635          */
7636         for (i = 0; i < dtrace_nprobes; i++) {
7637                 if ((probe = dtrace_probes[i]) == NULL)
7638                         continue;
7639
7640                 if (probe->dtpr_provider != prov)
7641                         continue;
7642
7643                 if (probe->dtpr_ecb != NULL)
7644                         continue;
7645
7646                 dtrace_probes[i] = NULL;
7647
7648                 dtrace_hash_remove(dtrace_bymod, probe);
7649                 dtrace_hash_remove(dtrace_byfunc, probe);
7650                 dtrace_hash_remove(dtrace_byname, probe);
7651
7652                 prov->dtpv_pops.dtps_destroy(prov->dtpv_arg, i + 1,
7653                     probe->dtpr_arg);
7654                 kmem_free(probe->dtpr_mod, strlen(probe->dtpr_mod) + 1);
7655                 kmem_free(probe->dtpr_func, strlen(probe->dtpr_func) + 1);
7656                 kmem_free(probe->dtpr_name, strlen(probe->dtpr_name) + 1);
7657                 kmem_free(probe, sizeof (dtrace_probe_t));
7658 #if defined(sun)
7659                 vmem_free(dtrace_arena, (void *)((uintptr_t)i + 1), 1);
7660 #else
7661                 free_unr(dtrace_arena, i + 1);
7662 #endif
7663         }
7664
7665         mutex_exit(&dtrace_lock);
7666         mutex_exit(&dtrace_provider_lock);
7667
7668         return (0);
7669 }
7670
7671 /*
7672  * DTrace Probe Management Functions
7673  *
7674  * The functions in this section perform the DTrace probe management,
7675  * including functions to create probes, look-up probes, and call into the
7676  * providers to request that probes be provided.  Some of these functions are
7677  * in the Provider-to-Framework API; these functions can be identified by the
7678  * fact that they are not declared "static".
7679  */
7680
7681 /*
7682  * Create a probe with the specified module name, function name, and name.
7683  */
7684 dtrace_id_t
7685 dtrace_probe_create(dtrace_provider_id_t prov, const char *mod,
7686     const char *func, const char *name, int aframes, void *arg)
7687 {
7688         dtrace_probe_t *probe, **probes;
7689         dtrace_provider_t *provider = (dtrace_provider_t *)prov;
7690         dtrace_id_t id;
7691
7692         if (provider == dtrace_provider) {
7693                 ASSERT(MUTEX_HELD(&dtrace_lock));
7694         } else {
7695                 mutex_enter(&dtrace_lock);
7696         }
7697
7698 #if defined(sun)
7699         id = (dtrace_id_t)(uintptr_t)vmem_alloc(dtrace_arena, 1,
7700             VM_BESTFIT | VM_SLEEP);
7701 #else
7702         id = alloc_unr(dtrace_arena);
7703 #endif
7704         probe = kmem_zalloc(sizeof (dtrace_probe_t), KM_SLEEP);
7705
7706         probe->dtpr_id = id;
7707         probe->dtpr_gen = dtrace_probegen++;
7708         probe->dtpr_mod = dtrace_strdup(mod);
7709         probe->dtpr_func = dtrace_strdup(func);
7710         probe->dtpr_name = dtrace_strdup(name);
7711         probe->dtpr_arg = arg;
7712         probe->dtpr_aframes = aframes;
7713         probe->dtpr_provider = provider;
7714
7715         dtrace_hash_add(dtrace_bymod, probe);
7716         dtrace_hash_add(dtrace_byfunc, probe);
7717         dtrace_hash_add(dtrace_byname, probe);
7718
7719         if (id - 1 >= dtrace_nprobes) {
7720                 size_t osize = dtrace_nprobes * sizeof (dtrace_probe_t *);
7721                 size_t nsize = osize << 1;
7722
7723                 if (nsize == 0) {
7724                         ASSERT(osize == 0);
7725                         ASSERT(dtrace_probes == NULL);
7726                         nsize = sizeof (dtrace_probe_t *);
7727                 }
7728
7729                 probes = kmem_zalloc(nsize, KM_SLEEP);
7730
7731                 if (dtrace_probes == NULL) {
7732                         ASSERT(osize == 0);
7733                         dtrace_probes = probes;
7734                         dtrace_nprobes = 1;
7735                 } else {
7736                         dtrace_probe_t **oprobes = dtrace_probes;
7737
7738                         bcopy(oprobes, probes, osize);
7739                         dtrace_membar_producer();
7740                         dtrace_probes = probes;
7741
7742                         dtrace_sync();
7743
7744                         /*
7745                          * All CPUs are now seeing the new probes array; we can
7746                          * safely free the old array.
7747                          */
7748                         kmem_free(oprobes, osize);
7749                         dtrace_nprobes <<= 1;
7750                 }
7751
7752                 ASSERT(id - 1 < dtrace_nprobes);
7753         }
7754
7755         ASSERT(dtrace_probes[id - 1] == NULL);
7756         dtrace_probes[id - 1] = probe;
7757
7758         if (provider != dtrace_provider)
7759                 mutex_exit(&dtrace_lock);
7760
7761         return (id);
7762 }
7763
7764 static dtrace_probe_t *
7765 dtrace_probe_lookup_id(dtrace_id_t id)
7766 {
7767         ASSERT(MUTEX_HELD(&dtrace_lock));
7768
7769         if (id == 0 || id > dtrace_nprobes)
7770                 return (NULL);
7771
7772         return (dtrace_probes[id - 1]);
7773 }
7774
7775 static int
7776 dtrace_probe_lookup_match(dtrace_probe_t *probe, void *arg)
7777 {
7778         *((dtrace_id_t *)arg) = probe->dtpr_id;
7779
7780         return (DTRACE_MATCH_DONE);
7781 }
7782
7783 /*
7784  * Look up a probe based on provider and one or more of module name, function
7785  * name and probe name.
7786  */
7787 dtrace_id_t
7788 dtrace_probe_lookup(dtrace_provider_id_t prid, char *mod,
7789     char *func, char *name)
7790 {
7791         dtrace_probekey_t pkey;
7792         dtrace_id_t id;
7793         int match;
7794
7795         pkey.dtpk_prov = ((dtrace_provider_t *)prid)->dtpv_name;
7796         pkey.dtpk_pmatch = &dtrace_match_string;
7797         pkey.dtpk_mod = mod;
7798         pkey.dtpk_mmatch = mod ? &dtrace_match_string : &dtrace_match_nul;
7799         pkey.dtpk_func = func;
7800         pkey.dtpk_fmatch = func ? &dtrace_match_string : &dtrace_match_nul;
7801         pkey.dtpk_name = name;
7802         pkey.dtpk_nmatch = name ? &dtrace_match_string : &dtrace_match_nul;
7803         pkey.dtpk_id = DTRACE_IDNONE;
7804
7805         mutex_enter(&dtrace_lock);
7806         match = dtrace_match(&pkey, DTRACE_PRIV_ALL, 0, 0,
7807             dtrace_probe_lookup_match, &id);
7808         mutex_exit(&dtrace_lock);
7809
7810         ASSERT(match == 1 || match == 0);
7811         return (match ? id : 0);
7812 }
7813
7814 /*
7815  * Returns the probe argument associated with the specified probe.
7816  */
7817 void *
7818 dtrace_probe_arg(dtrace_provider_id_t id, dtrace_id_t pid)
7819 {
7820         dtrace_probe_t *probe;
7821         void *rval = NULL;
7822
7823         mutex_enter(&dtrace_lock);
7824
7825         if ((probe = dtrace_probe_lookup_id(pid)) != NULL &&
7826             probe->dtpr_provider == (dtrace_provider_t *)id)
7827                 rval = probe->dtpr_arg;
7828
7829         mutex_exit(&dtrace_lock);
7830
7831         return (rval);
7832 }
7833
7834 /*
7835  * Copy a probe into a probe description.
7836  */
7837 static void
7838 dtrace_probe_description(const dtrace_probe_t *prp, dtrace_probedesc_t *pdp)
7839 {
7840         bzero(pdp, sizeof (dtrace_probedesc_t));
7841         pdp->dtpd_id = prp->dtpr_id;
7842
7843         (void) strncpy(pdp->dtpd_provider,
7844             prp->dtpr_provider->dtpv_name, DTRACE_PROVNAMELEN - 1);
7845
7846         (void) strncpy(pdp->dtpd_mod, prp->dtpr_mod, DTRACE_MODNAMELEN - 1);
7847         (void) strncpy(pdp->dtpd_func, prp->dtpr_func, DTRACE_FUNCNAMELEN - 1);
7848         (void) strncpy(pdp->dtpd_name, prp->dtpr_name, DTRACE_NAMELEN - 1);
7849 }
7850
7851 #if !defined(sun)
7852 static int
7853 dtrace_probe_provide_cb(linker_file_t lf, void *arg)
7854 {
7855         dtrace_provider_t *prv = (dtrace_provider_t *) arg;
7856
7857         prv->dtpv_pops.dtps_provide_module(prv->dtpv_arg, lf);
7858
7859         return(0);
7860 }
7861 #endif
7862
7863
7864 /*
7865  * Called to indicate that a probe -- or probes -- should be provided by a
7866  * specfied provider.  If the specified description is NULL, the provider will
7867  * be told to provide all of its probes.  (This is done whenever a new
7868  * consumer comes along, or whenever a retained enabling is to be matched.) If
7869  * the specified description is non-NULL, the provider is given the
7870  * opportunity to dynamically provide the specified probe, allowing providers
7871  * to support the creation of probes on-the-fly.  (So-called _autocreated_
7872  * probes.)  If the provider is NULL, the operations will be applied to all
7873  * providers; if the provider is non-NULL the operations will only be applied
7874  * to the specified provider.  The dtrace_provider_lock must be held, and the
7875  * dtrace_lock must _not_ be held -- the provider's dtps_provide() operation
7876  * will need to grab the dtrace_lock when it reenters the framework through
7877  * dtrace_probe_lookup(), dtrace_probe_create(), etc.
7878  */
7879 static void
7880 dtrace_probe_provide(dtrace_probedesc_t *desc, dtrace_provider_t *prv)
7881 {
7882 #if defined(sun)
7883         modctl_t *ctl;
7884 #endif
7885         int all = 0;
7886
7887         ASSERT(MUTEX_HELD(&dtrace_provider_lock));
7888
7889         if (prv == NULL) {
7890                 all = 1;
7891                 prv = dtrace_provider;
7892         }
7893
7894         do {
7895                 /*
7896                  * First, call the blanket provide operation.
7897                  */
7898                 prv->dtpv_pops.dtps_provide(prv->dtpv_arg, desc);
7899
7900                 /*
7901                  * Now call the per-module provide operation.  We will grab
7902                  * mod_lock to prevent the list from being modified.  Note
7903                  * that this also prevents the mod_busy bits from changing.
7904                  * (mod_busy can only be changed with mod_lock held.)
7905                  */
7906                 mutex_enter(&mod_lock);
7907
7908 #if defined(sun)
7909                 ctl = &modules;
7910                 do {
7911                         if (ctl->mod_busy || ctl->mod_mp == NULL)
7912                                 continue;
7913
7914                         prv->dtpv_pops.dtps_provide_module(prv->dtpv_arg, ctl);
7915
7916                 } while ((ctl = ctl->mod_next) != &modules);
7917 #else
7918                 (void) linker_file_foreach(dtrace_probe_provide_cb, prv);
7919 #endif
7920
7921                 mutex_exit(&mod_lock);
7922         } while (all && (prv = prv->dtpv_next) != NULL);
7923 }
7924
7925 #if defined(sun)
7926 /*
7927  * Iterate over each probe, and call the Framework-to-Provider API function
7928  * denoted by offs.
7929  */
7930 static void
7931 dtrace_probe_foreach(uintptr_t offs)
7932 {
7933         dtrace_provider_t *prov;
7934         void (*func)(void *, dtrace_id_t, void *);
7935         dtrace_probe_t *probe;
7936         dtrace_icookie_t cookie;
7937         int i;
7938
7939         /*
7940          * We disable interrupts to walk through the probe array.  This is
7941          * safe -- the dtrace_sync() in dtrace_unregister() assures that we
7942          * won't see stale data.
7943          */
7944         cookie = dtrace_interrupt_disable();
7945
7946         for (i = 0; i < dtrace_nprobes; i++) {
7947                 if ((probe = dtrace_probes[i]) == NULL)
7948                         continue;
7949
7950                 if (probe->dtpr_ecb == NULL) {
7951                         /*
7952                          * This probe isn't enabled -- don't call the function.
7953                          */
7954                         continue;
7955                 }
7956
7957                 prov = probe->dtpr_provider;
7958                 func = *((void(**)(void *, dtrace_id_t, void *))
7959                     ((uintptr_t)&prov->dtpv_pops + offs));
7960
7961                 func(prov->dtpv_arg, i + 1, probe->dtpr_arg);
7962         }
7963
7964         dtrace_interrupt_enable(cookie);
7965 }
7966 #endif
7967
7968 static int
7969 dtrace_probe_enable(dtrace_probedesc_t *desc, dtrace_enabling_t *enab)
7970 {
7971         dtrace_probekey_t pkey;
7972         uint32_t priv;
7973         uid_t uid;
7974         zoneid_t zoneid;
7975
7976         ASSERT(MUTEX_HELD(&dtrace_lock));
7977         dtrace_ecb_create_cache = NULL;
7978
7979         if (desc == NULL) {
7980                 /*
7981                  * If we're passed a NULL description, we're being asked to
7982                  * create an ECB with a NULL probe.
7983                  */
7984                 (void) dtrace_ecb_create_enable(NULL, enab);
7985                 return (0);
7986         }
7987
7988         dtrace_probekey(desc, &pkey);
7989         dtrace_cred2priv(enab->dten_vstate->dtvs_state->dts_cred.dcr_cred,
7990             &priv, &uid, &zoneid);
7991
7992         return (dtrace_match(&pkey, priv, uid, zoneid, dtrace_ecb_create_enable,
7993             enab));
7994 }
7995
7996 /*
7997  * DTrace Helper Provider Functions
7998  */
7999 static void
8000 dtrace_dofattr2attr(dtrace_attribute_t *attr, const dof_attr_t dofattr)
8001 {
8002         attr->dtat_name = DOF_ATTR_NAME(dofattr);
8003         attr->dtat_data = DOF_ATTR_DATA(dofattr);
8004         attr->dtat_class = DOF_ATTR_CLASS(dofattr);
8005 }
8006
8007 static void
8008 dtrace_dofprov2hprov(dtrace_helper_provdesc_t *hprov,
8009     const dof_provider_t *dofprov, char *strtab)
8010 {
8011         hprov->dthpv_provname = strtab + dofprov->dofpv_name;
8012         dtrace_dofattr2attr(&hprov->dthpv_pattr.dtpa_provider,
8013             dofprov->dofpv_provattr);
8014         dtrace_dofattr2attr(&hprov->dthpv_pattr.dtpa_mod,
8015             dofprov->dofpv_modattr);
8016         dtrace_dofattr2attr(&hprov->dthpv_pattr.dtpa_func,
8017             dofprov->dofpv_funcattr);
8018         dtrace_dofattr2attr(&hprov->dthpv_pattr.dtpa_name,
8019             dofprov->dofpv_nameattr);
8020         dtrace_dofattr2attr(&hprov->dthpv_pattr.dtpa_args,
8021             dofprov->dofpv_argsattr);
8022 }
8023
8024 static void
8025 dtrace_helper_provide_one(dof_helper_t *dhp, dof_sec_t *sec, pid_t pid)
8026 {
8027         uintptr_t daddr = (uintptr_t)dhp->dofhp_dof;
8028         dof_hdr_t *dof = (dof_hdr_t *)daddr;
8029         dof_sec_t *str_sec, *prb_sec, *arg_sec, *off_sec, *enoff_sec;
8030         dof_provider_t *provider;
8031         dof_probe_t *probe;
8032         uint32_t *off, *enoff;
8033         uint8_t *arg;
8034         char *strtab;
8035         uint_t i, nprobes;
8036         dtrace_helper_provdesc_t dhpv;
8037         dtrace_helper_probedesc_t dhpb;
8038         dtrace_meta_t *meta = dtrace_meta_pid;
8039         dtrace_mops_t *mops = &meta->dtm_mops;
8040         void *parg;
8041
8042         provider = (dof_provider_t *)(uintptr_t)(daddr + sec->dofs_offset);
8043         str_sec = (dof_sec_t *)(uintptr_t)(daddr + dof->dofh_secoff +
8044             provider->dofpv_strtab * dof->dofh_secsize);
8045         prb_sec = (dof_sec_t *)(uintptr_t)(daddr + dof->dofh_secoff +
8046             provider->dofpv_probes * dof->dofh_secsize);
8047         arg_sec = (dof_sec_t *)(uintptr_t)(daddr + dof->dofh_secoff +
8048             provider->dofpv_prargs * dof->dofh_secsize);
8049         off_sec = (dof_sec_t *)(uintptr_t)(daddr + dof->dofh_secoff +
8050             provider->dofpv_proffs * dof->dofh_secsize);
8051
8052         strtab = (char *)(uintptr_t)(daddr + str_sec->dofs_offset);
8053         off = (uint32_t *)(uintptr_t)(daddr + off_sec->dofs_offset);
8054         arg = (uint8_t *)(uintptr_t)(daddr + arg_sec->dofs_offset);
8055         enoff = NULL;
8056
8057         /*
8058          * See dtrace_helper_provider_validate().
8059          */
8060         if (dof->dofh_ident[DOF_ID_VERSION] != DOF_VERSION_1 &&
8061             provider->dofpv_prenoffs != DOF_SECT_NONE) {
8062                 enoff_sec = (dof_sec_t *)(uintptr_t)(daddr + dof->dofh_secoff +
8063                     provider->dofpv_prenoffs * dof->dofh_secsize);
8064                 enoff = (uint32_t *)(uintptr_t)(daddr + enoff_sec->dofs_offset);
8065         }
8066
8067         nprobes = prb_sec->dofs_size / prb_sec->dofs_entsize;
8068
8069         /*
8070          * Create the provider.
8071          */
8072         dtrace_dofprov2hprov(&dhpv, provider, strtab);
8073
8074         if ((parg = mops->dtms_provide_pid(meta->dtm_arg, &dhpv, pid)) == NULL)
8075                 return;
8076
8077         meta->dtm_count++;
8078
8079         /*
8080          * Create the probes.
8081          */
8082         for (i = 0; i < nprobes; i++) {
8083                 probe = (dof_probe_t *)(uintptr_t)(daddr +
8084                     prb_sec->dofs_offset + i * prb_sec->dofs_entsize);
8085
8086                 dhpb.dthpb_mod = dhp->dofhp_mod;
8087                 dhpb.dthpb_func = strtab + probe->dofpr_func;
8088                 dhpb.dthpb_name = strtab + probe->dofpr_name;
8089                 dhpb.dthpb_base = probe->dofpr_addr;
8090                 dhpb.dthpb_offs = off + probe->dofpr_offidx;
8091                 dhpb.dthpb_noffs = probe->dofpr_noffs;
8092                 if (enoff != NULL) {
8093                         dhpb.dthpb_enoffs = enoff + probe->dofpr_enoffidx;
8094                         dhpb.dthpb_nenoffs = probe->dofpr_nenoffs;
8095                 } else {
8096                         dhpb.dthpb_enoffs = NULL;
8097                         dhpb.dthpb_nenoffs = 0;
8098                 }
8099                 dhpb.dthpb_args = arg + probe->dofpr_argidx;
8100                 dhpb.dthpb_nargc = probe->dofpr_nargc;
8101                 dhpb.dthpb_xargc = probe->dofpr_xargc;
8102                 dhpb.dthpb_ntypes = strtab + probe->dofpr_nargv;
8103                 dhpb.dthpb_xtypes = strtab + probe->dofpr_xargv;
8104
8105                 mops->dtms_create_probe(meta->dtm_arg, parg, &dhpb);
8106         }
8107 }
8108
8109 static void
8110 dtrace_helper_provide(dof_helper_t *dhp, pid_t pid)
8111 {
8112         uintptr_t daddr = (uintptr_t)dhp->dofhp_dof;
8113         dof_hdr_t *dof = (dof_hdr_t *)daddr;
8114         int i;
8115
8116         ASSERT(MUTEX_HELD(&dtrace_meta_lock));
8117
8118         for (i = 0; i < dof->dofh_secnum; i++) {
8119                 dof_sec_t *sec = (dof_sec_t *)(uintptr_t)(daddr +
8120                     dof->dofh_secoff + i * dof->dofh_secsize);
8121
8122                 if (sec->dofs_type != DOF_SECT_PROVIDER)
8123                         continue;
8124
8125                 dtrace_helper_provide_one(dhp, sec, pid);
8126         }
8127
8128         /*
8129          * We may have just created probes, so we must now rematch against
8130          * any retained enablings.  Note that this call will acquire both
8131          * cpu_lock and dtrace_lock; the fact that we are holding
8132          * dtrace_meta_lock now is what defines the ordering with respect to
8133          * these three locks.
8134          */
8135         dtrace_enabling_matchall();
8136 }
8137
8138 #if defined(sun)
8139 static void
8140 dtrace_helper_provider_remove_one(dof_helper_t *dhp, dof_sec_t *sec, pid_t pid)
8141 {
8142         uintptr_t daddr = (uintptr_t)dhp->dofhp_dof;
8143         dof_hdr_t *dof = (dof_hdr_t *)daddr;
8144         dof_sec_t *str_sec;
8145         dof_provider_t *provider;
8146         char *strtab;
8147         dtrace_helper_provdesc_t dhpv;
8148         dtrace_meta_t *meta = dtrace_meta_pid;
8149         dtrace_mops_t *mops = &meta->dtm_mops;
8150
8151         provider = (dof_provider_t *)(uintptr_t)(daddr + sec->dofs_offset);
8152         str_sec = (dof_sec_t *)(uintptr_t)(daddr + dof->dofh_secoff +
8153             provider->dofpv_strtab * dof->dofh_secsize);
8154
8155         strtab = (char *)(uintptr_t)(daddr + str_sec->dofs_offset);
8156
8157         /*
8158          * Create the provider.
8159          */
8160         dtrace_dofprov2hprov(&dhpv, provider, strtab);
8161
8162         mops->dtms_remove_pid(meta->dtm_arg, &dhpv, pid);
8163
8164         meta->dtm_count--;
8165 }
8166
8167 static void
8168 dtrace_helper_provider_remove(dof_helper_t *dhp, pid_t pid)
8169 {
8170         uintptr_t daddr = (uintptr_t)dhp->dofhp_dof;
8171         dof_hdr_t *dof = (dof_hdr_t *)daddr;
8172         int i;
8173
8174         ASSERT(MUTEX_HELD(&dtrace_meta_lock));
8175
8176         for (i = 0; i < dof->dofh_secnum; i++) {
8177                 dof_sec_t *sec = (dof_sec_t *)(uintptr_t)(daddr +
8178                     dof->dofh_secoff + i * dof->dofh_secsize);
8179
8180                 if (sec->dofs_type != DOF_SECT_PROVIDER)
8181                         continue;
8182
8183                 dtrace_helper_provider_remove_one(dhp, sec, pid);
8184         }
8185 }
8186 #endif
8187
8188 /*
8189  * DTrace Meta Provider-to-Framework API Functions
8190  *
8191  * These functions implement the Meta Provider-to-Framework API, as described
8192  * in <sys/dtrace.h>.
8193  */
8194 int
8195 dtrace_meta_register(const char *name, const dtrace_mops_t *mops, void *arg,
8196     dtrace_meta_provider_id_t *idp)
8197 {
8198         dtrace_meta_t *meta;
8199         dtrace_helpers_t *help, *next;
8200         int i;
8201
8202         *idp = DTRACE_METAPROVNONE;
8203
8204         /*
8205          * We strictly don't need the name, but we hold onto it for
8206          * debuggability. All hail error queues!
8207          */
8208         if (name == NULL) {
8209                 cmn_err(CE_WARN, "failed to register meta-provider: "
8210                     "invalid name");
8211                 return (EINVAL);
8212         }
8213
8214         if (mops == NULL ||
8215             mops->dtms_create_probe == NULL ||
8216             mops->dtms_provide_pid == NULL ||
8217             mops->dtms_remove_pid == NULL) {
8218                 cmn_err(CE_WARN, "failed to register meta-register %s: "
8219                     "invalid ops", name);
8220                 return (EINVAL);
8221         }
8222
8223         meta = kmem_zalloc(sizeof (dtrace_meta_t), KM_SLEEP);
8224         meta->dtm_mops = *mops;
8225         meta->dtm_name = kmem_alloc(strlen(name) + 1, KM_SLEEP);
8226         (void) strcpy(meta->dtm_name, name);
8227         meta->dtm_arg = arg;
8228
8229         mutex_enter(&dtrace_meta_lock);
8230         mutex_enter(&dtrace_lock);
8231
8232         if (dtrace_meta_pid != NULL) {
8233                 mutex_exit(&dtrace_lock);
8234                 mutex_exit(&dtrace_meta_lock);
8235                 cmn_err(CE_WARN, "failed to register meta-register %s: "
8236                     "user-land meta-provider exists", name);
8237                 kmem_free(meta->dtm_name, strlen(meta->dtm_name) + 1);
8238                 kmem_free(meta, sizeof (dtrace_meta_t));
8239                 return (EINVAL);
8240         }
8241
8242         dtrace_meta_pid = meta;
8243         *idp = (dtrace_meta_provider_id_t)meta;
8244
8245         /*
8246          * If there are providers and probes ready to go, pass them
8247          * off to the new meta provider now.
8248          */
8249
8250         help = dtrace_deferred_pid;
8251         dtrace_deferred_pid = NULL;
8252
8253         mutex_exit(&dtrace_lock);
8254
8255         while (help != NULL) {
8256                 for (i = 0; i < help->dthps_nprovs; i++) {
8257                         dtrace_helper_provide(&help->dthps_provs[i]->dthp_prov,
8258                             help->dthps_pid);
8259                 }
8260
8261                 next = help->dthps_next;
8262                 help->dthps_next = NULL;
8263                 help->dthps_prev = NULL;
8264                 help->dthps_deferred = 0;
8265                 help = next;
8266         }
8267
8268         mutex_exit(&dtrace_meta_lock);
8269
8270         return (0);
8271 }
8272
8273 int
8274 dtrace_meta_unregister(dtrace_meta_provider_id_t id)
8275 {
8276         dtrace_meta_t **pp, *old = (dtrace_meta_t *)id;
8277
8278         mutex_enter(&dtrace_meta_lock);
8279         mutex_enter(&dtrace_lock);
8280
8281         if (old == dtrace_meta_pid) {
8282                 pp = &dtrace_meta_pid;
8283         } else {
8284                 panic("attempt to unregister non-existent "
8285                     "dtrace meta-provider %p\n", (void *)old);
8286         }
8287
8288         if (old->dtm_count != 0) {
8289                 mutex_exit(&dtrace_lock);
8290                 mutex_exit(&dtrace_meta_lock);
8291                 return (EBUSY);
8292         }
8293
8294         *pp = NULL;
8295
8296         mutex_exit(&dtrace_lock);
8297         mutex_exit(&dtrace_meta_lock);
8298
8299         kmem_free(old->dtm_name, strlen(old->dtm_name) + 1);
8300         kmem_free(old, sizeof (dtrace_meta_t));
8301
8302         return (0);
8303 }
8304
8305
8306 /*
8307  * DTrace DIF Object Functions
8308  */
8309 static int
8310 dtrace_difo_err(uint_t pc, const char *format, ...)
8311 {
8312         if (dtrace_err_verbose) {
8313                 va_list alist;
8314
8315                 (void) uprintf("dtrace DIF object error: [%u]: ", pc);
8316                 va_start(alist, format);
8317                 (void) vuprintf(format, alist);
8318                 va_end(alist);
8319         }
8320
8321 #ifdef DTRACE_ERRDEBUG
8322         dtrace_errdebug(format);
8323 #endif
8324         return (1);
8325 }
8326
8327 /*
8328  * Validate a DTrace DIF object by checking the IR instructions.  The following
8329  * rules are currently enforced by dtrace_difo_validate():
8330  *
8331  * 1. Each instruction must have a valid opcode
8332  * 2. Each register, string, variable, or subroutine reference must be valid
8333  * 3. No instruction can modify register %r0 (must be zero)
8334  * 4. All instruction reserved bits must be set to zero
8335  * 5. The last instruction must be a "ret" instruction
8336  * 6. All branch targets must reference a valid instruction _after_ the branch
8337  */
8338 static int
8339 dtrace_difo_validate(dtrace_difo_t *dp, dtrace_vstate_t *vstate, uint_t nregs,
8340     cred_t *cr)
8341 {
8342         int err = 0, i;
8343         int (*efunc)(uint_t pc, const char *, ...) = dtrace_difo_err;
8344         int kcheckload;
8345         uint_t pc;
8346
8347         kcheckload = cr == NULL ||
8348             (vstate->dtvs_state->dts_cred.dcr_visible & DTRACE_CRV_KERNEL) == 0;
8349
8350         dp->dtdo_destructive = 0;
8351
8352         for (pc = 0; pc < dp->dtdo_len && err == 0; pc++) {
8353                 dif_instr_t instr = dp->dtdo_buf[pc];
8354
8355                 uint_t r1 = DIF_INSTR_R1(instr);
8356                 uint_t r2 = DIF_INSTR_R2(instr);
8357                 uint_t rd = DIF_INSTR_RD(instr);
8358                 uint_t rs = DIF_INSTR_RS(instr);
8359                 uint_t label = DIF_INSTR_LABEL(instr);
8360                 uint_t v = DIF_INSTR_VAR(instr);
8361                 uint_t subr = DIF_INSTR_SUBR(instr);
8362                 uint_t type = DIF_INSTR_TYPE(instr);
8363                 uint_t op = DIF_INSTR_OP(instr);
8364
8365                 switch (op) {
8366                 case DIF_OP_OR:
8367                 case DIF_OP_XOR:
8368                 case DIF_OP_AND:
8369                 case DIF_OP_SLL:
8370                 case DIF_OP_SRL:
8371                 case DIF_OP_SRA:
8372                 case DIF_OP_SUB:
8373                 case DIF_OP_ADD:
8374                 case DIF_OP_MUL:
8375                 case DIF_OP_SDIV:
8376                 case DIF_OP_UDIV:
8377                 case DIF_OP_SREM:
8378                 case DIF_OP_UREM:
8379                 case DIF_OP_COPYS:
8380                         if (r1 >= nregs)
8381                                 err += efunc(pc, "invalid register %u\n", r1);
8382                         if (r2 >= nregs)
8383                                 err += efunc(pc, "invalid register %u\n", r2);
8384                         if (rd >= nregs)
8385                                 err += efunc(pc, "invalid register %u\n", rd);
8386                         if (rd == 0)
8387                                 err += efunc(pc, "cannot write to %r0\n");
8388                         break;
8389                 case DIF_OP_NOT:
8390                 case DIF_OP_MOV:
8391                 case DIF_OP_ALLOCS:
8392                         if (r1 >= nregs)
8393                                 err += efunc(pc, "invalid register %u\n", r1);
8394                         if (r2 != 0)
8395                                 err += efunc(pc, "non-zero reserved bits\n");
8396                         if (rd >= nregs)
8397                                 err += efunc(pc, "invalid register %u\n", rd);
8398                         if (rd == 0)
8399                                 err += efunc(pc, "cannot write to %r0\n");
8400                         break;
8401                 case DIF_OP_LDSB:
8402                 case DIF_OP_LDSH:
8403                 case DIF_OP_LDSW:
8404                 case DIF_OP_LDUB:
8405                 case DIF_OP_LDUH:
8406                 case DIF_OP_LDUW:
8407                 case DIF_OP_LDX:
8408                         if (r1 >= nregs)
8409                                 err += efunc(pc, "invalid register %u\n", r1);
8410                         if (r2 != 0)
8411                                 err += efunc(pc, "non-zero reserved bits\n");
8412                         if (rd >= nregs)
8413                                 err += efunc(pc, "invalid register %u\n", rd);
8414                         if (rd == 0)
8415                                 err += efunc(pc, "cannot write to %r0\n");
8416                         if (kcheckload)
8417                                 dp->dtdo_buf[pc] = DIF_INSTR_LOAD(op +
8418                                     DIF_OP_RLDSB - DIF_OP_LDSB, r1, rd);
8419                         break;
8420                 case DIF_OP_RLDSB:
8421                 case DIF_OP_RLDSH:
8422                 case DIF_OP_RLDSW:
8423                 case DIF_OP_RLDUB:
8424                 case DIF_OP_RLDUH:
8425                 case DIF_OP_RLDUW:
8426                 case DIF_OP_RLDX:
8427                         if (r1 >= nregs)
8428                                 err += efunc(pc, "invalid register %u\n", r1);
8429                         if (r2 != 0)
8430                                 err += efunc(pc, "non-zero reserved bits\n");
8431                         if (rd >= nregs)
8432                                 err += efunc(pc, "invalid register %u\n", rd);
8433                         if (rd == 0)
8434                                 err += efunc(pc, "cannot write to %r0\n");
8435                         break;
8436                 case DIF_OP_ULDSB:
8437                 case DIF_OP_ULDSH:
8438                 case DIF_OP_ULDSW:
8439                 case DIF_OP_ULDUB:
8440                 case DIF_OP_ULDUH:
8441                 case DIF_OP_ULDUW:
8442                 case DIF_OP_ULDX:
8443                         if (r1 >= nregs)
8444                                 err += efunc(pc, "invalid register %u\n", r1);
8445                         if (r2 != 0)
8446                                 err += efunc(pc, "non-zero reserved bits\n");
8447                         if (rd >= nregs)
8448                                 err += efunc(pc, "invalid register %u\n", rd);
8449                         if (rd == 0)
8450                                 err += efunc(pc, "cannot write to %r0\n");
8451                         break;
8452                 case DIF_OP_STB:
8453                 case DIF_OP_STH:
8454                 case DIF_OP_STW:
8455                 case DIF_OP_STX:
8456                         if (r1 >= nregs)
8457                                 err += efunc(pc, "invalid register %u\n", r1);
8458                         if (r2 != 0)
8459                                 err += efunc(pc, "non-zero reserved bits\n");
8460                         if (rd >= nregs)
8461                                 err += efunc(pc, "invalid register %u\n", rd);
8462                         if (rd == 0)
8463                                 err += efunc(pc, "cannot write to 0 address\n");
8464                         break;
8465                 case DIF_OP_CMP:
8466                 case DIF_OP_SCMP:
8467                         if (r1 >= nregs)
8468                                 err += efunc(pc, "invalid register %u\n", r1);
8469                         if (r2 >= nregs)
8470                                 err += efunc(pc, "invalid register %u\n", r2);
8471                         if (rd != 0)
8472                                 err += efunc(pc, "non-zero reserved bits\n");
8473                         break;
8474                 case DIF_OP_TST:
8475                         if (r1 >= nregs)
8476                                 err += efunc(pc, "invalid register %u\n", r1);
8477                         if (r2 != 0 || rd != 0)
8478                                 err += efunc(pc, "non-zero reserved bits\n");
8479                         break;
8480                 case DIF_OP_BA:
8481                 case DIF_OP_BE:
8482                 case DIF_OP_BNE:
8483                 case DIF_OP_BG:
8484                 case DIF_OP_BGU:
8485                 case DIF_OP_BGE:
8486                 case DIF_OP_BGEU:
8487                 case DIF_OP_BL:
8488                 case DIF_OP_BLU:
8489                 case DIF_OP_BLE:
8490                 case DIF_OP_BLEU:
8491                         if (label >= dp->dtdo_len) {
8492                                 err += efunc(pc, "invalid branch target %u\n",
8493                                     label);
8494                         }
8495                         if (label <= pc) {
8496                                 err += efunc(pc, "backward branch to %u\n",
8497                                     label);
8498                         }
8499                         break;
8500                 case DIF_OP_RET:
8501                         if (r1 != 0 || r2 != 0)
8502                                 err += efunc(pc, "non-zero reserved bits\n");
8503                         if (rd >= nregs)
8504                                 err += efunc(pc, "invalid register %u\n", rd);
8505                         break;
8506                 case DIF_OP_NOP:
8507                 case DIF_OP_POPTS:
8508                 case DIF_OP_FLUSHTS:
8509                         if (r1 != 0 || r2 != 0 || rd != 0)
8510                                 err += efunc(pc, "non-zero reserved bits\n");
8511                         break;
8512                 case DIF_OP_SETX:
8513                         if (DIF_INSTR_INTEGER(instr) >= dp->dtdo_intlen) {
8514                                 err += efunc(pc, "invalid integer ref %u\n",
8515                                     DIF_INSTR_INTEGER(instr));
8516                         }
8517                         if (rd >= nregs)
8518                                 err += efunc(pc, "invalid register %u\n", rd);
8519                         if (rd == 0)
8520                                 err += efunc(pc, "cannot write to %r0\n");
8521                         break;
8522                 case DIF_OP_SETS:
8523                         if (DIF_INSTR_STRING(instr) >= dp->dtdo_strlen) {
8524                                 err += efunc(pc, "invalid string ref %u\n",
8525                                     DIF_INSTR_STRING(instr));
8526                         }
8527                         if (rd >= nregs)
8528                                 err += efunc(pc, "invalid register %u\n", rd);
8529                         if (rd == 0)
8530                                 err += efunc(pc, "cannot write to %r0\n");
8531                         break;
8532                 case DIF_OP_LDGA:
8533                 case DIF_OP_LDTA:
8534                         if (r1 > DIF_VAR_ARRAY_MAX)
8535                                 err += efunc(pc, "invalid array %u\n", r1);
8536                         if (r2 >= nregs)
8537                                 err += efunc(pc, "invalid register %u\n", r2);
8538                         if (rd >= nregs)
8539                                 err += efunc(pc, "invalid register %u\n", rd);
8540                         if (rd == 0)
8541                                 err += efunc(pc, "cannot write to %r0\n");
8542                         break;
8543                 case DIF_OP_LDGS:
8544                 case DIF_OP_LDTS:
8545                 case DIF_OP_LDLS:
8546                 case DIF_OP_LDGAA:
8547                 case DIF_OP_LDTAA:
8548                         if (v < DIF_VAR_OTHER_MIN || v > DIF_VAR_OTHER_MAX)
8549                                 err += efunc(pc, "invalid variable %u\n", v);
8550                         if (rd >= nregs)
8551                                 err += efunc(pc, "invalid register %u\n", rd);
8552                         if (rd == 0)
8553                                 err += efunc(pc, "cannot write to %r0\n");
8554                         break;
8555                 case DIF_OP_STGS:
8556                 case DIF_OP_STTS:
8557                 case DIF_OP_STLS:
8558                 case DIF_OP_STGAA:
8559                 case DIF_OP_STTAA:
8560                         if (v < DIF_VAR_OTHER_UBASE || v > DIF_VAR_OTHER_MAX)
8561                                 err += efunc(pc, "invalid variable %u\n", v);
8562                         if (rs >= nregs)
8563                                 err += efunc(pc, "invalid register %u\n", rd);
8564                         break;
8565                 case DIF_OP_CALL:
8566                         if (subr > DIF_SUBR_MAX)
8567                                 err += efunc(pc, "invalid subr %u\n", subr);
8568                         if (rd >= nregs)
8569                                 err += efunc(pc, "invalid register %u\n", rd);
8570                         if (rd == 0)
8571                                 err += efunc(pc, "cannot write to %r0\n");
8572
8573                         if (subr == DIF_SUBR_COPYOUT ||
8574                             subr == DIF_SUBR_COPYOUTSTR) {
8575                                 dp->dtdo_destructive = 1;
8576                         }
8577                         break;
8578                 case DIF_OP_PUSHTR:
8579                         if (type != DIF_TYPE_STRING && type != DIF_TYPE_CTF)
8580                                 err += efunc(pc, "invalid ref type %u\n", type);
8581                         if (r2 >= nregs)
8582                                 err += efunc(pc, "invalid register %u\n", r2);
8583                         if (rs >= nregs)
8584                                 err += efunc(pc, "invalid register %u\n", rs);
8585                         break;
8586                 case DIF_OP_PUSHTV:
8587                         if (type != DIF_TYPE_CTF)
8588                                 err += efunc(pc, "invalid val type %u\n", type);
8589                         if (r2 >= nregs)
8590                                 err += efunc(pc, "invalid register %u\n", r2);
8591                         if (rs >= nregs)
8592                                 err += efunc(pc, "invalid register %u\n", rs);
8593                         break;
8594                 default:
8595                         err += efunc(pc, "invalid opcode %u\n",
8596                             DIF_INSTR_OP(instr));
8597                 }
8598         }
8599
8600         if (dp->dtdo_len != 0 &&
8601             DIF_INSTR_OP(dp->dtdo_buf[dp->dtdo_len - 1]) != DIF_OP_RET) {
8602                 err += efunc(dp->dtdo_len - 1,
8603                     "expected 'ret' as last DIF instruction\n");
8604         }
8605
8606         if (!(dp->dtdo_rtype.dtdt_flags & DIF_TF_BYREF)) {
8607                 /*
8608                  * If we're not returning by reference, the size must be either
8609                  * 0 or the size of one of the base types.
8610                  */
8611                 switch (dp->dtdo_rtype.dtdt_size) {
8612                 case 0:
8613                 case sizeof (uint8_t):
8614                 case sizeof (uint16_t):
8615                 case sizeof (uint32_t):
8616                 case sizeof (uint64_t):
8617                         break;
8618
8619                 default:
8620                         err += efunc(dp->dtdo_len - 1, "bad return size");
8621                 }
8622         }
8623
8624         for (i = 0; i < dp->dtdo_varlen && err == 0; i++) {
8625                 dtrace_difv_t *v = &dp->dtdo_vartab[i], *existing = NULL;
8626                 dtrace_diftype_t *vt, *et;
8627                 uint_t id, ndx;
8628
8629                 if (v->dtdv_scope != DIFV_SCOPE_GLOBAL &&
8630                     v->dtdv_scope != DIFV_SCOPE_THREAD &&
8631                     v->dtdv_scope != DIFV_SCOPE_LOCAL) {
8632                         err += efunc(i, "unrecognized variable scope %d\n",
8633                             v->dtdv_scope);
8634                         break;
8635                 }
8636
8637                 if (v->dtdv_kind != DIFV_KIND_ARRAY &&
8638                     v->dtdv_kind != DIFV_KIND_SCALAR) {
8639                         err += efunc(i, "unrecognized variable type %d\n",
8640                             v->dtdv_kind);
8641                         break;
8642                 }
8643
8644                 if ((id = v->dtdv_id) > DIF_VARIABLE_MAX) {
8645                         err += efunc(i, "%d exceeds variable id limit\n", id);
8646                         break;
8647                 }
8648
8649                 if (id < DIF_VAR_OTHER_UBASE)
8650                         continue;
8651
8652                 /*
8653                  * For user-defined variables, we need to check that this
8654                  * definition is identical to any previous definition that we
8655                  * encountered.
8656                  */
8657                 ndx = id - DIF_VAR_OTHER_UBASE;
8658
8659                 switch (v->dtdv_scope) {
8660                 case DIFV_SCOPE_GLOBAL:
8661                         if (ndx < vstate->dtvs_nglobals) {
8662                                 dtrace_statvar_t *svar;
8663
8664                                 if ((svar = vstate->dtvs_globals[ndx]) != NULL)
8665                                         existing = &svar->dtsv_var;
8666                         }
8667
8668                         break;
8669
8670                 case DIFV_SCOPE_THREAD:
8671                         if (ndx < vstate->dtvs_ntlocals)
8672                                 existing = &vstate->dtvs_tlocals[ndx];
8673                         break;
8674
8675                 case DIFV_SCOPE_LOCAL:
8676                         if (ndx < vstate->dtvs_nlocals) {
8677                                 dtrace_statvar_t *svar;
8678
8679                                 if ((svar = vstate->dtvs_locals[ndx]) != NULL)
8680                                         existing = &svar->dtsv_var;
8681                         }
8682
8683                         break;
8684                 }
8685
8686                 vt = &v->dtdv_type;
8687
8688                 if (vt->dtdt_flags & DIF_TF_BYREF) {
8689                         if (vt->dtdt_size == 0) {
8690                                 err += efunc(i, "zero-sized variable\n");
8691                                 break;
8692                         }
8693
8694                         if (v->dtdv_scope == DIFV_SCOPE_GLOBAL &&
8695                             vt->dtdt_size > dtrace_global_maxsize) {
8696                                 err += efunc(i, "oversized by-ref global\n");
8697                                 break;
8698                         }
8699                 }
8700
8701                 if (existing == NULL || existing->dtdv_id == 0)
8702                         continue;
8703
8704                 ASSERT(existing->dtdv_id == v->dtdv_id);
8705                 ASSERT(existing->dtdv_scope == v->dtdv_scope);
8706
8707                 if (existing->dtdv_kind != v->dtdv_kind)
8708                         err += efunc(i, "%d changed variable kind\n", id);
8709
8710                 et = &existing->dtdv_type;
8711
8712                 if (vt->dtdt_flags != et->dtdt_flags) {
8713                         err += efunc(i, "%d changed variable type flags\n", id);
8714                         break;
8715                 }
8716
8717                 if (vt->dtdt_size != 0 && vt->dtdt_size != et->dtdt_size) {
8718                         err += efunc(i, "%d changed variable type size\n", id);
8719                         break;
8720                 }
8721         }
8722
8723         return (err);
8724 }
8725
8726 #if defined(sun)
8727 /*
8728  * Validate a DTrace DIF object that it is to be used as a helper.  Helpers
8729  * are much more constrained than normal DIFOs.  Specifically, they may
8730  * not:
8731  *
8732  * 1. Make calls to subroutines other than copyin(), copyinstr() or
8733  *    miscellaneous string routines
8734  * 2. Access DTrace variables other than the args[] array, and the
8735  *    curthread, pid, ppid, tid, execname, zonename, uid and gid variables.
8736  * 3. Have thread-local variables.
8737  * 4. Have dynamic variables.
8738  */
8739 static int
8740 dtrace_difo_validate_helper(dtrace_difo_t *dp)
8741 {
8742         int (*efunc)(uint_t pc, const char *, ...) = dtrace_difo_err;
8743         int err = 0;
8744         uint_t pc;
8745
8746         for (pc = 0; pc < dp->dtdo_len; pc++) {
8747                 dif_instr_t instr = dp->dtdo_buf[pc];
8748
8749                 uint_t v = DIF_INSTR_VAR(instr);
8750                 uint_t subr = DIF_INSTR_SUBR(instr);
8751                 uint_t op = DIF_INSTR_OP(instr);
8752
8753                 switch (op) {
8754                 case DIF_OP_OR:
8755                 case DIF_OP_XOR:
8756                 case DIF_OP_AND:
8757                 case DIF_OP_SLL:
8758                 case DIF_OP_SRL:
8759                 case DIF_OP_SRA:
8760                 case DIF_OP_SUB:
8761                 case DIF_OP_ADD:
8762                 case DIF_OP_MUL:
8763                 case DIF_OP_SDIV:
8764                 case DIF_OP_UDIV:
8765                 case DIF_OP_SREM:
8766                 case DIF_OP_UREM:
8767                 case DIF_OP_COPYS:
8768                 case DIF_OP_NOT:
8769                 case DIF_OP_MOV:
8770                 case DIF_OP_RLDSB:
8771                 case DIF_OP_RLDSH:
8772                 case DIF_OP_RLDSW:
8773                 case DIF_OP_RLDUB:
8774                 case DIF_OP_RLDUH:
8775                 case DIF_OP_RLDUW:
8776                 case DIF_OP_RLDX:
8777                 case DIF_OP_ULDSB:
8778                 case DIF_OP_ULDSH:
8779                 case DIF_OP_ULDSW:
8780                 case DIF_OP_ULDUB:
8781                 case DIF_OP_ULDUH:
8782                 case DIF_OP_ULDUW:
8783                 case DIF_OP_ULDX:
8784                 case DIF_OP_STB:
8785                 case DIF_OP_STH:
8786                 case DIF_OP_STW:
8787                 case DIF_OP_STX:
8788                 case DIF_OP_ALLOCS:
8789                 case DIF_OP_CMP:
8790                 case DIF_OP_SCMP:
8791                 case DIF_OP_TST:
8792                 case DIF_OP_BA:
8793                 case DIF_OP_BE:
8794                 case DIF_OP_BNE:
8795                 case DIF_OP_BG:
8796                 case DIF_OP_BGU:
8797                 case DIF_OP_BGE:
8798                 case DIF_OP_BGEU:
8799                 case DIF_OP_BL:
8800                 case DIF_OP_BLU:
8801                 case DIF_OP_BLE:
8802                 case DIF_OP_BLEU:
8803                 case DIF_OP_RET:
8804                 case DIF_OP_NOP:
8805                 case DIF_OP_POPTS:
8806                 case DIF_OP_FLUSHTS:
8807                 case DIF_OP_SETX:
8808                 case DIF_OP_SETS:
8809                 case DIF_OP_LDGA:
8810                 case DIF_OP_LDLS:
8811                 case DIF_OP_STGS:
8812                 case DIF_OP_STLS:
8813                 case DIF_OP_PUSHTR:
8814                 case DIF_OP_PUSHTV:
8815                         break;
8816
8817                 case DIF_OP_LDGS:
8818                         if (v >= DIF_VAR_OTHER_UBASE)
8819                                 break;
8820
8821                         if (v >= DIF_VAR_ARG0 && v <= DIF_VAR_ARG9)
8822                                 break;
8823
8824                         if (v == DIF_VAR_CURTHREAD || v == DIF_VAR_PID ||
8825                             v == DIF_VAR_PPID || v == DIF_VAR_TID ||
8826                             v == DIF_VAR_EXECARGS ||
8827                             v == DIF_VAR_EXECNAME || v == DIF_VAR_ZONENAME ||
8828                             v == DIF_VAR_UID || v == DIF_VAR_GID)
8829                                 break;
8830
8831                         err += efunc(pc, "illegal variable %u\n", v);
8832                         break;
8833
8834                 case DIF_OP_LDTA:
8835                 case DIF_OP_LDTS:
8836                 case DIF_OP_LDGAA:
8837                 case DIF_OP_LDTAA:
8838                         err += efunc(pc, "illegal dynamic variable load\n");
8839                         break;
8840
8841                 case DIF_OP_STTS:
8842                 case DIF_OP_STGAA:
8843                 case DIF_OP_STTAA:
8844                         err += efunc(pc, "illegal dynamic variable store\n");
8845                         break;
8846
8847                 case DIF_OP_CALL:
8848                         if (subr == DIF_SUBR_ALLOCA ||
8849                             subr == DIF_SUBR_BCOPY ||
8850                             subr == DIF_SUBR_COPYIN ||
8851                             subr == DIF_SUBR_COPYINTO ||
8852                             subr == DIF_SUBR_COPYINSTR ||
8853                             subr == DIF_SUBR_INDEX ||
8854                             subr == DIF_SUBR_INET_NTOA ||
8855                             subr == DIF_SUBR_INET_NTOA6 ||
8856                             subr == DIF_SUBR_INET_NTOP ||
8857                             subr == DIF_SUBR_LLTOSTR ||
8858                             subr == DIF_SUBR_RINDEX ||
8859                             subr == DIF_SUBR_STRCHR ||
8860                             subr == DIF_SUBR_STRJOIN ||
8861                             subr == DIF_SUBR_STRRCHR ||
8862                             subr == DIF_SUBR_STRSTR ||
8863                             subr == DIF_SUBR_HTONS ||
8864                             subr == DIF_SUBR_HTONL ||
8865                             subr == DIF_SUBR_HTONLL ||
8866                             subr == DIF_SUBR_NTOHS ||
8867                             subr == DIF_SUBR_NTOHL ||
8868                             subr == DIF_SUBR_NTOHLL ||
8869                             subr == DIF_SUBR_MEMREF ||
8870                             subr == DIF_SUBR_TYPEREF)
8871                                 break;
8872
8873                         err += efunc(pc, "invalid subr %u\n", subr);
8874                         break;
8875
8876                 default:
8877                         err += efunc(pc, "invalid opcode %u\n",
8878                             DIF_INSTR_OP(instr));
8879                 }
8880         }
8881
8882         return (err);
8883 }
8884 #endif
8885
8886 /*
8887  * Returns 1 if the expression in the DIF object can be cached on a per-thread
8888  * basis; 0 if not.
8889  */
8890 static int
8891 dtrace_difo_cacheable(dtrace_difo_t *dp)
8892 {
8893         int i;
8894
8895         if (dp == NULL)
8896                 return (0);
8897
8898         for (i = 0; i < dp->dtdo_varlen; i++) {
8899                 dtrace_difv_t *v = &dp->dtdo_vartab[i];
8900
8901                 if (v->dtdv_scope != DIFV_SCOPE_GLOBAL)
8902                         continue;
8903
8904                 switch (v->dtdv_id) {
8905                 case DIF_VAR_CURTHREAD:
8906                 case DIF_VAR_PID:
8907                 case DIF_VAR_TID:
8908                 case DIF_VAR_EXECARGS:
8909                 case DIF_VAR_EXECNAME:
8910                 case DIF_VAR_ZONENAME:
8911                         break;
8912
8913                 default:
8914                         return (0);
8915                 }
8916         }
8917
8918         /*
8919          * This DIF object may be cacheable.  Now we need to look for any
8920          * array loading instructions, any memory loading instructions, or
8921          * any stores to thread-local variables.
8922          */
8923         for (i = 0; i < dp->dtdo_len; i++) {
8924                 uint_t op = DIF_INSTR_OP(dp->dtdo_buf[i]);
8925
8926                 if ((op >= DIF_OP_LDSB && op <= DIF_OP_LDX) ||
8927                     (op >= DIF_OP_ULDSB && op <= DIF_OP_ULDX) ||
8928                     (op >= DIF_OP_RLDSB && op <= DIF_OP_RLDX) ||
8929                     op == DIF_OP_LDGA || op == DIF_OP_STTS)
8930                         return (0);
8931         }
8932
8933         return (1);
8934 }
8935
8936 static void
8937 dtrace_difo_hold(dtrace_difo_t *dp)
8938 {
8939         int i;
8940
8941         ASSERT(MUTEX_HELD(&dtrace_lock));
8942
8943         dp->dtdo_refcnt++;
8944         ASSERT(dp->dtdo_refcnt != 0);
8945
8946         /*
8947          * We need to check this DIF object for references to the variable
8948          * DIF_VAR_VTIMESTAMP.
8949          */
8950         for (i = 0; i < dp->dtdo_varlen; i++) {
8951                 dtrace_difv_t *v = &dp->dtdo_vartab[i];
8952
8953                 if (v->dtdv_id != DIF_VAR_VTIMESTAMP)
8954                         continue;
8955
8956                 if (dtrace_vtime_references++ == 0)
8957                         dtrace_vtime_enable();
8958         }
8959 }
8960
8961 /*
8962  * This routine calculates the dynamic variable chunksize for a given DIF
8963  * object.  The calculation is not fool-proof, and can probably be tricked by
8964  * malicious DIF -- but it works for all compiler-generated DIF.  Because this
8965  * calculation is likely imperfect, dtrace_dynvar() is able to gracefully fail
8966  * if a dynamic variable size exceeds the chunksize.
8967  */
8968 static void
8969 dtrace_difo_chunksize(dtrace_difo_t *dp, dtrace_vstate_t *vstate)
8970 {
8971         uint64_t sval = 0;
8972         dtrace_key_t tupregs[DIF_DTR_NREGS + 2]; /* +2 for thread and id */
8973         const dif_instr_t *text = dp->dtdo_buf;
8974         uint_t pc, srd = 0;
8975         uint_t ttop = 0;
8976         size_t size, ksize;
8977         uint_t id, i;
8978
8979         for (pc = 0; pc < dp->dtdo_len; pc++) {
8980                 dif_instr_t instr = text[pc];
8981                 uint_t op = DIF_INSTR_OP(instr);
8982                 uint_t rd = DIF_INSTR_RD(instr);
8983                 uint_t r1 = DIF_INSTR_R1(instr);
8984                 uint_t nkeys = 0;
8985                 uchar_t scope = 0;
8986
8987                 dtrace_key_t *key = tupregs;
8988
8989                 switch (op) {
8990                 case DIF_OP_SETX:
8991                         sval = dp->dtdo_inttab[DIF_INSTR_INTEGER(instr)];
8992                         srd = rd;
8993                         continue;
8994
8995                 case DIF_OP_STTS:
8996                         key = &tupregs[DIF_DTR_NREGS];
8997                         key[0].dttk_size = 0;
8998                         key[1].dttk_size = 0;
8999                         nkeys = 2;
9000                         scope = DIFV_SCOPE_THREAD;
9001                         break;
9002
9003                 case DIF_OP_STGAA:
9004                 case DIF_OP_STTAA:
9005                         nkeys = ttop;
9006
9007                         if (DIF_INSTR_OP(instr) == DIF_OP_STTAA)
9008                                 key[nkeys++].dttk_size = 0;
9009
9010                         key[nkeys++].dttk_size = 0;
9011
9012                         if (op == DIF_OP_STTAA) {
9013                                 scope = DIFV_SCOPE_THREAD;
9014                         } else {
9015                                 scope = DIFV_SCOPE_GLOBAL;
9016                         }
9017
9018                         break;
9019
9020                 case DIF_OP_PUSHTR:
9021                         if (ttop == DIF_DTR_NREGS)
9022                                 return;
9023
9024                         if ((srd == 0 || sval == 0) && r1 == DIF_TYPE_STRING) {
9025                                 /*
9026                                  * If the register for the size of the "pushtr"
9027                                  * is %r0 (or the value is 0) and the type is
9028                                  * a string, we'll use the system-wide default
9029                                  * string size.
9030                                  */
9031                                 tupregs[ttop++].dttk_size =
9032                                     dtrace_strsize_default;
9033                         } else {
9034                                 if (srd == 0)
9035                                         return;
9036
9037                                 tupregs[ttop++].dttk_size = sval;
9038                         }
9039
9040                         break;
9041
9042                 case DIF_OP_PUSHTV:
9043                         if (ttop == DIF_DTR_NREGS)
9044                                 return;
9045
9046                         tupregs[ttop++].dttk_size = 0;
9047                         break;
9048
9049                 case DIF_OP_FLUSHTS:
9050                         ttop = 0;
9051                         break;
9052
9053                 case DIF_OP_POPTS:
9054                         if (ttop != 0)
9055                                 ttop--;
9056                         break;
9057                 }
9058
9059                 sval = 0;
9060                 srd = 0;
9061
9062                 if (nkeys == 0)
9063                         continue;
9064
9065                 /*
9066                  * We have a dynamic variable allocation; calculate its size.
9067                  */
9068                 for (ksize = 0, i = 0; i < nkeys; i++)
9069                         ksize += P2ROUNDUP(key[i].dttk_size, sizeof (uint64_t));
9070
9071                 size = sizeof (dtrace_dynvar_t);
9072                 size += sizeof (dtrace_key_t) * (nkeys - 1);
9073                 size += ksize;
9074
9075                 /*
9076                  * Now we need to determine the size of the stored data.
9077                  */
9078                 id = DIF_INSTR_VAR(instr);
9079
9080                 for (i = 0; i < dp->dtdo_varlen; i++) {
9081                         dtrace_difv_t *v = &dp->dtdo_vartab[i];
9082
9083                         if (v->dtdv_id == id && v->dtdv_scope == scope) {
9084                                 size += v->dtdv_type.dtdt_size;
9085                                 break;
9086                         }
9087                 }
9088
9089                 if (i == dp->dtdo_varlen)
9090                         return;
9091
9092                 /*
9093                  * We have the size.  If this is larger than the chunk size
9094                  * for our dynamic variable state, reset the chunk size.
9095                  */
9096                 size = P2ROUNDUP(size, sizeof (uint64_t));
9097
9098                 if (size > vstate->dtvs_dynvars.dtds_chunksize)
9099                         vstate->dtvs_dynvars.dtds_chunksize = size;
9100         }
9101 }
9102
9103 static void
9104 dtrace_difo_init(dtrace_difo_t *dp, dtrace_vstate_t *vstate)
9105 {
9106         int i, oldsvars, osz, nsz, otlocals, ntlocals;
9107         uint_t id;
9108
9109         ASSERT(MUTEX_HELD(&dtrace_lock));
9110         ASSERT(dp->dtdo_buf != NULL && dp->dtdo_len != 0);
9111
9112         for (i = 0; i < dp->dtdo_varlen; i++) {
9113                 dtrace_difv_t *v = &dp->dtdo_vartab[i];
9114                 dtrace_statvar_t *svar, ***svarp = NULL;
9115                 size_t dsize = 0;
9116                 uint8_t scope = v->dtdv_scope;
9117                 int *np = NULL;
9118
9119                 if ((id = v->dtdv_id) < DIF_VAR_OTHER_UBASE)
9120                         continue;
9121
9122                 id -= DIF_VAR_OTHER_UBASE;
9123
9124                 switch (scope) {
9125                 case DIFV_SCOPE_THREAD:
9126                         while (id >= (otlocals = vstate->dtvs_ntlocals)) {
9127                                 dtrace_difv_t *tlocals;
9128
9129                                 if ((ntlocals = (otlocals << 1)) == 0)
9130                                         ntlocals = 1;
9131
9132                                 osz = otlocals * sizeof (dtrace_difv_t);
9133                                 nsz = ntlocals * sizeof (dtrace_difv_t);
9134
9135                                 tlocals = kmem_zalloc(nsz, KM_SLEEP);
9136
9137                                 if (osz != 0) {
9138                                         bcopy(vstate->dtvs_tlocals,
9139                                             tlocals, osz);
9140                                         kmem_free(vstate->dtvs_tlocals, osz);
9141                                 }
9142
9143                                 vstate->dtvs_tlocals = tlocals;
9144                                 vstate->dtvs_ntlocals = ntlocals;
9145                         }
9146
9147                         vstate->dtvs_tlocals[id] = *v;
9148                         continue;
9149
9150                 case DIFV_SCOPE_LOCAL:
9151                         np = &vstate->dtvs_nlocals;
9152                         svarp = &vstate->dtvs_locals;
9153
9154                         if (v->dtdv_type.dtdt_flags & DIF_TF_BYREF)
9155                                 dsize = NCPU * (v->dtdv_type.dtdt_size +
9156                                     sizeof (uint64_t));
9157                         else
9158                                 dsize = NCPU * sizeof (uint64_t);
9159
9160                         break;
9161
9162                 case DIFV_SCOPE_GLOBAL:
9163                         np = &vstate->dtvs_nglobals;
9164                         svarp = &vstate->dtvs_globals;
9165
9166                         if (v->dtdv_type.dtdt_flags & DIF_TF_BYREF)
9167                                 dsize = v->dtdv_type.dtdt_size +
9168                                     sizeof (uint64_t);
9169
9170                         break;
9171
9172                 default:
9173                         ASSERT(0);
9174                 }
9175
9176                 while (id >= (oldsvars = *np)) {
9177                         dtrace_statvar_t **statics;
9178                         int newsvars, oldsize, newsize;
9179
9180                         if ((newsvars = (oldsvars << 1)) == 0)
9181                                 newsvars = 1;
9182
9183                         oldsize = oldsvars * sizeof (dtrace_statvar_t *);
9184                         newsize = newsvars * sizeof (dtrace_statvar_t *);
9185
9186                         statics = kmem_zalloc(newsize, KM_SLEEP);
9187
9188                         if (oldsize != 0) {
9189                                 bcopy(*svarp, statics, oldsize);
9190                                 kmem_free(*svarp, oldsize);
9191                         }
9192
9193                         *svarp = statics;
9194                         *np = newsvars;
9195                 }
9196
9197                 if ((svar = (*svarp)[id]) == NULL) {
9198                         svar = kmem_zalloc(sizeof (dtrace_statvar_t), KM_SLEEP);
9199                         svar->dtsv_var = *v;
9200
9201                         if ((svar->dtsv_size = dsize) != 0) {
9202                                 svar->dtsv_data = (uint64_t)(uintptr_t)
9203                                     kmem_zalloc(dsize, KM_SLEEP);
9204                         }
9205
9206                         (*svarp)[id] = svar;
9207                 }
9208
9209                 svar->dtsv_refcnt++;
9210         }
9211
9212         dtrace_difo_chunksize(dp, vstate);
9213         dtrace_difo_hold(dp);
9214 }
9215
9216 #if defined(sun)
9217 static dtrace_difo_t *
9218 dtrace_difo_duplicate(dtrace_difo_t *dp, dtrace_vstate_t *vstate)
9219 {
9220         dtrace_difo_t *new;
9221         size_t sz;
9222
9223         ASSERT(dp->dtdo_buf != NULL);
9224         ASSERT(dp->dtdo_refcnt != 0);
9225
9226         new = kmem_zalloc(sizeof (dtrace_difo_t), KM_SLEEP);
9227
9228         ASSERT(dp->dtdo_buf != NULL);
9229         sz = dp->dtdo_len * sizeof (dif_instr_t);
9230         new->dtdo_buf = kmem_alloc(sz, KM_SLEEP);
9231         bcopy(dp->dtdo_buf, new->dtdo_buf, sz);
9232         new->dtdo_len = dp->dtdo_len;
9233
9234         if (dp->dtdo_strtab != NULL) {
9235                 ASSERT(dp->dtdo_strlen != 0);
9236                 new->dtdo_strtab = kmem_alloc(dp->dtdo_strlen, KM_SLEEP);
9237                 bcopy(dp->dtdo_strtab, new->dtdo_strtab, dp->dtdo_strlen);
9238                 new->dtdo_strlen = dp->dtdo_strlen;
9239         }
9240
9241         if (dp->dtdo_inttab != NULL) {
9242                 ASSERT(dp->dtdo_intlen != 0);
9243                 sz = dp->dtdo_intlen * sizeof (uint64_t);
9244                 new->dtdo_inttab = kmem_alloc(sz, KM_SLEEP);
9245                 bcopy(dp->dtdo_inttab, new->dtdo_inttab, sz);
9246                 new->dtdo_intlen = dp->dtdo_intlen;
9247         }
9248
9249         if (dp->dtdo_vartab != NULL) {
9250                 ASSERT(dp->dtdo_varlen != 0);
9251                 sz = dp->dtdo_varlen * sizeof (dtrace_difv_t);
9252                 new->dtdo_vartab = kmem_alloc(sz, KM_SLEEP);
9253                 bcopy(dp->dtdo_vartab, new->dtdo_vartab, sz);
9254                 new->dtdo_varlen = dp->dtdo_varlen;
9255         }
9256
9257         dtrace_difo_init(new, vstate);
9258         return (new);
9259 }
9260 #endif
9261
9262 static void
9263 dtrace_difo_destroy(dtrace_difo_t *dp, dtrace_vstate_t *vstate)
9264 {
9265         int i;
9266
9267         ASSERT(dp->dtdo_refcnt == 0);
9268
9269         for (i = 0; i < dp->dtdo_varlen; i++) {
9270                 dtrace_difv_t *v = &dp->dtdo_vartab[i];
9271                 dtrace_statvar_t *svar, **svarp = NULL;
9272                 uint_t id;
9273                 uint8_t scope = v->dtdv_scope;
9274                 int *np = NULL;
9275
9276                 switch (scope) {
9277                 case DIFV_SCOPE_THREAD:
9278                         continue;
9279
9280                 case DIFV_SCOPE_LOCAL:
9281                         np = &vstate->dtvs_nlocals;
9282                         svarp = vstate->dtvs_locals;
9283                         break;
9284
9285                 case DIFV_SCOPE_GLOBAL:
9286                         np = &vstate->dtvs_nglobals;
9287                         svarp = vstate->dtvs_globals;
9288                         break;
9289
9290                 default:
9291                         ASSERT(0);
9292                 }
9293
9294                 if ((id = v->dtdv_id) < DIF_VAR_OTHER_UBASE)
9295                         continue;
9296
9297                 id -= DIF_VAR_OTHER_UBASE;
9298                 ASSERT(id < *np);
9299
9300                 svar = svarp[id];
9301                 ASSERT(svar != NULL);
9302                 ASSERT(svar->dtsv_refcnt > 0);
9303
9304                 if (--svar->dtsv_refcnt > 0)
9305                         continue;
9306
9307                 if (svar->dtsv_size != 0) {
9308                         ASSERT(svar->dtsv_data != 0);
9309                         kmem_free((void *)(uintptr_t)svar->dtsv_data,
9310                             svar->dtsv_size);
9311                 }
9312
9313                 kmem_free(svar, sizeof (dtrace_statvar_t));
9314                 svarp[id] = NULL;
9315         }
9316
9317         if (dp->dtdo_buf != NULL)
9318                 kmem_free(dp->dtdo_buf, dp->dtdo_len * sizeof (dif_instr_t));
9319         if (dp->dtdo_inttab != NULL)
9320                 kmem_free(dp->dtdo_inttab, dp->dtdo_intlen * sizeof (uint64_t));
9321         if (dp->dtdo_strtab != NULL)
9322                 kmem_free(dp->dtdo_strtab, dp->dtdo_strlen);
9323         if (dp->dtdo_vartab != NULL)
9324                 kmem_free(dp->dtdo_vartab, dp->dtdo_varlen * sizeof (dtrace_difv_t));
9325
9326         kmem_free(dp, sizeof (dtrace_difo_t));
9327 }
9328
9329 static void
9330 dtrace_difo_release(dtrace_difo_t *dp, dtrace_vstate_t *vstate)
9331 {
9332         int i;
9333
9334         ASSERT(MUTEX_HELD(&dtrace_lock));
9335         ASSERT(dp->dtdo_refcnt != 0);
9336
9337         for (i = 0; i < dp->dtdo_varlen; i++) {
9338                 dtrace_difv_t *v = &dp->dtdo_vartab[i];
9339
9340                 if (v->dtdv_id != DIF_VAR_VTIMESTAMP)
9341                         continue;
9342
9343                 ASSERT(dtrace_vtime_references > 0);
9344                 if (--dtrace_vtime_references == 0)
9345                         dtrace_vtime_disable();
9346         }
9347
9348         if (--dp->dtdo_refcnt == 0)
9349                 dtrace_difo_destroy(dp, vstate);
9350 }
9351
9352 /*
9353  * DTrace Format Functions
9354  */
9355 static uint16_t
9356 dtrace_format_add(dtrace_state_t *state, char *str)
9357 {
9358         char *fmt, **new;
9359         uint16_t ndx, len = strlen(str) + 1;
9360
9361         fmt = kmem_zalloc(len, KM_SLEEP);
9362         bcopy(str, fmt, len);
9363
9364         for (ndx = 0; ndx < state->dts_nformats; ndx++) {
9365                 if (state->dts_formats[ndx] == NULL) {
9366                         state->dts_formats[ndx] = fmt;
9367                         return (ndx + 1);
9368                 }
9369         }
9370
9371         if (state->dts_nformats == USHRT_MAX) {
9372                 /*
9373                  * This is only likely if a denial-of-service attack is being
9374                  * attempted.  As such, it's okay to fail silently here.
9375                  */
9376                 kmem_free(fmt, len);
9377                 return (0);
9378         }
9379
9380         /*
9381          * For simplicity, we always resize the formats array to be exactly the
9382          * number of formats.
9383          */
9384         ndx = state->dts_nformats++;
9385         new = kmem_alloc((ndx + 1) * sizeof (char *), KM_SLEEP);
9386
9387         if (state->dts_formats != NULL) {
9388                 ASSERT(ndx != 0);
9389                 bcopy(state->dts_formats, new, ndx * sizeof (char *));
9390                 kmem_free(state->dts_formats, ndx * sizeof (char *));
9391         }
9392
9393         state->dts_formats = new;
9394         state->dts_formats[ndx] = fmt;
9395
9396         return (ndx + 1);
9397 }
9398
9399 static void
9400 dtrace_format_remove(dtrace_state_t *state, uint16_t format)
9401 {
9402         char *fmt;
9403
9404         ASSERT(state->dts_formats != NULL);
9405         ASSERT(format <= state->dts_nformats);
9406         ASSERT(state->dts_formats[format - 1] != NULL);
9407
9408         fmt = state->dts_formats[format - 1];
9409         kmem_free(fmt, strlen(fmt) + 1);
9410         state->dts_formats[format - 1] = NULL;
9411 }
9412
9413 static void
9414 dtrace_format_destroy(dtrace_state_t *state)
9415 {
9416         int i;
9417
9418         if (state->dts_nformats == 0) {
9419                 ASSERT(state->dts_formats == NULL);
9420                 return;
9421         }
9422
9423         ASSERT(state->dts_formats != NULL);
9424
9425         for (i = 0; i < state->dts_nformats; i++) {
9426                 char *fmt = state->dts_formats[i];
9427
9428                 if (fmt == NULL)
9429                         continue;
9430
9431                 kmem_free(fmt, strlen(fmt) + 1);
9432         }
9433
9434         kmem_free(state->dts_formats, state->dts_nformats * sizeof (char *));
9435         state->dts_nformats = 0;
9436         state->dts_formats = NULL;
9437 }
9438
9439 /*
9440  * DTrace Predicate Functions
9441  */
9442 static dtrace_predicate_t *
9443 dtrace_predicate_create(dtrace_difo_t *dp)
9444 {
9445         dtrace_predicate_t *pred;
9446
9447         ASSERT(MUTEX_HELD(&dtrace_lock));
9448         ASSERT(dp->dtdo_refcnt != 0);
9449
9450         pred = kmem_zalloc(sizeof (dtrace_predicate_t), KM_SLEEP);
9451         pred->dtp_difo = dp;
9452         pred->dtp_refcnt = 1;
9453
9454         if (!dtrace_difo_cacheable(dp))
9455                 return (pred);
9456
9457         if (dtrace_predcache_id == DTRACE_CACHEIDNONE) {
9458                 /*
9459                  * This is only theoretically possible -- we have had 2^32
9460                  * cacheable predicates on this machine.  We cannot allow any
9461                  * more predicates to become cacheable:  as unlikely as it is,
9462                  * there may be a thread caching a (now stale) predicate cache
9463                  * ID. (N.B.: the temptation is being successfully resisted to
9464                  * have this cmn_err() "Holy shit -- we executed this code!")
9465                  */
9466                 return (pred);
9467         }
9468
9469         pred->dtp_cacheid = dtrace_predcache_id++;
9470
9471         return (pred);
9472 }
9473
9474 static void
9475 dtrace_predicate_hold(dtrace_predicate_t *pred)
9476 {
9477         ASSERT(MUTEX_HELD(&dtrace_lock));
9478         ASSERT(pred->dtp_difo != NULL && pred->dtp_difo->dtdo_refcnt != 0);
9479         ASSERT(pred->dtp_refcnt > 0);
9480
9481         pred->dtp_refcnt++;
9482 }
9483
9484 static void
9485 dtrace_predicate_release(dtrace_predicate_t *pred, dtrace_vstate_t *vstate)
9486 {
9487         dtrace_difo_t *dp = pred->dtp_difo;
9488
9489         ASSERT(MUTEX_HELD(&dtrace_lock));
9490         ASSERT(dp != NULL && dp->dtdo_refcnt != 0);
9491         ASSERT(pred->dtp_refcnt > 0);
9492
9493         if (--pred->dtp_refcnt == 0) {
9494                 dtrace_difo_release(pred->dtp_difo, vstate);
9495                 kmem_free(pred, sizeof (dtrace_predicate_t));
9496         }
9497 }
9498
9499 /*
9500  * DTrace Action Description Functions
9501  */
9502 static dtrace_actdesc_t *
9503 dtrace_actdesc_create(dtrace_actkind_t kind, uint32_t ntuple,
9504     uint64_t uarg, uint64_t arg)
9505 {
9506         dtrace_actdesc_t *act;
9507
9508 #if defined(sun)
9509         ASSERT(!DTRACEACT_ISPRINTFLIKE(kind) || (arg != NULL &&
9510             arg >= KERNELBASE) || (arg == NULL && kind == DTRACEACT_PRINTA));
9511 #endif
9512
9513         act = kmem_zalloc(sizeof (dtrace_actdesc_t), KM_SLEEP);
9514         act->dtad_kind = kind;
9515         act->dtad_ntuple = ntuple;
9516         act->dtad_uarg = uarg;
9517         act->dtad_arg = arg;
9518         act->dtad_refcnt = 1;
9519
9520         return (act);
9521 }
9522
9523 static void
9524 dtrace_actdesc_hold(dtrace_actdesc_t *act)
9525 {
9526         ASSERT(act->dtad_refcnt >= 1);
9527         act->dtad_refcnt++;
9528 }
9529
9530 static void
9531 dtrace_actdesc_release(dtrace_actdesc_t *act, dtrace_vstate_t *vstate)
9532 {
9533         dtrace_actkind_t kind = act->dtad_kind;
9534         dtrace_difo_t *dp;
9535
9536         ASSERT(act->dtad_refcnt >= 1);
9537
9538         if (--act->dtad_refcnt != 0)
9539                 return;
9540
9541         if ((dp = act->dtad_difo) != NULL)
9542                 dtrace_difo_release(dp, vstate);
9543
9544         if (DTRACEACT_ISPRINTFLIKE(kind)) {
9545                 char *str = (char *)(uintptr_t)act->dtad_arg;
9546
9547 #if defined(sun)
9548                 ASSERT((str != NULL && (uintptr_t)str >= KERNELBASE) ||
9549                     (str == NULL && act->dtad_kind == DTRACEACT_PRINTA));
9550 #endif
9551
9552                 if (str != NULL)
9553                         kmem_free(str, strlen(str) + 1);
9554         }
9555
9556         kmem_free(act, sizeof (dtrace_actdesc_t));
9557 }
9558
9559 /*
9560  * DTrace ECB Functions
9561  */
9562 static dtrace_ecb_t *
9563 dtrace_ecb_add(dtrace_state_t *state, dtrace_probe_t *probe)
9564 {
9565         dtrace_ecb_t *ecb;
9566         dtrace_epid_t epid;
9567
9568         ASSERT(MUTEX_HELD(&dtrace_lock));
9569
9570         ecb = kmem_zalloc(sizeof (dtrace_ecb_t), KM_SLEEP);
9571         ecb->dte_predicate = NULL;
9572         ecb->dte_probe = probe;
9573
9574         /*
9575          * The default size is the size of the default action: recording
9576          * the epid.
9577          */
9578         ecb->dte_size = ecb->dte_needed = sizeof (dtrace_epid_t);
9579         ecb->dte_alignment = sizeof (dtrace_epid_t);
9580
9581         epid = state->dts_epid++;
9582
9583         if (epid - 1 >= state->dts_necbs) {
9584                 dtrace_ecb_t **oecbs = state->dts_ecbs, **ecbs;
9585                 int necbs = state->dts_necbs << 1;
9586
9587                 ASSERT(epid == state->dts_necbs + 1);
9588
9589                 if (necbs == 0) {
9590                         ASSERT(oecbs == NULL);
9591                         necbs = 1;
9592                 }
9593
9594                 ecbs = kmem_zalloc(necbs * sizeof (*ecbs), KM_SLEEP);
9595
9596                 if (oecbs != NULL)
9597                         bcopy(oecbs, ecbs, state->dts_necbs * sizeof (*ecbs));
9598
9599                 dtrace_membar_producer();
9600                 state->dts_ecbs = ecbs;
9601
9602                 if (oecbs != NULL) {
9603                         /*
9604                          * If this state is active, we must dtrace_sync()
9605                          * before we can free the old dts_ecbs array:  we're
9606                          * coming in hot, and there may be active ring
9607                          * buffer processing (which indexes into the dts_ecbs
9608                          * array) on another CPU.
9609                          */
9610                         if (state->dts_activity != DTRACE_ACTIVITY_INACTIVE)
9611                                 dtrace_sync();
9612
9613                         kmem_free(oecbs, state->dts_necbs * sizeof (*ecbs));
9614                 }
9615
9616                 dtrace_membar_producer();
9617                 state->dts_necbs = necbs;
9618         }
9619
9620         ecb->dte_state = state;
9621
9622         ASSERT(state->dts_ecbs[epid - 1] == NULL);
9623         dtrace_membar_producer();
9624         state->dts_ecbs[(ecb->dte_epid = epid) - 1] = ecb;
9625
9626         return (ecb);
9627 }
9628
9629 static void
9630 dtrace_ecb_enable(dtrace_ecb_t *ecb)
9631 {
9632         dtrace_probe_t *probe = ecb->dte_probe;
9633
9634         ASSERT(MUTEX_HELD(&cpu_lock));
9635         ASSERT(MUTEX_HELD(&dtrace_lock));
9636         ASSERT(ecb->dte_next == NULL);
9637
9638         if (probe == NULL) {
9639                 /*
9640                  * This is the NULL probe -- there's nothing to do.
9641                  */
9642                 return;
9643         }
9644
9645         if (probe->dtpr_ecb == NULL) {
9646                 dtrace_provider_t *prov = probe->dtpr_provider;
9647
9648                 /*
9649                  * We're the first ECB on this probe.
9650                  */
9651                 probe->dtpr_ecb = probe->dtpr_ecb_last = ecb;
9652
9653                 if (ecb->dte_predicate != NULL)
9654                         probe->dtpr_predcache = ecb->dte_predicate->dtp_cacheid;
9655
9656                 prov->dtpv_pops.dtps_enable(prov->dtpv_arg,
9657                     probe->dtpr_id, probe->dtpr_arg);
9658         } else {
9659                 /*
9660                  * This probe is already active.  Swing the last pointer to
9661                  * point to the new ECB, and issue a dtrace_sync() to assure
9662                  * that all CPUs have seen the change.
9663                  */
9664                 ASSERT(probe->dtpr_ecb_last != NULL);
9665                 probe->dtpr_ecb_last->dte_next = ecb;
9666                 probe->dtpr_ecb_last = ecb;
9667                 probe->dtpr_predcache = 0;
9668
9669                 dtrace_sync();
9670         }
9671 }
9672
9673 static void
9674 dtrace_ecb_resize(dtrace_ecb_t *ecb)
9675 {
9676         uint32_t maxalign = sizeof (dtrace_epid_t);
9677         uint32_t align = sizeof (uint8_t), offs, diff;
9678         dtrace_action_t *act;
9679         int wastuple = 0;
9680         uint32_t aggbase = UINT32_MAX;
9681         dtrace_state_t *state = ecb->dte_state;
9682
9683         /*
9684          * If we record anything, we always record the epid.  (And we always
9685          * record it first.)
9686          */
9687         offs = sizeof (dtrace_epid_t);
9688         ecb->dte_size = ecb->dte_needed = sizeof (dtrace_epid_t);
9689
9690         for (act = ecb->dte_action; act != NULL; act = act->dta_next) {
9691                 dtrace_recdesc_t *rec = &act->dta_rec;
9692
9693                 if ((align = rec->dtrd_alignment) > maxalign)
9694                         maxalign = align;
9695
9696                 if (!wastuple && act->dta_intuple) {
9697                         /*
9698                          * This is the first record in a tuple.  Align the
9699                          * offset to be at offset 4 in an 8-byte aligned
9700                          * block.
9701                          */
9702                         diff = offs + sizeof (dtrace_aggid_t);
9703
9704                         if ((diff = (diff & (sizeof (uint64_t) - 1))))
9705                                 offs += sizeof (uint64_t) - diff;
9706
9707                         aggbase = offs - sizeof (dtrace_aggid_t);
9708                         ASSERT(!(aggbase & (sizeof (uint64_t) - 1)));
9709                 }
9710
9711                 /*LINTED*/
9712                 if (rec->dtrd_size != 0 && (diff = (offs & (align - 1)))) {
9713                         /*
9714                          * The current offset is not properly aligned; align it.
9715                          */
9716                         offs += align - diff;
9717                 }
9718
9719                 rec->dtrd_offset = offs;
9720
9721                 if (offs + rec->dtrd_size > ecb->dte_needed) {
9722                         ecb->dte_needed = offs + rec->dtrd_size;
9723
9724                         if (ecb->dte_needed > state->dts_needed)
9725                                 state->dts_needed = ecb->dte_needed;
9726                 }
9727
9728                 if (DTRACEACT_ISAGG(act->dta_kind)) {
9729                         dtrace_aggregation_t *agg = (dtrace_aggregation_t *)act;
9730                         dtrace_action_t *first = agg->dtag_first, *prev;
9731
9732                         ASSERT(rec->dtrd_size != 0 && first != NULL);
9733                         ASSERT(wastuple);
9734                         ASSERT(aggbase != UINT32_MAX);
9735
9736                         agg->dtag_base = aggbase;
9737
9738                         while ((prev = first->dta_prev) != NULL &&
9739                             DTRACEACT_ISAGG(prev->dta_kind)) {
9740                                 agg = (dtrace_aggregation_t *)prev;
9741                                 first = agg->dtag_first;
9742                         }
9743
9744                         if (prev != NULL) {
9745                                 offs = prev->dta_rec.dtrd_offset +
9746                                     prev->dta_rec.dtrd_size;
9747                         } else {
9748                                 offs = sizeof (dtrace_epid_t);
9749                         }
9750                         wastuple = 0;
9751                 } else {
9752                         if (!act->dta_intuple)
9753                                 ecb->dte_size = offs + rec->dtrd_size;
9754
9755                         offs += rec->dtrd_size;
9756                 }
9757
9758                 wastuple = act->dta_intuple;
9759         }
9760
9761         if ((act = ecb->dte_action) != NULL &&
9762             !(act->dta_kind == DTRACEACT_SPECULATE && act->dta_next == NULL) &&
9763             ecb->dte_size == sizeof (dtrace_epid_t)) {
9764                 /*
9765                  * If the size is still sizeof (dtrace_epid_t), then all
9766                  * actions store no data; set the size to 0.
9767                  */
9768                 ecb->dte_alignment = maxalign;
9769                 ecb->dte_size = 0;
9770
9771                 /*
9772                  * If the needed space is still sizeof (dtrace_epid_t), then
9773                  * all actions need no additional space; set the needed
9774                  * size to 0.
9775                  */
9776                 if (ecb->dte_needed == sizeof (dtrace_epid_t))
9777                         ecb->dte_needed = 0;
9778
9779                 return;
9780         }
9781
9782         /*
9783          * Set our alignment, and make sure that the dte_size and dte_needed
9784          * are aligned to the size of an EPID.
9785          */
9786         ecb->dte_alignment = maxalign;
9787         ecb->dte_size = (ecb->dte_size + (sizeof (dtrace_epid_t) - 1)) &
9788             ~(sizeof (dtrace_epid_t) - 1);
9789         ecb->dte_needed = (ecb->dte_needed + (sizeof (dtrace_epid_t) - 1)) &
9790             ~(sizeof (dtrace_epid_t) - 1);
9791         ASSERT(ecb->dte_size <= ecb->dte_needed);
9792 }
9793
9794 static dtrace_action_t *
9795 dtrace_ecb_aggregation_create(dtrace_ecb_t *ecb, dtrace_actdesc_t *desc)
9796 {
9797         dtrace_aggregation_t *agg;
9798         size_t size = sizeof (uint64_t);
9799         int ntuple = desc->dtad_ntuple;
9800         dtrace_action_t *act;
9801         dtrace_recdesc_t *frec;
9802         dtrace_aggid_t aggid;
9803         dtrace_state_t *state = ecb->dte_state;
9804
9805         agg = kmem_zalloc(sizeof (dtrace_aggregation_t), KM_SLEEP);
9806         agg->dtag_ecb = ecb;
9807
9808         ASSERT(DTRACEACT_ISAGG(desc->dtad_kind));
9809
9810         switch (desc->dtad_kind) {
9811         case DTRACEAGG_MIN:
9812                 agg->dtag_initial = INT64_MAX;
9813                 agg->dtag_aggregate = dtrace_aggregate_min;
9814                 break;
9815
9816         case DTRACEAGG_MAX:
9817                 agg->dtag_initial = INT64_MIN;
9818                 agg->dtag_aggregate = dtrace_aggregate_max;
9819                 break;
9820
9821         case DTRACEAGG_COUNT:
9822                 agg->dtag_aggregate = dtrace_aggregate_count;
9823                 break;
9824
9825         case DTRACEAGG_QUANTIZE:
9826                 agg->dtag_aggregate = dtrace_aggregate_quantize;
9827                 size = (((sizeof (uint64_t) * NBBY) - 1) * 2 + 1) *
9828                     sizeof (uint64_t);
9829                 break;
9830
9831         case DTRACEAGG_LQUANTIZE: {
9832                 uint16_t step = DTRACE_LQUANTIZE_STEP(desc->dtad_arg);
9833                 uint16_t levels = DTRACE_LQUANTIZE_LEVELS(desc->dtad_arg);
9834
9835                 agg->dtag_initial = desc->dtad_arg;
9836                 agg->dtag_aggregate = dtrace_aggregate_lquantize;
9837
9838                 if (step == 0 || levels == 0)
9839                         goto err;
9840
9841                 size = levels * sizeof (uint64_t) + 3 * sizeof (uint64_t);
9842                 break;
9843         }
9844
9845         case DTRACEAGG_AVG:
9846                 agg->dtag_aggregate = dtrace_aggregate_avg;
9847                 size = sizeof (uint64_t) * 2;
9848                 break;
9849
9850         case DTRACEAGG_STDDEV:
9851                 agg->dtag_aggregate = dtrace_aggregate_stddev;
9852                 size = sizeof (uint64_t) * 4;
9853                 break;
9854
9855         case DTRACEAGG_SUM:
9856                 agg->dtag_aggregate = dtrace_aggregate_sum;
9857                 break;
9858
9859         default:
9860                 goto err;
9861         }
9862
9863         agg->dtag_action.dta_rec.dtrd_size = size;
9864
9865         if (ntuple == 0)
9866                 goto err;
9867
9868         /*
9869          * We must make sure that we have enough actions for the n-tuple.
9870          */
9871         for (act = ecb->dte_action_last; act != NULL; act = act->dta_prev) {
9872                 if (DTRACEACT_ISAGG(act->dta_kind))
9873                         break;
9874
9875                 if (--ntuple == 0) {
9876                         /*
9877                          * This is the action with which our n-tuple begins.
9878                          */
9879                         agg->dtag_first = act;
9880                         goto success;
9881                 }
9882         }
9883
9884         /*
9885          * This n-tuple is short by ntuple elements.  Return failure.
9886          */
9887         ASSERT(ntuple != 0);
9888 err:
9889         kmem_free(agg, sizeof (dtrace_aggregation_t));
9890         return (NULL);
9891
9892 success:
9893         /*
9894          * If the last action in the tuple has a size of zero, it's actually
9895          * an expression argument for the aggregating action.
9896          */
9897         ASSERT(ecb->dte_action_last != NULL);
9898         act = ecb->dte_action_last;
9899
9900         if (act->dta_kind == DTRACEACT_DIFEXPR) {
9901                 ASSERT(act->dta_difo != NULL);
9902
9903                 if (act->dta_difo->dtdo_rtype.dtdt_size == 0)
9904                         agg->dtag_hasarg = 1;
9905         }
9906
9907         /*
9908          * We need to allocate an id for this aggregation.
9909          */
9910 #if defined(sun)
9911         aggid = (dtrace_aggid_t)(uintptr_t)vmem_alloc(state->dts_aggid_arena, 1,
9912             VM_BESTFIT | VM_SLEEP);
9913 #else
9914         aggid = alloc_unr(state->dts_aggid_arena);
9915 #endif
9916
9917         if (aggid - 1 >= state->dts_naggregations) {
9918                 dtrace_aggregation_t **oaggs = state->dts_aggregations;
9919                 dtrace_aggregation_t **aggs;
9920                 int naggs = state->dts_naggregations << 1;
9921                 int onaggs = state->dts_naggregations;
9922
9923                 ASSERT(aggid == state->dts_naggregations + 1);
9924
9925                 if (naggs == 0) {
9926                         ASSERT(oaggs == NULL);
9927                         naggs = 1;
9928                 }
9929
9930                 aggs = kmem_zalloc(naggs * sizeof (*aggs), KM_SLEEP);
9931
9932                 if (oaggs != NULL) {
9933                         bcopy(oaggs, aggs, onaggs * sizeof (*aggs));
9934                         kmem_free(oaggs, onaggs * sizeof (*aggs));
9935                 }
9936
9937                 state->dts_aggregations = aggs;
9938                 state->dts_naggregations = naggs;
9939         }
9940
9941         ASSERT(state->dts_aggregations[aggid - 1] == NULL);
9942         state->dts_aggregations[(agg->dtag_id = aggid) - 1] = agg;
9943
9944         frec = &agg->dtag_first->dta_rec;
9945         if (frec->dtrd_alignment < sizeof (dtrace_aggid_t))
9946                 frec->dtrd_alignment = sizeof (dtrace_aggid_t);
9947
9948         for (act = agg->dtag_first; act != NULL; act = act->dta_next) {
9949                 ASSERT(!act->dta_intuple);
9950                 act->dta_intuple = 1;
9951         }
9952
9953         return (&agg->dtag_action);
9954 }
9955
9956 static void
9957 dtrace_ecb_aggregation_destroy(dtrace_ecb_t *ecb, dtrace_action_t *act)
9958 {
9959         dtrace_aggregation_t *agg = (dtrace_aggregation_t *)act;
9960         dtrace_state_t *state = ecb->dte_state;
9961         dtrace_aggid_t aggid = agg->dtag_id;
9962
9963         ASSERT(DTRACEACT_ISAGG(act->dta_kind));
9964 #if defined(sun)
9965         vmem_free(state->dts_aggid_arena, (void *)(uintptr_t)aggid, 1);
9966 #else
9967         free_unr(state->dts_aggid_arena, aggid);
9968 #endif
9969
9970         ASSERT(state->dts_aggregations[aggid - 1] == agg);
9971         state->dts_aggregations[aggid - 1] = NULL;
9972
9973         kmem_free(agg, sizeof (dtrace_aggregation_t));
9974 }
9975
9976 static int
9977 dtrace_ecb_action_add(dtrace_ecb_t *ecb, dtrace_actdesc_t *desc)
9978 {
9979         dtrace_action_t *action, *last;
9980         dtrace_difo_t *dp = desc->dtad_difo;
9981         uint32_t size = 0, align = sizeof (uint8_t), mask;
9982         uint16_t format = 0;
9983         dtrace_recdesc_t *rec;
9984         dtrace_state_t *state = ecb->dte_state;
9985         dtrace_optval_t *opt = state->dts_options, nframes = 0, strsize;
9986         uint64_t arg = desc->dtad_arg;
9987
9988         ASSERT(MUTEX_HELD(&dtrace_lock));
9989         ASSERT(ecb->dte_action == NULL || ecb->dte_action->dta_refcnt == 1);
9990
9991         if (DTRACEACT_ISAGG(desc->dtad_kind)) {
9992                 /*
9993                  * If this is an aggregating action, there must be neither
9994                  * a speculate nor a commit on the action chain.
9995                  */
9996                 dtrace_action_t *act;
9997
9998                 for (act = ecb->dte_action; act != NULL; act = act->dta_next) {
9999                         if (act->dta_kind == DTRACEACT_COMMIT)
10000                                 return (EINVAL);
10001
10002                         if (act->dta_kind == DTRACEACT_SPECULATE)
10003                                 return (EINVAL);
10004                 }
10005
10006                 action = dtrace_ecb_aggregation_create(ecb, desc);
10007
10008                 if (action == NULL)
10009                         return (EINVAL);
10010         } else {
10011                 if (DTRACEACT_ISDESTRUCTIVE(desc->dtad_kind) ||
10012                     (desc->dtad_kind == DTRACEACT_DIFEXPR &&
10013                     dp != NULL && dp->dtdo_destructive)) {
10014                         state->dts_destructive = 1;
10015                 }
10016
10017                 switch (desc->dtad_kind) {
10018                 case DTRACEACT_PRINTF:
10019                 case DTRACEACT_PRINTA:
10020                 case DTRACEACT_SYSTEM:
10021                 case DTRACEACT_FREOPEN:
10022                         /*
10023                          * We know that our arg is a string -- turn it into a
10024                          * format.
10025                          */
10026                         if (arg == 0) {
10027                                 ASSERT(desc->dtad_kind == DTRACEACT_PRINTA);
10028                                 format = 0;
10029                         } else {
10030                                 ASSERT(arg != 0);
10031 #if defined(sun)
10032                                 ASSERT(arg > KERNELBASE);
10033 #endif
10034                                 format = dtrace_format_add(state,
10035                                     (char *)(uintptr_t)arg);
10036                         }
10037
10038                         /*FALLTHROUGH*/
10039                 case DTRACEACT_LIBACT:
10040                 case DTRACEACT_DIFEXPR:
10041                         if (dp == NULL)
10042                                 return (EINVAL);
10043
10044                         if ((size = dp->dtdo_rtype.dtdt_size) != 0)
10045                                 break;
10046
10047                         if (dp->dtdo_rtype.dtdt_kind == DIF_TYPE_STRING) {
10048                                 if (!(dp->dtdo_rtype.dtdt_flags & DIF_TF_BYREF))
10049                                         return (EINVAL);
10050
10051                                 size = opt[DTRACEOPT_STRSIZE];
10052                         }
10053
10054                         break;
10055
10056                 case DTRACEACT_STACK:
10057                         if ((nframes = arg) == 0) {
10058                                 nframes = opt[DTRACEOPT_STACKFRAMES];
10059                                 ASSERT(nframes > 0);
10060                                 arg = nframes;
10061                         }
10062
10063                         size = nframes * sizeof (pc_t);
10064                         break;
10065
10066                 case DTRACEACT_JSTACK:
10067                         if ((strsize = DTRACE_USTACK_STRSIZE(arg)) == 0)
10068                                 strsize = opt[DTRACEOPT_JSTACKSTRSIZE];
10069
10070                         if ((nframes = DTRACE_USTACK_NFRAMES(arg)) == 0)
10071                                 nframes = opt[DTRACEOPT_JSTACKFRAMES];
10072
10073                         arg = DTRACE_USTACK_ARG(nframes, strsize);
10074
10075                         /*FALLTHROUGH*/
10076                 case DTRACEACT_USTACK:
10077                         if (desc->dtad_kind != DTRACEACT_JSTACK &&
10078                             (nframes = DTRACE_USTACK_NFRAMES(arg)) == 0) {
10079                                 strsize = DTRACE_USTACK_STRSIZE(arg);
10080                                 nframes = opt[DTRACEOPT_USTACKFRAMES];
10081                                 ASSERT(nframes > 0);
10082                                 arg = DTRACE_USTACK_ARG(nframes, strsize);
10083                         }
10084
10085                         /*
10086                          * Save a slot for the pid.
10087                          */
10088                         size = (nframes + 1) * sizeof (uint64_t);
10089                         size += DTRACE_USTACK_STRSIZE(arg);
10090                         size = P2ROUNDUP(size, (uint32_t)(sizeof (uintptr_t)));
10091
10092                         break;
10093
10094                 case DTRACEACT_SYM:
10095                 case DTRACEACT_MOD:
10096                         if (dp == NULL || ((size = dp->dtdo_rtype.dtdt_size) !=
10097                             sizeof (uint64_t)) ||
10098                             (dp->dtdo_rtype.dtdt_flags & DIF_TF_BYREF))
10099                                 return (EINVAL);
10100                         break;
10101
10102                 case DTRACEACT_USYM:
10103                 case DTRACEACT_UMOD:
10104                 case DTRACEACT_UADDR:
10105                         if (dp == NULL ||
10106                             (dp->dtdo_rtype.dtdt_size != sizeof (uint64_t)) ||
10107                             (dp->dtdo_rtype.dtdt_flags & DIF_TF_BYREF))
10108                                 return (EINVAL);
10109
10110                         /*
10111                          * We have a slot for the pid, plus a slot for the
10112                          * argument.  To keep things simple (aligned with
10113                          * bitness-neutral sizing), we store each as a 64-bit
10114                          * quantity.
10115                          */
10116                         size = 2 * sizeof (uint64_t);
10117                         break;
10118
10119                 case DTRACEACT_STOP:
10120                 case DTRACEACT_BREAKPOINT:
10121                 case DTRACEACT_PANIC:
10122                         break;
10123
10124                 case DTRACEACT_CHILL:
10125                 case DTRACEACT_DISCARD:
10126                 case DTRACEACT_RAISE:
10127                         if (dp == NULL)
10128                                 return (EINVAL);
10129                         break;
10130
10131                 case DTRACEACT_EXIT:
10132                         if (dp == NULL ||
10133                             (size = dp->dtdo_rtype.dtdt_size) != sizeof (int) ||
10134                             (dp->dtdo_rtype.dtdt_flags & DIF_TF_BYREF))
10135                                 return (EINVAL);
10136                         break;
10137
10138                 case DTRACEACT_SPECULATE:
10139                         if (ecb->dte_size > sizeof (dtrace_epid_t))
10140                                 return (EINVAL);
10141
10142                         if (dp == NULL)
10143                                 return (EINVAL);
10144
10145                         state->dts_speculates = 1;
10146                         break;
10147
10148                 case DTRACEACT_PRINTM:
10149                         size = dp->dtdo_rtype.dtdt_size;
10150                         break;
10151
10152                 case DTRACEACT_PRINTT:
10153                         size = dp->dtdo_rtype.dtdt_size;
10154                         break;
10155
10156                 case DTRACEACT_COMMIT: {
10157                         dtrace_action_t *act = ecb->dte_action;
10158
10159                         for (; act != NULL; act = act->dta_next) {
10160                                 if (act->dta_kind == DTRACEACT_COMMIT)
10161                                         return (EINVAL);
10162                         }
10163
10164                         if (dp == NULL)
10165                                 return (EINVAL);
10166                         break;
10167                 }
10168
10169                 default:
10170                         return (EINVAL);
10171                 }
10172
10173                 if (size != 0 || desc->dtad_kind == DTRACEACT_SPECULATE) {
10174                         /*
10175                          * If this is a data-storing action or a speculate,
10176                          * we must be sure that there isn't a commit on the
10177                          * action chain.
10178                          */
10179                         dtrace_action_t *act = ecb->dte_action;
10180
10181                         for (; act != NULL; act = act->dta_next) {
10182                                 if (act->dta_kind == DTRACEACT_COMMIT)
10183                                         return (EINVAL);
10184                         }
10185                 }
10186
10187                 action = kmem_zalloc(sizeof (dtrace_action_t), KM_SLEEP);
10188                 action->dta_rec.dtrd_size = size;
10189         }
10190
10191         action->dta_refcnt = 1;
10192         rec = &action->dta_rec;
10193         size = rec->dtrd_size;
10194
10195         for (mask = sizeof (uint64_t) - 1; size != 0 && mask > 0; mask >>= 1) {
10196                 if (!(size & mask)) {
10197                         align = mask + 1;
10198                         break;
10199                 }
10200         }
10201
10202         action->dta_kind = desc->dtad_kind;
10203
10204         if ((action->dta_difo = dp) != NULL)
10205                 dtrace_difo_hold(dp);
10206
10207         rec->dtrd_action = action->dta_kind;
10208         rec->dtrd_arg = arg;
10209         rec->dtrd_uarg = desc->dtad_uarg;
10210         rec->dtrd_alignment = (uint16_t)align;
10211         rec->dtrd_format = format;
10212
10213         if ((last = ecb->dte_action_last) != NULL) {
10214                 ASSERT(ecb->dte_action != NULL);
10215                 action->dta_prev = last;
10216                 last->dta_next = action;
10217         } else {
10218                 ASSERT(ecb->dte_action == NULL);
10219                 ecb->dte_action = action;
10220         }
10221
10222         ecb->dte_action_last = action;
10223
10224         return (0);
10225 }
10226
10227 static void
10228 dtrace_ecb_action_remove(dtrace_ecb_t *ecb)
10229 {
10230         dtrace_action_t *act = ecb->dte_action, *next;
10231         dtrace_vstate_t *vstate = &ecb->dte_state->dts_vstate;
10232         dtrace_difo_t *dp;
10233         uint16_t format;
10234
10235         if (act != NULL && act->dta_refcnt > 1) {
10236                 ASSERT(act->dta_next == NULL || act->dta_next->dta_refcnt == 1);
10237                 act->dta_refcnt--;
10238         } else {
10239                 for (; act != NULL; act = next) {
10240                         next = act->dta_next;
10241                         ASSERT(next != NULL || act == ecb->dte_action_last);
10242                         ASSERT(act->dta_refcnt == 1);
10243
10244                         if ((format = act->dta_rec.dtrd_format) != 0)
10245                                 dtrace_format_remove(ecb->dte_state, format);
10246
10247                         if ((dp = act->dta_difo) != NULL)
10248                                 dtrace_difo_release(dp, vstate);
10249
10250                         if (DTRACEACT_ISAGG(act->dta_kind)) {
10251                                 dtrace_ecb_aggregation_destroy(ecb, act);
10252                         } else {
10253                                 kmem_free(act, sizeof (dtrace_action_t));
10254                         }
10255                 }
10256         }
10257
10258         ecb->dte_action = NULL;
10259         ecb->dte_action_last = NULL;
10260         ecb->dte_size = sizeof (dtrace_epid_t);
10261 }
10262
10263 static void
10264 dtrace_ecb_disable(dtrace_ecb_t *ecb)
10265 {
10266         /*
10267          * We disable the ECB by removing it from its probe.
10268          */
10269         dtrace_ecb_t *pecb, *prev = NULL;
10270         dtrace_probe_t *probe = ecb->dte_probe;
10271
10272         ASSERT(MUTEX_HELD(&dtrace_lock));
10273
10274         if (probe == NULL) {
10275                 /*
10276                  * This is the NULL probe; there is nothing to disable.
10277                  */
10278                 return;
10279         }
10280
10281         for (pecb = probe->dtpr_ecb; pecb != NULL; pecb = pecb->dte_next) {
10282                 if (pecb == ecb)
10283                         break;
10284                 prev = pecb;
10285         }
10286
10287         ASSERT(pecb != NULL);
10288
10289         if (prev == NULL) {
10290                 probe->dtpr_ecb = ecb->dte_next;
10291         } else {
10292                 prev->dte_next = ecb->dte_next;
10293         }
10294
10295         if (ecb == probe->dtpr_ecb_last) {
10296                 ASSERT(ecb->dte_next == NULL);
10297                 probe->dtpr_ecb_last = prev;
10298         }
10299
10300         /*
10301          * The ECB has been disconnected from the probe; now sync to assure
10302          * that all CPUs have seen the change before returning.
10303          */
10304         dtrace_sync();
10305
10306         if (probe->dtpr_ecb == NULL) {
10307                 /*
10308                  * That was the last ECB on the probe; clear the predicate
10309                  * cache ID for the probe, disable it and sync one more time
10310                  * to assure that we'll never hit it again.
10311                  */
10312                 dtrace_provider_t *prov = probe->dtpr_provider;
10313
10314                 ASSERT(ecb->dte_next == NULL);
10315                 ASSERT(probe->dtpr_ecb_last == NULL);
10316                 probe->dtpr_predcache = DTRACE_CACHEIDNONE;
10317                 prov->dtpv_pops.dtps_disable(prov->dtpv_arg,
10318                     probe->dtpr_id, probe->dtpr_arg);
10319                 dtrace_sync();
10320         } else {
10321                 /*
10322                  * There is at least one ECB remaining on the probe.  If there
10323                  * is _exactly_ one, set the probe's predicate cache ID to be
10324                  * the predicate cache ID of the remaining ECB.
10325                  */
10326                 ASSERT(probe->dtpr_ecb_last != NULL);
10327                 ASSERT(probe->dtpr_predcache == DTRACE_CACHEIDNONE);
10328
10329                 if (probe->dtpr_ecb == probe->dtpr_ecb_last) {
10330                         dtrace_predicate_t *p = probe->dtpr_ecb->dte_predicate;
10331
10332                         ASSERT(probe->dtpr_ecb->dte_next == NULL);
10333
10334                         if (p != NULL)
10335                                 probe->dtpr_predcache = p->dtp_cacheid;
10336                 }
10337
10338                 ecb->dte_next = NULL;
10339         }
10340 }
10341
10342 static void
10343 dtrace_ecb_destroy(dtrace_ecb_t *ecb)
10344 {
10345         dtrace_state_t *state = ecb->dte_state;
10346         dtrace_vstate_t *vstate = &state->dts_vstate;
10347         dtrace_predicate_t *pred;
10348         dtrace_epid_t epid = ecb->dte_epid;
10349
10350         ASSERT(MUTEX_HELD(&dtrace_lock));
10351         ASSERT(ecb->dte_next == NULL);
10352         ASSERT(ecb->dte_probe == NULL || ecb->dte_probe->dtpr_ecb != ecb);
10353
10354         if ((pred = ecb->dte_predicate) != NULL)
10355                 dtrace_predicate_release(pred, vstate);
10356
10357         dtrace_ecb_action_remove(ecb);
10358
10359         ASSERT(state->dts_ecbs[epid - 1] == ecb);
10360         state->dts_ecbs[epid - 1] = NULL;
10361
10362         kmem_free(ecb, sizeof (dtrace_ecb_t));
10363 }
10364
10365 static dtrace_ecb_t *
10366 dtrace_ecb_create(dtrace_state_t *state, dtrace_probe_t *probe,
10367     dtrace_enabling_t *enab)
10368 {
10369         dtrace_ecb_t *ecb;
10370         dtrace_predicate_t *pred;
10371         dtrace_actdesc_t *act;
10372         dtrace_provider_t *prov;
10373         dtrace_ecbdesc_t *desc = enab->dten_current;
10374
10375         ASSERT(MUTEX_HELD(&dtrace_lock));
10376         ASSERT(state != NULL);
10377
10378         ecb = dtrace_ecb_add(state, probe);
10379         ecb->dte_uarg = desc->dted_uarg;
10380
10381         if ((pred = desc->dted_pred.dtpdd_predicate) != NULL) {
10382                 dtrace_predicate_hold(pred);
10383                 ecb->dte_predicate = pred;
10384         }
10385
10386         if (probe != NULL) {
10387                 /*
10388                  * If the provider shows more leg than the consumer is old
10389                  * enough to see, we need to enable the appropriate implicit
10390                  * predicate bits to prevent the ecb from activating at
10391                  * revealing times.
10392                  *
10393                  * Providers specifying DTRACE_PRIV_USER at register time
10394                  * are stating that they need the /proc-style privilege
10395                  * model to be enforced, and this is what DTRACE_COND_OWNER
10396                  * and DTRACE_COND_ZONEOWNER will then do at probe time.
10397                  */
10398                 prov = probe->dtpr_provider;
10399                 if (!(state->dts_cred.dcr_visible & DTRACE_CRV_ALLPROC) &&
10400                     (prov->dtpv_priv.dtpp_flags & DTRACE_PRIV_USER))
10401                         ecb->dte_cond |= DTRACE_COND_OWNER;
10402
10403                 if (!(state->dts_cred.dcr_visible & DTRACE_CRV_ALLZONE) &&
10404                     (prov->dtpv_priv.dtpp_flags & DTRACE_PRIV_USER))
10405                         ecb->dte_cond |= DTRACE_COND_ZONEOWNER;
10406
10407                 /*
10408                  * If the provider shows us kernel innards and the user
10409                  * is lacking sufficient privilege, enable the
10410                  * DTRACE_COND_USERMODE implicit predicate.
10411                  */
10412                 if (!(state->dts_cred.dcr_visible & DTRACE_CRV_KERNEL) &&
10413                     (prov->dtpv_priv.dtpp_flags & DTRACE_PRIV_KERNEL))
10414                         ecb->dte_cond |= DTRACE_COND_USERMODE;
10415         }
10416
10417         if (dtrace_ecb_create_cache != NULL) {
10418                 /*
10419                  * If we have a cached ecb, we'll use its action list instead
10420                  * of creating our own (saving both time and space).
10421                  */
10422                 dtrace_ecb_t *cached = dtrace_ecb_create_cache;
10423                 dtrace_action_t *act = cached->dte_action;
10424
10425                 if (act != NULL) {
10426                         ASSERT(act->dta_refcnt > 0);
10427                         act->dta_refcnt++;
10428                         ecb->dte_action = act;
10429                         ecb->dte_action_last = cached->dte_action_last;
10430                         ecb->dte_needed = cached->dte_needed;
10431                         ecb->dte_size = cached->dte_size;
10432                         ecb->dte_alignment = cached->dte_alignment;
10433                 }
10434
10435                 return (ecb);
10436         }
10437
10438         for (act = desc->dted_action; act != NULL; act = act->dtad_next) {
10439                 if ((enab->dten_error = dtrace_ecb_action_add(ecb, act)) != 0) {
10440                         dtrace_ecb_destroy(ecb);
10441                         return (NULL);
10442                 }
10443         }
10444
10445         dtrace_ecb_resize(ecb);
10446
10447         return (dtrace_ecb_create_cache = ecb);
10448 }
10449
10450 static int
10451 dtrace_ecb_create_enable(dtrace_probe_t *probe, void *arg)
10452 {
10453         dtrace_ecb_t *ecb;
10454         dtrace_enabling_t *enab = arg;
10455         dtrace_state_t *state = enab->dten_vstate->dtvs_state;
10456
10457         ASSERT(state != NULL);
10458
10459         if (probe != NULL && probe->dtpr_gen < enab->dten_probegen) {
10460                 /*
10461                  * This probe was created in a generation for which this
10462                  * enabling has previously created ECBs; we don't want to
10463                  * enable it again, so just kick out.
10464                  */
10465                 return (DTRACE_MATCH_NEXT);
10466         }
10467
10468         if ((ecb = dtrace_ecb_create(state, probe, enab)) == NULL)
10469                 return (DTRACE_MATCH_DONE);
10470
10471         dtrace_ecb_enable(ecb);
10472         return (DTRACE_MATCH_NEXT);
10473 }
10474
10475 static dtrace_ecb_t *
10476 dtrace_epid2ecb(dtrace_state_t *state, dtrace_epid_t id)
10477 {
10478         dtrace_ecb_t *ecb;
10479
10480         ASSERT(MUTEX_HELD(&dtrace_lock));
10481
10482         if (id == 0 || id > state->dts_necbs)
10483                 return (NULL);
10484
10485         ASSERT(state->dts_necbs > 0 && state->dts_ecbs != NULL);
10486         ASSERT((ecb = state->dts_ecbs[id - 1]) == NULL || ecb->dte_epid == id);
10487
10488         return (state->dts_ecbs[id - 1]);
10489 }
10490
10491 static dtrace_aggregation_t *
10492 dtrace_aggid2agg(dtrace_state_t *state, dtrace_aggid_t id)
10493 {
10494         dtrace_aggregation_t *agg;
10495
10496         ASSERT(MUTEX_HELD(&dtrace_lock));
10497
10498         if (id == 0 || id > state->dts_naggregations)
10499                 return (NULL);
10500
10501         ASSERT(state->dts_naggregations > 0 && state->dts_aggregations != NULL);
10502         ASSERT((agg = state->dts_aggregations[id - 1]) == NULL ||
10503             agg->dtag_id == id);
10504
10505         return (state->dts_aggregations[id - 1]);
10506 }
10507
10508 /*
10509  * DTrace Buffer Functions
10510  *
10511  * The following functions manipulate DTrace buffers.  Most of these functions
10512  * are called in the context of establishing or processing consumer state;
10513  * exceptions are explicitly noted.
10514  */
10515
10516 /*
10517  * Note:  called from cross call context.  This function switches the two
10518  * buffers on a given CPU.  The atomicity of this operation is assured by
10519  * disabling interrupts while the actual switch takes place; the disabling of
10520  * interrupts serializes the execution with any execution of dtrace_probe() on
10521  * the same CPU.
10522  */
10523 static void
10524 dtrace_buffer_switch(dtrace_buffer_t *buf)
10525 {
10526         caddr_t tomax = buf->dtb_tomax;
10527         caddr_t xamot = buf->dtb_xamot;
10528         dtrace_icookie_t cookie;
10529
10530         ASSERT(!(buf->dtb_flags & DTRACEBUF_NOSWITCH));
10531         ASSERT(!(buf->dtb_flags & DTRACEBUF_RING));
10532
10533         cookie = dtrace_interrupt_disable();
10534         buf->dtb_tomax = xamot;
10535         buf->dtb_xamot = tomax;
10536         buf->dtb_xamot_drops = buf->dtb_drops;
10537         buf->dtb_xamot_offset = buf->dtb_offset;
10538         buf->dtb_xamot_errors = buf->dtb_errors;
10539         buf->dtb_xamot_flags = buf->dtb_flags;
10540         buf->dtb_offset = 0;
10541         buf->dtb_drops = 0;
10542         buf->dtb_errors = 0;
10543         buf->dtb_flags &= ~(DTRACEBUF_ERROR | DTRACEBUF_DROPPED);
10544         dtrace_interrupt_enable(cookie);
10545 }
10546
10547 /*
10548  * Note:  called from cross call context.  This function activates a buffer
10549  * on a CPU.  As with dtrace_buffer_switch(), the atomicity of the operation
10550  * is guaranteed by the disabling of interrupts.
10551  */
10552 static void
10553 dtrace_buffer_activate(dtrace_state_t *state)
10554 {
10555         dtrace_buffer_t *buf;
10556         dtrace_icookie_t cookie = dtrace_interrupt_disable();
10557
10558         buf = &state->dts_buffer[curcpu];
10559
10560         if (buf->dtb_tomax != NULL) {
10561                 /*
10562                  * We might like to assert that the buffer is marked inactive,
10563                  * but this isn't necessarily true:  the buffer for the CPU
10564                  * that processes the BEGIN probe has its buffer activated
10565                  * manually.  In this case, we take the (harmless) action
10566                  * re-clearing the bit INACTIVE bit.
10567                  */
10568                 buf->dtb_flags &= ~DTRACEBUF_INACTIVE;
10569         }
10570
10571         dtrace_interrupt_enable(cookie);
10572 }
10573
10574 static int
10575 dtrace_buffer_alloc(dtrace_buffer_t *bufs, size_t size, int flags,
10576     processorid_t cpu)
10577 {
10578 #if defined(sun)
10579         cpu_t *cp;
10580 #else
10581         struct pcpu *cp;
10582 #endif
10583         dtrace_buffer_t *buf;
10584
10585 #if defined(sun)
10586         ASSERT(MUTEX_HELD(&cpu_lock));
10587         ASSERT(MUTEX_HELD(&dtrace_lock));
10588
10589         if (size > dtrace_nonroot_maxsize &&
10590             !PRIV_POLICY_CHOICE(CRED(), PRIV_ALL, B_FALSE))
10591                 return (EFBIG);
10592
10593         cp = cpu_list;
10594
10595         do {
10596                 if (cpu != DTRACE_CPUALL && cpu != cp->cpu_id)
10597                         continue;
10598
10599                 buf = &bufs[cp->cpu_id];
10600
10601                 /*
10602                  * If there is already a buffer allocated for this CPU, it
10603                  * is only possible that this is a DR event.  In this case,
10604                  */
10605                 if (buf->dtb_tomax != NULL) {
10606                         ASSERT(buf->dtb_size == size);
10607                         continue;
10608                 }
10609
10610                 ASSERT(buf->dtb_xamot == NULL);
10611
10612                 if ((buf->dtb_tomax = kmem_zalloc(size, KM_NOSLEEP)) == NULL)
10613                         goto err;
10614
10615                 buf->dtb_size = size;
10616                 buf->dtb_flags = flags;
10617                 buf->dtb_offset = 0;
10618                 buf->dtb_drops = 0;
10619
10620                 if (flags & DTRACEBUF_NOSWITCH)
10621                         continue;
10622
10623                 if ((buf->dtb_xamot = kmem_zalloc(size, KM_NOSLEEP)) == NULL)
10624                         goto err;
10625         } while ((cp = cp->cpu_next) != cpu_list);
10626
10627         return (0);
10628
10629 err:
10630         cp = cpu_list;
10631
10632         do {
10633                 if (cpu != DTRACE_CPUALL && cpu != cp->cpu_id)
10634                         continue;
10635
10636                 buf = &bufs[cp->cpu_id];
10637
10638                 if (buf->dtb_xamot != NULL) {
10639                         ASSERT(buf->dtb_tomax != NULL);
10640                         ASSERT(buf->dtb_size == size);
10641                         kmem_free(buf->dtb_xamot, size);
10642                 }
10643
10644                 if (buf->dtb_tomax != NULL) {
10645                         ASSERT(buf->dtb_size == size);
10646                         kmem_free(buf->dtb_tomax, size);
10647                 }
10648
10649                 buf->dtb_tomax = NULL;
10650                 buf->dtb_xamot = NULL;
10651                 buf->dtb_size = 0;
10652         } while ((cp = cp->cpu_next) != cpu_list);
10653
10654         return (ENOMEM);
10655 #else
10656         int i;
10657
10658 #if defined(__amd64__)
10659         /*
10660          * FreeBSD isn't good at limiting the amount of memory we
10661          * ask to malloc, so let's place a limit here before trying
10662          * to do something that might well end in tears at bedtime.
10663          */
10664         if (size > physmem * PAGE_SIZE / (128 * (mp_maxid + 1)))
10665                 return(ENOMEM);
10666 #endif
10667
10668         ASSERT(MUTEX_HELD(&dtrace_lock));
10669         for (i = 0; i <= mp_maxid; i++) {
10670                 if ((cp = pcpu_find(i)) == NULL)
10671                         continue;
10672
10673                 if (cpu != DTRACE_CPUALL && cpu != i)
10674                         continue;
10675
10676                 buf = &bufs[i];
10677
10678                 /*
10679                  * If there is already a buffer allocated for this CPU, it
10680                  * is only possible that this is a DR event.  In this case,
10681                  * the buffer size must match our specified size.
10682                  */
10683                 if (buf->dtb_tomax != NULL) {
10684                         ASSERT(buf->dtb_size == size);
10685                         continue;
10686                 }
10687
10688                 ASSERT(buf->dtb_xamot == NULL);
10689
10690                 if ((buf->dtb_tomax = kmem_zalloc(size, KM_NOSLEEP)) == NULL)
10691                         goto err;
10692
10693                 buf->dtb_size = size;
10694                 buf->dtb_flags = flags;
10695                 buf->dtb_offset = 0;
10696                 buf->dtb_drops = 0;
10697
10698                 if (flags & DTRACEBUF_NOSWITCH)
10699                         continue;
10700
10701                 if ((buf->dtb_xamot = kmem_zalloc(size, KM_NOSLEEP)) == NULL)
10702                         goto err;
10703         }
10704
10705         return (0);
10706
10707 err:
10708         /*
10709          * Error allocating memory, so free the buffers that were
10710          * allocated before the failed allocation.
10711          */
10712         for (i = 0; i <= mp_maxid; i++) {
10713                 if ((cp = pcpu_find(i)) == NULL)
10714                         continue;
10715
10716                 if (cpu != DTRACE_CPUALL && cpu != i)
10717                         continue;
10718
10719                 buf = &bufs[i];
10720
10721                 if (buf->dtb_xamot != NULL) {
10722                         ASSERT(buf->dtb_tomax != NULL);
10723                         ASSERT(buf->dtb_size == size);
10724                         kmem_free(buf->dtb_xamot, size);
10725                 }
10726
10727                 if (buf->dtb_tomax != NULL) {
10728                         ASSERT(buf->dtb_size == size);
10729                         kmem_free(buf->dtb_tomax, size);
10730                 }
10731
10732                 buf->dtb_tomax = NULL;
10733                 buf->dtb_xamot = NULL;
10734                 buf->dtb_size = 0;
10735
10736         }
10737
10738         return (ENOMEM);
10739 #endif
10740 }
10741
10742 /*
10743  * Note:  called from probe context.  This function just increments the drop
10744  * count on a buffer.  It has been made a function to allow for the
10745  * possibility of understanding the source of mysterious drop counts.  (A
10746  * problem for which one may be particularly disappointed that DTrace cannot
10747  * be used to understand DTrace.)
10748  */
10749 static void
10750 dtrace_buffer_drop(dtrace_buffer_t *buf)
10751 {
10752         buf->dtb_drops++;
10753 }
10754
10755 /*
10756  * Note:  called from probe context.  This function is called to reserve space
10757  * in a buffer.  If mstate is non-NULL, sets the scratch base and size in the
10758  * mstate.  Returns the new offset in the buffer, or a negative value if an
10759  * error has occurred.
10760  */
10761 static intptr_t
10762 dtrace_buffer_reserve(dtrace_buffer_t *buf, size_t needed, size_t align,
10763     dtrace_state_t *state, dtrace_mstate_t *mstate)
10764 {
10765         intptr_t offs = buf->dtb_offset, soffs;
10766         intptr_t woffs;
10767         caddr_t tomax;
10768         size_t total;
10769
10770         if (buf->dtb_flags & DTRACEBUF_INACTIVE)
10771                 return (-1);
10772
10773         if ((tomax = buf->dtb_tomax) == NULL) {
10774                 dtrace_buffer_drop(buf);
10775                 return (-1);
10776         }
10777
10778         if (!(buf->dtb_flags & (DTRACEBUF_RING | DTRACEBUF_FILL))) {
10779                 while (offs & (align - 1)) {
10780                         /*
10781                          * Assert that our alignment is off by a number which
10782                          * is itself sizeof (uint32_t) aligned.
10783                          */
10784                         ASSERT(!((align - (offs & (align - 1))) &
10785                             (sizeof (uint32_t) - 1)));
10786                         DTRACE_STORE(uint32_t, tomax, offs, DTRACE_EPIDNONE);
10787                         offs += sizeof (uint32_t);
10788                 }
10789
10790                 if ((soffs = offs + needed) > buf->dtb_size) {
10791                         dtrace_buffer_drop(buf);
10792                         return (-1);
10793                 }
10794
10795                 if (mstate == NULL)
10796                         return (offs);
10797
10798                 mstate->dtms_scratch_base = (uintptr_t)tomax + soffs;
10799                 mstate->dtms_scratch_size = buf->dtb_size - soffs;
10800                 mstate->dtms_scratch_ptr = mstate->dtms_scratch_base;
10801
10802                 return (offs);
10803         }
10804
10805         if (buf->dtb_flags & DTRACEBUF_FILL) {
10806                 if (state->dts_activity != DTRACE_ACTIVITY_COOLDOWN &&
10807                     (buf->dtb_flags & DTRACEBUF_FULL))
10808                         return (-1);
10809                 goto out;
10810         }
10811
10812         total = needed + (offs & (align - 1));
10813
10814         /*
10815          * For a ring buffer, life is quite a bit more complicated.  Before
10816          * we can store any padding, we need to adjust our wrapping offset.
10817          * (If we've never before wrapped or we're not about to, no adjustment
10818          * is required.)
10819          */
10820         if ((buf->dtb_flags & DTRACEBUF_WRAPPED) ||
10821             offs + total > buf->dtb_size) {
10822                 woffs = buf->dtb_xamot_offset;
10823
10824                 if (offs + total > buf->dtb_size) {
10825                         /*
10826                          * We can't fit in the end of the buffer.  First, a
10827                          * sanity check that we can fit in the buffer at all.
10828                          */
10829                         if (total > buf->dtb_size) {
10830                                 dtrace_buffer_drop(buf);
10831                                 return (-1);
10832                         }
10833
10834                         /*
10835                          * We're going to be storing at the top of the buffer,
10836                          * so now we need to deal with the wrapped offset.  We
10837                          * only reset our wrapped offset to 0 if it is
10838                          * currently greater than the current offset.  If it
10839                          * is less than the current offset, it is because a
10840                          * previous allocation induced a wrap -- but the
10841                          * allocation didn't subsequently take the space due
10842                          * to an error or false predicate evaluation.  In this
10843                          * case, we'll just leave the wrapped offset alone: if
10844                          * the wrapped offset hasn't been advanced far enough
10845                          * for this allocation, it will be adjusted in the
10846                          * lower loop.
10847                          */
10848                         if (buf->dtb_flags & DTRACEBUF_WRAPPED) {
10849                                 if (woffs >= offs)
10850                                         woffs = 0;
10851                         } else {
10852                                 woffs = 0;
10853                         }
10854
10855                         /*
10856                          * Now we know that we're going to be storing to the
10857                          * top of the buffer and that there is room for us
10858                          * there.  We need to clear the buffer from the current
10859                          * offset to the end (there may be old gunk there).
10860                          */
10861                         while (offs < buf->dtb_size)
10862                                 tomax[offs++] = 0;
10863
10864                         /*
10865                          * We need to set our offset to zero.  And because we
10866                          * are wrapping, we need to set the bit indicating as
10867                          * much.  We can also adjust our needed space back
10868                          * down to the space required by the ECB -- we know
10869                          * that the top of the buffer is aligned.
10870                          */
10871                         offs = 0;
10872                         total = needed;
10873                         buf->dtb_flags |= DTRACEBUF_WRAPPED;
10874                 } else {
10875                         /*
10876                          * There is room for us in the buffer, so we simply
10877                          * need to check the wrapped offset.
10878                          */
10879                         if (woffs < offs) {
10880                                 /*
10881                                  * The wrapped offset is less than the offset.
10882                                  * This can happen if we allocated buffer space
10883                                  * that induced a wrap, but then we didn't
10884                                  * subsequently take the space due to an error
10885                                  * or false predicate evaluation.  This is
10886                                  * okay; we know that _this_ allocation isn't
10887                                  * going to induce a wrap.  We still can't
10888                                  * reset the wrapped offset to be zero,
10889                                  * however: the space may have been trashed in
10890                                  * the previous failed probe attempt.  But at
10891                                  * least the wrapped offset doesn't need to
10892                                  * be adjusted at all...
10893                                  */
10894                                 goto out;
10895                         }
10896                 }
10897
10898                 while (offs + total > woffs) {
10899                         dtrace_epid_t epid = *(uint32_t *)(tomax + woffs);
10900                         size_t size;
10901
10902                         if (epid == DTRACE_EPIDNONE) {
10903                                 size = sizeof (uint32_t);
10904                         } else {
10905                                 ASSERT(epid <= state->dts_necbs);
10906                                 ASSERT(state->dts_ecbs[epid - 1] != NULL);
10907
10908                                 size = state->dts_ecbs[epid - 1]->dte_size;
10909                         }
10910
10911                         ASSERT(woffs + size <= buf->dtb_size);
10912                         ASSERT(size != 0);
10913
10914                         if (woffs + size == buf->dtb_size) {
10915                                 /*
10916                                  * We've reached the end of the buffer; we want
10917                                  * to set the wrapped offset to 0 and break
10918                                  * out.  However, if the offs is 0, then we're
10919                                  * in a strange edge-condition:  the amount of
10920                                  * space that we want to reserve plus the size
10921                                  * of the record that we're overwriting is
10922                                  * greater than the size of the buffer.  This
10923                                  * is problematic because if we reserve the
10924                                  * space but subsequently don't consume it (due
10925                                  * to a failed predicate or error) the wrapped
10926                                  * offset will be 0 -- yet the EPID at offset 0
10927                                  * will not be committed.  This situation is
10928                                  * relatively easy to deal with:  if we're in
10929                                  * this case, the buffer is indistinguishable
10930                                  * from one that hasn't wrapped; we need only
10931                                  * finish the job by clearing the wrapped bit,
10932                                  * explicitly setting the offset to be 0, and
10933                                  * zero'ing out the old data in the buffer.
10934                                  */
10935                                 if (offs == 0) {
10936                                         buf->dtb_flags &= ~DTRACEBUF_WRAPPED;
10937                                         buf->dtb_offset = 0;
10938                                         woffs = total;
10939
10940                                         while (woffs < buf->dtb_size)
10941                                                 tomax[woffs++] = 0;
10942                                 }
10943
10944                                 woffs = 0;
10945                                 break;
10946                         }
10947
10948                         woffs += size;
10949                 }
10950
10951                 /*
10952                  * We have a wrapped offset.  It may be that the wrapped offset
10953                  * has become zero -- that's okay.
10954                  */
10955                 buf->dtb_xamot_offset = woffs;
10956         }
10957
10958 out:
10959         /*
10960          * Now we can plow the buffer with any necessary padding.
10961          */
10962         while (offs & (align - 1)) {
10963                 /*
10964                  * Assert that our alignment is off by a number which
10965                  * is itself sizeof (uint32_t) aligned.
10966                  */
10967                 ASSERT(!((align - (offs & (align - 1))) &
10968                     (sizeof (uint32_t) - 1)));
10969                 DTRACE_STORE(uint32_t, tomax, offs, DTRACE_EPIDNONE);
10970                 offs += sizeof (uint32_t);
10971         }
10972
10973         if (buf->dtb_flags & DTRACEBUF_FILL) {
10974                 if (offs + needed > buf->dtb_size - state->dts_reserve) {
10975                         buf->dtb_flags |= DTRACEBUF_FULL;
10976                         return (-1);
10977                 }
10978         }
10979
10980         if (mstate == NULL)
10981                 return (offs);
10982
10983         /*
10984          * For ring buffers and fill buffers, the scratch space is always
10985          * the inactive buffer.
10986          */
10987         mstate->dtms_scratch_base = (uintptr_t)buf->dtb_xamot;
10988         mstate->dtms_scratch_size = buf->dtb_size;
10989         mstate->dtms_scratch_ptr = mstate->dtms_scratch_base;
10990
10991         return (offs);
10992 }
10993
10994 static void
10995 dtrace_buffer_polish(dtrace_buffer_t *buf)
10996 {
10997         ASSERT(buf->dtb_flags & DTRACEBUF_RING);
10998         ASSERT(MUTEX_HELD(&dtrace_lock));
10999
11000         if (!(buf->dtb_flags & DTRACEBUF_WRAPPED))
11001                 return;
11002
11003         /*
11004          * We need to polish the ring buffer.  There are three cases:
11005          *
11006          * - The first (and presumably most common) is that there is no gap
11007          *   between the buffer offset and the wrapped offset.  In this case,
11008          *   there is nothing in the buffer that isn't valid data; we can
11009          *   mark the buffer as polished and return.
11010          *
11011          * - The second (less common than the first but still more common
11012          *   than the third) is that there is a gap between the buffer offset
11013          *   and the wrapped offset, and the wrapped offset is larger than the
11014          *   buffer offset.  This can happen because of an alignment issue, or
11015          *   can happen because of a call to dtrace_buffer_reserve() that
11016          *   didn't subsequently consume the buffer space.  In this case,
11017          *   we need to zero the data from the buffer offset to the wrapped
11018          *   offset.
11019          *
11020          * - The third (and least common) is that there is a gap between the
11021          *   buffer offset and the wrapped offset, but the wrapped offset is
11022          *   _less_ than the buffer offset.  This can only happen because a
11023          *   call to dtrace_buffer_reserve() induced a wrap, but the space
11024          *   was not subsequently consumed.  In this case, we need to zero the
11025          *   space from the offset to the end of the buffer _and_ from the
11026          *   top of the buffer to the wrapped offset.
11027          */
11028         if (buf->dtb_offset < buf->dtb_xamot_offset) {
11029                 bzero(buf->dtb_tomax + buf->dtb_offset,
11030                     buf->dtb_xamot_offset - buf->dtb_offset);
11031         }
11032
11033         if (buf->dtb_offset > buf->dtb_xamot_offset) {
11034                 bzero(buf->dtb_tomax + buf->dtb_offset,
11035                     buf->dtb_size - buf->dtb_offset);
11036                 bzero(buf->dtb_tomax, buf->dtb_xamot_offset);
11037         }
11038 }
11039
11040 static void
11041 dtrace_buffer_free(dtrace_buffer_t *bufs)
11042 {
11043         int i;
11044
11045         for (i = 0; i < NCPU; i++) {
11046                 dtrace_buffer_t *buf = &bufs[i];
11047
11048                 if (buf->dtb_tomax == NULL) {
11049                         ASSERT(buf->dtb_xamot == NULL);
11050                         ASSERT(buf->dtb_size == 0);
11051                         continue;
11052                 }
11053
11054                 if (buf->dtb_xamot != NULL) {
11055                         ASSERT(!(buf->dtb_flags & DTRACEBUF_NOSWITCH));
11056                         kmem_free(buf->dtb_xamot, buf->dtb_size);
11057                 }
11058
11059                 kmem_free(buf->dtb_tomax, buf->dtb_size);
11060                 buf->dtb_size = 0;
11061                 buf->dtb_tomax = NULL;
11062                 buf->dtb_xamot = NULL;
11063         }
11064 }
11065
11066 /*
11067  * DTrace Enabling Functions
11068  */
11069 static dtrace_enabling_t *
11070 dtrace_enabling_create(dtrace_vstate_t *vstate)
11071 {
11072         dtrace_enabling_t *enab;
11073
11074         enab = kmem_zalloc(sizeof (dtrace_enabling_t), KM_SLEEP);
11075         enab->dten_vstate = vstate;
11076
11077         return (enab);
11078 }
11079
11080 static void
11081 dtrace_enabling_add(dtrace_enabling_t *enab, dtrace_ecbdesc_t *ecb)
11082 {
11083         dtrace_ecbdesc_t **ndesc;
11084         size_t osize, nsize;
11085
11086         /*
11087          * We can't add to enablings after we've enabled them, or after we've
11088          * retained them.
11089          */
11090         ASSERT(enab->dten_probegen == 0);
11091         ASSERT(enab->dten_next == NULL && enab->dten_prev == NULL);
11092
11093         if (enab->dten_ndesc < enab->dten_maxdesc) {
11094                 enab->dten_desc[enab->dten_ndesc++] = ecb;
11095                 return;
11096         }
11097
11098         osize = enab->dten_maxdesc * sizeof (dtrace_enabling_t *);
11099
11100         if (enab->dten_maxdesc == 0) {
11101                 enab->dten_maxdesc = 1;
11102         } else {
11103                 enab->dten_maxdesc <<= 1;
11104         }
11105
11106         ASSERT(enab->dten_ndesc < enab->dten_maxdesc);
11107
11108         nsize = enab->dten_maxdesc * sizeof (dtrace_enabling_t *);
11109         ndesc = kmem_zalloc(nsize, KM_SLEEP);
11110         bcopy(enab->dten_desc, ndesc, osize);
11111         if (enab->dten_desc != NULL)
11112                 kmem_free(enab->dten_desc, osize);
11113
11114         enab->dten_desc = ndesc;
11115         enab->dten_desc[enab->dten_ndesc++] = ecb;
11116 }
11117
11118 static void
11119 dtrace_enabling_addlike(dtrace_enabling_t *enab, dtrace_ecbdesc_t *ecb,
11120     dtrace_probedesc_t *pd)
11121 {
11122         dtrace_ecbdesc_t *new;
11123         dtrace_predicate_t *pred;
11124         dtrace_actdesc_t *act;
11125
11126         /*
11127          * We're going to create a new ECB description that matches the
11128          * specified ECB in every way, but has the specified probe description.
11129          */
11130         new = kmem_zalloc(sizeof (dtrace_ecbdesc_t), KM_SLEEP);
11131
11132         if ((pred = ecb->dted_pred.dtpdd_predicate) != NULL)
11133                 dtrace_predicate_hold(pred);
11134
11135         for (act = ecb->dted_action; act != NULL; act = act->dtad_next)
11136                 dtrace_actdesc_hold(act);
11137
11138         new->dted_action = ecb->dted_action;
11139         new->dted_pred = ecb->dted_pred;
11140         new->dted_probe = *pd;
11141         new->dted_uarg = ecb->dted_uarg;
11142
11143         dtrace_enabling_add(enab, new);
11144 }
11145
11146 static void
11147 dtrace_enabling_dump(dtrace_enabling_t *enab)
11148 {
11149         int i;
11150
11151         for (i = 0; i < enab->dten_ndesc; i++) {
11152                 dtrace_probedesc_t *desc = &enab->dten_desc[i]->dted_probe;
11153
11154                 cmn_err(CE_NOTE, "enabling probe %d (%s:%s:%s:%s)", i,
11155                     desc->dtpd_provider, desc->dtpd_mod,
11156                     desc->dtpd_func, desc->dtpd_name);
11157         }
11158 }
11159
11160 static void
11161 dtrace_enabling_destroy(dtrace_enabling_t *enab)
11162 {
11163         int i;
11164         dtrace_ecbdesc_t *ep;
11165         dtrace_vstate_t *vstate = enab->dten_vstate;
11166
11167         ASSERT(MUTEX_HELD(&dtrace_lock));
11168
11169         for (i = 0; i < enab->dten_ndesc; i++) {
11170                 dtrace_actdesc_t *act, *next;
11171                 dtrace_predicate_t *pred;
11172
11173                 ep = enab->dten_desc[i];
11174
11175                 if ((pred = ep->dted_pred.dtpdd_predicate) != NULL)
11176                         dtrace_predicate_release(pred, vstate);
11177
11178                 for (act = ep->dted_action; act != NULL; act = next) {
11179                         next = act->dtad_next;
11180                         dtrace_actdesc_release(act, vstate);
11181                 }
11182
11183                 kmem_free(ep, sizeof (dtrace_ecbdesc_t));
11184         }
11185
11186         if (enab->dten_desc != NULL)
11187                 kmem_free(enab->dten_desc,
11188                     enab->dten_maxdesc * sizeof (dtrace_enabling_t *));
11189
11190         /*
11191          * If this was a retained enabling, decrement the dts_nretained count
11192          * and take it off of the dtrace_retained list.
11193          */
11194         if (enab->dten_prev != NULL || enab->dten_next != NULL ||
11195             dtrace_retained == enab) {
11196                 ASSERT(enab->dten_vstate->dtvs_state != NULL);
11197                 ASSERT(enab->dten_vstate->dtvs_state->dts_nretained > 0);
11198                 enab->dten_vstate->dtvs_state->dts_nretained--;
11199         }
11200
11201         if (enab->dten_prev == NULL) {
11202                 if (dtrace_retained == enab) {
11203                         dtrace_retained = enab->dten_next;
11204
11205                         if (dtrace_retained != NULL)
11206                                 dtrace_retained->dten_prev = NULL;
11207                 }
11208         } else {
11209                 ASSERT(enab != dtrace_retained);
11210                 ASSERT(dtrace_retained != NULL);
11211                 enab->dten_prev->dten_next = enab->dten_next;
11212         }
11213
11214         if (enab->dten_next != NULL) {
11215                 ASSERT(dtrace_retained != NULL);
11216                 enab->dten_next->dten_prev = enab->dten_prev;
11217         }
11218
11219         kmem_free(enab, sizeof (dtrace_enabling_t));
11220 }
11221
11222 static int
11223 dtrace_enabling_retain(dtrace_enabling_t *enab)
11224 {
11225         dtrace_state_t *state;
11226
11227         ASSERT(MUTEX_HELD(&dtrace_lock));
11228         ASSERT(enab->dten_next == NULL && enab->dten_prev == NULL);
11229         ASSERT(enab->dten_vstate != NULL);
11230
11231         state = enab->dten_vstate->dtvs_state;
11232         ASSERT(state != NULL);
11233
11234         /*
11235          * We only allow each state to retain dtrace_retain_max enablings.
11236          */
11237         if (state->dts_nretained >= dtrace_retain_max)
11238                 return (ENOSPC);
11239
11240         state->dts_nretained++;
11241
11242         if (dtrace_retained == NULL) {
11243                 dtrace_retained = enab;
11244                 return (0);
11245         }
11246
11247         enab->dten_next = dtrace_retained;
11248         dtrace_retained->dten_prev = enab;
11249         dtrace_retained = enab;
11250
11251         return (0);
11252 }
11253
11254 static int
11255 dtrace_enabling_replicate(dtrace_state_t *state, dtrace_probedesc_t *match,
11256     dtrace_probedesc_t *create)
11257 {
11258         dtrace_enabling_t *new, *enab;
11259         int found = 0, err = ENOENT;
11260
11261         ASSERT(MUTEX_HELD(&dtrace_lock));
11262         ASSERT(strlen(match->dtpd_provider) < DTRACE_PROVNAMELEN);
11263         ASSERT(strlen(match->dtpd_mod) < DTRACE_MODNAMELEN);
11264         ASSERT(strlen(match->dtpd_func) < DTRACE_FUNCNAMELEN);
11265         ASSERT(strlen(match->dtpd_name) < DTRACE_NAMELEN);
11266
11267         new = dtrace_enabling_create(&state->dts_vstate);
11268
11269         /*
11270          * Iterate over all retained enablings, looking for enablings that
11271          * match the specified state.
11272          */
11273         for (enab = dtrace_retained; enab != NULL; enab = enab->dten_next) {
11274                 int i;
11275
11276                 /*
11277                  * dtvs_state can only be NULL for helper enablings -- and
11278                  * helper enablings can't be retained.
11279                  */
11280                 ASSERT(enab->dten_vstate->dtvs_state != NULL);
11281
11282                 if (enab->dten_vstate->dtvs_state != state)
11283                         continue;
11284
11285                 /*
11286                  * Now iterate over each probe description; we're looking for
11287                  * an exact match to the specified probe description.
11288                  */
11289                 for (i = 0; i < enab->dten_ndesc; i++) {
11290                         dtrace_ecbdesc_t *ep = enab->dten_desc[i];
11291                         dtrace_probedesc_t *pd = &ep->dted_probe;
11292
11293                         if (strcmp(pd->dtpd_provider, match->dtpd_provider))
11294                                 continue;
11295
11296                         if (strcmp(pd->dtpd_mod, match->dtpd_mod))
11297                                 continue;
11298
11299                         if (strcmp(pd->dtpd_func, match->dtpd_func))
11300                                 continue;
11301
11302                         if (strcmp(pd->dtpd_name, match->dtpd_name))
11303                                 continue;
11304
11305                         /*
11306                          * We have a winning probe!  Add it to our growing
11307                          * enabling.
11308                          */
11309                         found = 1;
11310                         dtrace_enabling_addlike(new, ep, create);
11311                 }
11312         }
11313
11314         if (!found || (err = dtrace_enabling_retain(new)) != 0) {
11315                 dtrace_enabling_destroy(new);
11316                 return (err);
11317         }
11318
11319         return (0);
11320 }
11321
11322 static void
11323 dtrace_enabling_retract(dtrace_state_t *state)
11324 {
11325         dtrace_enabling_t *enab, *next;
11326
11327         ASSERT(MUTEX_HELD(&dtrace_lock));
11328
11329         /*
11330          * Iterate over all retained enablings, destroy the enablings retained
11331          * for the specified state.
11332          */
11333         for (enab = dtrace_retained; enab != NULL; enab = next) {
11334                 next = enab->dten_next;
11335
11336                 /*
11337                  * dtvs_state can only be NULL for helper enablings -- and
11338                  * helper enablings can't be retained.
11339                  */
11340                 ASSERT(enab->dten_vstate->dtvs_state != NULL);
11341
11342                 if (enab->dten_vstate->dtvs_state == state) {
11343                         ASSERT(state->dts_nretained > 0);
11344                         dtrace_enabling_destroy(enab);
11345                 }
11346         }
11347
11348         ASSERT(state->dts_nretained == 0);
11349 }
11350
11351 static int
11352 dtrace_enabling_match(dtrace_enabling_t *enab, int *nmatched)
11353 {
11354         int i = 0;
11355         int matched = 0;
11356
11357         ASSERT(MUTEX_HELD(&cpu_lock));
11358         ASSERT(MUTEX_HELD(&dtrace_lock));
11359
11360         for (i = 0; i < enab->dten_ndesc; i++) {
11361                 dtrace_ecbdesc_t *ep = enab->dten_desc[i];
11362
11363                 enab->dten_current = ep;
11364                 enab->dten_error = 0;
11365
11366                 matched += dtrace_probe_enable(&ep->dted_probe, enab);
11367
11368                 if (enab->dten_error != 0) {
11369                         /*
11370                          * If we get an error half-way through enabling the
11371                          * probes, we kick out -- perhaps with some number of
11372                          * them enabled.  Leaving enabled probes enabled may
11373                          * be slightly confusing for user-level, but we expect
11374                          * that no one will attempt to actually drive on in
11375                          * the face of such errors.  If this is an anonymous
11376                          * enabling (indicated with a NULL nmatched pointer),
11377                          * we cmn_err() a message.  We aren't expecting to
11378                          * get such an error -- such as it can exist at all,
11379                          * it would be a result of corrupted DOF in the driver
11380                          * properties.
11381                          */
11382                         if (nmatched == NULL) {
11383                                 cmn_err(CE_WARN, "dtrace_enabling_match() "
11384                                     "error on %p: %d", (void *)ep,
11385                                     enab->dten_error);
11386                         }
11387
11388                         return (enab->dten_error);
11389                 }
11390         }
11391
11392         enab->dten_probegen = dtrace_probegen;
11393         if (nmatched != NULL)
11394                 *nmatched = matched;
11395
11396         return (0);
11397 }
11398
11399 static void
11400 dtrace_enabling_matchall(void)
11401 {
11402         dtrace_enabling_t *enab;
11403
11404         mutex_enter(&cpu_lock);
11405         mutex_enter(&dtrace_lock);
11406
11407         /*
11408          * Iterate over all retained enablings to see if any probes match
11409          * against them.  We only perform this operation on enablings for which
11410          * we have sufficient permissions by virtue of being in the global zone
11411          * or in the same zone as the DTrace client.  Because we can be called
11412          * after dtrace_detach() has been called, we cannot assert that there
11413          * are retained enablings.  We can safely load from dtrace_retained,
11414          * however:  the taskq_destroy() at the end of dtrace_detach() will
11415          * block pending our completion.
11416          */
11417         for (enab = dtrace_retained; enab != NULL; enab = enab->dten_next) {
11418 #if defined(sun)
11419                 cred_t *cr = enab->dten_vstate->dtvs_state->dts_cred.dcr_cred;
11420
11421                 if (INGLOBALZONE(curproc) || getzoneid() == crgetzoneid(cr))
11422 #endif
11423                         (void) dtrace_enabling_match(enab, NULL);
11424         }
11425
11426         mutex_exit(&dtrace_lock);
11427         mutex_exit(&cpu_lock);
11428 }
11429
11430 /*
11431  * If an enabling is to be enabled without having matched probes (that is, if
11432  * dtrace_state_go() is to be called on the underlying dtrace_state_t), the
11433  * enabling must be _primed_ by creating an ECB for every ECB description.
11434  * This must be done to assure that we know the number of speculations, the
11435  * number of aggregations, the minimum buffer size needed, etc. before we
11436  * transition out of DTRACE_ACTIVITY_INACTIVE.  To do this without actually
11437  * enabling any probes, we create ECBs for every ECB decription, but with a
11438  * NULL probe -- which is exactly what this function does.
11439  */
11440 static void
11441 dtrace_enabling_prime(dtrace_state_t *state)
11442 {
11443         dtrace_enabling_t *enab;
11444         int i;
11445
11446         for (enab = dtrace_retained; enab != NULL; enab = enab->dten_next) {
11447                 ASSERT(enab->dten_vstate->dtvs_state != NULL);
11448
11449                 if (enab->dten_vstate->dtvs_state != state)
11450                         continue;
11451
11452                 /*
11453                  * We don't want to prime an enabling more than once, lest
11454                  * we allow a malicious user to induce resource exhaustion.
11455                  * (The ECBs that result from priming an enabling aren't
11456                  * leaked -- but they also aren't deallocated until the
11457                  * consumer state is destroyed.)
11458                  */
11459                 if (enab->dten_primed)
11460                         continue;
11461
11462                 for (i = 0; i < enab->dten_ndesc; i++) {
11463                         enab->dten_current = enab->dten_desc[i];
11464                         (void) dtrace_probe_enable(NULL, enab);
11465                 }
11466
11467                 enab->dten_primed = 1;
11468         }
11469 }
11470
11471 /*
11472  * Called to indicate that probes should be provided due to retained
11473  * enablings.  This is implemented in terms of dtrace_probe_provide(), but it
11474  * must take an initial lap through the enabling calling the dtps_provide()
11475  * entry point explicitly to allow for autocreated probes.
11476  */
11477 static void
11478 dtrace_enabling_provide(dtrace_provider_t *prv)
11479 {
11480         int i, all = 0;
11481         dtrace_probedesc_t desc;
11482
11483         ASSERT(MUTEX_HELD(&dtrace_lock));
11484         ASSERT(MUTEX_HELD(&dtrace_provider_lock));
11485
11486         if (prv == NULL) {
11487                 all = 1;
11488                 prv = dtrace_provider;
11489         }
11490
11491         do {
11492                 dtrace_enabling_t *enab = dtrace_retained;
11493                 void *parg = prv->dtpv_arg;
11494
11495                 for (; enab != NULL; enab = enab->dten_next) {
11496                         for (i = 0; i < enab->dten_ndesc; i++) {
11497                                 desc = enab->dten_desc[i]->dted_probe;
11498                                 mutex_exit(&dtrace_lock);
11499                                 prv->dtpv_pops.dtps_provide(parg, &desc);
11500                                 mutex_enter(&dtrace_lock);
11501                         }
11502                 }
11503         } while (all && (prv = prv->dtpv_next) != NULL);
11504
11505         mutex_exit(&dtrace_lock);
11506         dtrace_probe_provide(NULL, all ? NULL : prv);
11507         mutex_enter(&dtrace_lock);
11508 }
11509
11510 /*
11511  * DTrace DOF Functions
11512  */
11513 /*ARGSUSED*/
11514 static void
11515 dtrace_dof_error(dof_hdr_t *dof, const char *str)
11516 {
11517         if (dtrace_err_verbose)
11518                 cmn_err(CE_WARN, "failed to process DOF: %s", str);
11519
11520 #ifdef DTRACE_ERRDEBUG
11521         dtrace_errdebug(str);
11522 #endif
11523 }
11524
11525 /*
11526  * Create DOF out of a currently enabled state.  Right now, we only create
11527  * DOF containing the run-time options -- but this could be expanded to create
11528  * complete DOF representing the enabled state.
11529  */
11530 static dof_hdr_t *
11531 dtrace_dof_create(dtrace_state_t *state)
11532 {
11533         dof_hdr_t *dof;
11534         dof_sec_t *sec;
11535         dof_optdesc_t *opt;
11536         int i, len = sizeof (dof_hdr_t) +
11537             roundup(sizeof (dof_sec_t), sizeof (uint64_t)) +
11538             sizeof (dof_optdesc_t) * DTRACEOPT_MAX;
11539
11540         ASSERT(MUTEX_HELD(&dtrace_lock));
11541
11542         dof = kmem_zalloc(len, KM_SLEEP);
11543         dof->dofh_ident[DOF_ID_MAG0] = DOF_MAG_MAG0;
11544         dof->dofh_ident[DOF_ID_MAG1] = DOF_MAG_MAG1;
11545         dof->dofh_ident[DOF_ID_MAG2] = DOF_MAG_MAG2;
11546         dof->dofh_ident[DOF_ID_MAG3] = DOF_MAG_MAG3;
11547
11548         dof->dofh_ident[DOF_ID_MODEL] = DOF_MODEL_NATIVE;
11549         dof->dofh_ident[DOF_ID_ENCODING] = DOF_ENCODE_NATIVE;
11550         dof->dofh_ident[DOF_ID_VERSION] = DOF_VERSION;
11551         dof->dofh_ident[DOF_ID_DIFVERS] = DIF_VERSION;
11552         dof->dofh_ident[DOF_ID_DIFIREG] = DIF_DIR_NREGS;
11553         dof->dofh_ident[DOF_ID_DIFTREG] = DIF_DTR_NREGS;
11554
11555         dof->dofh_flags = 0;
11556         dof->dofh_hdrsize = sizeof (dof_hdr_t);
11557         dof->dofh_secsize = sizeof (dof_sec_t);
11558         dof->dofh_secnum = 1;   /* only DOF_SECT_OPTDESC */
11559         dof->dofh_secoff = sizeof (dof_hdr_t);
11560         dof->dofh_loadsz = len;
11561         dof->dofh_filesz = len;
11562         dof->dofh_pad = 0;
11563
11564         /*
11565          * Fill in the option section header...
11566          */
11567         sec = (dof_sec_t *)((uintptr_t)dof + sizeof (dof_hdr_t));
11568         sec->dofs_type = DOF_SECT_OPTDESC;
11569         sec->dofs_align = sizeof (uint64_t);
11570         sec->dofs_flags = DOF_SECF_LOAD;
11571         sec->dofs_entsize = sizeof (dof_optdesc_t);
11572
11573         opt = (dof_optdesc_t *)((uintptr_t)sec +
11574             roundup(sizeof (dof_sec_t), sizeof (uint64_t)));
11575
11576         sec->dofs_offset = (uintptr_t)opt - (uintptr_t)dof;
11577         sec->dofs_size = sizeof (dof_optdesc_t) * DTRACEOPT_MAX;
11578
11579         for (i = 0; i < DTRACEOPT_MAX; i++) {
11580                 opt[i].dofo_option = i;
11581                 opt[i].dofo_strtab = DOF_SECIDX_NONE;
11582                 opt[i].dofo_value = state->dts_options[i];
11583         }
11584
11585         return (dof);
11586 }
11587
11588 static dof_hdr_t *
11589 dtrace_dof_copyin(uintptr_t uarg, int *errp)
11590 {
11591         dof_hdr_t hdr, *dof;
11592
11593         ASSERT(!MUTEX_HELD(&dtrace_lock));
11594
11595         /*
11596          * First, we're going to copyin() the sizeof (dof_hdr_t).
11597          */
11598         if (copyin((void *)uarg, &hdr, sizeof (hdr)) != 0) {
11599                 dtrace_dof_error(NULL, "failed to copyin DOF header");
11600                 *errp = EFAULT;
11601                 return (NULL);
11602         }
11603
11604         /*
11605          * Now we'll allocate the entire DOF and copy it in -- provided
11606          * that the length isn't outrageous.
11607          */
11608         if (hdr.dofh_loadsz >= dtrace_dof_maxsize) {
11609                 dtrace_dof_error(&hdr, "load size exceeds maximum");
11610                 *errp = E2BIG;
11611                 return (NULL);
11612         }
11613
11614         if (hdr.dofh_loadsz < sizeof (hdr)) {
11615                 dtrace_dof_error(&hdr, "invalid load size");
11616                 *errp = EINVAL;
11617                 return (NULL);
11618         }
11619
11620         dof = kmem_alloc(hdr.dofh_loadsz, KM_SLEEP);
11621
11622         if (copyin((void *)uarg, dof, hdr.dofh_loadsz) != 0) {
11623                 kmem_free(dof, hdr.dofh_loadsz);
11624                 *errp = EFAULT;
11625                 return (NULL);
11626         }
11627
11628         return (dof);
11629 }
11630
11631 #if !defined(sun)
11632 static __inline uchar_t
11633 dtrace_dof_char(char c) {
11634         switch (c) {
11635         case '0':
11636         case '1':
11637         case '2':
11638         case '3':
11639         case '4':
11640         case '5':
11641         case '6':
11642         case '7':
11643         case '8':
11644         case '9':
11645                 return (c - '0');
11646         case 'A':
11647         case 'B':
11648         case 'C':
11649         case 'D':
11650         case 'E':
11651         case 'F':
11652                 return (c - 'A' + 10);
11653         case 'a':
11654         case 'b':
11655         case 'c':
11656         case 'd':
11657         case 'e':
11658         case 'f':
11659                 return (c - 'a' + 10);
11660         }
11661         /* Should not reach here. */
11662         return (0);
11663 }
11664 #endif
11665
11666 static dof_hdr_t *
11667 dtrace_dof_property(const char *name)
11668 {
11669         uchar_t *buf;
11670         uint64_t loadsz;
11671         unsigned int len, i;
11672         dof_hdr_t *dof;
11673
11674 #if defined(sun)
11675         /*
11676          * Unfortunately, array of values in .conf files are always (and
11677          * only) interpreted to be integer arrays.  We must read our DOF
11678          * as an integer array, and then squeeze it into a byte array.
11679          */
11680         if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dtrace_devi, 0,
11681             (char *)name, (int **)&buf, &len) != DDI_PROP_SUCCESS)
11682                 return (NULL);
11683
11684         for (i = 0; i < len; i++)
11685                 buf[i] = (uchar_t)(((int *)buf)[i]);
11686
11687         if (len < sizeof (dof_hdr_t)) {
11688                 ddi_prop_free(buf);
11689                 dtrace_dof_error(NULL, "truncated header");
11690                 return (NULL);
11691         }
11692
11693         if (len < (loadsz = ((dof_hdr_t *)buf)->dofh_loadsz)) {
11694                 ddi_prop_free(buf);
11695                 dtrace_dof_error(NULL, "truncated DOF");
11696                 return (NULL);
11697         }
11698
11699         if (loadsz >= dtrace_dof_maxsize) {
11700                 ddi_prop_free(buf);
11701                 dtrace_dof_error(NULL, "oversized DOF");
11702                 return (NULL);
11703         }
11704
11705         dof = kmem_alloc(loadsz, KM_SLEEP);
11706         bcopy(buf, dof, loadsz);
11707         ddi_prop_free(buf);
11708 #else
11709         char *p;
11710         char *p_env;
11711
11712         if ((p_env = getenv(name)) == NULL)
11713                 return (NULL);
11714
11715         len = strlen(p_env) / 2;
11716
11717         buf = kmem_alloc(len, KM_SLEEP);
11718
11719         dof = (dof_hdr_t *) buf;
11720
11721         p = p_env;
11722
11723         for (i = 0; i < len; i++) {
11724                 buf[i] = (dtrace_dof_char(p[0]) << 4) |
11725                      dtrace_dof_char(p[1]);
11726                 p += 2;
11727         }
11728
11729         freeenv(p_env);
11730
11731         if (len < sizeof (dof_hdr_t)) {
11732                 kmem_free(buf, 0);
11733                 dtrace_dof_error(NULL, "truncated header");
11734                 return (NULL);
11735         }
11736
11737         if (len < (loadsz = dof->dofh_loadsz)) {
11738                 kmem_free(buf, 0);
11739                 dtrace_dof_error(NULL, "truncated DOF");
11740                 return (NULL);
11741         }
11742
11743         if (loadsz >= dtrace_dof_maxsize) {
11744                 kmem_free(buf, 0);
11745                 dtrace_dof_error(NULL, "oversized DOF");
11746                 return (NULL);
11747         }
11748 #endif
11749
11750         return (dof);
11751 }
11752
11753 static void
11754 dtrace_dof_destroy(dof_hdr_t *dof)
11755 {
11756         kmem_free(dof, dof->dofh_loadsz);
11757 }
11758
11759 /*
11760  * Return the dof_sec_t pointer corresponding to a given section index.  If the
11761  * index is not valid, dtrace_dof_error() is called and NULL is returned.  If
11762  * a type other than DOF_SECT_NONE is specified, the header is checked against
11763  * this type and NULL is returned if the types do not match.
11764  */
11765 static dof_sec_t *
11766 dtrace_dof_sect(dof_hdr_t *dof, uint32_t type, dof_secidx_t i)
11767 {
11768         dof_sec_t *sec = (dof_sec_t *)(uintptr_t)
11769             ((uintptr_t)dof + dof->dofh_secoff + i * dof->dofh_secsize);
11770
11771         if (i >= dof->dofh_secnum) {
11772                 dtrace_dof_error(dof, "referenced section index is invalid");
11773                 return (NULL);
11774         }
11775
11776         if (!(sec->dofs_flags & DOF_SECF_LOAD)) {
11777                 dtrace_dof_error(dof, "referenced section is not loadable");
11778                 return (NULL);
11779         }
11780
11781         if (type != DOF_SECT_NONE && type != sec->dofs_type) {
11782                 dtrace_dof_error(dof, "referenced section is the wrong type");
11783                 return (NULL);
11784         }
11785
11786         return (sec);
11787 }
11788
11789 static dtrace_probedesc_t *
11790 dtrace_dof_probedesc(dof_hdr_t *dof, dof_sec_t *sec, dtrace_probedesc_t *desc)
11791 {
11792         dof_probedesc_t *probe;
11793         dof_sec_t *strtab;
11794         uintptr_t daddr = (uintptr_t)dof;
11795         uintptr_t str;
11796         size_t size;
11797
11798         if (sec->dofs_type != DOF_SECT_PROBEDESC) {
11799                 dtrace_dof_error(dof, "invalid probe section");
11800                 return (NULL);
11801         }
11802
11803         if (sec->dofs_align != sizeof (dof_secidx_t)) {
11804                 dtrace_dof_error(dof, "bad alignment in probe description");
11805                 return (NULL);
11806         }
11807
11808         if (sec->dofs_offset + sizeof (dof_probedesc_t) > dof->dofh_loadsz) {
11809                 dtrace_dof_error(dof, "truncated probe description");
11810                 return (NULL);
11811         }
11812
11813         probe = (dof_probedesc_t *)(uintptr_t)(daddr + sec->dofs_offset);
11814         strtab = dtrace_dof_sect(dof, DOF_SECT_STRTAB, probe->dofp_strtab);
11815
11816         if (strtab == NULL)
11817                 return (NULL);
11818
11819         str = daddr + strtab->dofs_offset;
11820         size = strtab->dofs_size;
11821
11822         if (probe->dofp_provider >= strtab->dofs_size) {
11823                 dtrace_dof_error(dof, "corrupt probe provider");
11824                 return (NULL);
11825         }
11826
11827         (void) strncpy(desc->dtpd_provider,
11828             (char *)(str + probe->dofp_provider),
11829             MIN(DTRACE_PROVNAMELEN - 1, size - probe->dofp_provider));
11830
11831         if (probe->dofp_mod >= strtab->dofs_size) {
11832                 dtrace_dof_error(dof, "corrupt probe module");
11833                 return (NULL);
11834         }
11835
11836         (void) strncpy(desc->dtpd_mod, (char *)(str + probe->dofp_mod),
11837             MIN(DTRACE_MODNAMELEN - 1, size - probe->dofp_mod));
11838
11839         if (probe->dofp_func >= strtab->dofs_size) {
11840                 dtrace_dof_error(dof, "corrupt probe function");
11841                 return (NULL);
11842         }
11843
11844         (void) strncpy(desc->dtpd_func, (char *)(str + probe->dofp_func),
11845             MIN(DTRACE_FUNCNAMELEN - 1, size - probe->dofp_func));
11846
11847         if (probe->dofp_name >= strtab->dofs_size) {
11848                 dtrace_dof_error(dof, "corrupt probe name");
11849                 return (NULL);
11850         }
11851
11852         (void) strncpy(desc->dtpd_name, (char *)(str + probe->dofp_name),
11853             MIN(DTRACE_NAMELEN - 1, size - probe->dofp_name));
11854
11855         return (desc);
11856 }
11857
11858 static dtrace_difo_t *
11859 dtrace_dof_difo(dof_hdr_t *dof, dof_sec_t *sec, dtrace_vstate_t *vstate,
11860     cred_t *cr)
11861 {
11862         dtrace_difo_t *dp;
11863         size_t ttl = 0;
11864         dof_difohdr_t *dofd;
11865         uintptr_t daddr = (uintptr_t)dof;
11866         size_t max = dtrace_difo_maxsize;
11867         int i, l, n;
11868
11869         static const struct {
11870                 int section;
11871                 int bufoffs;
11872                 int lenoffs;
11873                 int entsize;
11874                 int align;
11875                 const char *msg;
11876         } difo[] = {
11877                 { DOF_SECT_DIF, offsetof(dtrace_difo_t, dtdo_buf),
11878                 offsetof(dtrace_difo_t, dtdo_len), sizeof (dif_instr_t),
11879                 sizeof (dif_instr_t), "multiple DIF sections" },
11880
11881                 { DOF_SECT_INTTAB, offsetof(dtrace_difo_t, dtdo_inttab),
11882                 offsetof(dtrace_difo_t, dtdo_intlen), sizeof (uint64_t),
11883                 sizeof (uint64_t), "multiple integer tables" },
11884
11885                 { DOF_SECT_STRTAB, offsetof(dtrace_difo_t, dtdo_strtab),
11886                 offsetof(dtrace_difo_t, dtdo_strlen), 0,
11887                 sizeof (char), "multiple string tables" },
11888
11889                 { DOF_SECT_VARTAB, offsetof(dtrace_difo_t, dtdo_vartab),
11890                 offsetof(dtrace_difo_t, dtdo_varlen), sizeof (dtrace_difv_t),
11891                 sizeof (uint_t), "multiple variable tables" },
11892
11893                 { DOF_SECT_NONE, 0, 0, 0, 0, NULL }
11894         };
11895
11896         if (sec->dofs_type != DOF_SECT_DIFOHDR) {
11897                 dtrace_dof_error(dof, "invalid DIFO header section");
11898                 return (NULL);
11899         }
11900
11901         if (sec->dofs_align != sizeof (dof_secidx_t)) {
11902                 dtrace_dof_error(dof, "bad alignment in DIFO header");
11903                 return (NULL);
11904         }
11905
11906         if (sec->dofs_size < sizeof (dof_difohdr_t) ||
11907             sec->dofs_size % sizeof (dof_secidx_t)) {
11908                 dtrace_dof_error(dof, "bad size in DIFO header");
11909                 return (NULL);
11910         }
11911
11912         dofd = (dof_difohdr_t *)(uintptr_t)(daddr + sec->dofs_offset);
11913         n = (sec->dofs_size - sizeof (*dofd)) / sizeof (dof_secidx_t) + 1;
11914
11915         dp = kmem_zalloc(sizeof (dtrace_difo_t), KM_SLEEP);
11916         dp->dtdo_rtype = dofd->dofd_rtype;
11917
11918         for (l = 0; l < n; l++) {
11919                 dof_sec_t *subsec;
11920                 void **bufp;
11921                 uint32_t *lenp;
11922
11923                 if ((subsec = dtrace_dof_sect(dof, DOF_SECT_NONE,
11924                     dofd->dofd_links[l])) == NULL)
11925                         goto err; /* invalid section link */
11926
11927                 if (ttl + subsec->dofs_size > max) {
11928                         dtrace_dof_error(dof, "exceeds maximum size");
11929                         goto err;
11930                 }
11931
11932                 ttl += subsec->dofs_size;
11933
11934                 for (i = 0; difo[i].section != DOF_SECT_NONE; i++) {
11935                         if (subsec->dofs_type != difo[i].section)
11936                                 continue;
11937
11938                         if (!(subsec->dofs_flags & DOF_SECF_LOAD)) {
11939                                 dtrace_dof_error(dof, "section not loaded");
11940                                 goto err;
11941                         }
11942
11943                         if (subsec->dofs_align != difo[i].align) {
11944                                 dtrace_dof_error(dof, "bad alignment");
11945                                 goto err;
11946                         }
11947
11948                         bufp = (void **)((uintptr_t)dp + difo[i].bufoffs);
11949                         lenp = (uint32_t *)((uintptr_t)dp + difo[i].lenoffs);
11950
11951                         if (*bufp != NULL) {
11952                                 dtrace_dof_error(dof, difo[i].msg);
11953                                 goto err;
11954                         }
11955
11956                         if (difo[i].entsize != subsec->dofs_entsize) {
11957                                 dtrace_dof_error(dof, "entry size mismatch");
11958                                 goto err;
11959                         }
11960
11961                         if (subsec->dofs_entsize != 0 &&
11962                             (subsec->dofs_size % subsec->dofs_entsize) != 0) {
11963                                 dtrace_dof_error(dof, "corrupt entry size");
11964                                 goto err;
11965                         }
11966
11967                         *lenp = subsec->dofs_size;
11968                         *bufp = kmem_alloc(subsec->dofs_size, KM_SLEEP);
11969                         bcopy((char *)(uintptr_t)(daddr + subsec->dofs_offset),
11970                             *bufp, subsec->dofs_size);
11971
11972                         if (subsec->dofs_entsize != 0)
11973                                 *lenp /= subsec->dofs_entsize;
11974
11975                         break;
11976                 }
11977
11978                 /*
11979                  * If we encounter a loadable DIFO sub-section that is not
11980                  * known to us, assume this is a broken program and fail.
11981                  */
11982                 if (difo[i].section == DOF_SECT_NONE &&
11983                     (subsec->dofs_flags & DOF_SECF_LOAD)) {
11984                         dtrace_dof_error(dof, "unrecognized DIFO subsection");
11985                         goto err;
11986                 }
11987         }
11988
11989         if (dp->dtdo_buf == NULL) {
11990                 /*
11991                  * We can't have a DIF object without DIF text.
11992                  */
11993                 dtrace_dof_error(dof, "missing DIF text");
11994                 goto err;
11995         }
11996
11997         /*
11998          * Before we validate the DIF object, run through the variable table
11999          * looking for the strings -- if any of their size are under, we'll set
12000          * their size to be the system-wide default string size.  Note that
12001          * this should _not_ happen if the "strsize" option has been set --
12002          * in this case, the compiler should have set the size to reflect the
12003          * setting of the option.
12004          */
12005         for (i = 0; i < dp->dtdo_varlen; i++) {
12006                 dtrace_difv_t *v = &dp->dtdo_vartab[i];
12007                 dtrace_diftype_t *t = &v->dtdv_type;
12008
12009                 if (v->dtdv_id < DIF_VAR_OTHER_UBASE)
12010                         continue;
12011
12012                 if (t->dtdt_kind == DIF_TYPE_STRING && t->dtdt_size == 0)
12013                         t->dtdt_size = dtrace_strsize_default;
12014         }
12015
12016         if (dtrace_difo_validate(dp, vstate, DIF_DIR_NREGS, cr) != 0)
12017                 goto err;
12018
12019         dtrace_difo_init(dp, vstate);
12020         return (dp);
12021
12022 err:
12023         kmem_free(dp->dtdo_buf, dp->dtdo_len * sizeof (dif_instr_t));
12024         kmem_free(dp->dtdo_inttab, dp->dtdo_intlen * sizeof (uint64_t));
12025         kmem_free(dp->dtdo_strtab, dp->dtdo_strlen);
12026         kmem_free(dp->dtdo_vartab, dp->dtdo_varlen * sizeof (dtrace_difv_t));
12027
12028         kmem_free(dp, sizeof (dtrace_difo_t));
12029         return (NULL);
12030 }
12031
12032 static dtrace_predicate_t *
12033 dtrace_dof_predicate(dof_hdr_t *dof, dof_sec_t *sec, dtrace_vstate_t *vstate,
12034     cred_t *cr)
12035 {
12036         dtrace_difo_t *dp;
12037
12038         if ((dp = dtrace_dof_difo(dof, sec, vstate, cr)) == NULL)
12039                 return (NULL);
12040
12041         return (dtrace_predicate_create(dp));
12042 }
12043
12044 static dtrace_actdesc_t *
12045 dtrace_dof_actdesc(dof_hdr_t *dof, dof_sec_t *sec, dtrace_vstate_t *vstate,
12046     cred_t *cr)
12047 {
12048         dtrace_actdesc_t *act, *first = NULL, *last = NULL, *next;
12049         dof_actdesc_t *desc;
12050         dof_sec_t *difosec;
12051         size_t offs;
12052         uintptr_t daddr = (uintptr_t)dof;
12053         uint64_t arg;
12054         dtrace_actkind_t kind;
12055
12056         if (sec->dofs_type != DOF_SECT_ACTDESC) {
12057                 dtrace_dof_error(dof, "invalid action section");
12058                 return (NULL);
12059         }
12060
12061         if (sec->dofs_offset + sizeof (dof_actdesc_t) > dof->dofh_loadsz) {
12062                 dtrace_dof_error(dof, "truncated action description");
12063                 return (NULL);
12064         }
12065
12066         if (sec->dofs_align != sizeof (uint64_t)) {
12067                 dtrace_dof_error(dof, "bad alignment in action description");
12068                 return (NULL);
12069         }
12070
12071         if (sec->dofs_size < sec->dofs_entsize) {
12072                 dtrace_dof_error(dof, "section entry size exceeds total size");
12073                 return (NULL);
12074         }
12075
12076         if (sec->dofs_entsize != sizeof (dof_actdesc_t)) {
12077                 dtrace_dof_error(dof, "bad entry size in action description");
12078                 return (NULL);
12079         }
12080
12081         if (sec->dofs_size / sec->dofs_entsize > dtrace_actions_max) {
12082                 dtrace_dof_error(dof, "actions exceed dtrace_actions_max");
12083                 return (NULL);
12084         }
12085
12086         for (offs = 0; offs < sec->dofs_size; offs += sec->dofs_entsize) {
12087                 desc = (dof_actdesc_t *)(daddr +
12088                     (uintptr_t)sec->dofs_offset + offs);
12089                 kind = (dtrace_actkind_t)desc->dofa_kind;
12090
12091                 if (DTRACEACT_ISPRINTFLIKE(kind) &&
12092                     (kind != DTRACEACT_PRINTA ||
12093                     desc->dofa_strtab != DOF_SECIDX_NONE)) {
12094                         dof_sec_t *strtab;
12095                         char *str, *fmt;
12096                         uint64_t i;
12097
12098                         /*
12099                          * printf()-like actions must have a format string.
12100                          */
12101                         if ((strtab = dtrace_dof_sect(dof,
12102                             DOF_SECT_STRTAB, desc->dofa_strtab)) == NULL)
12103                                 goto err;
12104
12105                         str = (char *)((uintptr_t)dof +
12106                             (uintptr_t)strtab->dofs_offset);
12107
12108                         for (i = desc->dofa_arg; i < strtab->dofs_size; i++) {
12109                                 if (str[i] == '\0')
12110                                         break;
12111                         }
12112
12113                         if (i >= strtab->dofs_size) {
12114                                 dtrace_dof_error(dof, "bogus format string");
12115                                 goto err;
12116                         }
12117
12118                         if (i == desc->dofa_arg) {
12119                                 dtrace_dof_error(dof, "empty format string");
12120                                 goto err;
12121                         }
12122
12123                         i -= desc->dofa_arg;
12124                         fmt = kmem_alloc(i + 1, KM_SLEEP);
12125                         bcopy(&str[desc->dofa_arg], fmt, i + 1);
12126                         arg = (uint64_t)(uintptr_t)fmt;
12127                 } else {
12128                         if (kind == DTRACEACT_PRINTA) {
12129                                 ASSERT(desc->dofa_strtab == DOF_SECIDX_NONE);
12130                                 arg = 0;
12131                         } else {
12132                                 arg = desc->dofa_arg;
12133                         }
12134                 }
12135
12136                 act = dtrace_actdesc_create(kind, desc->dofa_ntuple,
12137                     desc->dofa_uarg, arg);
12138
12139                 if (last != NULL) {
12140                         last->dtad_next = act;
12141                 } else {
12142                         first = act;
12143                 }
12144
12145                 last = act;
12146
12147                 if (desc->dofa_difo == DOF_SECIDX_NONE)
12148                         continue;
12149
12150                 if ((difosec = dtrace_dof_sect(dof,
12151                     DOF_SECT_DIFOHDR, desc->dofa_difo)) == NULL)
12152                         goto err;
12153
12154                 act->dtad_difo = dtrace_dof_difo(dof, difosec, vstate, cr);
12155
12156                 if (act->dtad_difo == NULL)
12157                         goto err;
12158         }
12159
12160         ASSERT(first != NULL);
12161         return (first);
12162
12163 err:
12164         for (act = first; act != NULL; act = next) {
12165                 next = act->dtad_next;
12166                 dtrace_actdesc_release(act, vstate);
12167         }
12168
12169         return (NULL);
12170 }
12171
12172 static dtrace_ecbdesc_t *
12173 dtrace_dof_ecbdesc(dof_hdr_t *dof, dof_sec_t *sec, dtrace_vstate_t *vstate,
12174     cred_t *cr)
12175 {
12176         dtrace_ecbdesc_t *ep;
12177         dof_ecbdesc_t *ecb;
12178         dtrace_probedesc_t *desc;
12179         dtrace_predicate_t *pred = NULL;
12180
12181         if (sec->dofs_size < sizeof (dof_ecbdesc_t)) {
12182                 dtrace_dof_error(dof, "truncated ECB description");
12183                 return (NULL);
12184         }
12185
12186         if (sec->dofs_align != sizeof (uint64_t)) {
12187                 dtrace_dof_error(dof, "bad alignment in ECB description");
12188                 return (NULL);
12189         }
12190
12191         ecb = (dof_ecbdesc_t *)((uintptr_t)dof + (uintptr_t)sec->dofs_offset);
12192         sec = dtrace_dof_sect(dof, DOF_SECT_PROBEDESC, ecb->dofe_probes);
12193
12194         if (sec == NULL)
12195                 return (NULL);
12196
12197         ep = kmem_zalloc(sizeof (dtrace_ecbdesc_t), KM_SLEEP);
12198         ep->dted_uarg = ecb->dofe_uarg;
12199         desc = &ep->dted_probe;
12200
12201         if (dtrace_dof_probedesc(dof, sec, desc) == NULL)
12202                 goto err;
12203
12204         if (ecb->dofe_pred != DOF_SECIDX_NONE) {
12205                 if ((sec = dtrace_dof_sect(dof,
12206                     DOF_SECT_DIFOHDR, ecb->dofe_pred)) == NULL)
12207                         goto err;
12208
12209                 if ((pred = dtrace_dof_predicate(dof, sec, vstate, cr)) == NULL)
12210                         goto err;
12211
12212                 ep->dted_pred.dtpdd_predicate = pred;
12213         }
12214
12215         if (ecb->dofe_actions != DOF_SECIDX_NONE) {
12216                 if ((sec = dtrace_dof_sect(dof,
12217                     DOF_SECT_ACTDESC, ecb->dofe_actions)) == NULL)
12218                         goto err;
12219
12220                 ep->dted_action = dtrace_dof_actdesc(dof, sec, vstate, cr);
12221
12222                 if (ep->dted_action == NULL)
12223                         goto err;
12224         }
12225
12226         return (ep);
12227
12228 err:
12229         if (pred != NULL)
12230                 dtrace_predicate_release(pred, vstate);
12231         kmem_free(ep, sizeof (dtrace_ecbdesc_t));
12232         return (NULL);
12233 }
12234
12235 /*
12236  * Apply the relocations from the specified 'sec' (a DOF_SECT_URELHDR) to the
12237  * specified DOF.  At present, this amounts to simply adding 'ubase' to the
12238  * site of any user SETX relocations to account for load object base address.
12239  * In the future, if we need other relocations, this function can be extended.
12240  */
12241 static int
12242 dtrace_dof_relocate(dof_hdr_t *dof, dof_sec_t *sec, uint64_t ubase)
12243 {
12244         uintptr_t daddr = (uintptr_t)dof;
12245         dof_relohdr_t *dofr =
12246             (dof_relohdr_t *)(uintptr_t)(daddr + sec->dofs_offset);
12247         dof_sec_t *ss, *rs, *ts;
12248         dof_relodesc_t *r;
12249         uint_t i, n;
12250
12251         if (sec->dofs_size < sizeof (dof_relohdr_t) ||
12252             sec->dofs_align != sizeof (dof_secidx_t)) {
12253                 dtrace_dof_error(dof, "invalid relocation header");
12254                 return (-1);
12255         }
12256
12257         ss = dtrace_dof_sect(dof, DOF_SECT_STRTAB, dofr->dofr_strtab);
12258         rs = dtrace_dof_sect(dof, DOF_SECT_RELTAB, dofr->dofr_relsec);
12259         ts = dtrace_dof_sect(dof, DOF_SECT_NONE, dofr->dofr_tgtsec);
12260
12261         if (ss == NULL || rs == NULL || ts == NULL)
12262                 return (-1); /* dtrace_dof_error() has been called already */
12263
12264         if (rs->dofs_entsize < sizeof (dof_relodesc_t) ||
12265             rs->dofs_align != sizeof (uint64_t)) {
12266                 dtrace_dof_error(dof, "invalid relocation section");
12267                 return (-1);
12268         }
12269
12270         r = (dof_relodesc_t *)(uintptr_t)(daddr + rs->dofs_offset);
12271         n = rs->dofs_size / rs->dofs_entsize;
12272
12273         for (i = 0; i < n; i++) {
12274                 uintptr_t taddr = daddr + ts->dofs_offset + r->dofr_offset;
12275
12276                 switch (r->dofr_type) {
12277                 case DOF_RELO_NONE:
12278                         break;
12279                 case DOF_RELO_SETX:
12280                         if (r->dofr_offset >= ts->dofs_size || r->dofr_offset +
12281                             sizeof (uint64_t) > ts->dofs_size) {
12282                                 dtrace_dof_error(dof, "bad relocation offset");
12283                                 return (-1);
12284                         }
12285
12286                         if (!IS_P2ALIGNED(taddr, sizeof (uint64_t))) {
12287                                 dtrace_dof_error(dof, "misaligned setx relo");
12288                                 return (-1);
12289                         }
12290
12291                         *(uint64_t *)taddr += ubase;
12292                         break;
12293                 default:
12294                         dtrace_dof_error(dof, "invalid relocation type");
12295                         return (-1);
12296                 }
12297
12298                 r = (dof_relodesc_t *)((uintptr_t)r + rs->dofs_entsize);
12299         }
12300
12301         return (0);
12302 }
12303
12304 /*
12305  * The dof_hdr_t passed to dtrace_dof_slurp() should be a partially validated
12306  * header:  it should be at the front of a memory region that is at least
12307  * sizeof (dof_hdr_t) in size -- and then at least dof_hdr.dofh_loadsz in
12308  * size.  It need not be validated in any other way.
12309  */
12310 static int
12311 dtrace_dof_slurp(dof_hdr_t *dof, dtrace_vstate_t *vstate, cred_t *cr,
12312     dtrace_enabling_t **enabp, uint64_t ubase, int noprobes)
12313 {
12314         uint64_t len = dof->dofh_loadsz, seclen;
12315         uintptr_t daddr = (uintptr_t)dof;
12316         dtrace_ecbdesc_t *ep;
12317         dtrace_enabling_t *enab;
12318         uint_t i;
12319
12320         ASSERT(MUTEX_HELD(&dtrace_lock));
12321         ASSERT(dof->dofh_loadsz >= sizeof (dof_hdr_t));
12322
12323         /*
12324          * Check the DOF header identification bytes.  In addition to checking
12325          * valid settings, we also verify that unused bits/bytes are zeroed so
12326          * we can use them later without fear of regressing existing binaries.
12327          */
12328         if (bcmp(&dof->dofh_ident[DOF_ID_MAG0],
12329             DOF_MAG_STRING, DOF_MAG_STRLEN) != 0) {
12330                 dtrace_dof_error(dof, "DOF magic string mismatch");
12331                 return (-1);
12332         }
12333
12334         if (dof->dofh_ident[DOF_ID_MODEL] != DOF_MODEL_ILP32 &&
12335             dof->dofh_ident[DOF_ID_MODEL] != DOF_MODEL_LP64) {
12336                 dtrace_dof_error(dof, "DOF has invalid data model");
12337                 return (-1);
12338         }
12339
12340         if (dof->dofh_ident[DOF_ID_ENCODING] != DOF_ENCODE_NATIVE) {
12341                 dtrace_dof_error(dof, "DOF encoding mismatch");
12342                 return (-1);
12343         }
12344
12345         if (dof->dofh_ident[DOF_ID_VERSION] != DOF_VERSION_1 &&
12346             dof->dofh_ident[DOF_ID_VERSION] != DOF_VERSION_2) {
12347                 dtrace_dof_error(dof, "DOF version mismatch");
12348                 return (-1);
12349         }
12350
12351         if (dof->dofh_ident[DOF_ID_DIFVERS] != DIF_VERSION_2) {
12352                 dtrace_dof_error(dof, "DOF uses unsupported instruction set");
12353                 return (-1);
12354         }
12355
12356         if (dof->dofh_ident[DOF_ID_DIFIREG] > DIF_DIR_NREGS) {
12357                 dtrace_dof_error(dof, "DOF uses too many integer registers");
12358                 return (-1);
12359         }
12360
12361         if (dof->dofh_ident[DOF_ID_DIFTREG] > DIF_DTR_NREGS) {
12362                 dtrace_dof_error(dof, "DOF uses too many tuple registers");
12363                 return (-1);
12364         }
12365
12366         for (i = DOF_ID_PAD; i < DOF_ID_SIZE; i++) {
12367                 if (dof->dofh_ident[i] != 0) {
12368                         dtrace_dof_error(dof, "DOF has invalid ident byte set");
12369                         return (-1);
12370                 }
12371         }
12372
12373         if (dof->dofh_flags & ~DOF_FL_VALID) {
12374                 dtrace_dof_error(dof, "DOF has invalid flag bits set");
12375                 return (-1);
12376         }
12377
12378         if (dof->dofh_secsize == 0) {
12379                 dtrace_dof_error(dof, "zero section header size");
12380                 return (-1);
12381         }
12382
12383         /*
12384          * Check that the section headers don't exceed the amount of DOF
12385          * data.  Note that we cast the section size and number of sections
12386          * to uint64_t's to prevent possible overflow in the multiplication.
12387          */
12388         seclen = (uint64_t)dof->dofh_secnum * (uint64_t)dof->dofh_secsize;
12389
12390         if (dof->dofh_secoff > len || seclen > len ||
12391             dof->dofh_secoff + seclen > len) {
12392                 dtrace_dof_error(dof, "truncated section headers");
12393                 return (-1);
12394         }
12395
12396         if (!IS_P2ALIGNED(dof->dofh_secoff, sizeof (uint64_t))) {
12397                 dtrace_dof_error(dof, "misaligned section headers");
12398                 return (-1);
12399         }
12400
12401         if (!IS_P2ALIGNED(dof->dofh_secsize, sizeof (uint64_t))) {
12402                 dtrace_dof_error(dof, "misaligned section size");
12403                 return (-1);
12404         }
12405
12406         /*
12407          * Take an initial pass through the section headers to be sure that
12408          * the headers don't have stray offsets.  If the 'noprobes' flag is
12409          * set, do not permit sections relating to providers, probes, or args.
12410          */
12411         for (i = 0; i < dof->dofh_secnum; i++) {
12412                 dof_sec_t *sec = (dof_sec_t *)(daddr +
12413                     (uintptr_t)dof->dofh_secoff + i * dof->dofh_secsize);
12414
12415                 if (noprobes) {
12416                         switch (sec->dofs_type) {
12417                         case DOF_SECT_PROVIDER:
12418                         case DOF_SECT_PROBES:
12419                         case DOF_SECT_PRARGS:
12420                         case DOF_SECT_PROFFS:
12421                                 dtrace_dof_error(dof, "illegal sections "
12422                                     "for enabling");
12423                                 return (-1);
12424                         }
12425                 }
12426
12427                 if (!(sec->dofs_flags & DOF_SECF_LOAD))
12428                         continue; /* just ignore non-loadable sections */
12429
12430                 if (sec->dofs_align & (sec->dofs_align - 1)) {
12431                         dtrace_dof_error(dof, "bad section alignment");
12432                         return (-1);
12433                 }
12434
12435                 if (sec->dofs_offset & (sec->dofs_align - 1)) {
12436                         dtrace_dof_error(dof, "misaligned section");
12437                         return (-1);
12438                 }
12439
12440                 if (sec->dofs_offset > len || sec->dofs_size > len ||
12441                     sec->dofs_offset + sec->dofs_size > len) {
12442                         dtrace_dof_error(dof, "corrupt section header");
12443                         return (-1);
12444                 }
12445
12446                 if (sec->dofs_type == DOF_SECT_STRTAB && *((char *)daddr +
12447                     sec->dofs_offset + sec->dofs_size - 1) != '\0') {
12448                         dtrace_dof_error(dof, "non-terminating string table");
12449                         return (-1);
12450                 }
12451         }
12452
12453         /*
12454          * Take a second pass through the sections and locate and perform any
12455          * relocations that are present.  We do this after the first pass to
12456          * be sure that all sections have had their headers validated.
12457          */
12458         for (i = 0; i < dof->dofh_secnum; i++) {
12459                 dof_sec_t *sec = (dof_sec_t *)(daddr +
12460                     (uintptr_t)dof->dofh_secoff + i * dof->dofh_secsize);
12461
12462                 if (!(sec->dofs_flags & DOF_SECF_LOAD))
12463                         continue; /* skip sections that are not loadable */
12464
12465                 switch (sec->dofs_type) {
12466                 case DOF_SECT_URELHDR:
12467                         if (dtrace_dof_relocate(dof, sec, ubase) != 0)
12468                                 return (-1);
12469                         break;
12470                 }
12471         }
12472
12473         if ((enab = *enabp) == NULL)
12474                 enab = *enabp = dtrace_enabling_create(vstate);
12475
12476         for (i = 0; i < dof->dofh_secnum; i++) {
12477                 dof_sec_t *sec = (dof_sec_t *)(daddr +
12478                     (uintptr_t)dof->dofh_secoff + i * dof->dofh_secsize);
12479
12480                 if (sec->dofs_type != DOF_SECT_ECBDESC)
12481                         continue;
12482
12483                 if ((ep = dtrace_dof_ecbdesc(dof, sec, vstate, cr)) == NULL) {
12484                         dtrace_enabling_destroy(enab);
12485                         *enabp = NULL;
12486                         return (-1);
12487                 }
12488
12489                 dtrace_enabling_add(enab, ep);
12490         }
12491
12492         return (0);
12493 }
12494
12495 /*
12496  * Process DOF for any options.  This routine assumes that the DOF has been
12497  * at least processed by dtrace_dof_slurp().
12498  */
12499 static int
12500 dtrace_dof_options(dof_hdr_t *dof, dtrace_state_t *state)
12501 {
12502         int i, rval;
12503         uint32_t entsize;
12504         size_t offs;
12505         dof_optdesc_t *desc;
12506
12507         for (i = 0; i < dof->dofh_secnum; i++) {
12508                 dof_sec_t *sec = (dof_sec_t *)((uintptr_t)dof +
12509                     (uintptr_t)dof->dofh_secoff + i * dof->dofh_secsize);
12510
12511                 if (sec->dofs_type != DOF_SECT_OPTDESC)
12512                         continue;
12513
12514                 if (sec->dofs_align != sizeof (uint64_t)) {
12515                         dtrace_dof_error(dof, "bad alignment in "
12516                             "option description");
12517                         return (EINVAL);
12518                 }
12519
12520                 if ((entsize = sec->dofs_entsize) == 0) {
12521                         dtrace_dof_error(dof, "zeroed option entry size");
12522                         return (EINVAL);
12523                 }
12524
12525                 if (entsize < sizeof (dof_optdesc_t)) {
12526                         dtrace_dof_error(dof, "bad option entry size");
12527                         return (EINVAL);
12528                 }
12529
12530                 for (offs = 0; offs < sec->dofs_size; offs += entsize) {
12531                         desc = (dof_optdesc_t *)((uintptr_t)dof +
12532                             (uintptr_t)sec->dofs_offset + offs);
12533
12534                         if (desc->dofo_strtab != DOF_SECIDX_NONE) {
12535                                 dtrace_dof_error(dof, "non-zero option string");
12536                                 return (EINVAL);
12537                         }
12538
12539                         if (desc->dofo_value == DTRACEOPT_UNSET) {
12540                                 dtrace_dof_error(dof, "unset option");
12541                                 return (EINVAL);
12542                         }
12543
12544                         if ((rval = dtrace_state_option(state,
12545                             desc->dofo_option, desc->dofo_value)) != 0) {
12546                                 dtrace_dof_error(dof, "rejected option");
12547                                 return (rval);
12548                         }
12549                 }
12550         }
12551
12552         return (0);
12553 }
12554
12555 /*
12556  * DTrace Consumer State Functions
12557  */
12558 static int
12559 dtrace_dstate_init(dtrace_dstate_t *dstate, size_t size)
12560 {
12561         size_t hashsize, maxper, min, chunksize = dstate->dtds_chunksize;
12562         void *base;
12563         uintptr_t limit;
12564         dtrace_dynvar_t *dvar, *next, *start;
12565         int i;
12566
12567         ASSERT(MUTEX_HELD(&dtrace_lock));
12568         ASSERT(dstate->dtds_base == NULL && dstate->dtds_percpu == NULL);
12569
12570         bzero(dstate, sizeof (dtrace_dstate_t));
12571
12572         if ((dstate->dtds_chunksize = chunksize) == 0)
12573                 dstate->dtds_chunksize = DTRACE_DYNVAR_CHUNKSIZE;
12574
12575         if (size < (min = dstate->dtds_chunksize + sizeof (dtrace_dynhash_t)))
12576                 size = min;
12577
12578         if ((base = kmem_zalloc(size, KM_NOSLEEP)) == NULL)
12579                 return (ENOMEM);
12580
12581         dstate->dtds_size = size;
12582         dstate->dtds_base = base;
12583         dstate->dtds_percpu = kmem_cache_alloc(dtrace_state_cache, KM_SLEEP);
12584         bzero(dstate->dtds_percpu, NCPU * sizeof (dtrace_dstate_percpu_t));
12585
12586         hashsize = size / (dstate->dtds_chunksize + sizeof (dtrace_dynhash_t));
12587
12588         if (hashsize != 1 && (hashsize & 1))
12589                 hashsize--;
12590
12591         dstate->dtds_hashsize = hashsize;
12592         dstate->dtds_hash = dstate->dtds_base;
12593
12594         /*
12595          * Set all of our hash buckets to point to the single sink, and (if
12596          * it hasn't already been set), set the sink's hash value to be the
12597          * sink sentinel value.  The sink is needed for dynamic variable
12598          * lookups to know that they have iterated over an entire, valid hash
12599          * chain.
12600          */
12601         for (i = 0; i < hashsize; i++)
12602                 dstate->dtds_hash[i].dtdh_chain = &dtrace_dynhash_sink;
12603
12604         if (dtrace_dynhash_sink.dtdv_hashval != DTRACE_DYNHASH_SINK)
12605                 dtrace_dynhash_sink.dtdv_hashval = DTRACE_DYNHASH_SINK;
12606
12607         /*
12608          * Determine number of active CPUs.  Divide free list evenly among
12609          * active CPUs.
12610          */
12611         start = (dtrace_dynvar_t *)
12612             ((uintptr_t)base + hashsize * sizeof (dtrace_dynhash_t));
12613         limit = (uintptr_t)base + size;
12614
12615         maxper = (limit - (uintptr_t)start) / NCPU;
12616         maxper = (maxper / dstate->dtds_chunksize) * dstate->dtds_chunksize;
12617
12618         for (i = 0; i < NCPU; i++) {
12619 #if !defined(sun)
12620                 if (CPU_ABSENT(i))
12621                         continue;
12622 #endif
12623                 dstate->dtds_percpu[i].dtdsc_free = dvar = start;
12624
12625                 /*
12626                  * If we don't even have enough chunks to make it once through
12627                  * NCPUs, we're just going to allocate everything to the first
12628                  * CPU.  And if we're on the last CPU, we're going to allocate
12629                  * whatever is left over.  In either case, we set the limit to
12630                  * be the limit of the dynamic variable space.
12631                  */
12632                 if (maxper == 0 || i == NCPU - 1) {
12633                         limit = (uintptr_t)base + size;
12634                         start = NULL;
12635                 } else {
12636                         limit = (uintptr_t)start + maxper;
12637                         start = (dtrace_dynvar_t *)limit;
12638                 }
12639
12640                 ASSERT(limit <= (uintptr_t)base + size);
12641
12642                 for (;;) {
12643                         next = (dtrace_dynvar_t *)((uintptr_t)dvar +
12644                             dstate->dtds_chunksize);
12645
12646                         if ((uintptr_t)next + dstate->dtds_chunksize >= limit)
12647                                 break;
12648
12649                         dvar->dtdv_next = next;
12650                         dvar = next;
12651                 }
12652
12653                 if (maxper == 0)
12654                         break;
12655         }
12656
12657         return (0);
12658 }
12659
12660 static void
12661 dtrace_dstate_fini(dtrace_dstate_t *dstate)
12662 {
12663         ASSERT(MUTEX_HELD(&cpu_lock));
12664
12665         if (dstate->dtds_base == NULL)
12666                 return;
12667
12668         kmem_free(dstate->dtds_base, dstate->dtds_size);
12669         kmem_cache_free(dtrace_state_cache, dstate->dtds_percpu);
12670 }
12671
12672 static void
12673 dtrace_vstate_fini(dtrace_vstate_t *vstate)
12674 {
12675         /*
12676          * Logical XOR, where are you?
12677          */
12678         ASSERT((vstate->dtvs_nglobals == 0) ^ (vstate->dtvs_globals != NULL));
12679
12680         if (vstate->dtvs_nglobals > 0) {
12681                 kmem_free(vstate->dtvs_globals, vstate->dtvs_nglobals *
12682                     sizeof (dtrace_statvar_t *));
12683         }
12684
12685         if (vstate->dtvs_ntlocals > 0) {
12686                 kmem_free(vstate->dtvs_tlocals, vstate->dtvs_ntlocals *
12687                     sizeof (dtrace_difv_t));
12688         }
12689
12690         ASSERT((vstate->dtvs_nlocals == 0) ^ (vstate->dtvs_locals != NULL));
12691
12692         if (vstate->dtvs_nlocals > 0) {
12693                 kmem_free(vstate->dtvs_locals, vstate->dtvs_nlocals *
12694                     sizeof (dtrace_statvar_t *));
12695         }
12696 }
12697
12698 #if defined(sun)
12699 static void
12700 dtrace_state_clean(dtrace_state_t *state)
12701 {
12702         if (state->dts_activity == DTRACE_ACTIVITY_INACTIVE)
12703                 return;
12704
12705         dtrace_dynvar_clean(&state->dts_vstate.dtvs_dynvars);
12706         dtrace_speculation_clean(state);
12707 }
12708
12709 static void
12710 dtrace_state_deadman(dtrace_state_t *state)
12711 {
12712         hrtime_t now;
12713
12714         dtrace_sync();
12715
12716         now = dtrace_gethrtime();
12717
12718         if (state != dtrace_anon.dta_state &&
12719             now - state->dts_laststatus >= dtrace_deadman_user)
12720                 return;
12721
12722         /*
12723          * We must be sure that dts_alive never appears to be less than the
12724          * value upon entry to dtrace_state_deadman(), and because we lack a
12725          * dtrace_cas64(), we cannot store to it atomically.  We thus instead
12726          * store INT64_MAX to it, followed by a memory barrier, followed by
12727          * the new value.  This assures that dts_alive never appears to be
12728          * less than its true value, regardless of the order in which the
12729          * stores to the underlying storage are issued.
12730          */
12731         state->dts_alive = INT64_MAX;
12732         dtrace_membar_producer();
12733         state->dts_alive = now;
12734 }
12735 #else
12736 static void
12737 dtrace_state_clean(void *arg)
12738 {
12739         dtrace_state_t *state = arg;
12740         dtrace_optval_t *opt = state->dts_options;
12741
12742         if (state->dts_activity == DTRACE_ACTIVITY_INACTIVE)
12743                 return;
12744
12745         dtrace_dynvar_clean(&state->dts_vstate.dtvs_dynvars);
12746         dtrace_speculation_clean(state);
12747
12748         callout_reset(&state->dts_cleaner, hz * opt[DTRACEOPT_CLEANRATE] / NANOSEC,
12749             dtrace_state_clean, state);
12750 }
12751
12752 static void
12753 dtrace_state_deadman(void *arg)
12754 {
12755         dtrace_state_t *state = arg;
12756         hrtime_t now;
12757
12758         dtrace_sync();
12759
12760         dtrace_debug_output();
12761
12762         now = dtrace_gethrtime();
12763
12764         if (state != dtrace_anon.dta_state &&
12765             now - state->dts_laststatus >= dtrace_deadman_user)
12766                 return;
12767
12768         /*
12769          * We must be sure that dts_alive never appears to be less than the
12770          * value upon entry to dtrace_state_deadman(), and because we lack a
12771          * dtrace_cas64(), we cannot store to it atomically.  We thus instead
12772          * store INT64_MAX to it, followed by a memory barrier, followed by
12773          * the new value.  This assures that dts_alive never appears to be
12774          * less than its true value, regardless of the order in which the
12775          * stores to the underlying storage are issued.
12776          */
12777         state->dts_alive = INT64_MAX;
12778         dtrace_membar_producer();
12779         state->dts_alive = now;
12780
12781         callout_reset(&state->dts_deadman, hz * dtrace_deadman_interval / NANOSEC,
12782             dtrace_state_deadman, state);
12783 }
12784 #endif
12785
12786 static dtrace_state_t *
12787 #if defined(sun)
12788 dtrace_state_create(dev_t *devp, cred_t *cr)
12789 #else
12790 dtrace_state_create(struct cdev *dev)
12791 #endif
12792 {
12793 #if defined(sun)
12794         minor_t minor;
12795         major_t major;
12796 #else
12797         cred_t *cr = NULL;
12798         int m = 0;
12799 #endif
12800         char c[30];
12801         dtrace_state_t *state;
12802         dtrace_optval_t *opt;
12803         int bufsize = NCPU * sizeof (dtrace_buffer_t), i;
12804
12805         ASSERT(MUTEX_HELD(&dtrace_lock));
12806         ASSERT(MUTEX_HELD(&cpu_lock));
12807
12808 #if defined(sun)
12809         minor = (minor_t)(uintptr_t)vmem_alloc(dtrace_minor, 1,
12810             VM_BESTFIT | VM_SLEEP);
12811
12812         if (ddi_soft_state_zalloc(dtrace_softstate, minor) != DDI_SUCCESS) {
12813                 vmem_free(dtrace_minor, (void *)(uintptr_t)minor, 1);
12814                 return (NULL);
12815         }
12816
12817         state = ddi_get_soft_state(dtrace_softstate, minor);
12818 #else
12819         if (dev != NULL) {
12820                 cr = dev->si_cred;
12821                 m = minor(dev);
12822                 }
12823
12824         /* Allocate memory for the state. */
12825         state = kmem_zalloc(sizeof(dtrace_state_t), KM_SLEEP);
12826 #endif
12827
12828         state->dts_epid = DTRACE_EPIDNONE + 1;
12829
12830         (void) snprintf(c, sizeof (c), "dtrace_aggid_%d", m);
12831 #if defined(sun)
12832         state->dts_aggid_arena = vmem_create(c, (void *)1, UINT32_MAX, 1,
12833             NULL, NULL, NULL, 0, VM_SLEEP | VMC_IDENTIFIER);
12834
12835         if (devp != NULL) {
12836                 major = getemajor(*devp);
12837         } else {
12838                 major = ddi_driver_major(dtrace_devi);
12839         }
12840
12841         state->dts_dev = makedevice(major, minor);
12842
12843         if (devp != NULL)
12844                 *devp = state->dts_dev;
12845 #else
12846         state->dts_aggid_arena = new_unrhdr(1, INT_MAX, &dtrace_unr_mtx);
12847         state->dts_dev = dev;
12848 #endif
12849
12850         /*
12851          * We allocate NCPU buffers.  On the one hand, this can be quite
12852          * a bit of memory per instance (nearly 36K on a Starcat).  On the
12853          * other hand, it saves an additional memory reference in the probe
12854          * path.
12855          */
12856         state->dts_buffer = kmem_zalloc(bufsize, KM_SLEEP);
12857         state->dts_aggbuffer = kmem_zalloc(bufsize, KM_SLEEP);
12858
12859 #if defined(sun)
12860         state->dts_cleaner = CYCLIC_NONE;
12861         state->dts_deadman = CYCLIC_NONE;
12862 #else
12863         callout_init(&state->dts_cleaner, CALLOUT_MPSAFE);
12864         callout_init(&state->dts_deadman, CALLOUT_MPSAFE);
12865 #endif
12866         state->dts_vstate.dtvs_state = state;
12867
12868         for (i = 0; i < DTRACEOPT_MAX; i++)
12869                 state->dts_options[i] = DTRACEOPT_UNSET;
12870
12871         /*
12872          * Set the default options.
12873          */
12874         opt = state->dts_options;
12875         opt[DTRACEOPT_BUFPOLICY] = DTRACEOPT_BUFPOLICY_SWITCH;
12876         opt[DTRACEOPT_BUFRESIZE] = DTRACEOPT_BUFRESIZE_AUTO;
12877         opt[DTRACEOPT_NSPEC] = dtrace_nspec_default;
12878         opt[DTRACEOPT_SPECSIZE] = dtrace_specsize_default;
12879         opt[DTRACEOPT_CPU] = (dtrace_optval_t)DTRACE_CPUALL;
12880         opt[DTRACEOPT_STRSIZE] = dtrace_strsize_default;
12881         opt[DTRACEOPT_STACKFRAMES] = dtrace_stackframes_default;
12882         opt[DTRACEOPT_USTACKFRAMES] = dtrace_ustackframes_default;
12883         opt[DTRACEOPT_CLEANRATE] = dtrace_cleanrate_default;
12884         opt[DTRACEOPT_AGGRATE] = dtrace_aggrate_default;
12885         opt[DTRACEOPT_SWITCHRATE] = dtrace_switchrate_default;
12886         opt[DTRACEOPT_STATUSRATE] = dtrace_statusrate_default;
12887         opt[DTRACEOPT_JSTACKFRAMES] = dtrace_jstackframes_default;
12888         opt[DTRACEOPT_JSTACKSTRSIZE] = dtrace_jstackstrsize_default;
12889
12890         state->dts_activity = DTRACE_ACTIVITY_INACTIVE;
12891
12892         /*
12893          * Depending on the user credentials, we set flag bits which alter probe
12894          * visibility or the amount of destructiveness allowed.  In the case of
12895          * actual anonymous tracing, or the possession of all privileges, all of
12896          * the normal checks are bypassed.
12897          */
12898         if (cr == NULL || PRIV_POLICY_ONLY(cr, PRIV_ALL, B_FALSE)) {
12899                 state->dts_cred.dcr_visible = DTRACE_CRV_ALL;
12900                 state->dts_cred.dcr_action = DTRACE_CRA_ALL;
12901         } else {
12902                 /*
12903                  * Set up the credentials for this instantiation.  We take a
12904                  * hold on the credential to prevent it from disappearing on
12905                  * us; this in turn prevents the zone_t referenced by this
12906                  * credential from disappearing.  This means that we can
12907                  * examine the credential and the zone from probe context.
12908                  */
12909                 crhold(cr);
12910                 state->dts_cred.dcr_cred = cr;
12911
12912                 /*
12913                  * CRA_PROC means "we have *some* privilege for dtrace" and
12914                  * unlocks the use of variables like pid, zonename, etc.
12915                  */
12916                 if (PRIV_POLICY_ONLY(cr, PRIV_DTRACE_USER, B_FALSE) ||
12917                     PRIV_POLICY_ONLY(cr, PRIV_DTRACE_PROC, B_FALSE)) {
12918                         state->dts_cred.dcr_action |= DTRACE_CRA_PROC;
12919                 }
12920
12921                 /*
12922                  * dtrace_user allows use of syscall and profile providers.
12923                  * If the user also has proc_owner and/or proc_zone, we
12924                  * extend the scope to include additional visibility and
12925                  * destructive power.
12926                  */
12927                 if (PRIV_POLICY_ONLY(cr, PRIV_DTRACE_USER, B_FALSE)) {
12928                         if (PRIV_POLICY_ONLY(cr, PRIV_PROC_OWNER, B_FALSE)) {
12929                                 state->dts_cred.dcr_visible |=
12930                                     DTRACE_CRV_ALLPROC;
12931
12932                                 state->dts_cred.dcr_action |=
12933                                     DTRACE_CRA_PROC_DESTRUCTIVE_ALLUSER;
12934                         }
12935
12936                         if (PRIV_POLICY_ONLY(cr, PRIV_PROC_ZONE, B_FALSE)) {
12937                                 state->dts_cred.dcr_visible |=
12938                                     DTRACE_CRV_ALLZONE;
12939
12940                                 state->dts_cred.dcr_action |=
12941                                     DTRACE_CRA_PROC_DESTRUCTIVE_ALLZONE;
12942                         }
12943
12944                         /*
12945                          * If we have all privs in whatever zone this is,
12946                          * we can do destructive things to processes which
12947                          * have altered credentials.
12948                          */
12949 #if defined(sun)
12950                         if (priv_isequalset(priv_getset(cr, PRIV_EFFECTIVE),
12951                             cr->cr_zone->zone_privset)) {
12952                                 state->dts_cred.dcr_action |=
12953                                     DTRACE_CRA_PROC_DESTRUCTIVE_CREDCHG;
12954                         }
12955 #endif
12956                 }
12957
12958                 /*
12959                  * Holding the dtrace_kernel privilege also implies that
12960                  * the user has the dtrace_user privilege from a visibility
12961                  * perspective.  But without further privileges, some
12962                  * destructive actions are not available.
12963                  */
12964                 if (PRIV_POLICY_ONLY(cr, PRIV_DTRACE_KERNEL, B_FALSE)) {
12965                         /*
12966                          * Make all probes in all zones visible.  However,
12967                          * this doesn't mean that all actions become available
12968                          * to all zones.
12969                          */
12970                         state->dts_cred.dcr_visible |= DTRACE_CRV_KERNEL |
12971                             DTRACE_CRV_ALLPROC | DTRACE_CRV_ALLZONE;
12972
12973                         state->dts_cred.dcr_action |= DTRACE_CRA_KERNEL |
12974                             DTRACE_CRA_PROC;
12975                         /*
12976                          * Holding proc_owner means that destructive actions
12977                          * for *this* zone are allowed.
12978                          */
12979                         if (PRIV_POLICY_ONLY(cr, PRIV_PROC_OWNER, B_FALSE))
12980                                 state->dts_cred.dcr_action |=
12981                                     DTRACE_CRA_PROC_DESTRUCTIVE_ALLUSER;
12982
12983                         /*
12984                          * Holding proc_zone means that destructive actions
12985                          * for this user/group ID in all zones is allowed.
12986                          */
12987                         if (PRIV_POLICY_ONLY(cr, PRIV_PROC_ZONE, B_FALSE))
12988                                 state->dts_cred.dcr_action |=
12989                                     DTRACE_CRA_PROC_DESTRUCTIVE_ALLZONE;
12990
12991 #if defined(sun)
12992                         /*
12993                          * If we have all privs in whatever zone this is,
12994                          * we can do destructive things to processes which
12995                          * have altered credentials.
12996                          */
12997                         if (priv_isequalset(priv_getset(cr, PRIV_EFFECTIVE),
12998                             cr->cr_zone->zone_privset)) {
12999                                 state->dts_cred.dcr_action |=
13000                                     DTRACE_CRA_PROC_DESTRUCTIVE_CREDCHG;
13001                         }
13002 #endif
13003                 }
13004
13005                 /*
13006                  * Holding the dtrace_proc privilege gives control over fasttrap
13007                  * and pid providers.  We need to grant wider destructive
13008                  * privileges in the event that the user has proc_owner and/or
13009                  * proc_zone.
13010                  */
13011                 if (PRIV_POLICY_ONLY(cr, PRIV_DTRACE_PROC, B_FALSE)) {
13012                         if (PRIV_POLICY_ONLY(cr, PRIV_PROC_OWNER, B_FALSE))
13013                                 state->dts_cred.dcr_action |=
13014                                     DTRACE_CRA_PROC_DESTRUCTIVE_ALLUSER;
13015
13016                         if (PRIV_POLICY_ONLY(cr, PRIV_PROC_ZONE, B_FALSE))
13017                                 state->dts_cred.dcr_action |=
13018                                     DTRACE_CRA_PROC_DESTRUCTIVE_ALLZONE;
13019                 }
13020         }
13021
13022         return (state);
13023 }
13024
13025 static int
13026 dtrace_state_buffer(dtrace_state_t *state, dtrace_buffer_t *buf, int which)
13027 {
13028         dtrace_optval_t *opt = state->dts_options, size;
13029         processorid_t cpu = 0;;
13030         int flags = 0, rval;
13031
13032         ASSERT(MUTEX_HELD(&dtrace_lock));
13033         ASSERT(MUTEX_HELD(&cpu_lock));
13034         ASSERT(which < DTRACEOPT_MAX);
13035         ASSERT(state->dts_activity == DTRACE_ACTIVITY_INACTIVE ||
13036             (state == dtrace_anon.dta_state &&
13037             state->dts_activity == DTRACE_ACTIVITY_ACTIVE));
13038
13039         if (opt[which] == DTRACEOPT_UNSET || opt[which] == 0)
13040                 return (0);
13041
13042         if (opt[DTRACEOPT_CPU] != DTRACEOPT_UNSET)
13043                 cpu = opt[DTRACEOPT_CPU];
13044
13045         if (which == DTRACEOPT_SPECSIZE)
13046                 flags |= DTRACEBUF_NOSWITCH;
13047
13048         if (which == DTRACEOPT_BUFSIZE) {
13049                 if (opt[DTRACEOPT_BUFPOLICY] == DTRACEOPT_BUFPOLICY_RING)
13050                         flags |= DTRACEBUF_RING;
13051
13052                 if (opt[DTRACEOPT_BUFPOLICY] == DTRACEOPT_BUFPOLICY_FILL)
13053                         flags |= DTRACEBUF_FILL;
13054
13055                 if (state != dtrace_anon.dta_state ||
13056                     state->dts_activity != DTRACE_ACTIVITY_ACTIVE)
13057                         flags |= DTRACEBUF_INACTIVE;
13058         }
13059
13060         for (size = opt[which]; size >= sizeof (uint64_t); size >>= 1) {
13061                 /*
13062                  * The size must be 8-byte aligned.  If the size is not 8-byte
13063                  * aligned, drop it down by the difference.
13064                  */
13065                 if (size & (sizeof (uint64_t) - 1))
13066                         size -= size & (sizeof (uint64_t) - 1);
13067
13068                 if (size < state->dts_reserve) {
13069                         /*
13070                          * Buffers always must be large enough to accommodate
13071                          * their prereserved space.  We return E2BIG instead
13072                          * of ENOMEM in this case to allow for user-level
13073                          * software to differentiate the cases.
13074                          */
13075                         return (E2BIG);
13076                 }
13077
13078                 rval = dtrace_buffer_alloc(buf, size, flags, cpu);
13079
13080                 if (rval != ENOMEM) {
13081                         opt[which] = size;
13082                         return (rval);
13083                 }
13084
13085                 if (opt[DTRACEOPT_BUFRESIZE] == DTRACEOPT_BUFRESIZE_MANUAL)
13086                         return (rval);
13087         }
13088
13089         return (ENOMEM);
13090 }
13091
13092 static int
13093 dtrace_state_buffers(dtrace_state_t *state)
13094 {
13095         dtrace_speculation_t *spec = state->dts_speculations;
13096         int rval, i;
13097
13098         if ((rval = dtrace_state_buffer(state, state->dts_buffer,
13099             DTRACEOPT_BUFSIZE)) != 0)
13100                 return (rval);
13101
13102         if ((rval = dtrace_state_buffer(state, state->dts_aggbuffer,
13103             DTRACEOPT_AGGSIZE)) != 0)
13104                 return (rval);
13105
13106         for (i = 0; i < state->dts_nspeculations; i++) {
13107                 if ((rval = dtrace_state_buffer(state,
13108                     spec[i].dtsp_buffer, DTRACEOPT_SPECSIZE)) != 0)
13109                         return (rval);
13110         }
13111
13112         return (0);
13113 }
13114
13115 static void
13116 dtrace_state_prereserve(dtrace_state_t *state)
13117 {
13118         dtrace_ecb_t *ecb;
13119         dtrace_probe_t *probe;
13120
13121         state->dts_reserve = 0;
13122
13123         if (state->dts_options[DTRACEOPT_BUFPOLICY] != DTRACEOPT_BUFPOLICY_FILL)
13124                 return;
13125
13126         /*
13127          * If our buffer policy is a "fill" buffer policy, we need to set the
13128          * prereserved space to be the space required by the END probes.
13129          */
13130         probe = dtrace_probes[dtrace_probeid_end - 1];
13131         ASSERT(probe != NULL);
13132
13133         for (ecb = probe->dtpr_ecb; ecb != NULL; ecb = ecb->dte_next) {
13134                 if (ecb->dte_state != state)
13135                         continue;
13136
13137                 state->dts_reserve += ecb->dte_needed + ecb->dte_alignment;
13138         }
13139 }
13140
13141 static int
13142 dtrace_state_go(dtrace_state_t *state, processorid_t *cpu)
13143 {
13144         dtrace_optval_t *opt = state->dts_options, sz, nspec;
13145         dtrace_speculation_t *spec;
13146         dtrace_buffer_t *buf;
13147 #if defined(sun)
13148         cyc_handler_t hdlr;
13149         cyc_time_t when;
13150 #endif
13151         int rval = 0, i, bufsize = NCPU * sizeof (dtrace_buffer_t);
13152         dtrace_icookie_t cookie;
13153
13154         mutex_enter(&cpu_lock);
13155         mutex_enter(&dtrace_lock);
13156
13157         if (state->dts_activity != DTRACE_ACTIVITY_INACTIVE) {
13158                 rval = EBUSY;
13159                 goto out;
13160         }
13161
13162         /*
13163          * Before we can perform any checks, we must prime all of the
13164          * retained enablings that correspond to this state.
13165          */
13166         dtrace_enabling_prime(state);
13167
13168         if (state->dts_destructive && !state->dts_cred.dcr_destructive) {
13169                 rval = EACCES;
13170                 goto out;
13171         }
13172
13173         dtrace_state_prereserve(state);
13174
13175         /*
13176          * Now we want to do is try to allocate our speculations.
13177          * We do not automatically resize the number of speculations; if
13178          * this fails, we will fail the operation.
13179          */
13180         nspec = opt[DTRACEOPT_NSPEC];
13181         ASSERT(nspec != DTRACEOPT_UNSET);
13182
13183         if (nspec > INT_MAX) {
13184                 rval = ENOMEM;
13185                 goto out;
13186         }
13187
13188         spec = kmem_zalloc(nspec * sizeof (dtrace_speculation_t), KM_NOSLEEP);
13189
13190         if (spec == NULL) {
13191                 rval = ENOMEM;
13192                 goto out;
13193         }
13194
13195         state->dts_speculations = spec;
13196         state->dts_nspeculations = (int)nspec;
13197
13198         for (i = 0; i < nspec; i++) {
13199                 if ((buf = kmem_zalloc(bufsize, KM_NOSLEEP)) == NULL) {
13200                         rval = ENOMEM;
13201                         goto err;
13202                 }
13203
13204                 spec[i].dtsp_buffer = buf;
13205         }
13206
13207         if (opt[DTRACEOPT_GRABANON] != DTRACEOPT_UNSET) {
13208                 if (dtrace_anon.dta_state == NULL) {
13209                         rval = ENOENT;
13210                         goto out;
13211                 }
13212
13213                 if (state->dts_necbs != 0) {
13214                         rval = EALREADY;
13215                         goto out;
13216                 }
13217
13218                 state->dts_anon = dtrace_anon_grab();
13219                 ASSERT(state->dts_anon != NULL);
13220                 state = state->dts_anon;
13221
13222                 /*
13223                  * We want "grabanon" to be set in the grabbed state, so we'll
13224                  * copy that option value from the grabbing state into the
13225                  * grabbed state.
13226                  */
13227                 state->dts_options[DTRACEOPT_GRABANON] =
13228                     opt[DTRACEOPT_GRABANON];
13229
13230                 *cpu = dtrace_anon.dta_beganon;
13231
13232                 /*
13233                  * If the anonymous state is active (as it almost certainly
13234                  * is if the anonymous enabling ultimately matched anything),
13235                  * we don't allow any further option processing -- but we
13236                  * don't return failure.
13237                  */
13238                 if (state->dts_activity != DTRACE_ACTIVITY_INACTIVE)
13239                         goto out;
13240         }
13241
13242         if (opt[DTRACEOPT_AGGSIZE] != DTRACEOPT_UNSET &&
13243             opt[DTRACEOPT_AGGSIZE] != 0) {
13244                 if (state->dts_aggregations == NULL) {
13245                         /*
13246                          * We're not going to create an aggregation buffer
13247                          * because we don't have any ECBs that contain
13248                          * aggregations -- set this option to 0.
13249                          */
13250                         opt[DTRACEOPT_AGGSIZE] = 0;
13251                 } else {
13252                         /*
13253                          * If we have an aggregation buffer, we must also have
13254                          * a buffer to use as scratch.
13255                          */
13256                         if (opt[DTRACEOPT_BUFSIZE] == DTRACEOPT_UNSET ||
13257                             opt[DTRACEOPT_BUFSIZE] < state->dts_needed) {
13258                                 opt[DTRACEOPT_BUFSIZE] = state->dts_needed;
13259                         }
13260                 }
13261         }
13262
13263         if (opt[DTRACEOPT_SPECSIZE] != DTRACEOPT_UNSET &&
13264             opt[DTRACEOPT_SPECSIZE] != 0) {
13265                 if (!state->dts_speculates) {
13266                         /*
13267                          * We're not going to create speculation buffers
13268                          * because we don't have any ECBs that actually
13269                          * speculate -- set the speculation size to 0.
13270                          */
13271                         opt[DTRACEOPT_SPECSIZE] = 0;
13272                 }
13273         }
13274
13275         /*
13276          * The bare minimum size for any buffer that we're actually going to
13277          * do anything to is sizeof (uint64_t).
13278          */
13279         sz = sizeof (uint64_t);
13280
13281         if ((state->dts_needed != 0 && opt[DTRACEOPT_BUFSIZE] < sz) ||
13282             (state->dts_speculates && opt[DTRACEOPT_SPECSIZE] < sz) ||
13283             (state->dts_aggregations != NULL && opt[DTRACEOPT_AGGSIZE] < sz)) {
13284                 /*
13285                  * A buffer size has been explicitly set to 0 (or to a size
13286                  * that will be adjusted to 0) and we need the space -- we
13287                  * need to return failure.  We return ENOSPC to differentiate
13288                  * it from failing to allocate a buffer due to failure to meet
13289                  * the reserve (for which we return E2BIG).
13290                  */
13291                 rval = ENOSPC;
13292                 goto out;
13293         }
13294
13295         if ((rval = dtrace_state_buffers(state)) != 0)
13296                 goto err;
13297
13298         if ((sz = opt[DTRACEOPT_DYNVARSIZE]) == DTRACEOPT_UNSET)
13299                 sz = dtrace_dstate_defsize;
13300
13301         do {
13302                 rval = dtrace_dstate_init(&state->dts_vstate.dtvs_dynvars, sz);
13303
13304                 if (rval == 0)
13305                         break;
13306
13307                 if (opt[DTRACEOPT_BUFRESIZE] == DTRACEOPT_BUFRESIZE_MANUAL)
13308                         goto err;
13309         } while (sz >>= 1);
13310
13311         opt[DTRACEOPT_DYNVARSIZE] = sz;
13312
13313         if (rval != 0)
13314                 goto err;
13315
13316         if (opt[DTRACEOPT_STATUSRATE] > dtrace_statusrate_max)
13317                 opt[DTRACEOPT_STATUSRATE] = dtrace_statusrate_max;
13318
13319         if (opt[DTRACEOPT_CLEANRATE] == 0)
13320                 opt[DTRACEOPT_CLEANRATE] = dtrace_cleanrate_max;
13321
13322         if (opt[DTRACEOPT_CLEANRATE] < dtrace_cleanrate_min)
13323                 opt[DTRACEOPT_CLEANRATE] = dtrace_cleanrate_min;
13324
13325         if (opt[DTRACEOPT_CLEANRATE] > dtrace_cleanrate_max)
13326                 opt[DTRACEOPT_CLEANRATE] = dtrace_cleanrate_max;
13327
13328         state->dts_alive = state->dts_laststatus = dtrace_gethrtime();
13329 #if defined(sun)
13330         hdlr.cyh_func = (cyc_func_t)dtrace_state_clean;
13331         hdlr.cyh_arg = state;
13332         hdlr.cyh_level = CY_LOW_LEVEL;
13333
13334         when.cyt_when = 0;
13335         when.cyt_interval = opt[DTRACEOPT_CLEANRATE];
13336
13337         state->dts_cleaner = cyclic_add(&hdlr, &when);
13338
13339         hdlr.cyh_func = (cyc_func_t)dtrace_state_deadman;
13340         hdlr.cyh_arg = state;
13341         hdlr.cyh_level = CY_LOW_LEVEL;
13342
13343         when.cyt_when = 0;
13344         when.cyt_interval = dtrace_deadman_interval;
13345
13346         state->dts_deadman = cyclic_add(&hdlr, &when);
13347 #else
13348         callout_reset(&state->dts_cleaner, hz * opt[DTRACEOPT_CLEANRATE] / NANOSEC,
13349             dtrace_state_clean, state);
13350         callout_reset(&state->dts_deadman, hz * dtrace_deadman_interval / NANOSEC,
13351             dtrace_state_deadman, state);
13352 #endif
13353
13354         state->dts_activity = DTRACE_ACTIVITY_WARMUP;
13355
13356         /*
13357          * Now it's time to actually fire the BEGIN probe.  We need to disable
13358          * interrupts here both to record the CPU on which we fired the BEGIN
13359          * probe (the data from this CPU will be processed first at user
13360          * level) and to manually activate the buffer for this CPU.
13361          */
13362         cookie = dtrace_interrupt_disable();
13363         *cpu = curcpu;
13364         ASSERT(state->dts_buffer[*cpu].dtb_flags & DTRACEBUF_INACTIVE);
13365         state->dts_buffer[*cpu].dtb_flags &= ~DTRACEBUF_INACTIVE;
13366
13367         dtrace_probe(dtrace_probeid_begin,
13368             (uint64_t)(uintptr_t)state, 0, 0, 0, 0);
13369         dtrace_interrupt_enable(cookie);
13370         /*
13371          * We may have had an exit action from a BEGIN probe; only change our
13372          * state to ACTIVE if we're still in WARMUP.
13373          */
13374         ASSERT(state->dts_activity == DTRACE_ACTIVITY_WARMUP ||
13375             state->dts_activity == DTRACE_ACTIVITY_DRAINING);
13376
13377         if (state->dts_activity == DTRACE_ACTIVITY_WARMUP)
13378                 state->dts_activity = DTRACE_ACTIVITY_ACTIVE;
13379
13380         /*
13381          * Regardless of whether or not now we're in ACTIVE or DRAINING, we
13382          * want each CPU to transition its principal buffer out of the
13383          * INACTIVE state.  Doing this assures that no CPU will suddenly begin
13384          * processing an ECB halfway down a probe's ECB chain; all CPUs will
13385          * atomically transition from processing none of a state's ECBs to
13386          * processing all of them.
13387          */
13388         dtrace_xcall(DTRACE_CPUALL,
13389             (dtrace_xcall_t)dtrace_buffer_activate, state);
13390         goto out;
13391
13392 err:
13393         dtrace_buffer_free(state->dts_buffer);
13394         dtrace_buffer_free(state->dts_aggbuffer);
13395
13396         if ((nspec = state->dts_nspeculations) == 0) {
13397                 ASSERT(state->dts_speculations == NULL);
13398                 goto out;
13399         }
13400
13401         spec = state->dts_speculations;
13402         ASSERT(spec != NULL);
13403
13404         for (i = 0; i < state->dts_nspeculations; i++) {
13405                 if ((buf = spec[i].dtsp_buffer) == NULL)
13406                         break;
13407
13408                 dtrace_buffer_free(buf);
13409                 kmem_free(buf, bufsize);
13410         }
13411
13412         kmem_free(spec, nspec * sizeof (dtrace_speculation_t));
13413         state->dts_nspeculations = 0;
13414         state->dts_speculations = NULL;
13415
13416 out:
13417         mutex_exit(&dtrace_lock);
13418         mutex_exit(&cpu_lock);
13419
13420         return (rval);
13421 }
13422
13423 static int
13424 dtrace_state_stop(dtrace_state_t *state, processorid_t *cpu)
13425 {
13426         dtrace_icookie_t cookie;
13427
13428         ASSERT(MUTEX_HELD(&dtrace_lock));
13429
13430         if (state->dts_activity != DTRACE_ACTIVITY_ACTIVE &&
13431             state->dts_activity != DTRACE_ACTIVITY_DRAINING)
13432                 return (EINVAL);
13433
13434         /*
13435          * We'll set the activity to DTRACE_ACTIVITY_DRAINING, and issue a sync
13436          * to be sure that every CPU has seen it.  See below for the details
13437          * on why this is done.
13438          */
13439         state->dts_activity = DTRACE_ACTIVITY_DRAINING;
13440         dtrace_sync();
13441
13442         /*
13443          * By this point, it is impossible for any CPU to be still processing
13444          * with DTRACE_ACTIVITY_ACTIVE.  We can thus set our activity to
13445          * DTRACE_ACTIVITY_COOLDOWN and know that we're not racing with any
13446          * other CPU in dtrace_buffer_reserve().  This allows dtrace_probe()
13447          * and callees to know that the activity is DTRACE_ACTIVITY_COOLDOWN
13448          * iff we're in the END probe.
13449          */
13450         state->dts_activity = DTRACE_ACTIVITY_COOLDOWN;
13451         dtrace_sync();
13452         ASSERT(state->dts_activity == DTRACE_ACTIVITY_COOLDOWN);
13453
13454         /*
13455          * Finally, we can release the reserve and call the END probe.  We
13456          * disable interrupts across calling the END probe to allow us to
13457          * return the CPU on which we actually called the END probe.  This
13458          * allows user-land to be sure that this CPU's principal buffer is
13459          * processed last.
13460          */
13461         state->dts_reserve = 0;
13462
13463         cookie = dtrace_interrupt_disable();
13464         *cpu = curcpu;
13465         dtrace_probe(dtrace_probeid_end,
13466             (uint64_t)(uintptr_t)state, 0, 0, 0, 0);
13467         dtrace_interrupt_enable(cookie);
13468
13469         state->dts_activity = DTRACE_ACTIVITY_STOPPED;
13470         dtrace_sync();
13471
13472         return (0);
13473 }
13474
13475 static int
13476 dtrace_state_option(dtrace_state_t *state, dtrace_optid_t option,
13477     dtrace_optval_t val)
13478 {
13479         ASSERT(MUTEX_HELD(&dtrace_lock));
13480
13481         if (state->dts_activity != DTRACE_ACTIVITY_INACTIVE)
13482                 return (EBUSY);
13483
13484         if (option >= DTRACEOPT_MAX)
13485                 return (EINVAL);
13486
13487         if (option != DTRACEOPT_CPU && val < 0)
13488                 return (EINVAL);
13489
13490         switch (option) {
13491         case DTRACEOPT_DESTRUCTIVE:
13492                 if (dtrace_destructive_disallow)
13493                         return (EACCES);
13494
13495                 state->dts_cred.dcr_destructive = 1;
13496                 break;
13497
13498         case DTRACEOPT_BUFSIZE:
13499         case DTRACEOPT_DYNVARSIZE:
13500         case DTRACEOPT_AGGSIZE:
13501         case DTRACEOPT_SPECSIZE:
13502         case DTRACEOPT_STRSIZE:
13503                 if (val < 0)
13504                         return (EINVAL);
13505
13506                 if (val >= LONG_MAX) {
13507                         /*
13508                          * If this is an otherwise negative value, set it to
13509                          * the highest multiple of 128m less than LONG_MAX.
13510                          * Technically, we're adjusting the size without
13511                          * regard to the buffer resizing policy, but in fact,
13512                          * this has no effect -- if we set the buffer size to
13513                          * ~LONG_MAX and the buffer policy is ultimately set to
13514                          * be "manual", the buffer allocation is guaranteed to
13515                          * fail, if only because the allocation requires two
13516                          * buffers.  (We set the the size to the highest
13517                          * multiple of 128m because it ensures that the size
13518                          * will remain a multiple of a megabyte when
13519                          * repeatedly halved -- all the way down to 15m.)
13520                          */
13521                         val = LONG_MAX - (1 << 27) + 1;
13522                 }
13523         }
13524
13525         state->dts_options[option] = val;
13526
13527         return (0);
13528 }
13529
13530 static void
13531 dtrace_state_destroy(dtrace_state_t *state)
13532 {
13533         dtrace_ecb_t *ecb;
13534         dtrace_vstate_t *vstate = &state->dts_vstate;
13535 #if defined(sun)
13536         minor_t minor = getminor(state->dts_dev);
13537 #endif
13538         int i, bufsize = NCPU * sizeof (dtrace_buffer_t);
13539         dtrace_speculation_t *spec = state->dts_speculations;
13540         int nspec = state->dts_nspeculations;
13541         uint32_t match;
13542
13543         ASSERT(MUTEX_HELD(&dtrace_lock));
13544         ASSERT(MUTEX_HELD(&cpu_lock));
13545
13546         /*
13547          * First, retract any retained enablings for this state.
13548          */
13549         dtrace_enabling_retract(state);
13550         ASSERT(state->dts_nretained == 0);
13551
13552         if (state->dts_activity == DTRACE_ACTIVITY_ACTIVE ||
13553             state->dts_activity == DTRACE_ACTIVITY_DRAINING) {
13554                 /*
13555                  * We have managed to come into dtrace_state_destroy() on a
13556                  * hot enabling -- almost certainly because of a disorderly
13557                  * shutdown of a consumer.  (That is, a consumer that is
13558                  * exiting without having called dtrace_stop().) In this case,
13559                  * we're going to set our activity to be KILLED, and then
13560                  * issue a sync to be sure that everyone is out of probe
13561                  * context before we start blowing away ECBs.
13562                  */
13563                 state->dts_activity = DTRACE_ACTIVITY_KILLED;
13564                 dtrace_sync();
13565         }
13566
13567         /*
13568          * Release the credential hold we took in dtrace_state_create().
13569          */
13570         if (state->dts_cred.dcr_cred != NULL)
13571                 crfree(state->dts_cred.dcr_cred);
13572
13573         /*
13574          * Now we can safely disable and destroy any enabled probes.  Because
13575          * any DTRACE_PRIV_KERNEL probes may actually be slowing our progress
13576          * (especially if they're all enabled), we take two passes through the
13577          * ECBs:  in the first, we disable just DTRACE_PRIV_KERNEL probes, and
13578          * in the second we disable whatever is left over.
13579          */
13580         for (match = DTRACE_PRIV_KERNEL; ; match = 0) {
13581                 for (i = 0; i < state->dts_necbs; i++) {
13582                         if ((ecb = state->dts_ecbs[i]) == NULL)
13583                                 continue;
13584
13585                         if (match && ecb->dte_probe != NULL) {
13586                                 dtrace_probe_t *probe = ecb->dte_probe;
13587                                 dtrace_provider_t *prov = probe->dtpr_provider;
13588
13589                                 if (!(prov->dtpv_priv.dtpp_flags & match))
13590                                         continue;
13591                         }
13592
13593                         dtrace_ecb_disable(ecb);
13594                         dtrace_ecb_destroy(ecb);
13595                 }
13596
13597                 if (!match)
13598                         break;
13599         }
13600
13601         /*
13602          * Before we free the buffers, perform one more sync to assure that
13603          * every CPU is out of probe context.
13604          */
13605         dtrace_sync();
13606
13607         dtrace_buffer_free(state->dts_buffer);
13608         dtrace_buffer_free(state->dts_aggbuffer);
13609
13610         for (i = 0; i < nspec; i++)
13611                 dtrace_buffer_free(spec[i].dtsp_buffer);
13612
13613 #if defined(sun)
13614         if (state->dts_cleaner != CYCLIC_NONE)
13615                 cyclic_remove(state->dts_cleaner);
13616
13617         if (state->dts_deadman != CYCLIC_NONE)
13618                 cyclic_remove(state->dts_deadman);
13619 #else
13620         callout_drain(&state->dts_cleaner);
13621         callout_drain(&state->dts_deadman);
13622 #endif
13623
13624         dtrace_dstate_fini(&vstate->dtvs_dynvars);
13625         dtrace_vstate_fini(vstate);
13626         if (state->dts_ecbs != NULL)
13627                 kmem_free(state->dts_ecbs, state->dts_necbs * sizeof (dtrace_ecb_t *));
13628
13629         if (state->dts_aggregations != NULL) {
13630 #ifdef DEBUG
13631                 for (i = 0; i < state->dts_naggregations; i++)
13632                         ASSERT(state->dts_aggregations[i] == NULL);
13633 #endif
13634                 ASSERT(state->dts_naggregations > 0);
13635                 kmem_free(state->dts_aggregations,
13636                     state->dts_naggregations * sizeof (dtrace_aggregation_t *));
13637         }
13638
13639         kmem_free(state->dts_buffer, bufsize);
13640         kmem_free(state->dts_aggbuffer, bufsize);
13641
13642         for (i = 0; i < nspec; i++)
13643                 kmem_free(spec[i].dtsp_buffer, bufsize);
13644
13645         if (spec != NULL)
13646                 kmem_free(spec, nspec * sizeof (dtrace_speculation_t));
13647
13648         dtrace_format_destroy(state);
13649
13650         if (state->dts_aggid_arena != NULL) {
13651 #if defined(sun)
13652                 vmem_destroy(state->dts_aggid_arena);
13653 #else
13654                 delete_unrhdr(state->dts_aggid_arena);
13655 #endif
13656                 state->dts_aggid_arena = NULL;
13657         }
13658 #if defined(sun)
13659         ddi_soft_state_free(dtrace_softstate, minor);
13660         vmem_free(dtrace_minor, (void *)(uintptr_t)minor, 1);
13661 #endif
13662 }
13663
13664 /*
13665  * DTrace Anonymous Enabling Functions
13666  */
13667 static dtrace_state_t *
13668 dtrace_anon_grab(void)
13669 {
13670         dtrace_state_t *state;
13671
13672         ASSERT(MUTEX_HELD(&dtrace_lock));
13673
13674         if ((state = dtrace_anon.dta_state) == NULL) {
13675                 ASSERT(dtrace_anon.dta_enabling == NULL);
13676                 return (NULL);
13677         }
13678
13679         ASSERT(dtrace_anon.dta_enabling != NULL);
13680         ASSERT(dtrace_retained != NULL);
13681
13682         dtrace_enabling_destroy(dtrace_anon.dta_enabling);
13683         dtrace_anon.dta_enabling = NULL;
13684         dtrace_anon.dta_state = NULL;
13685
13686         return (state);
13687 }
13688
13689 static void
13690 dtrace_anon_property(void)
13691 {
13692         int i, rv;
13693         dtrace_state_t *state;
13694         dof_hdr_t *dof;
13695         char c[32];             /* enough for "dof-data-" + digits */
13696
13697         ASSERT(MUTEX_HELD(&dtrace_lock));
13698         ASSERT(MUTEX_HELD(&cpu_lock));
13699
13700         for (i = 0; ; i++) {
13701                 (void) snprintf(c, sizeof (c), "dof-data-%d", i);
13702
13703                 dtrace_err_verbose = 1;
13704
13705                 if ((dof = dtrace_dof_property(c)) == NULL) {
13706                         dtrace_err_verbose = 0;
13707                         break;
13708                 }
13709
13710 #if defined(sun)
13711                 /*
13712                  * We want to create anonymous state, so we need to transition
13713                  * the kernel debugger to indicate that DTrace is active.  If
13714                  * this fails (e.g. because the debugger has modified text in
13715                  * some way), we won't continue with the processing.
13716                  */
13717                 if (kdi_dtrace_set(KDI_DTSET_DTRACE_ACTIVATE) != 0) {
13718                         cmn_err(CE_NOTE, "kernel debugger active; anonymous "
13719                             "enabling ignored.");
13720                         dtrace_dof_destroy(dof);
13721                         break;
13722                 }
13723 #endif
13724
13725                 /*
13726                  * If we haven't allocated an anonymous state, we'll do so now.
13727                  */
13728                 if ((state = dtrace_anon.dta_state) == NULL) {
13729 #if defined(sun)
13730                         state = dtrace_state_create(NULL, NULL);
13731 #else
13732                         state = dtrace_state_create(NULL);
13733 #endif
13734                         dtrace_anon.dta_state = state;
13735
13736                         if (state == NULL) {
13737                                 /*
13738                                  * This basically shouldn't happen:  the only
13739                                  * failure mode from dtrace_state_create() is a
13740                                  * failure of ddi_soft_state_zalloc() that
13741                                  * itself should never happen.  Still, the
13742                                  * interface allows for a failure mode, and
13743                                  * we want to fail as gracefully as possible:
13744                                  * we'll emit an error message and cease
13745                                  * processing anonymous state in this case.
13746                                  */
13747                                 cmn_err(CE_WARN, "failed to create "
13748                                     "anonymous state");
13749                                 dtrace_dof_destroy(dof);
13750                                 break;
13751                         }
13752                 }
13753
13754                 rv = dtrace_dof_slurp(dof, &state->dts_vstate, CRED(),
13755                     &dtrace_anon.dta_enabling, 0, B_TRUE);
13756
13757                 if (rv == 0)
13758                         rv = dtrace_dof_options(dof, state);
13759
13760                 dtrace_err_verbose = 0;
13761                 dtrace_dof_destroy(dof);
13762
13763                 if (rv != 0) {
13764                         /*
13765                          * This is malformed DOF; chuck any anonymous state
13766                          * that we created.
13767                          */
13768                         ASSERT(dtrace_anon.dta_enabling == NULL);
13769                         dtrace_state_destroy(state);
13770                         dtrace_anon.dta_state = NULL;
13771                         break;
13772                 }
13773
13774                 ASSERT(dtrace_anon.dta_enabling != NULL);
13775         }
13776
13777         if (dtrace_anon.dta_enabling != NULL) {
13778                 int rval;
13779
13780                 /*
13781                  * dtrace_enabling_retain() can only fail because we are
13782                  * trying to retain more enablings than are allowed -- but
13783                  * we only have one anonymous enabling, and we are guaranteed
13784                  * to be allowed at least one retained enabling; we assert
13785                  * that dtrace_enabling_retain() returns success.
13786                  */
13787                 rval = dtrace_enabling_retain(dtrace_anon.dta_enabling);
13788                 ASSERT(rval == 0);
13789
13790                 dtrace_enabling_dump(dtrace_anon.dta_enabling);
13791         }
13792 }
13793
13794 #if defined(sun)
13795 /*
13796  * DTrace Helper Functions
13797  */
13798 static void
13799 dtrace_helper_trace(dtrace_helper_action_t *helper,
13800     dtrace_mstate_t *mstate, dtrace_vstate_t *vstate, int where)
13801 {
13802         uint32_t size, next, nnext, i;
13803         dtrace_helptrace_t *ent;
13804         uint16_t flags = cpu_core[curcpu].cpuc_dtrace_flags;
13805
13806         if (!dtrace_helptrace_enabled)
13807                 return;
13808
13809         ASSERT(vstate->dtvs_nlocals <= dtrace_helptrace_nlocals);
13810
13811         /*
13812          * What would a tracing framework be without its own tracing
13813          * framework?  (Well, a hell of a lot simpler, for starters...)
13814          */
13815         size = sizeof (dtrace_helptrace_t) + dtrace_helptrace_nlocals *
13816             sizeof (uint64_t) - sizeof (uint64_t);
13817
13818         /*
13819          * Iterate until we can allocate a slot in the trace buffer.
13820          */
13821         do {
13822                 next = dtrace_helptrace_next;
13823
13824                 if (next + size < dtrace_helptrace_bufsize) {
13825                         nnext = next + size;
13826                 } else {
13827                         nnext = size;
13828                 }
13829         } while (dtrace_cas32(&dtrace_helptrace_next, next, nnext) != next);
13830
13831         /*
13832          * We have our slot; fill it in.
13833          */
13834         if (nnext == size)
13835                 next = 0;
13836
13837         ent = (dtrace_helptrace_t *)&dtrace_helptrace_buffer[next];
13838         ent->dtht_helper = helper;
13839         ent->dtht_where = where;
13840         ent->dtht_nlocals = vstate->dtvs_nlocals;
13841
13842         ent->dtht_fltoffs = (mstate->dtms_present & DTRACE_MSTATE_FLTOFFS) ?
13843             mstate->dtms_fltoffs : -1;
13844         ent->dtht_fault = DTRACE_FLAGS2FLT(flags);
13845         ent->dtht_illval = cpu_core[curcpu].cpuc_dtrace_illval;
13846
13847         for (i = 0; i < vstate->dtvs_nlocals; i++) {
13848                 dtrace_statvar_t *svar;
13849
13850                 if ((svar = vstate->dtvs_locals[i]) == NULL)
13851                         continue;
13852
13853                 ASSERT(svar->dtsv_size >= NCPU * sizeof (uint64_t));
13854                 ent->dtht_locals[i] =
13855                     ((uint64_t *)(uintptr_t)svar->dtsv_data)[curcpu];
13856         }
13857 }
13858 #endif
13859
13860 #if defined(sun)
13861 static uint64_t
13862 dtrace_helper(int which, dtrace_mstate_t *mstate,
13863     dtrace_state_t *state, uint64_t arg0, uint64_t arg1)
13864 {
13865         uint16_t *flags = &cpu_core[curcpu].cpuc_dtrace_flags;
13866         uint64_t sarg0 = mstate->dtms_arg[0];
13867         uint64_t sarg1 = mstate->dtms_arg[1];
13868         uint64_t rval;
13869         dtrace_helpers_t *helpers = curproc->p_dtrace_helpers;
13870         dtrace_helper_action_t *helper;
13871         dtrace_vstate_t *vstate;
13872         dtrace_difo_t *pred;
13873         int i, trace = dtrace_helptrace_enabled;
13874
13875         ASSERT(which >= 0 && which < DTRACE_NHELPER_ACTIONS);
13876
13877         if (helpers == NULL)
13878                 return (0);
13879
13880         if ((helper = helpers->dthps_actions[which]) == NULL)
13881                 return (0);
13882
13883         vstate = &helpers->dthps_vstate;
13884         mstate->dtms_arg[0] = arg0;
13885         mstate->dtms_arg[1] = arg1;
13886
13887         /*
13888          * Now iterate over each helper.  If its predicate evaluates to 'true',
13889          * we'll call the corresponding actions.  Note that the below calls
13890          * to dtrace_dif_emulate() may set faults in machine state.  This is
13891          * okay:  our caller (the outer dtrace_dif_emulate()) will simply plow
13892          * the stored DIF offset with its own (which is the desired behavior).
13893          * Also, note the calls to dtrace_dif_emulate() may allocate scratch
13894          * from machine state; this is okay, too.
13895          */
13896         for (; helper != NULL; helper = helper->dtha_next) {
13897                 if ((pred = helper->dtha_predicate) != NULL) {
13898                         if (trace)
13899                                 dtrace_helper_trace(helper, mstate, vstate, 0);
13900
13901                         if (!dtrace_dif_emulate(pred, mstate, vstate, state))
13902                                 goto next;
13903
13904                         if (*flags & CPU_DTRACE_FAULT)
13905                                 goto err;
13906                 }
13907
13908                 for (i = 0; i < helper->dtha_nactions; i++) {
13909                         if (trace)
13910                                 dtrace_helper_trace(helper,
13911                                     mstate, vstate, i + 1);
13912
13913                         rval = dtrace_dif_emulate(helper->dtha_actions[i],
13914                             mstate, vstate, state);
13915
13916                         if (*flags & CPU_DTRACE_FAULT)
13917                                 goto err;
13918                 }
13919
13920 next:
13921                 if (trace)
13922                         dtrace_helper_trace(helper, mstate, vstate,
13923                             DTRACE_HELPTRACE_NEXT);
13924         }
13925
13926         if (trace)
13927                 dtrace_helper_trace(helper, mstate, vstate,
13928                     DTRACE_HELPTRACE_DONE);
13929
13930         /*
13931          * Restore the arg0 that we saved upon entry.
13932          */
13933         mstate->dtms_arg[0] = sarg0;
13934         mstate->dtms_arg[1] = sarg1;
13935
13936         return (rval);
13937
13938 err:
13939         if (trace)
13940                 dtrace_helper_trace(helper, mstate, vstate,
13941                     DTRACE_HELPTRACE_ERR);
13942
13943         /*
13944          * Restore the arg0 that we saved upon entry.
13945          */
13946         mstate->dtms_arg[0] = sarg0;
13947         mstate->dtms_arg[1] = sarg1;
13948
13949         return (0);
13950 }
13951
13952 static void
13953 dtrace_helper_action_destroy(dtrace_helper_action_t *helper,
13954     dtrace_vstate_t *vstate)
13955 {
13956         int i;
13957
13958         if (helper->dtha_predicate != NULL)
13959                 dtrace_difo_release(helper->dtha_predicate, vstate);
13960
13961         for (i = 0; i < helper->dtha_nactions; i++) {
13962                 ASSERT(helper->dtha_actions[i] != NULL);
13963                 dtrace_difo_release(helper->dtha_actions[i], vstate);
13964         }
13965
13966         kmem_free(helper->dtha_actions,
13967             helper->dtha_nactions * sizeof (dtrace_difo_t *));
13968         kmem_free(helper, sizeof (dtrace_helper_action_t));
13969 }
13970
13971 static int
13972 dtrace_helper_destroygen(int gen)
13973 {
13974         proc_t *p = curproc;
13975         dtrace_helpers_t *help = p->p_dtrace_helpers;
13976         dtrace_vstate_t *vstate;
13977         int i;
13978
13979         ASSERT(MUTEX_HELD(&dtrace_lock));
13980
13981         if (help == NULL || gen > help->dthps_generation)
13982                 return (EINVAL);
13983
13984         vstate = &help->dthps_vstate;
13985
13986         for (i = 0; i < DTRACE_NHELPER_ACTIONS; i++) {
13987                 dtrace_helper_action_t *last = NULL, *h, *next;
13988
13989                 for (h = help->dthps_actions[i]; h != NULL; h = next) {
13990                         next = h->dtha_next;
13991
13992                         if (h->dtha_generation == gen) {
13993                                 if (last != NULL) {
13994                                         last->dtha_next = next;
13995                                 } else {
13996                                         help->dthps_actions[i] = next;
13997                                 }
13998
13999                                 dtrace_helper_action_destroy(h, vstate);
14000                         } else {
14001                                 last = h;
14002                         }
14003                 }
14004         }
14005
14006         /*
14007          * Interate until we've cleared out all helper providers with the
14008          * given generation number.
14009          */
14010         for (;;) {
14011                 dtrace_helper_provider_t *prov;
14012
14013                 /*
14014                  * Look for a helper provider with the right generation. We
14015                  * have to start back at the beginning of the list each time
14016                  * because we drop dtrace_lock. It's unlikely that we'll make
14017                  * more than two passes.
14018                  */
14019                 for (i = 0; i < help->dthps_nprovs; i++) {
14020                         prov = help->dthps_provs[i];
14021
14022                         if (prov->dthp_generation == gen)
14023                                 break;
14024                 }
14025
14026                 /*
14027                  * If there were no matches, we're done.
14028                  */
14029                 if (i == help->dthps_nprovs)
14030                         break;
14031
14032                 /*
14033                  * Move the last helper provider into this slot.
14034                  */
14035                 help->dthps_nprovs--;
14036                 help->dthps_provs[i] = help->dthps_provs[help->dthps_nprovs];
14037                 help->dthps_provs[help->dthps_nprovs] = NULL;
14038
14039                 mutex_exit(&dtrace_lock);
14040
14041                 /*
14042                  * If we have a meta provider, remove this helper provider.
14043                  */
14044                 mutex_enter(&dtrace_meta_lock);
14045                 if (dtrace_meta_pid != NULL) {
14046                         ASSERT(dtrace_deferred_pid == NULL);
14047                         dtrace_helper_provider_remove(&prov->dthp_prov,
14048                             p->p_pid);
14049                 }
14050                 mutex_exit(&dtrace_meta_lock);
14051
14052                 dtrace_helper_provider_destroy(prov);
14053
14054                 mutex_enter(&dtrace_lock);
14055         }
14056
14057         return (0);
14058 }
14059 #endif
14060
14061 #if defined(sun)
14062 static int
14063 dtrace_helper_validate(dtrace_helper_action_t *helper)
14064 {
14065         int err = 0, i;
14066         dtrace_difo_t *dp;
14067
14068         if ((dp = helper->dtha_predicate) != NULL)
14069                 err += dtrace_difo_validate_helper(dp);
14070
14071         for (i = 0; i < helper->dtha_nactions; i++)
14072                 err += dtrace_difo_validate_helper(helper->dtha_actions[i]);
14073
14074         return (err == 0);
14075 }
14076 #endif
14077
14078 #if defined(sun)
14079 static int
14080 dtrace_helper_action_add(int which, dtrace_ecbdesc_t *ep)
14081 {
14082         dtrace_helpers_t *help;
14083         dtrace_helper_action_t *helper, *last;
14084         dtrace_actdesc_t *act;
14085         dtrace_vstate_t *vstate;
14086         dtrace_predicate_t *pred;
14087         int count = 0, nactions = 0, i;
14088
14089         if (which < 0 || which >= DTRACE_NHELPER_ACTIONS)
14090                 return (EINVAL);
14091
14092         help = curproc->p_dtrace_helpers;
14093         last = help->dthps_actions[which];
14094         vstate = &help->dthps_vstate;
14095
14096         for (count = 0; last != NULL; last = last->dtha_next) {
14097                 count++;
14098                 if (last->dtha_next == NULL)
14099                         break;
14100         }
14101
14102         /*
14103          * If we already have dtrace_helper_actions_max helper actions for this
14104          * helper action type, we'll refuse to add a new one.
14105          */
14106         if (count >= dtrace_helper_actions_max)
14107                 return (ENOSPC);
14108
14109         helper = kmem_zalloc(sizeof (dtrace_helper_action_t), KM_SLEEP);
14110         helper->dtha_generation = help->dthps_generation;
14111
14112         if ((pred = ep->dted_pred.dtpdd_predicate) != NULL) {
14113                 ASSERT(pred->dtp_difo != NULL);
14114                 dtrace_difo_hold(pred->dtp_difo);
14115                 helper->dtha_predicate = pred->dtp_difo;
14116         }
14117
14118         for (act = ep->dted_action; act != NULL; act = act->dtad_next) {
14119                 if (act->dtad_kind != DTRACEACT_DIFEXPR)
14120                         goto err;
14121
14122                 if (act->dtad_difo == NULL)
14123                         goto err;
14124
14125                 nactions++;
14126         }
14127
14128         helper->dtha_actions = kmem_zalloc(sizeof (dtrace_difo_t *) *
14129             (helper->dtha_nactions = nactions), KM_SLEEP);
14130
14131         for (act = ep->dted_action, i = 0; act != NULL; act = act->dtad_next) {
14132                 dtrace_difo_hold(act->dtad_difo);
14133                 helper->dtha_actions[i++] = act->dtad_difo;
14134         }
14135
14136         if (!dtrace_helper_validate(helper))
14137                 goto err;
14138
14139         if (last == NULL) {
14140                 help->dthps_actions[which] = helper;
14141         } else {
14142                 last->dtha_next = helper;
14143         }
14144
14145         if (vstate->dtvs_nlocals > dtrace_helptrace_nlocals) {
14146                 dtrace_helptrace_nlocals = vstate->dtvs_nlocals;
14147                 dtrace_helptrace_next = 0;
14148         }
14149
14150         return (0);
14151 err:
14152         dtrace_helper_action_destroy(helper, vstate);
14153         return (EINVAL);
14154 }
14155
14156 static void
14157 dtrace_helper_provider_register(proc_t *p, dtrace_helpers_t *help,
14158     dof_helper_t *dofhp)
14159 {
14160         ASSERT(MUTEX_NOT_HELD(&dtrace_lock));
14161
14162         mutex_enter(&dtrace_meta_lock);
14163         mutex_enter(&dtrace_lock);
14164
14165         if (!dtrace_attached() || dtrace_meta_pid == NULL) {
14166                 /*
14167                  * If the dtrace module is loaded but not attached, or if
14168                  * there aren't isn't a meta provider registered to deal with
14169                  * these provider descriptions, we need to postpone creating
14170                  * the actual providers until later.
14171                  */
14172
14173                 if (help->dthps_next == NULL && help->dthps_prev == NULL &&
14174                     dtrace_deferred_pid != help) {
14175                         help->dthps_deferred = 1;
14176                         help->dthps_pid = p->p_pid;
14177                         help->dthps_next = dtrace_deferred_pid;
14178                         help->dthps_prev = NULL;
14179                         if (dtrace_deferred_pid != NULL)
14180                                 dtrace_deferred_pid->dthps_prev = help;
14181                         dtrace_deferred_pid = help;
14182                 }
14183
14184                 mutex_exit(&dtrace_lock);
14185
14186         } else if (dofhp != NULL) {
14187                 /*
14188                  * If the dtrace module is loaded and we have a particular
14189                  * helper provider description, pass that off to the
14190                  * meta provider.
14191                  */
14192
14193                 mutex_exit(&dtrace_lock);
14194
14195                 dtrace_helper_provide(dofhp, p->p_pid);
14196
14197         } else {
14198                 /*
14199                  * Otherwise, just pass all the helper provider descriptions
14200                  * off to the meta provider.
14201                  */
14202
14203                 int i;
14204                 mutex_exit(&dtrace_lock);
14205
14206                 for (i = 0; i < help->dthps_nprovs; i++) {
14207                         dtrace_helper_provide(&help->dthps_provs[i]->dthp_prov,
14208                             p->p_pid);
14209                 }
14210         }
14211
14212         mutex_exit(&dtrace_meta_lock);
14213 }
14214
14215 static int
14216 dtrace_helper_provider_add(dof_helper_t *dofhp, int gen)
14217 {
14218         dtrace_helpers_t *help;
14219         dtrace_helper_provider_t *hprov, **tmp_provs;
14220         uint_t tmp_maxprovs, i;
14221
14222         ASSERT(MUTEX_HELD(&dtrace_lock));
14223
14224         help = curproc->p_dtrace_helpers;
14225         ASSERT(help != NULL);
14226
14227         /*
14228          * If we already have dtrace_helper_providers_max helper providers,
14229          * we're refuse to add a new one.
14230          */
14231         if (help->dthps_nprovs >= dtrace_helper_providers_max)
14232                 return (ENOSPC);
14233
14234         /*
14235          * Check to make sure this isn't a duplicate.
14236          */
14237         for (i = 0; i < help->dthps_nprovs; i++) {
14238                 if (dofhp->dofhp_addr ==
14239                     help->dthps_provs[i]->dthp_prov.dofhp_addr)
14240                         return (EALREADY);
14241         }
14242
14243         hprov = kmem_zalloc(sizeof (dtrace_helper_provider_t), KM_SLEEP);
14244         hprov->dthp_prov = *dofhp;
14245         hprov->dthp_ref = 1;
14246         hprov->dthp_generation = gen;
14247
14248         /*
14249          * Allocate a bigger table for helper providers if it's already full.
14250          */
14251         if (help->dthps_maxprovs == help->dthps_nprovs) {
14252                 tmp_maxprovs = help->dthps_maxprovs;
14253                 tmp_provs = help->dthps_provs;
14254
14255                 if (help->dthps_maxprovs == 0)
14256                         help->dthps_maxprovs = 2;
14257                 else
14258                         help->dthps_maxprovs *= 2;
14259                 if (help->dthps_maxprovs > dtrace_helper_providers_max)
14260                         help->dthps_maxprovs = dtrace_helper_providers_max;
14261
14262                 ASSERT(tmp_maxprovs < help->dthps_maxprovs);
14263
14264                 help->dthps_provs = kmem_zalloc(help->dthps_maxprovs *
14265                     sizeof (dtrace_helper_provider_t *), KM_SLEEP);
14266
14267                 if (tmp_provs != NULL) {
14268                         bcopy(tmp_provs, help->dthps_provs, tmp_maxprovs *
14269                             sizeof (dtrace_helper_provider_t *));
14270                         kmem_free(tmp_provs, tmp_maxprovs *
14271                             sizeof (dtrace_helper_provider_t *));
14272                 }
14273         }
14274
14275         help->dthps_provs[help->dthps_nprovs] = hprov;
14276         help->dthps_nprovs++;
14277
14278         return (0);
14279 }
14280
14281 static void
14282 dtrace_helper_provider_destroy(dtrace_helper_provider_t *hprov)
14283 {
14284         mutex_enter(&dtrace_lock);
14285
14286         if (--hprov->dthp_ref == 0) {
14287                 dof_hdr_t *dof;
14288                 mutex_exit(&dtrace_lock);
14289                 dof = (dof_hdr_t *)(uintptr_t)hprov->dthp_prov.dofhp_dof;
14290                 dtrace_dof_destroy(dof);
14291                 kmem_free(hprov, sizeof (dtrace_helper_provider_t));
14292         } else {
14293                 mutex_exit(&dtrace_lock);
14294         }
14295 }
14296
14297 static int
14298 dtrace_helper_provider_validate(dof_hdr_t *dof, dof_sec_t *sec)
14299 {
14300         uintptr_t daddr = (uintptr_t)dof;
14301         dof_sec_t *str_sec, *prb_sec, *arg_sec, *off_sec, *enoff_sec;
14302         dof_provider_t *provider;
14303         dof_probe_t *probe;
14304         uint8_t *arg;
14305         char *strtab, *typestr;
14306         dof_stridx_t typeidx;
14307         size_t typesz;
14308         uint_t nprobes, j, k;
14309
14310         ASSERT(sec->dofs_type == DOF_SECT_PROVIDER);
14311
14312         if (sec->dofs_offset & (sizeof (uint_t) - 1)) {
14313                 dtrace_dof_error(dof, "misaligned section offset");
14314                 return (-1);
14315         }
14316
14317         /*
14318          * The section needs to be large enough to contain the DOF provider
14319          * structure appropriate for the given version.
14320          */
14321         if (sec->dofs_size <
14322             ((dof->dofh_ident[DOF_ID_VERSION] == DOF_VERSION_1) ?
14323             offsetof(dof_provider_t, dofpv_prenoffs) :
14324             sizeof (dof_provider_t))) {
14325                 dtrace_dof_error(dof, "provider section too small");
14326                 return (-1);
14327         }
14328
14329         provider = (dof_provider_t *)(uintptr_t)(daddr + sec->dofs_offset);
14330         str_sec = dtrace_dof_sect(dof, DOF_SECT_STRTAB, provider->dofpv_strtab);
14331         prb_sec = dtrace_dof_sect(dof, DOF_SECT_PROBES, provider->dofpv_probes);
14332         arg_sec = dtrace_dof_sect(dof, DOF_SECT_PRARGS, provider->dofpv_prargs);
14333         off_sec = dtrace_dof_sect(dof, DOF_SECT_PROFFS, provider->dofpv_proffs);
14334
14335         if (str_sec == NULL || prb_sec == NULL ||
14336             arg_sec == NULL || off_sec == NULL)
14337                 return (-1);
14338
14339         enoff_sec = NULL;
14340
14341         if (dof->dofh_ident[DOF_ID_VERSION] != DOF_VERSION_1 &&
14342             provider->dofpv_prenoffs != DOF_SECT_NONE &&
14343             (enoff_sec = dtrace_dof_sect(dof, DOF_SECT_PRENOFFS,
14344             provider->dofpv_prenoffs)) == NULL)
14345                 return (-1);
14346
14347         strtab = (char *)(uintptr_t)(daddr + str_sec->dofs_offset);
14348
14349         if (provider->dofpv_name >= str_sec->dofs_size ||
14350             strlen(strtab + provider->dofpv_name) >= DTRACE_PROVNAMELEN) {
14351                 dtrace_dof_error(dof, "invalid provider name");
14352                 return (-1);
14353         }
14354
14355         if (prb_sec->dofs_entsize == 0 ||
14356             prb_sec->dofs_entsize > prb_sec->dofs_size) {
14357                 dtrace_dof_error(dof, "invalid entry size");
14358                 return (-1);
14359         }
14360
14361         if (prb_sec->dofs_entsize & (sizeof (uintptr_t) - 1)) {
14362                 dtrace_dof_error(dof, "misaligned entry size");
14363                 return (-1);
14364         }
14365
14366         if (off_sec->dofs_entsize != sizeof (uint32_t)) {
14367                 dtrace_dof_error(dof, "invalid entry size");
14368                 return (-1);
14369         }
14370
14371         if (off_sec->dofs_offset & (sizeof (uint32_t) - 1)) {
14372                 dtrace_dof_error(dof, "misaligned section offset");
14373                 return (-1);
14374         }
14375
14376         if (arg_sec->dofs_entsize != sizeof (uint8_t)) {
14377                 dtrace_dof_error(dof, "invalid entry size");
14378                 return (-1);
14379         }
14380
14381         arg = (uint8_t *)(uintptr_t)(daddr + arg_sec->dofs_offset);
14382
14383         nprobes = prb_sec->dofs_size / prb_sec->dofs_entsize;
14384
14385         /*
14386          * Take a pass through the probes to check for errors.
14387          */
14388         for (j = 0; j < nprobes; j++) {
14389                 probe = (dof_probe_t *)(uintptr_t)(daddr +
14390                     prb_sec->dofs_offset + j * prb_sec->dofs_entsize);
14391
14392                 if (probe->dofpr_func >= str_sec->dofs_size) {
14393                         dtrace_dof_error(dof, "invalid function name");
14394                         return (-1);
14395                 }
14396
14397                 if (strlen(strtab + probe->dofpr_func) >= DTRACE_FUNCNAMELEN) {
14398                         dtrace_dof_error(dof, "function name too long");
14399                         return (-1);
14400                 }
14401
14402                 if (probe->dofpr_name >= str_sec->dofs_size ||
14403                     strlen(strtab + probe->dofpr_name) >= DTRACE_NAMELEN) {
14404                         dtrace_dof_error(dof, "invalid probe name");
14405                         return (-1);
14406                 }
14407
14408                 /*
14409                  * The offset count must not wrap the index, and the offsets
14410                  * must also not overflow the section's data.
14411                  */
14412                 if (probe->dofpr_offidx + probe->dofpr_noffs <
14413                     probe->dofpr_offidx ||
14414                     (probe->dofpr_offidx + probe->dofpr_noffs) *
14415                     off_sec->dofs_entsize > off_sec->dofs_size) {
14416                         dtrace_dof_error(dof, "invalid probe offset");
14417                         return (-1);
14418                 }
14419
14420                 if (dof->dofh_ident[DOF_ID_VERSION] != DOF_VERSION_1) {
14421                         /*
14422                          * If there's no is-enabled offset section, make sure
14423                          * there aren't any is-enabled offsets. Otherwise
14424                          * perform the same checks as for probe offsets
14425                          * (immediately above).
14426                          */
14427                         if (enoff_sec == NULL) {
14428                                 if (probe->dofpr_enoffidx != 0 ||
14429                                     probe->dofpr_nenoffs != 0) {
14430                                         dtrace_dof_error(dof, "is-enabled "
14431                                             "offsets with null section");
14432                                         return (-1);
14433                                 }
14434                         } else if (probe->dofpr_enoffidx +
14435                             probe->dofpr_nenoffs < probe->dofpr_enoffidx ||
14436                             (probe->dofpr_enoffidx + probe->dofpr_nenoffs) *
14437                             enoff_sec->dofs_entsize > enoff_sec->dofs_size) {
14438                                 dtrace_dof_error(dof, "invalid is-enabled "
14439                                     "offset");
14440                                 return (-1);
14441                         }
14442
14443                         if (probe->dofpr_noffs + probe->dofpr_nenoffs == 0) {
14444                                 dtrace_dof_error(dof, "zero probe and "
14445                                     "is-enabled offsets");
14446                                 return (-1);
14447                         }
14448                 } else if (probe->dofpr_noffs == 0) {
14449                         dtrace_dof_error(dof, "zero probe offsets");
14450                         return (-1);
14451                 }
14452
14453                 if (probe->dofpr_argidx + probe->dofpr_xargc <
14454                     probe->dofpr_argidx ||
14455                     (probe->dofpr_argidx + probe->dofpr_xargc) *
14456                     arg_sec->dofs_entsize > arg_sec->dofs_size) {
14457                         dtrace_dof_error(dof, "invalid args");
14458                         return (-1);
14459                 }
14460
14461                 typeidx = probe->dofpr_nargv;
14462                 typestr = strtab + probe->dofpr_nargv;
14463                 for (k = 0; k < probe->dofpr_nargc; k++) {
14464                         if (typeidx >= str_sec->dofs_size) {
14465                                 dtrace_dof_error(dof, "bad "
14466                                     "native argument type");
14467                                 return (-1);
14468                         }
14469
14470                         typesz = strlen(typestr) + 1;
14471                         if (typesz > DTRACE_ARGTYPELEN) {
14472                                 dtrace_dof_error(dof, "native "
14473                                     "argument type too long");
14474                                 return (-1);
14475                         }
14476                         typeidx += typesz;
14477                         typestr += typesz;
14478                 }
14479
14480                 typeidx = probe->dofpr_xargv;
14481                 typestr = strtab + probe->dofpr_xargv;
14482                 for (k = 0; k < probe->dofpr_xargc; k++) {
14483                         if (arg[probe->dofpr_argidx + k] > probe->dofpr_nargc) {
14484                                 dtrace_dof_error(dof, "bad "
14485                                     "native argument index");
14486                                 return (-1);
14487                         }
14488
14489                         if (typeidx >= str_sec->dofs_size) {
14490                                 dtrace_dof_error(dof, "bad "
14491                                     "translated argument type");
14492                                 return (-1);
14493                         }
14494
14495                         typesz = strlen(typestr) + 1;
14496                         if (typesz > DTRACE_ARGTYPELEN) {
14497                                 dtrace_dof_error(dof, "translated argument "
14498                                     "type too long");
14499                                 return (-1);
14500                         }
14501
14502                         typeidx += typesz;
14503                         typestr += typesz;
14504                 }
14505         }
14506
14507         return (0);
14508 }
14509
14510 static int
14511 dtrace_helper_slurp(dof_hdr_t *dof, dof_helper_t *dhp)
14512 {
14513         dtrace_helpers_t *help;
14514         dtrace_vstate_t *vstate;
14515         dtrace_enabling_t *enab = NULL;
14516         int i, gen, rv, nhelpers = 0, nprovs = 0, destroy = 1;
14517         uintptr_t daddr = (uintptr_t)dof;
14518
14519         ASSERT(MUTEX_HELD(&dtrace_lock));
14520
14521         if ((help = curproc->p_dtrace_helpers) == NULL)
14522                 help = dtrace_helpers_create(curproc);
14523
14524         vstate = &help->dthps_vstate;
14525
14526         if ((rv = dtrace_dof_slurp(dof, vstate, NULL, &enab,
14527             dhp != NULL ? dhp->dofhp_addr : 0, B_FALSE)) != 0) {
14528                 dtrace_dof_destroy(dof);
14529                 return (rv);
14530         }
14531
14532         /*
14533          * Look for helper providers and validate their descriptions.
14534          */
14535         if (dhp != NULL) {
14536                 for (i = 0; i < dof->dofh_secnum; i++) {
14537                         dof_sec_t *sec = (dof_sec_t *)(uintptr_t)(daddr +
14538                             dof->dofh_secoff + i * dof->dofh_secsize);
14539
14540                         if (sec->dofs_type != DOF_SECT_PROVIDER)
14541                                 continue;
14542
14543                         if (dtrace_helper_provider_validate(dof, sec) != 0) {
14544                                 dtrace_enabling_destroy(enab);
14545                                 dtrace_dof_destroy(dof);
14546                                 return (-1);
14547                         }
14548
14549                         nprovs++;
14550                 }
14551         }
14552
14553         /*
14554          * Now we need to walk through the ECB descriptions in the enabling.
14555          */
14556         for (i = 0; i < enab->dten_ndesc; i++) {
14557                 dtrace_ecbdesc_t *ep = enab->dten_desc[i];
14558                 dtrace_probedesc_t *desc = &ep->dted_probe;
14559
14560                 if (strcmp(desc->dtpd_provider, "dtrace") != 0)
14561                         continue;
14562
14563                 if (strcmp(desc->dtpd_mod, "helper") != 0)
14564                         continue;
14565
14566                 if (strcmp(desc->dtpd_func, "ustack") != 0)
14567                         continue;
14568
14569                 if ((rv = dtrace_helper_action_add(DTRACE_HELPER_ACTION_USTACK,
14570                     ep)) != 0) {
14571                         /*
14572                          * Adding this helper action failed -- we are now going
14573                          * to rip out the entire generation and return failure.
14574                          */
14575                         (void) dtrace_helper_destroygen(help->dthps_generation);
14576                         dtrace_enabling_destroy(enab);
14577                         dtrace_dof_destroy(dof);
14578                         return (-1);
14579                 }
14580
14581                 nhelpers++;
14582         }
14583
14584         if (nhelpers < enab->dten_ndesc)
14585                 dtrace_dof_error(dof, "unmatched helpers");
14586
14587         gen = help->dthps_generation++;
14588         dtrace_enabling_destroy(enab);
14589
14590         if (dhp != NULL && nprovs > 0) {
14591                 dhp->dofhp_dof = (uint64_t)(uintptr_t)dof;
14592                 if (dtrace_helper_provider_add(dhp, gen) == 0) {
14593                         mutex_exit(&dtrace_lock);
14594                         dtrace_helper_provider_register(curproc, help, dhp);
14595                         mutex_enter(&dtrace_lock);
14596
14597                         destroy = 0;
14598                 }
14599         }
14600
14601         if (destroy)
14602                 dtrace_dof_destroy(dof);
14603
14604         return (gen);
14605 }
14606
14607 static dtrace_helpers_t *
14608 dtrace_helpers_create(proc_t *p)
14609 {
14610         dtrace_helpers_t *help;
14611
14612         ASSERT(MUTEX_HELD(&dtrace_lock));
14613         ASSERT(p->p_dtrace_helpers == NULL);
14614
14615         help = kmem_zalloc(sizeof (dtrace_helpers_t), KM_SLEEP);
14616         help->dthps_actions = kmem_zalloc(sizeof (dtrace_helper_action_t *) *
14617             DTRACE_NHELPER_ACTIONS, KM_SLEEP);
14618
14619         p->p_dtrace_helpers = help;
14620         dtrace_helpers++;
14621
14622         return (help);
14623 }
14624
14625 static void
14626 dtrace_helpers_destroy(void)
14627 {
14628         dtrace_helpers_t *help;
14629         dtrace_vstate_t *vstate;
14630         proc_t *p = curproc;
14631         int i;
14632
14633         mutex_enter(&dtrace_lock);
14634
14635         ASSERT(p->p_dtrace_helpers != NULL);
14636         ASSERT(dtrace_helpers > 0);
14637
14638         help = p->p_dtrace_helpers;
14639         vstate = &help->dthps_vstate;
14640
14641         /*
14642          * We're now going to lose the help from this process.
14643          */
14644         p->p_dtrace_helpers = NULL;
14645         dtrace_sync();
14646
14647         /*
14648          * Destory the helper actions.
14649          */
14650         for (i = 0; i < DTRACE_NHELPER_ACTIONS; i++) {
14651                 dtrace_helper_action_t *h, *next;
14652
14653                 for (h = help->dthps_actions[i]; h != NULL; h = next) {
14654                         next = h->dtha_next;
14655                         dtrace_helper_action_destroy(h, vstate);
14656                         h = next;
14657                 }
14658         }
14659
14660         mutex_exit(&dtrace_lock);
14661
14662         /*
14663          * Destroy the helper providers.
14664          */
14665         if (help->dthps_maxprovs > 0) {
14666                 mutex_enter(&dtrace_meta_lock);
14667                 if (dtrace_meta_pid != NULL) {
14668                         ASSERT(dtrace_deferred_pid == NULL);
14669
14670                         for (i = 0; i < help->dthps_nprovs; i++) {
14671                                 dtrace_helper_provider_remove(
14672                                     &help->dthps_provs[i]->dthp_prov, p->p_pid);
14673                         }
14674                 } else {
14675                         mutex_enter(&dtrace_lock);
14676                         ASSERT(help->dthps_deferred == 0 ||
14677                             help->dthps_next != NULL ||
14678                             help->dthps_prev != NULL ||
14679                             help == dtrace_deferred_pid);
14680
14681                         /*
14682                          * Remove the helper from the deferred list.
14683                          */
14684                         if (help->dthps_next != NULL)
14685                                 help->dthps_next->dthps_prev = help->dthps_prev;
14686                         if (help->dthps_prev != NULL)
14687                                 help->dthps_prev->dthps_next = help->dthps_next;
14688                         if (dtrace_deferred_pid == help) {
14689                                 dtrace_deferred_pid = help->dthps_next;
14690                                 ASSERT(help->dthps_prev == NULL);
14691                         }
14692
14693                         mutex_exit(&dtrace_lock);
14694                 }
14695
14696                 mutex_exit(&dtrace_meta_lock);
14697
14698                 for (i = 0; i < help->dthps_nprovs; i++) {
14699                         dtrace_helper_provider_destroy(help->dthps_provs[i]);
14700                 }
14701
14702                 kmem_free(help->dthps_provs, help->dthps_maxprovs *
14703                     sizeof (dtrace_helper_provider_t *));
14704         }
14705
14706         mutex_enter(&dtrace_lock);
14707
14708         dtrace_vstate_fini(&help->dthps_vstate);
14709         kmem_free(help->dthps_actions,
14710             sizeof (dtrace_helper_action_t *) * DTRACE_NHELPER_ACTIONS);
14711         kmem_free(help, sizeof (dtrace_helpers_t));
14712
14713         --dtrace_helpers;
14714         mutex_exit(&dtrace_lock);
14715 }
14716
14717 static void
14718 dtrace_helpers_duplicate(proc_t *from, proc_t *to)
14719 {
14720         dtrace_helpers_t *help, *newhelp;
14721         dtrace_helper_action_t *helper, *new, *last;
14722         dtrace_difo_t *dp;
14723         dtrace_vstate_t *vstate;
14724         int i, j, sz, hasprovs = 0;
14725
14726         mutex_enter(&dtrace_lock);
14727         ASSERT(from->p_dtrace_helpers != NULL);
14728         ASSERT(dtrace_helpers > 0);
14729
14730         help = from->p_dtrace_helpers;
14731         newhelp = dtrace_helpers_create(to);
14732         ASSERT(to->p_dtrace_helpers != NULL);
14733
14734         newhelp->dthps_generation = help->dthps_generation;
14735         vstate = &newhelp->dthps_vstate;
14736
14737         /*
14738          * Duplicate the helper actions.
14739          */
14740         for (i = 0; i < DTRACE_NHELPER_ACTIONS; i++) {
14741                 if ((helper = help->dthps_actions[i]) == NULL)
14742                         continue;
14743
14744                 for (last = NULL; helper != NULL; helper = helper->dtha_next) {
14745                         new = kmem_zalloc(sizeof (dtrace_helper_action_t),
14746                             KM_SLEEP);
14747                         new->dtha_generation = helper->dtha_generation;
14748
14749                         if ((dp = helper->dtha_predicate) != NULL) {
14750                                 dp = dtrace_difo_duplicate(dp, vstate);
14751                                 new->dtha_predicate = dp;
14752                         }
14753
14754                         new->dtha_nactions = helper->dtha_nactions;
14755                         sz = sizeof (dtrace_difo_t *) * new->dtha_nactions;
14756                         new->dtha_actions = kmem_alloc(sz, KM_SLEEP);
14757
14758                         for (j = 0; j < new->dtha_nactions; j++) {
14759                                 dtrace_difo_t *dp = helper->dtha_actions[j];
14760
14761                                 ASSERT(dp != NULL);
14762                                 dp = dtrace_difo_duplicate(dp, vstate);
14763                                 new->dtha_actions[j] = dp;
14764                         }
14765
14766                         if (last != NULL) {
14767                                 last->dtha_next = new;
14768                         } else {
14769                                 newhelp->dthps_actions[i] = new;
14770                         }
14771
14772                         last = new;
14773                 }
14774         }
14775
14776         /*
14777          * Duplicate the helper providers and register them with the
14778          * DTrace framework.
14779          */
14780         if (help->dthps_nprovs > 0) {
14781                 newhelp->dthps_nprovs = help->dthps_nprovs;
14782                 newhelp->dthps_maxprovs = help->dthps_nprovs;
14783                 newhelp->dthps_provs = kmem_alloc(newhelp->dthps_nprovs *
14784                     sizeof (dtrace_helper_provider_t *), KM_SLEEP);
14785                 for (i = 0; i < newhelp->dthps_nprovs; i++) {
14786                         newhelp->dthps_provs[i] = help->dthps_provs[i];
14787                         newhelp->dthps_provs[i]->dthp_ref++;
14788                 }
14789
14790                 hasprovs = 1;
14791         }
14792
14793         mutex_exit(&dtrace_lock);
14794
14795         if (hasprovs)
14796                 dtrace_helper_provider_register(to, newhelp, NULL);
14797 }
14798 #endif
14799
14800 #if defined(sun)
14801 /*
14802  * DTrace Hook Functions
14803  */
14804 static void
14805 dtrace_module_loaded(modctl_t *ctl)
14806 {
14807         dtrace_provider_t *prv;
14808
14809         mutex_enter(&dtrace_provider_lock);
14810         mutex_enter(&mod_lock);
14811
14812         ASSERT(ctl->mod_busy);
14813
14814         /*
14815          * We're going to call each providers per-module provide operation
14816          * specifying only this module.
14817          */
14818         for (prv = dtrace_provider; prv != NULL; prv = prv->dtpv_next)
14819                 prv->dtpv_pops.dtps_provide_module(prv->dtpv_arg, ctl);
14820
14821         mutex_exit(&mod_lock);
14822         mutex_exit(&dtrace_provider_lock);
14823
14824         /*
14825          * If we have any retained enablings, we need to match against them.
14826          * Enabling probes requires that cpu_lock be held, and we cannot hold
14827          * cpu_lock here -- it is legal for cpu_lock to be held when loading a
14828          * module.  (In particular, this happens when loading scheduling
14829          * classes.)  So if we have any retained enablings, we need to dispatch
14830          * our task queue to do the match for us.
14831          */
14832         mutex_enter(&dtrace_lock);
14833
14834         if (dtrace_retained == NULL) {
14835                 mutex_exit(&dtrace_lock);
14836                 return;
14837         }
14838
14839         (void) taskq_dispatch(dtrace_taskq,
14840             (task_func_t *)dtrace_enabling_matchall, NULL, TQ_SLEEP);
14841
14842         mutex_exit(&dtrace_lock);
14843
14844         /*
14845          * And now, for a little heuristic sleaze:  in general, we want to
14846          * match modules as soon as they load.  However, we cannot guarantee
14847          * this, because it would lead us to the lock ordering violation
14848          * outlined above.  The common case, of course, is that cpu_lock is
14849          * _not_ held -- so we delay here for a clock tick, hoping that that's
14850          * long enough for the task queue to do its work.  If it's not, it's
14851          * not a serious problem -- it just means that the module that we
14852          * just loaded may not be immediately instrumentable.
14853          */
14854         delay(1);
14855 }
14856
14857 static void
14858 dtrace_module_unloaded(modctl_t *ctl)
14859 {
14860         dtrace_probe_t template, *probe, *first, *next;
14861         dtrace_provider_t *prov;
14862
14863         template.dtpr_mod = ctl->mod_modname;
14864
14865         mutex_enter(&dtrace_provider_lock);
14866         mutex_enter(&mod_lock);
14867         mutex_enter(&dtrace_lock);
14868
14869         if (dtrace_bymod == NULL) {
14870                 /*
14871                  * The DTrace module is loaded (obviously) but not attached;
14872                  * we don't have any work to do.
14873                  */
14874                 mutex_exit(&dtrace_provider_lock);
14875                 mutex_exit(&mod_lock);
14876                 mutex_exit(&dtrace_lock);
14877                 return;
14878         }
14879
14880         for (probe = first = dtrace_hash_lookup(dtrace_bymod, &template);
14881             probe != NULL; probe = probe->dtpr_nextmod) {
14882                 if (probe->dtpr_ecb != NULL) {
14883                         mutex_exit(&dtrace_provider_lock);
14884                         mutex_exit(&mod_lock);
14885                         mutex_exit(&dtrace_lock);
14886
14887                         /*
14888                          * This shouldn't _actually_ be possible -- we're
14889                          * unloading a module that has an enabled probe in it.
14890                          * (It's normally up to the provider to make sure that
14891                          * this can't happen.)  However, because dtps_enable()
14892                          * doesn't have a failure mode, there can be an
14893                          * enable/unload race.  Upshot:  we don't want to
14894                          * assert, but we're not going to disable the
14895                          * probe, either.
14896                          */
14897                         if (dtrace_err_verbose) {
14898                                 cmn_err(CE_WARN, "unloaded module '%s' had "
14899                                     "enabled probes", ctl->mod_modname);
14900                         }
14901
14902                         return;
14903                 }
14904         }
14905
14906         probe = first;
14907
14908         for (first = NULL; probe != NULL; probe = next) {
14909                 ASSERT(dtrace_probes[probe->dtpr_id - 1] == probe);
14910
14911                 dtrace_probes[probe->dtpr_id - 1] = NULL;
14912
14913                 next = probe->dtpr_nextmod;
14914                 dtrace_hash_remove(dtrace_bymod, probe);
14915                 dtrace_hash_remove(dtrace_byfunc, probe);
14916                 dtrace_hash_remove(dtrace_byname, probe);
14917
14918                 if (first == NULL) {
14919                         first = probe;
14920                         probe->dtpr_nextmod = NULL;
14921                 } else {
14922                         probe->dtpr_nextmod = first;
14923                         first = probe;
14924                 }
14925         }
14926
14927         /*
14928          * We've removed all of the module's probes from the hash chains and
14929          * from the probe array.  Now issue a dtrace_sync() to be sure that
14930          * everyone has cleared out from any probe array processing.
14931          */
14932         dtrace_sync();
14933
14934         for (probe = first; probe != NULL; probe = first) {
14935                 first = probe->dtpr_nextmod;
14936                 prov = probe->dtpr_provider;
14937                 prov->dtpv_pops.dtps_destroy(prov->dtpv_arg, probe->dtpr_id,
14938                     probe->dtpr_arg);
14939                 kmem_free(probe->dtpr_mod, strlen(probe->dtpr_mod) + 1);
14940                 kmem_free(probe->dtpr_func, strlen(probe->dtpr_func) + 1);
14941                 kmem_free(probe->dtpr_name, strlen(probe->dtpr_name) + 1);
14942                 vmem_free(dtrace_arena, (void *)(uintptr_t)probe->dtpr_id, 1);
14943                 kmem_free(probe, sizeof (dtrace_probe_t));
14944         }
14945
14946         mutex_exit(&dtrace_lock);
14947         mutex_exit(&mod_lock);
14948         mutex_exit(&dtrace_provider_lock);
14949 }
14950
14951 static void
14952 dtrace_suspend(void)
14953 {
14954         dtrace_probe_foreach(offsetof(dtrace_pops_t, dtps_suspend));
14955 }
14956
14957 static void
14958 dtrace_resume(void)
14959 {
14960         dtrace_probe_foreach(offsetof(dtrace_pops_t, dtps_resume));
14961 }
14962 #endif
14963
14964 static int
14965 dtrace_cpu_setup(cpu_setup_t what, processorid_t cpu)
14966 {
14967         ASSERT(MUTEX_HELD(&cpu_lock));
14968         mutex_enter(&dtrace_lock);
14969
14970         switch (what) {
14971         case CPU_CONFIG: {
14972                 dtrace_state_t *state;
14973                 dtrace_optval_t *opt, rs, c;
14974
14975                 /*
14976                  * For now, we only allocate a new buffer for anonymous state.
14977                  */
14978                 if ((state = dtrace_anon.dta_state) == NULL)
14979                         break;
14980
14981                 if (state->dts_activity != DTRACE_ACTIVITY_ACTIVE)
14982                         break;
14983
14984                 opt = state->dts_options;
14985                 c = opt[DTRACEOPT_CPU];
14986
14987                 if (c != DTRACE_CPUALL && c != DTRACEOPT_UNSET && c != cpu)
14988                         break;
14989
14990                 /*
14991                  * Regardless of what the actual policy is, we're going to
14992                  * temporarily set our resize policy to be manual.  We're
14993                  * also going to temporarily set our CPU option to denote
14994                  * the newly configured CPU.
14995                  */
14996                 rs = opt[DTRACEOPT_BUFRESIZE];
14997                 opt[DTRACEOPT_BUFRESIZE] = DTRACEOPT_BUFRESIZE_MANUAL;
14998                 opt[DTRACEOPT_CPU] = (dtrace_optval_t)cpu;
14999
15000                 (void) dtrace_state_buffers(state);
15001
15002                 opt[DTRACEOPT_BUFRESIZE] = rs;
15003                 opt[DTRACEOPT_CPU] = c;
15004
15005                 break;
15006         }
15007
15008         case CPU_UNCONFIG:
15009                 /*
15010                  * We don't free the buffer in the CPU_UNCONFIG case.  (The
15011                  * buffer will be freed when the consumer exits.)
15012                  */
15013                 break;
15014
15015         default:
15016                 break;
15017         }
15018
15019         mutex_exit(&dtrace_lock);
15020         return (0);
15021 }
15022
15023 #if defined(sun)
15024 static void
15025 dtrace_cpu_setup_initial(processorid_t cpu)
15026 {
15027         (void) dtrace_cpu_setup(CPU_CONFIG, cpu);
15028 }
15029 #endif
15030
15031 static void
15032 dtrace_toxrange_add(uintptr_t base, uintptr_t limit)
15033 {
15034         if (dtrace_toxranges >= dtrace_toxranges_max) {
15035                 int osize, nsize;
15036                 dtrace_toxrange_t *range;
15037
15038                 osize = dtrace_toxranges_max * sizeof (dtrace_toxrange_t);
15039
15040                 if (osize == 0) {
15041                         ASSERT(dtrace_toxrange == NULL);
15042                         ASSERT(dtrace_toxranges_max == 0);
15043                         dtrace_toxranges_max = 1;
15044                 } else {
15045                         dtrace_toxranges_max <<= 1;
15046                 }
15047
15048                 nsize = dtrace_toxranges_max * sizeof (dtrace_toxrange_t);
15049                 range = kmem_zalloc(nsize, KM_SLEEP);
15050
15051                 if (dtrace_toxrange != NULL) {
15052                         ASSERT(osize != 0);
15053                         bcopy(dtrace_toxrange, range, osize);
15054                         kmem_free(dtrace_toxrange, osize);
15055                 }
15056
15057                 dtrace_toxrange = range;
15058         }
15059
15060         ASSERT(dtrace_toxrange[dtrace_toxranges].dtt_base == 0);
15061         ASSERT(dtrace_toxrange[dtrace_toxranges].dtt_limit == 0);
15062
15063         dtrace_toxrange[dtrace_toxranges].dtt_base = base;
15064         dtrace_toxrange[dtrace_toxranges].dtt_limit = limit;
15065         dtrace_toxranges++;
15066 }
15067
15068 /*
15069  * DTrace Driver Cookbook Functions
15070  */
15071 #if defined(sun)
15072 /*ARGSUSED*/
15073 static int
15074 dtrace_attach(dev_info_t *devi, ddi_attach_cmd_t cmd)
15075 {
15076         dtrace_provider_id_t id;
15077         dtrace_state_t *state = NULL;
15078         dtrace_enabling_t *enab;
15079
15080         mutex_enter(&cpu_lock);
15081         mutex_enter(&dtrace_provider_lock);
15082         mutex_enter(&dtrace_lock);
15083
15084         if (ddi_soft_state_init(&dtrace_softstate,
15085             sizeof (dtrace_state_t), 0) != 0) {
15086                 cmn_err(CE_NOTE, "/dev/dtrace failed to initialize soft state");
15087                 mutex_exit(&cpu_lock);
15088                 mutex_exit(&dtrace_provider_lock);
15089                 mutex_exit(&dtrace_lock);
15090                 return (DDI_FAILURE);
15091         }
15092
15093         if (ddi_create_minor_node(devi, DTRACEMNR_DTRACE, S_IFCHR,
15094             DTRACEMNRN_DTRACE, DDI_PSEUDO, NULL) == DDI_FAILURE ||
15095             ddi_create_minor_node(devi, DTRACEMNR_HELPER, S_IFCHR,
15096             DTRACEMNRN_HELPER, DDI_PSEUDO, NULL) == DDI_FAILURE) {
15097                 cmn_err(CE_NOTE, "/dev/dtrace couldn't create minor nodes");
15098                 ddi_remove_minor_node(devi, NULL);
15099                 ddi_soft_state_fini(&dtrace_softstate);
15100                 mutex_exit(&cpu_lock);
15101                 mutex_exit(&dtrace_provider_lock);
15102                 mutex_exit(&dtrace_lock);
15103                 return (DDI_FAILURE);
15104         }
15105
15106         ddi_report_dev(devi);
15107         dtrace_devi = devi;
15108
15109         dtrace_modload = dtrace_module_loaded;
15110         dtrace_modunload = dtrace_module_unloaded;
15111         dtrace_cpu_init = dtrace_cpu_setup_initial;
15112         dtrace_helpers_cleanup = dtrace_helpers_destroy;
15113         dtrace_helpers_fork = dtrace_helpers_duplicate;
15114         dtrace_cpustart_init = dtrace_suspend;
15115         dtrace_cpustart_fini = dtrace_resume;
15116         dtrace_debugger_init = dtrace_suspend;
15117         dtrace_debugger_fini = dtrace_resume;
15118
15119         register_cpu_setup_func((cpu_setup_func_t *)dtrace_cpu_setup, NULL);
15120
15121         ASSERT(MUTEX_HELD(&cpu_lock));
15122
15123         dtrace_arena = vmem_create("dtrace", (void *)1, UINT32_MAX, 1,
15124             NULL, NULL, NULL, 0, VM_SLEEP | VMC_IDENTIFIER);
15125         dtrace_minor = vmem_create("dtrace_minor", (void *)DTRACEMNRN_CLONE,
15126             UINT32_MAX - DTRACEMNRN_CLONE, 1, NULL, NULL, NULL, 0,
15127             VM_SLEEP | VMC_IDENTIFIER);
15128         dtrace_taskq = taskq_create("dtrace_taskq", 1, maxclsyspri,
15129             1, INT_MAX, 0);
15130
15131         dtrace_state_cache = kmem_cache_create("dtrace_state_cache",
15132             sizeof (dtrace_dstate_percpu_t) * NCPU, DTRACE_STATE_ALIGN,
15133             NULL, NULL, NULL, NULL, NULL, 0);
15134
15135         ASSERT(MUTEX_HELD(&cpu_lock));
15136         dtrace_bymod = dtrace_hash_create(offsetof(dtrace_probe_t, dtpr_mod),
15137             offsetof(dtrace_probe_t, dtpr_nextmod),
15138             offsetof(dtrace_probe_t, dtpr_prevmod));
15139
15140         dtrace_byfunc = dtrace_hash_create(offsetof(dtrace_probe_t, dtpr_func),
15141             offsetof(dtrace_probe_t, dtpr_nextfunc),
15142             offsetof(dtrace_probe_t, dtpr_prevfunc));
15143
15144         dtrace_byname = dtrace_hash_create(offsetof(dtrace_probe_t, dtpr_name),
15145             offsetof(dtrace_probe_t, dtpr_nextname),
15146             offsetof(dtrace_probe_t, dtpr_prevname));
15147
15148         if (dtrace_retain_max < 1) {
15149                 cmn_err(CE_WARN, "illegal value (%lu) for dtrace_retain_max; "
15150                     "setting to 1", dtrace_retain_max);
15151                 dtrace_retain_max = 1;
15152         }
15153
15154         /*
15155          * Now discover our toxic ranges.
15156          */
15157         dtrace_toxic_ranges(dtrace_toxrange_add);
15158
15159         /*
15160          * Before we register ourselves as a provider to our own framework,
15161          * we would like to assert that dtrace_provider is NULL -- but that's
15162          * not true if we were loaded as a dependency of a DTrace provider.
15163          * Once we've registered, we can assert that dtrace_provider is our
15164          * pseudo provider.
15165          */
15166         (void) dtrace_register("dtrace", &dtrace_provider_attr,
15167             DTRACE_PRIV_NONE, 0, &dtrace_provider_ops, NULL, &id);
15168
15169         ASSERT(dtrace_provider != NULL);
15170         ASSERT((dtrace_provider_id_t)dtrace_provider == id);
15171
15172         dtrace_probeid_begin = dtrace_probe_create((dtrace_provider_id_t)
15173             dtrace_provider, NULL, NULL, "BEGIN", 0, NULL);
15174         dtrace_probeid_end = dtrace_probe_create((dtrace_provider_id_t)
15175             dtrace_provider, NULL, NULL, "END", 0, NULL);
15176         dtrace_probeid_error = dtrace_probe_create((dtrace_provider_id_t)
15177             dtrace_provider, NULL, NULL, "ERROR", 1, NULL);
15178
15179         dtrace_anon_property();
15180         mutex_exit(&cpu_lock);
15181
15182         /*
15183          * If DTrace helper tracing is enabled, we need to allocate the
15184          * trace buffer and initialize the values.
15185          */
15186         if (dtrace_helptrace_enabled) {
15187                 ASSERT(dtrace_helptrace_buffer == NULL);
15188                 dtrace_helptrace_buffer =
15189                     kmem_zalloc(dtrace_helptrace_bufsize, KM_SLEEP);
15190                 dtrace_helptrace_next = 0;
15191         }
15192
15193         /*
15194          * If there are already providers, we must ask them to provide their
15195          * probes, and then match any anonymous enabling against them.  Note
15196          * that there should be no other retained enablings at this time:
15197          * the only retained enablings at this time should be the anonymous
15198          * enabling.
15199          */
15200         if (dtrace_anon.dta_enabling != NULL) {
15201                 ASSERT(dtrace_retained == dtrace_anon.dta_enabling);
15202
15203                 dtrace_enabling_provide(NULL);
15204                 state = dtrace_anon.dta_state;
15205
15206                 /*
15207                  * We couldn't hold cpu_lock across the above call to
15208                  * dtrace_enabling_provide(), but we must hold it to actually
15209                  * enable the probes.  We have to drop all of our locks, pick
15210                  * up cpu_lock, and regain our locks before matching the
15211                  * retained anonymous enabling.
15212                  */
15213                 mutex_exit(&dtrace_lock);
15214                 mutex_exit(&dtrace_provider_lock);
15215
15216                 mutex_enter(&cpu_lock);
15217                 mutex_enter(&dtrace_provider_lock);
15218                 mutex_enter(&dtrace_lock);
15219
15220                 if ((enab = dtrace_anon.dta_enabling) != NULL)
15221                         (void) dtrace_enabling_match(enab, NULL);
15222
15223                 mutex_exit(&cpu_lock);
15224         }
15225
15226         mutex_exit(&dtrace_lock);
15227         mutex_exit(&dtrace_provider_lock);
15228
15229         if (state != NULL) {
15230                 /*
15231                  * If we created any anonymous state, set it going now.
15232                  */
15233                 (void) dtrace_state_go(state, &dtrace_anon.dta_beganon);
15234         }
15235
15236         return (DDI_SUCCESS);
15237 }
15238 #endif
15239
15240 #if !defined(sun)
15241 static void
15242 dtrace_dtr(void *data __unused)
15243 {
15244 }
15245 #endif
15246
15247 /*ARGSUSED*/
15248 static int
15249 #if defined(sun)
15250 dtrace_open(dev_t *devp, int flag, int otyp, cred_t *cred_p)
15251 #else
15252 dtrace_open(struct cdev *dev, int oflags, int devtype, struct thread *td)
15253 #endif
15254 {
15255         dtrace_state_t *state;
15256         uint32_t priv;
15257         uid_t uid;
15258         zoneid_t zoneid;
15259
15260 #if defined(sun)
15261         if (getminor(*devp) == DTRACEMNRN_HELPER)
15262                 return (0);
15263
15264         /*
15265          * If this wasn't an open with the "helper" minor, then it must be
15266          * the "dtrace" minor.
15267          */
15268         ASSERT(getminor(*devp) == DTRACEMNRN_DTRACE);
15269 #else
15270         cred_t *cred_p = NULL;
15271
15272         cred_p = dev->si_cred;
15273 #endif
15274
15275         /*
15276          * If no DTRACE_PRIV_* bits are set in the credential, then the
15277          * caller lacks sufficient permission to do anything with DTrace.
15278          */
15279         dtrace_cred2priv(cred_p, &priv, &uid, &zoneid);
15280         if (priv == DTRACE_PRIV_NONE) {
15281                 return (EACCES);
15282         }
15283
15284         /*
15285          * Ask all providers to provide all their probes.
15286          */
15287         mutex_enter(&dtrace_provider_lock);
15288         dtrace_probe_provide(NULL, NULL);
15289         mutex_exit(&dtrace_provider_lock);
15290
15291         mutex_enter(&cpu_lock);
15292         mutex_enter(&dtrace_lock);
15293         dtrace_opens++;
15294         dtrace_membar_producer();
15295
15296 #if defined(sun)
15297         /*
15298          * If the kernel debugger is active (that is, if the kernel debugger
15299          * modified text in some way), we won't allow the open.
15300          */
15301         if (kdi_dtrace_set(KDI_DTSET_DTRACE_ACTIVATE) != 0) {
15302                 dtrace_opens--;
15303                 mutex_exit(&cpu_lock);
15304                 mutex_exit(&dtrace_lock);
15305                 return (EBUSY);
15306         }
15307
15308         state = dtrace_state_create(devp, cred_p);
15309 #else
15310         state = dtrace_state_create(dev);
15311         devfs_set_cdevpriv(state, dtrace_dtr);
15312 #endif
15313
15314         mutex_exit(&cpu_lock);
15315
15316         if (state == NULL) {
15317 #if defined(sun)
15318                 if (--dtrace_opens == 0)
15319                         (void) kdi_dtrace_set(KDI_DTSET_DTRACE_DEACTIVATE);
15320 #else
15321                 --dtrace_opens;
15322 #endif
15323                 mutex_exit(&dtrace_lock);
15324                 return (EAGAIN);
15325         }
15326
15327         mutex_exit(&dtrace_lock);
15328
15329         return (0);
15330 }
15331
15332 /*ARGSUSED*/
15333 static int
15334 #if defined(sun)
15335 dtrace_close(dev_t dev, int flag, int otyp, cred_t *cred_p)
15336 #else
15337 dtrace_close(struct cdev *dev, int flags, int fmt __unused, struct thread *td)
15338 #endif
15339 {
15340 #if defined(sun)
15341         minor_t minor = getminor(dev);
15342         dtrace_state_t *state;
15343
15344         if (minor == DTRACEMNRN_HELPER)
15345                 return (0);
15346
15347         state = ddi_get_soft_state(dtrace_softstate, minor);
15348 #else
15349         dtrace_state_t *state;
15350         devfs_get_cdevpriv((void **) &state);
15351
15352 #endif
15353
15354         mutex_enter(&cpu_lock);
15355         mutex_enter(&dtrace_lock);
15356
15357         if (state != NULL) {
15358                 if (state->dts_anon) {
15359                         /*
15360                          * There is anonymous state. Destroy that first.
15361                          */
15362                         ASSERT(dtrace_anon.dta_state == NULL);
15363                         dtrace_state_destroy(state->dts_anon);
15364                 }
15365
15366                 dtrace_state_destroy(state);
15367
15368 #if !defined(sun)
15369                 kmem_free(state, 0);
15370                 devfs_clear_cdevpriv();
15371 #endif
15372         }
15373
15374         ASSERT(dtrace_opens > 0);
15375 #if defined(sun)
15376         if (--dtrace_opens == 0)
15377                 (void) kdi_dtrace_set(KDI_DTSET_DTRACE_DEACTIVATE);
15378 #else
15379         --dtrace_opens;
15380 #endif
15381
15382         mutex_exit(&dtrace_lock);
15383         mutex_exit(&cpu_lock);
15384
15385         return (0);
15386 }
15387
15388 #if defined(sun)
15389 /*ARGSUSED*/
15390 static int
15391 dtrace_ioctl_helper(int cmd, intptr_t arg, int *rv)
15392 {
15393         int rval;
15394         dof_helper_t help, *dhp = NULL;
15395
15396         switch (cmd) {
15397         case DTRACEHIOC_ADDDOF:
15398                 if (copyin((void *)arg, &help, sizeof (help)) != 0) {
15399                         dtrace_dof_error(NULL, "failed to copyin DOF helper");
15400                         return (EFAULT);
15401                 }
15402
15403                 dhp = &help;
15404                 arg = (intptr_t)help.dofhp_dof;
15405                 /*FALLTHROUGH*/
15406
15407         case DTRACEHIOC_ADD: {
15408                 dof_hdr_t *dof = dtrace_dof_copyin(arg, &rval);
15409
15410                 if (dof == NULL)
15411                         return (rval);
15412
15413                 mutex_enter(&dtrace_lock);
15414
15415                 /*
15416                  * dtrace_helper_slurp() takes responsibility for the dof --
15417                  * it may free it now or it may save it and free it later.
15418                  */
15419                 if ((rval = dtrace_helper_slurp(dof, dhp)) != -1) {
15420                         *rv = rval;
15421                         rval = 0;
15422                 } else {
15423                         rval = EINVAL;
15424                 }
15425
15426                 mutex_exit(&dtrace_lock);
15427                 return (rval);
15428         }
15429
15430         case DTRACEHIOC_REMOVE: {
15431                 mutex_enter(&dtrace_lock);
15432                 rval = dtrace_helper_destroygen(arg);
15433                 mutex_exit(&dtrace_lock);
15434
15435                 return (rval);
15436         }
15437
15438         default:
15439                 break;
15440         }
15441
15442         return (ENOTTY);
15443 }
15444
15445 /*ARGSUSED*/
15446 static int
15447 dtrace_ioctl(dev_t dev, int cmd, intptr_t arg, int md, cred_t *cr, int *rv)
15448 {
15449         minor_t minor = getminor(dev);
15450         dtrace_state_t *state;
15451         int rval;
15452
15453         if (minor == DTRACEMNRN_HELPER)
15454                 return (dtrace_ioctl_helper(cmd, arg, rv));
15455
15456         state = ddi_get_soft_state(dtrace_softstate, minor);
15457
15458         if (state->dts_anon) {
15459                 ASSERT(dtrace_anon.dta_state == NULL);
15460                 state = state->dts_anon;
15461         }
15462
15463         switch (cmd) {
15464         case DTRACEIOC_PROVIDER: {
15465                 dtrace_providerdesc_t pvd;
15466                 dtrace_provider_t *pvp;
15467
15468                 if (copyin((void *)arg, &pvd, sizeof (pvd)) != 0)
15469                         return (EFAULT);
15470
15471                 pvd.dtvd_name[DTRACE_PROVNAMELEN - 1] = '\0';
15472                 mutex_enter(&dtrace_provider_lock);
15473
15474                 for (pvp = dtrace_provider; pvp != NULL; pvp = pvp->dtpv_next) {
15475                         if (strcmp(pvp->dtpv_name, pvd.dtvd_name) == 0)
15476                                 break;
15477                 }
15478
15479                 mutex_exit(&dtrace_provider_lock);
15480
15481                 if (pvp == NULL)
15482                         return (ESRCH);
15483
15484                 bcopy(&pvp->dtpv_priv, &pvd.dtvd_priv, sizeof (dtrace_ppriv_t));
15485                 bcopy(&pvp->dtpv_attr, &pvd.dtvd_attr, sizeof (dtrace_pattr_t));
15486
15487                 if (copyout(&pvd, (void *)arg, sizeof (pvd)) != 0)
15488                         return (EFAULT);
15489
15490                 return (0);
15491         }
15492
15493         case DTRACEIOC_EPROBE: {
15494                 dtrace_eprobedesc_t epdesc;
15495                 dtrace_ecb_t *ecb;
15496                 dtrace_action_t *act;
15497                 void *buf;
15498                 size_t size;
15499                 uintptr_t dest;
15500                 int nrecs;
15501
15502                 if (copyin((void *)arg, &epdesc, sizeof (epdesc)) != 0)
15503                         return (EFAULT);
15504
15505                 mutex_enter(&dtrace_lock);
15506
15507                 if ((ecb = dtrace_epid2ecb(state, epdesc.dtepd_epid)) == NULL) {
15508                         mutex_exit(&dtrace_lock);
15509                         return (EINVAL);
15510                 }
15511
15512                 if (ecb->dte_probe == NULL) {
15513                         mutex_exit(&dtrace_lock);
15514                         return (EINVAL);
15515                 }
15516
15517                 epdesc.dtepd_probeid = ecb->dte_probe->dtpr_id;
15518                 epdesc.dtepd_uarg = ecb->dte_uarg;
15519                 epdesc.dtepd_size = ecb->dte_size;
15520
15521                 nrecs = epdesc.dtepd_nrecs;
15522                 epdesc.dtepd_nrecs = 0;
15523                 for (act = ecb->dte_action; act != NULL; act = act->dta_next) {
15524                         if (DTRACEACT_ISAGG(act->dta_kind) || act->dta_intuple)
15525                                 continue;
15526
15527                         epdesc.dtepd_nrecs++;
15528                 }
15529
15530                 /*
15531                  * Now that we have the size, we need to allocate a temporary
15532                  * buffer in which to store the complete description.  We need
15533                  * the temporary buffer to be able to drop dtrace_lock()
15534                  * across the copyout(), below.
15535                  */
15536                 size = sizeof (dtrace_eprobedesc_t) +
15537                     (epdesc.dtepd_nrecs * sizeof (dtrace_recdesc_t));
15538
15539                 buf = kmem_alloc(size, KM_SLEEP);
15540                 dest = (uintptr_t)buf;
15541
15542                 bcopy(&epdesc, (void *)dest, sizeof (epdesc));
15543                 dest += offsetof(dtrace_eprobedesc_t, dtepd_rec[0]);
15544
15545                 for (act = ecb->dte_action; act != NULL; act = act->dta_next) {
15546                         if (DTRACEACT_ISAGG(act->dta_kind) || act->dta_intuple)
15547                                 continue;
15548
15549                         if (nrecs-- == 0)
15550                                 break;
15551
15552                         bcopy(&act->dta_rec, (void *)dest,
15553                             sizeof (dtrace_recdesc_t));
15554                         dest += sizeof (dtrace_recdesc_t);
15555                 }
15556
15557                 mutex_exit(&dtrace_lock);
15558
15559                 if (copyout(buf, (void *)arg, dest - (uintptr_t)buf) != 0) {
15560                         kmem_free(buf, size);
15561                         return (EFAULT);
15562                 }
15563
15564                 kmem_free(buf, size);
15565                 return (0);
15566         }
15567
15568         case DTRACEIOC_AGGDESC: {
15569                 dtrace_aggdesc_t aggdesc;
15570                 dtrace_action_t *act;
15571                 dtrace_aggregation_t *agg;
15572                 int nrecs;
15573                 uint32_t offs;
15574                 dtrace_recdesc_t *lrec;
15575                 void *buf;
15576                 size_t size;
15577                 uintptr_t dest;
15578
15579                 if (copyin((void *)arg, &aggdesc, sizeof (aggdesc)) != 0)
15580                         return (EFAULT);
15581
15582                 mutex_enter(&dtrace_lock);
15583
15584                 if ((agg = dtrace_aggid2agg(state, aggdesc.dtagd_id)) == NULL) {
15585                         mutex_exit(&dtrace_lock);
15586                         return (EINVAL);
15587                 }
15588
15589                 aggdesc.dtagd_epid = agg->dtag_ecb->dte_epid;
15590
15591                 nrecs = aggdesc.dtagd_nrecs;
15592                 aggdesc.dtagd_nrecs = 0;
15593
15594                 offs = agg->dtag_base;
15595                 lrec = &agg->dtag_action.dta_rec;
15596                 aggdesc.dtagd_size = lrec->dtrd_offset + lrec->dtrd_size - offs;
15597
15598                 for (act = agg->dtag_first; ; act = act->dta_next) {
15599                         ASSERT(act->dta_intuple ||
15600                             DTRACEACT_ISAGG(act->dta_kind));
15601
15602                         /*
15603                          * If this action has a record size of zero, it
15604                          * denotes an argument to the aggregating action.
15605                          * Because the presence of this record doesn't (or
15606                          * shouldn't) affect the way the data is interpreted,
15607                          * we don't copy it out to save user-level the
15608                          * confusion of dealing with a zero-length record.
15609                          */
15610                         if (act->dta_rec.dtrd_size == 0) {
15611                                 ASSERT(agg->dtag_hasarg);
15612                                 continue;
15613                         }
15614
15615                         aggdesc.dtagd_nrecs++;
15616
15617                         if (act == &agg->dtag_action)
15618                                 break;
15619                 }
15620
15621                 /*
15622                  * Now that we have the size, we need to allocate a temporary
15623                  * buffer in which to store the complete description.  We need
15624                  * the temporary buffer to be able to drop dtrace_lock()
15625                  * across the copyout(), below.
15626                  */
15627                 size = sizeof (dtrace_aggdesc_t) +
15628                     (aggdesc.dtagd_nrecs * sizeof (dtrace_recdesc_t));
15629
15630                 buf = kmem_alloc(size, KM_SLEEP);
15631                 dest = (uintptr_t)buf;
15632
15633                 bcopy(&aggdesc, (void *)dest, sizeof (aggdesc));
15634                 dest += offsetof(dtrace_aggdesc_t, dtagd_rec[0]);
15635
15636                 for (act = agg->dtag_first; ; act = act->dta_next) {
15637                         dtrace_recdesc_t rec = act->dta_rec;
15638
15639                         /*
15640                          * See the comment in the above loop for why we pass
15641                          * over zero-length records.
15642                          */
15643                         if (rec.dtrd_size == 0) {
15644                                 ASSERT(agg->dtag_hasarg);
15645                                 continue;
15646                         }
15647
15648                         if (nrecs-- == 0)
15649                                 break;
15650
15651                         rec.dtrd_offset -= offs;
15652                         bcopy(&rec, (void *)dest, sizeof (rec));
15653                         dest += sizeof (dtrace_recdesc_t);
15654
15655                         if (act == &agg->dtag_action)
15656                                 break;
15657                 }
15658
15659                 mutex_exit(&dtrace_lock);
15660
15661                 if (copyout(buf, (void *)arg, dest - (uintptr_t)buf) != 0) {
15662                         kmem_free(buf, size);
15663                         return (EFAULT);
15664                 }
15665
15666                 kmem_free(buf, size);
15667                 return (0);
15668         }
15669
15670         case DTRACEIOC_ENABLE: {
15671                 dof_hdr_t *dof;
15672                 dtrace_enabling_t *enab = NULL;
15673                 dtrace_vstate_t *vstate;
15674                 int err = 0;
15675
15676                 *rv = 0;
15677
15678                 /*
15679                  * If a NULL argument has been passed, we take this as our
15680                  * cue to reevaluate our enablings.
15681                  */
15682                 if (arg == NULL) {
15683                         dtrace_enabling_matchall();
15684
15685                         return (0);
15686                 }
15687
15688                 if ((dof = dtrace_dof_copyin(arg, &rval)) == NULL)
15689                         return (rval);
15690
15691                 mutex_enter(&cpu_lock);
15692                 mutex_enter(&dtrace_lock);
15693                 vstate = &state->dts_vstate;
15694
15695                 if (state->dts_activity != DTRACE_ACTIVITY_INACTIVE) {
15696                         mutex_exit(&dtrace_lock);
15697                         mutex_exit(&cpu_lock);
15698                         dtrace_dof_destroy(dof);
15699                         return (EBUSY);
15700                 }
15701
15702                 if (dtrace_dof_slurp(dof, vstate, cr, &enab, 0, B_TRUE) != 0) {
15703                         mutex_exit(&dtrace_lock);
15704                         mutex_exit(&cpu_lock);
15705                         dtrace_dof_destroy(dof);
15706                         return (EINVAL);
15707                 }
15708
15709                 if ((rval = dtrace_dof_options(dof, state)) != 0) {
15710                         dtrace_enabling_destroy(enab);
15711                         mutex_exit(&dtrace_lock);
15712                         mutex_exit(&cpu_lock);
15713                         dtrace_dof_destroy(dof);
15714                         return (rval);
15715                 }
15716
15717                 if ((err = dtrace_enabling_match(enab, rv)) == 0) {
15718                         err = dtrace_enabling_retain(enab);
15719                 } else {
15720                         dtrace_enabling_destroy(enab);
15721                 }
15722
15723                 mutex_exit(&cpu_lock);
15724                 mutex_exit(&dtrace_lock);
15725                 dtrace_dof_destroy(dof);
15726
15727                 return (err);
15728         }
15729
15730         case DTRACEIOC_REPLICATE: {
15731                 dtrace_repldesc_t desc;
15732                 dtrace_probedesc_t *match = &desc.dtrpd_match;
15733                 dtrace_probedesc_t *create = &desc.dtrpd_create;
15734                 int err;
15735
15736                 if (copyin((void *)arg, &desc, sizeof (desc)) != 0)
15737                         return (EFAULT);
15738
15739                 match->dtpd_provider[DTRACE_PROVNAMELEN - 1] = '\0';
15740                 match->dtpd_mod[DTRACE_MODNAMELEN - 1] = '\0';
15741                 match->dtpd_func[DTRACE_FUNCNAMELEN - 1] = '\0';
15742                 match->dtpd_name[DTRACE_NAMELEN - 1] = '\0';
15743
15744                 create->dtpd_provider[DTRACE_PROVNAMELEN - 1] = '\0';
15745                 create->dtpd_mod[DTRACE_MODNAMELEN - 1] = '\0';
15746                 create->dtpd_func[DTRACE_FUNCNAMELEN - 1] = '\0';
15747                 create->dtpd_name[DTRACE_NAMELEN - 1] = '\0';
15748
15749                 mutex_enter(&dtrace_lock);
15750                 err = dtrace_enabling_replicate(state, match, create);
15751                 mutex_exit(&dtrace_lock);
15752
15753                 return (err);
15754         }
15755
15756         case DTRACEIOC_PROBEMATCH:
15757         case DTRACEIOC_PROBES: {
15758                 dtrace_probe_t *probe = NULL;
15759                 dtrace_probedesc_t desc;
15760                 dtrace_probekey_t pkey;
15761                 dtrace_id_t i;
15762                 int m = 0;
15763                 uint32_t priv;
15764                 uid_t uid;
15765                 zoneid_t zoneid;
15766
15767                 if (copyin((void *)arg, &desc, sizeof (desc)) != 0)
15768                         return (EFAULT);
15769
15770                 desc.dtpd_provider[DTRACE_PROVNAMELEN - 1] = '\0';
15771                 desc.dtpd_mod[DTRACE_MODNAMELEN - 1] = '\0';
15772                 desc.dtpd_func[DTRACE_FUNCNAMELEN - 1] = '\0';
15773                 desc.dtpd_name[DTRACE_NAMELEN - 1] = '\0';
15774
15775                 /*
15776                  * Before we attempt to match this probe, we want to give
15777                  * all providers the opportunity to provide it.
15778                  */
15779                 if (desc.dtpd_id == DTRACE_IDNONE) {
15780                         mutex_enter(&dtrace_provider_lock);
15781                         dtrace_probe_provide(&desc, NULL);
15782                         mutex_exit(&dtrace_provider_lock);
15783                         desc.dtpd_id++;
15784                 }
15785
15786                 if (cmd == DTRACEIOC_PROBEMATCH)  {
15787                         dtrace_probekey(&desc, &pkey);
15788                         pkey.dtpk_id = DTRACE_IDNONE;
15789                 }
15790
15791                 dtrace_cred2priv(cr, &priv, &uid, &zoneid);
15792
15793                 mutex_enter(&dtrace_lock);
15794
15795                 if (cmd == DTRACEIOC_PROBEMATCH) {
15796                         for (i = desc.dtpd_id; i <= dtrace_nprobes; i++) {
15797                                 if ((probe = dtrace_probes[i - 1]) != NULL &&
15798                                     (m = dtrace_match_probe(probe, &pkey,
15799                                     priv, uid, zoneid)) != 0)
15800                                         break;
15801                         }
15802
15803                         if (m < 0) {
15804                                 mutex_exit(&dtrace_lock);
15805                                 return (EINVAL);
15806                         }
15807
15808                 } else {
15809                         for (i = desc.dtpd_id; i <= dtrace_nprobes; i++) {
15810                                 if ((probe = dtrace_probes[i - 1]) != NULL &&
15811                                     dtrace_match_priv(probe, priv, uid, zoneid))
15812                                         break;
15813                         }
15814                 }
15815
15816                 if (probe == NULL) {
15817                         mutex_exit(&dtrace_lock);
15818                         return (ESRCH);
15819                 }
15820
15821                 dtrace_probe_description(probe, &desc);
15822                 mutex_exit(&dtrace_lock);
15823
15824                 if (copyout(&desc, (void *)arg, sizeof (desc)) != 0)
15825                         return (EFAULT);
15826
15827                 return (0);
15828         }
15829
15830         case DTRACEIOC_PROBEARG: {
15831                 dtrace_argdesc_t desc;
15832                 dtrace_probe_t *probe;
15833                 dtrace_provider_t *prov;
15834
15835                 if (copyin((void *)arg, &desc, sizeof (desc)) != 0)
15836                         return (EFAULT);
15837
15838                 if (desc.dtargd_id == DTRACE_IDNONE)
15839                         return (EINVAL);
15840
15841                 if (desc.dtargd_ndx == DTRACE_ARGNONE)
15842                         return (EINVAL);
15843
15844                 mutex_enter(&dtrace_provider_lock);
15845                 mutex_enter(&mod_lock);
15846                 mutex_enter(&dtrace_lock);
15847
15848                 if (desc.dtargd_id > dtrace_nprobes) {
15849                         mutex_exit(&dtrace_lock);
15850                         mutex_exit(&mod_lock);
15851                         mutex_exit(&dtrace_provider_lock);
15852                         return (EINVAL);
15853                 }
15854
15855                 if ((probe = dtrace_probes[desc.dtargd_id - 1]) == NULL) {
15856                         mutex_exit(&dtrace_lock);
15857                         mutex_exit(&mod_lock);
15858                         mutex_exit(&dtrace_provider_lock);
15859                         return (EINVAL);
15860                 }
15861
15862                 mutex_exit(&dtrace_lock);
15863
15864                 prov = probe->dtpr_provider;
15865
15866                 if (prov->dtpv_pops.dtps_getargdesc == NULL) {
15867                         /*
15868                          * There isn't any typed information for this probe.
15869                          * Set the argument number to DTRACE_ARGNONE.
15870                          */
15871                         desc.dtargd_ndx = DTRACE_ARGNONE;
15872                 } else {
15873                         desc.dtargd_native[0] = '\0';
15874                         desc.dtargd_xlate[0] = '\0';
15875                         desc.dtargd_mapping = desc.dtargd_ndx;
15876
15877                         prov->dtpv_pops.dtps_getargdesc(prov->dtpv_arg,
15878                             probe->dtpr_id, probe->dtpr_arg, &desc);
15879                 }
15880
15881                 mutex_exit(&mod_lock);
15882                 mutex_exit(&dtrace_provider_lock);
15883
15884                 if (copyout(&desc, (void *)arg, sizeof (desc)) != 0)
15885                         return (EFAULT);
15886
15887                 return (0);
15888         }
15889
15890         case DTRACEIOC_GO: {
15891                 processorid_t cpuid;
15892                 rval = dtrace_state_go(state, &cpuid);
15893
15894                 if (rval != 0)
15895                         return (rval);
15896
15897                 if (copyout(&cpuid, (void *)arg, sizeof (cpuid)) != 0)
15898                         return (EFAULT);
15899
15900                 return (0);
15901         }
15902
15903         case DTRACEIOC_STOP: {
15904                 processorid_t cpuid;
15905
15906                 mutex_enter(&dtrace_lock);
15907                 rval = dtrace_state_stop(state, &cpuid);
15908                 mutex_exit(&dtrace_lock);
15909
15910                 if (rval != 0)
15911                         return (rval);
15912
15913                 if (copyout(&cpuid, (void *)arg, sizeof (cpuid)) != 0)
15914                         return (EFAULT);
15915
15916                 return (0);
15917         }
15918
15919         case DTRACEIOC_DOFGET: {
15920                 dof_hdr_t hdr, *dof;
15921                 uint64_t len;
15922
15923                 if (copyin((void *)arg, &hdr, sizeof (hdr)) != 0)
15924                         return (EFAULT);
15925
15926                 mutex_enter(&dtrace_lock);
15927                 dof = dtrace_dof_create(state);
15928                 mutex_exit(&dtrace_lock);
15929
15930                 len = MIN(hdr.dofh_loadsz, dof->dofh_loadsz);
15931                 rval = copyout(dof, (void *)arg, len);
15932                 dtrace_dof_destroy(dof);
15933
15934                 return (rval == 0 ? 0 : EFAULT);
15935         }
15936
15937         case DTRACEIOC_AGGSNAP:
15938         case DTRACEIOC_BUFSNAP: {
15939                 dtrace_bufdesc_t desc;
15940                 caddr_t cached;
15941                 dtrace_buffer_t *buf;
15942
15943                 if (copyin((void *)arg, &desc, sizeof (desc)) != 0)
15944                         return (EFAULT);
15945
15946                 if (desc.dtbd_cpu < 0 || desc.dtbd_cpu >= NCPU)
15947                         return (EINVAL);
15948
15949                 mutex_enter(&dtrace_lock);
15950
15951                 if (cmd == DTRACEIOC_BUFSNAP) {
15952                         buf = &state->dts_buffer[desc.dtbd_cpu];
15953                 } else {
15954                         buf = &state->dts_aggbuffer[desc.dtbd_cpu];
15955                 }
15956
15957                 if (buf->dtb_flags & (DTRACEBUF_RING | DTRACEBUF_FILL)) {
15958                         size_t sz = buf->dtb_offset;
15959
15960                         if (state->dts_activity != DTRACE_ACTIVITY_STOPPED) {
15961                                 mutex_exit(&dtrace_lock);
15962                                 return (EBUSY);
15963                         }
15964
15965                         /*
15966                          * If this buffer has already been consumed, we're
15967                          * going to indicate that there's nothing left here
15968                          * to consume.
15969                          */
15970                         if (buf->dtb_flags & DTRACEBUF_CONSUMED) {
15971                                 mutex_exit(&dtrace_lock);
15972
15973                                 desc.dtbd_size = 0;
15974                                 desc.dtbd_drops = 0;
15975                                 desc.dtbd_errors = 0;
15976                                 desc.dtbd_oldest = 0;
15977                                 sz = sizeof (desc);
15978
15979                                 if (copyout(&desc, (void *)arg, sz) != 0)
15980                                         return (EFAULT);
15981
15982                                 return (0);
15983                         }
15984
15985                         /*
15986                          * If this is a ring buffer that has wrapped, we want
15987                          * to copy the whole thing out.
15988                          */
15989                         if (buf->dtb_flags & DTRACEBUF_WRAPPED) {
15990                                 dtrace_buffer_polish(buf);
15991                                 sz = buf->dtb_size;
15992                         }
15993
15994                         if (copyout(buf->dtb_tomax, desc.dtbd_data, sz) != 0) {
15995                                 mutex_exit(&dtrace_lock);
15996                                 return (EFAULT);
15997                         }
15998
15999                         desc.dtbd_size = sz;
16000                         desc.dtbd_drops = buf->dtb_drops;
16001                         desc.dtbd_errors = buf->dtb_errors;
16002                         desc.dtbd_oldest = buf->dtb_xamot_offset;
16003
16004                         mutex_exit(&dtrace_lock);
16005
16006                         if (copyout(&desc, (void *)arg, sizeof (desc)) != 0)
16007                                 return (EFAULT);
16008
16009                         buf->dtb_flags |= DTRACEBUF_CONSUMED;
16010
16011                         return (0);
16012                 }
16013
16014                 if (buf->dtb_tomax == NULL) {
16015                         ASSERT(buf->dtb_xamot == NULL);
16016                         mutex_exit(&dtrace_lock);
16017                         return (ENOENT);
16018                 }
16019
16020                 cached = buf->dtb_tomax;
16021                 ASSERT(!(buf->dtb_flags & DTRACEBUF_NOSWITCH));
16022
16023                 dtrace_xcall(desc.dtbd_cpu,
16024                     (dtrace_xcall_t)dtrace_buffer_switch, buf);
16025
16026                 state->dts_errors += buf->dtb_xamot_errors;
16027
16028                 /*
16029                  * If the buffers did not actually switch, then the cross call
16030                  * did not take place -- presumably because the given CPU is
16031                  * not in the ready set.  If this is the case, we'll return
16032                  * ENOENT.
16033                  */
16034                 if (buf->dtb_tomax == cached) {
16035                         ASSERT(buf->dtb_xamot != cached);
16036                         mutex_exit(&dtrace_lock);
16037                         return (ENOENT);
16038                 }
16039
16040                 ASSERT(cached == buf->dtb_xamot);
16041
16042                 /*
16043                  * We have our snapshot; now copy it out.
16044                  */
16045                 if (copyout(buf->dtb_xamot, desc.dtbd_data,
16046                     buf->dtb_xamot_offset) != 0) {
16047                         mutex_exit(&dtrace_lock);
16048                         return (EFAULT);
16049                 }
16050
16051                 desc.dtbd_size = buf->dtb_xamot_offset;
16052                 desc.dtbd_drops = buf->dtb_xamot_drops;
16053                 desc.dtbd_errors = buf->dtb_xamot_errors;
16054                 desc.dtbd_oldest = 0;
16055
16056                 mutex_exit(&dtrace_lock);
16057
16058                 /*
16059                  * Finally, copy out the buffer description.
16060                  */
16061                 if (copyout(&desc, (void *)arg, sizeof (desc)) != 0)
16062                         return (EFAULT);
16063
16064                 return (0);
16065         }
16066
16067         case DTRACEIOC_CONF: {
16068                 dtrace_conf_t conf;
16069
16070                 bzero(&conf, sizeof (conf));
16071                 conf.dtc_difversion = DIF_VERSION;
16072                 conf.dtc_difintregs = DIF_DIR_NREGS;
16073                 conf.dtc_diftupregs = DIF_DTR_NREGS;
16074                 conf.dtc_ctfmodel = CTF_MODEL_NATIVE;
16075
16076                 if (copyout(&conf, (void *)arg, sizeof (conf)) != 0)
16077                         return (EFAULT);
16078
16079                 return (0);
16080         }
16081
16082         case DTRACEIOC_STATUS: {
16083                 dtrace_status_t stat;
16084                 dtrace_dstate_t *dstate;
16085                 int i, j;
16086                 uint64_t nerrs;
16087
16088                 /*
16089                  * See the comment in dtrace_state_deadman() for the reason
16090                  * for setting dts_laststatus to INT64_MAX before setting
16091                  * it to the correct value.
16092                  */
16093                 state->dts_laststatus = INT64_MAX;
16094                 dtrace_membar_producer();
16095                 state->dts_laststatus = dtrace_gethrtime();
16096
16097                 bzero(&stat, sizeof (stat));
16098
16099                 mutex_enter(&dtrace_lock);
16100
16101                 if (state->dts_activity == DTRACE_ACTIVITY_INACTIVE) {
16102                         mutex_exit(&dtrace_lock);
16103                         return (ENOENT);
16104                 }
16105
16106                 if (state->dts_activity == DTRACE_ACTIVITY_DRAINING)
16107                         stat.dtst_exiting = 1;
16108
16109                 nerrs = state->dts_errors;
16110                 dstate = &state->dts_vstate.dtvs_dynvars;
16111
16112                 for (i = 0; i < NCPU; i++) {
16113                         dtrace_dstate_percpu_t *dcpu = &dstate->dtds_percpu[i];
16114
16115                         stat.dtst_dyndrops += dcpu->dtdsc_drops;
16116                         stat.dtst_dyndrops_dirty += dcpu->dtdsc_dirty_drops;
16117                         stat.dtst_dyndrops_rinsing += dcpu->dtdsc_rinsing_drops;
16118
16119                         if (state->dts_buffer[i].dtb_flags & DTRACEBUF_FULL)
16120                                 stat.dtst_filled++;
16121
16122                         nerrs += state->dts_buffer[i].dtb_errors;
16123
16124                         for (j = 0; j < state->dts_nspeculations; j++) {
16125                                 dtrace_speculation_t *spec;
16126                                 dtrace_buffer_t *buf;
16127
16128                                 spec = &state->dts_speculations[j];
16129                                 buf = &spec->dtsp_buffer[i];
16130                                 stat.dtst_specdrops += buf->dtb_xamot_drops;
16131                         }
16132                 }
16133
16134                 stat.dtst_specdrops_busy = state->dts_speculations_busy;
16135                 stat.dtst_specdrops_unavail = state->dts_speculations_unavail;
16136                 stat.dtst_stkstroverflows = state->dts_stkstroverflows;
16137                 stat.dtst_dblerrors = state->dts_dblerrors;
16138                 stat.dtst_killed =
16139                     (state->dts_activity == DTRACE_ACTIVITY_KILLED);
16140                 stat.dtst_errors = nerrs;
16141
16142                 mutex_exit(&dtrace_lock);
16143
16144                 if (copyout(&stat, (void *)arg, sizeof (stat)) != 0)
16145                         return (EFAULT);
16146
16147                 return (0);
16148         }
16149
16150         case DTRACEIOC_FORMAT: {
16151                 dtrace_fmtdesc_t fmt;
16152                 char *str;
16153                 int len;
16154
16155                 if (copyin((void *)arg, &fmt, sizeof (fmt)) != 0)
16156                         return (EFAULT);
16157
16158                 mutex_enter(&dtrace_lock);
16159
16160                 if (fmt.dtfd_format == 0 ||
16161                     fmt.dtfd_format > state->dts_nformats) {
16162                         mutex_exit(&dtrace_lock);
16163                         return (EINVAL);
16164                 }
16165
16166                 /*
16167                  * Format strings are allocated contiguously and they are
16168                  * never freed; if a format index is less than the number
16169                  * of formats, we can assert that the format map is non-NULL
16170                  * and that the format for the specified index is non-NULL.
16171                  */
16172                 ASSERT(state->dts_formats != NULL);
16173                 str = state->dts_formats[fmt.dtfd_format - 1];
16174                 ASSERT(str != NULL);
16175
16176                 len = strlen(str) + 1;
16177
16178                 if (len > fmt.dtfd_length) {
16179                         fmt.dtfd_length = len;
16180
16181                         if (copyout(&fmt, (void *)arg, sizeof (fmt)) != 0) {
16182                                 mutex_exit(&dtrace_lock);
16183                                 return (EINVAL);
16184                         }
16185                 } else {
16186                         if (copyout(str, fmt.dtfd_string, len) != 0) {
16187                                 mutex_exit(&dtrace_lock);
16188                                 return (EINVAL);
16189                         }
16190                 }
16191
16192                 mutex_exit(&dtrace_lock);
16193                 return (0);
16194         }
16195
16196         default:
16197                 break;
16198         }
16199
16200         return (ENOTTY);
16201 }
16202
16203 /*ARGSUSED*/
16204 static int
16205 dtrace_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
16206 {
16207         dtrace_state_t *state;
16208
16209         switch (cmd) {
16210         case DDI_DETACH:
16211                 break;
16212
16213         case DDI_SUSPEND:
16214                 return (DDI_SUCCESS);
16215
16216         default:
16217                 return (DDI_FAILURE);
16218         }
16219
16220         mutex_enter(&cpu_lock);
16221         mutex_enter(&dtrace_provider_lock);
16222         mutex_enter(&dtrace_lock);
16223
16224         ASSERT(dtrace_opens == 0);
16225
16226         if (dtrace_helpers > 0) {
16227                 mutex_exit(&dtrace_provider_lock);
16228                 mutex_exit(&dtrace_lock);
16229                 mutex_exit(&cpu_lock);
16230                 return (DDI_FAILURE);
16231         }
16232
16233         if (dtrace_unregister((dtrace_provider_id_t)dtrace_provider) != 0) {
16234                 mutex_exit(&dtrace_provider_lock);
16235                 mutex_exit(&dtrace_lock);
16236                 mutex_exit(&cpu_lock);
16237                 return (DDI_FAILURE);
16238         }
16239
16240         dtrace_provider = NULL;
16241
16242         if ((state = dtrace_anon_grab()) != NULL) {
16243                 /*
16244                  * If there were ECBs on this state, the provider should
16245                  * have not been allowed to detach; assert that there is
16246                  * none.
16247                  */
16248                 ASSERT(state->dts_necbs == 0);
16249                 dtrace_state_destroy(state);
16250
16251                 /*
16252                  * If we're being detached with anonymous state, we need to
16253                  * indicate to the kernel debugger that DTrace is now inactive.
16254                  */
16255                 (void) kdi_dtrace_set(KDI_DTSET_DTRACE_DEACTIVATE);
16256         }
16257
16258         bzero(&dtrace_anon, sizeof (dtrace_anon_t));
16259         unregister_cpu_setup_func((cpu_setup_func_t *)dtrace_cpu_setup, NULL);
16260         dtrace_cpu_init = NULL;
16261         dtrace_helpers_cleanup = NULL;
16262         dtrace_helpers_fork = NULL;
16263         dtrace_cpustart_init = NULL;
16264         dtrace_cpustart_fini = NULL;
16265         dtrace_debugger_init = NULL;
16266         dtrace_debugger_fini = NULL;
16267         dtrace_modload = NULL;
16268         dtrace_modunload = NULL;
16269
16270         mutex_exit(&cpu_lock);
16271
16272         if (dtrace_helptrace_enabled) {
16273                 kmem_free(dtrace_helptrace_buffer, dtrace_helptrace_bufsize);
16274                 dtrace_helptrace_buffer = NULL;
16275         }
16276
16277         kmem_free(dtrace_probes, dtrace_nprobes * sizeof (dtrace_probe_t *));
16278         dtrace_probes = NULL;
16279         dtrace_nprobes = 0;
16280
16281         dtrace_hash_destroy(dtrace_bymod);
16282         dtrace_hash_destroy(dtrace_byfunc);
16283         dtrace_hash_destroy(dtrace_byname);
16284         dtrace_bymod = NULL;
16285         dtrace_byfunc = NULL;
16286         dtrace_byname = NULL;
16287
16288         kmem_cache_destroy(dtrace_state_cache);
16289         vmem_destroy(dtrace_minor);
16290         vmem_destroy(dtrace_arena);
16291
16292         if (dtrace_toxrange != NULL) {
16293                 kmem_free(dtrace_toxrange,
16294                     dtrace_toxranges_max * sizeof (dtrace_toxrange_t));
16295                 dtrace_toxrange = NULL;
16296                 dtrace_toxranges = 0;
16297                 dtrace_toxranges_max = 0;
16298         }
16299
16300         ddi_remove_minor_node(dtrace_devi, NULL);
16301         dtrace_devi = NULL;
16302
16303         ddi_soft_state_fini(&dtrace_softstate);
16304
16305         ASSERT(dtrace_vtime_references == 0);
16306         ASSERT(dtrace_opens == 0);
16307         ASSERT(dtrace_retained == NULL);
16308
16309         mutex_exit(&dtrace_lock);
16310         mutex_exit(&dtrace_provider_lock);
16311
16312         /*
16313          * We don't destroy the task queue until after we have dropped our
16314          * locks (taskq_destroy() may block on running tasks).  To prevent
16315          * attempting to do work after we have effectively detached but before
16316          * the task queue has been destroyed, all tasks dispatched via the
16317          * task queue must check that DTrace is still attached before
16318          * performing any operation.
16319          */
16320         taskq_destroy(dtrace_taskq);
16321         dtrace_taskq = NULL;
16322
16323         return (DDI_SUCCESS);
16324 }
16325 #endif
16326
16327 #if defined(sun)
16328 /*ARGSUSED*/
16329 static int
16330 dtrace_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result)
16331 {
16332         int error;
16333
16334         switch (infocmd) {
16335         case DDI_INFO_DEVT2DEVINFO:
16336                 *result = (void *)dtrace_devi;
16337                 error = DDI_SUCCESS;
16338                 break;
16339         case DDI_INFO_DEVT2INSTANCE:
16340                 *result = (void *)0;
16341                 error = DDI_SUCCESS;
16342                 break;
16343         default:
16344                 error = DDI_FAILURE;
16345         }
16346         return (error);
16347 }
16348 #endif
16349
16350 #if defined(sun)
16351 static struct cb_ops dtrace_cb_ops = {
16352         dtrace_open,            /* open */
16353         dtrace_close,           /* close */
16354         nulldev,                /* strategy */
16355         nulldev,                /* print */
16356         nodev,                  /* dump */
16357         nodev,                  /* read */
16358         nodev,                  /* write */
16359         dtrace_ioctl,           /* ioctl */
16360         nodev,                  /* devmap */
16361         nodev,                  /* mmap */
16362         nodev,                  /* segmap */
16363         nochpoll,               /* poll */
16364         ddi_prop_op,            /* cb_prop_op */
16365         0,                      /* streamtab  */
16366         D_NEW | D_MP            /* Driver compatibility flag */
16367 };
16368
16369 static struct dev_ops dtrace_ops = {
16370         DEVO_REV,               /* devo_rev */
16371         0,                      /* refcnt */
16372         dtrace_info,            /* get_dev_info */
16373         nulldev,                /* identify */
16374         nulldev,                /* probe */
16375         dtrace_attach,          /* attach */
16376         dtrace_detach,          /* detach */
16377         nodev,                  /* reset */
16378         &dtrace_cb_ops,         /* driver operations */
16379         NULL,                   /* bus operations */
16380         nodev                   /* dev power */
16381 };
16382
16383 static struct modldrv modldrv = {
16384         &mod_driverops,         /* module type (this is a pseudo driver) */
16385         "Dynamic Tracing",      /* name of module */
16386         &dtrace_ops,            /* driver ops */
16387 };
16388
16389 static struct modlinkage modlinkage = {
16390         MODREV_1,
16391         (void *)&modldrv,
16392         NULL
16393 };
16394
16395 int
16396 _init(void)
16397 {
16398         return (mod_install(&modlinkage));
16399 }
16400
16401 int
16402 _info(struct modinfo *modinfop)
16403 {
16404         return (mod_info(&modlinkage, modinfop));
16405 }
16406
16407 int
16408 _fini(void)
16409 {
16410         return (mod_remove(&modlinkage));
16411 }
16412 #else
16413
16414 static d_ioctl_t        dtrace_ioctl;
16415 static void             dtrace_load(void *);
16416 static int              dtrace_unload(void);
16417 static struct cdev      *dtrace_dev;
16418
16419 void dtrace_invop_init(void);
16420 void dtrace_invop_uninit(void);
16421
16422 static struct cdevsw dtrace_cdevsw = {
16423         .d_version      = D_VERSION,
16424         .d_flags        = D_TRACKCLOSE,
16425         .d_close        = dtrace_close,
16426         .d_ioctl        = dtrace_ioctl,
16427         .d_open         = dtrace_open,
16428         .d_name         = "dtrace",
16429 };
16430
16431 #include <dtrace_anon.c>
16432 #include <dtrace_ioctl.c>
16433 #include <dtrace_load.c>
16434 #include <dtrace_modevent.c>
16435 #include <dtrace_sysctl.c>
16436 #include <dtrace_unload.c>
16437 #include <dtrace_vtime.c>
16438 #include <dtrace_hacks.c>
16439 #include <dtrace_isa.c>
16440
16441 SYSINIT(dtrace_load, SI_SUB_DTRACE, SI_ORDER_FIRST, dtrace_load, NULL);
16442 SYSUNINIT(dtrace_unload, SI_SUB_DTRACE, SI_ORDER_FIRST, dtrace_unload, NULL);
16443 SYSINIT(dtrace_anon_init, SI_SUB_DTRACE_ANON, SI_ORDER_FIRST, dtrace_anon_init, NULL);
16444
16445 DEV_MODULE(dtrace, dtrace_modevent, NULL);
16446 MODULE_VERSION(dtrace, 1);
16447 MODULE_DEPEND(dtrace, cyclic, 1, 1, 1);
16448 MODULE_DEPEND(dtrace, opensolaris, 1, 1, 1);
16449 #endif