Deleted Added
sdiff udiff text old ( 268572 ) new ( 268578 )
full compact
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

--- 4 unchanged lines hidden (view full) ---

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: stable/10/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c 268572 2014-07-12 18:23:35Z pfg $
22 */
23
24/*
25 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
26 * Copyright (c) 2013, Joyent, Inc. All rights reserved.
27 * Copyright (c) 2012 by Delphix. All rights reserved.
28 */
29

--- 74 unchanged lines hidden (view full) ---

104#include <sys/taskq.h>
105#if defined(sun)
106#include <sys/mkdev.h>
107#include <sys/kdi.h>
108#endif
109#include <sys/zone.h>
110#include <sys/socket.h>
111#include <netinet/in.h>
112
113/* FreeBSD includes: */
114#if !defined(sun)
115#include <sys/callout.h>
116#include <sys/ctype.h>
117#include <sys/eventhandler.h>
118#include <sys/limits.h>
119#include <sys/kdb.h>

--- 89 unchanged lines hidden (view full) ---

209static struct unrhdr *dtrace_arena; /* Probe ID number. */
210#endif
211static dtrace_probe_t **dtrace_probes; /* array of all probes */
212static int dtrace_nprobes; /* number of probes */
213static dtrace_provider_t *dtrace_provider; /* provider list */
214static dtrace_meta_t *dtrace_meta_pid; /* user-land meta provider */
215static int dtrace_opens; /* number of opens */
216static int dtrace_helpers; /* number of helpers */
217#if defined(sun)
218static void *dtrace_softstate; /* softstate pointer */
219#endif
220static dtrace_hash_t *dtrace_bymod; /* probes hashed by module */
221static dtrace_hash_t *dtrace_byfunc; /* probes hashed by function */
222static dtrace_hash_t *dtrace_byname; /* probes hashed by name */
223static dtrace_toxrange_t *dtrace_toxrange; /* toxic range array */
224static int dtrace_toxranges; /* number of toxic ranges */

--- 234 unchanged lines hidden (view full) ---

459
460/*
461 * Test whether a range of memory starting at testaddr of size testsz falls
462 * within the range of memory described by addr, sz. We take care to avoid
463 * problems with overflow and underflow of the unsigned quantities, and
464 * disallow all negative sizes. Ranges of size 0 are allowed.
465 */
466#define DTRACE_INRANGE(testaddr, testsz, baseaddr, basesz) \
467 ((testaddr) - (baseaddr) < (basesz) && \
468 (testaddr) + (testsz) - (baseaddr) <= (basesz) && \
469 (testaddr) + (testsz) >= (testaddr))
470
471/*
472 * Test whether alloc_sz bytes will fit in the scratch region. We isolate
473 * alloc_sz on the righthand side of the comparison in order to avoid overflow
474 * or underflow in the comparison with it. This is simpler than the INRANGE
475 * check above, because we know that the dtms_scratch_ptr is valid in the
476 * range. Allocations of size zero are allowed.

--- 92 unchanged lines hidden (view full) ---

569uint16_t dtrace_load16(uintptr_t);
570uint32_t dtrace_load32(uintptr_t);
571uint64_t dtrace_load64(uintptr_t);
572uint8_t dtrace_load8(uintptr_t);
573void dtrace_dynvar_clean(dtrace_dstate_t *);
574dtrace_dynvar_t *dtrace_dynvar(dtrace_dstate_t *, uint_t, dtrace_key_t *,
575 size_t, dtrace_dynvar_op_t, dtrace_mstate_t *, dtrace_vstate_t *);
576uintptr_t dtrace_dif_varstr(uintptr_t, dtrace_state_t *, dtrace_mstate_t *);
577
578/*
579 * DTrace Probe Context Functions
580 *
581 * These functions are called from probe context. Because probe context is
582 * any context in which C may be called, arbitrarily locks may be held,
583 * interrupts may be disabled, we may be in arbitrary dispatched state, etc.
584 * As a result, functions called from probe context may only call other DTrace

--- 128 unchanged lines hidden (view full) ---

713 mstate->dtms_scratch_size))
714 return (1);
715
716 /*
717 * Now check to see if it's a dynamic variable. This check will pick
718 * up both thread-local variables and any global dynamically-allocated
719 * variables.
720 */
721 if (DTRACE_INRANGE(addr, sz, (uintptr_t)vstate->dtvs_dynvars.dtds_base,
722 vstate->dtvs_dynvars.dtds_size)) {
723 dtrace_dstate_t *dstate = &vstate->dtvs_dynvars;
724 uintptr_t base = (uintptr_t)dstate->dtds_base +
725 (dstate->dtds_hashsize * sizeof (dtrace_dynhash_t));
726 uintptr_t chunkoffs;
727
728 /*
729 * Before we assume that we can store here, we need to make

--- 50 unchanged lines hidden (view full) ---

780 * DTrace subroutines (DIF_SUBR_*) should use this helper to implement
781 * appropriate memory access protection.
782 */
783static int
784dtrace_canload(uint64_t addr, size_t sz, dtrace_mstate_t *mstate,
785 dtrace_vstate_t *vstate)
786{
787 volatile uintptr_t *illval = &cpu_core[curcpu].cpuc_dtrace_illval;
788
789 /*
790 * If we hold the privilege to read from kernel memory, then
791 * everything is readable.
792 */
793 if ((mstate->dtms_access & DTRACE_ACCESS_KERNEL) != 0)
794 return (1);
795
796 /*
797 * You can obviously read that which you can store.
798 */
799 if (dtrace_canstore(addr, sz, mstate, vstate))
800 return (1);
801
802 /*
803 * We're allowed to read from our own string table.
804 */
805 if (DTRACE_INRANGE(addr, sz, (uintptr_t)mstate->dtms_difo->dtdo_strtab,
806 mstate->dtms_difo->dtdo_strlen))
807 return (1);
808
809 DTRACE_CPUFLAG_SET(CPU_DTRACE_KPRIV);
810 *illval = addr;
811 return (0);
812}
813
814/*
815 * Convenience routine to check to see if a given string is within a memory
816 * region in which a load may be issued given the user's privilege level;

--- 43 unchanged lines hidden (view full) ---

860 vstate->dtvs_state->dts_options[DTRACEOPT_STRSIZE]) + 1;
861 else
862 sz = type->dtdt_size;
863
864 return (dtrace_canload((uintptr_t)src, sz, mstate, vstate));
865}
866
867/*
868 * Compare two strings using safe loads.
869 */
870static int
871dtrace_strncmp(char *s1, char *s2, size_t limit)
872{
873 uint8_t c1, c2;
874 volatile uint16_t *flags;
875

--- 304 unchanged lines hidden (view full) ---

1180 cred_t *cr, *s_cr = state->dts_cred.dcr_cred;
1181
1182 /*
1183 * We should always have a non-NULL state cred here, since if cred
1184 * is null (anonymous tracing), we fast-path bypass this routine.
1185 */
1186 ASSERT(s_cr != NULL);
1187
1188 if ((cr = CRED()) != NULL &&
1189 s_cr->cr_zone == cr->cr_zone)
1190 return (1);
1191
1192 return (0);
1193#else
1194 return (1);
1195#endif
1196}
1197

--- 83 unchanged lines hidden (view full) ---

1281 return (1);
1282
1283 cpu_core[curcpu].cpuc_dtrace_flags |= CPU_DTRACE_KPRIV;
1284
1285 return (0);
1286}
1287
1288/*
1289 * Note: not called from probe context. This function is called
1290 * asynchronously (and at a regular interval) from outside of probe context to
1291 * clean the dirty dynamic variable lists on all CPUs. Dynamic variable
1292 * cleaning is explained in detail in <sys/dtrace_impl.h>.
1293 */
1294void
1295dtrace_dynvar_clean(dtrace_dstate_t *dstate)
1296{

--- 1601 unchanged lines hidden (view full) ---

2898 return (0);
2899 }
2900
2901 return (dtrace_getreg(tframe, ndx));
2902 }
2903#endif
2904
2905 case DIF_VAR_CURTHREAD:
2906 if (!dtrace_priv_kernel(state))
2907 return (0);
2908 return ((uint64_t)(uintptr_t)curthread);
2909
2910 case DIF_VAR_TIMESTAMP:
2911 if (!(mstate->dtms_present & DTRACE_MSTATE_TIMESTAMP)) {
2912 mstate->dtms_timestamp = dtrace_gethrtime();
2913 mstate->dtms_present |= DTRACE_MSTATE_TIMESTAMP;
2914 }

--- 339 unchanged lines hidden (view full) ---

3254 }
3255#endif
3256 default:
3257 DTRACE_CPUFLAG_SET(CPU_DTRACE_ILLOP);
3258 return (0);
3259 }
3260}
3261
3262/*
3263 * Emulate the execution of DTrace ID subroutines invoked by the call opcode.
3264 * Notice that we don't bother validating the proper number of arguments or
3265 * their types in the tuple stack. This isn't needed because all argument
3266 * interpretation is safe because of our load safety -- the worst that can
3267 * happen is that a bogus program can obtain bogus results.
3268 */
3269static void
3270dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs,

--- 779 unchanged lines hidden (view full) ---

4050
4051 d[i] = '\0';
4052
4053 mstate->dtms_scratch_ptr += size;
4054 regs[rd] = (uintptr_t)d;
4055 break;
4056 }
4057
4058 case DIF_SUBR_TOUPPER:
4059 case DIF_SUBR_TOLOWER: {
4060 uintptr_t s = tupregs[0].dttk_value;
4061 uint64_t size = state->dts_options[DTRACEOPT_STRSIZE];
4062 char *dest = (char *)mstate->dtms_scratch_ptr, c;
4063 size_t len = dtrace_strlen((char *)s, size);
4064 char lower, upper, convert;
4065 int64_t i;

--- 293 unchanged lines hidden (view full) ---

4359 if (i < size) {
4360 mstate->dtms_scratch_ptr += i;
4361 regs[rd] = (uintptr_t)d;
4362 }
4363
4364 break;
4365 }
4366
4367 case DIF_SUBR_LLTOSTR: {
4368 int64_t i = (int64_t)tupregs[0].dttk_value;
4369 uint64_t val, digit;
4370 uint64_t size = 65; /* enough room for 2^64 in binary */
4371 char *end = (char *)mstate->dtms_scratch_ptr + size - 1;
4372 int base = 10;
4373
4374 if (nargs > 1) {

--- 193 unchanged lines hidden (view full) ---

4568 dest[j] = dtrace_load8(src + i);
4569
4570 dest[j] = '\0';
4571 regs[rd] = (uintptr_t)dest;
4572 mstate->dtms_scratch_ptr += size;
4573 break;
4574 }
4575
4576 case DIF_SUBR_CLEANPATH: {
4577 char *dest = (char *)mstate->dtms_scratch_ptr, c;
4578 uint64_t size = state->dts_options[DTRACEOPT_STRSIZE];
4579 uintptr_t src = tupregs[0].dttk_value;
4580 int i = 0, j = 0;
4581
4582 if (!dtrace_strcanload(src, size, mstate, vstate)) {
4583 regs[rd] = 0;
4584 break;
4585 }
4586
4587 if (!DTRACE_INSCRATCH(mstate, size)) {
4588 DTRACE_CPUFLAG_SET(CPU_DTRACE_NOSCRATCH);

--- 82 unchanged lines hidden (view full) ---

4671 while (j != 0 && dest[--j] != '/')
4672 continue;
4673
4674 if (c == '\0')
4675 dest[++j] = '/';
4676 } while (c != '\0');
4677
4678 dest[j] = '\0';
4679 regs[rd] = (uintptr_t)dest;
4680 mstate->dtms_scratch_ptr += size;
4681 break;
4682 }
4683
4684 case DIF_SUBR_INET_NTOA:
4685 case DIF_SUBR_INET_NTOA6:
4686 case DIF_SUBR_INET_NTOP: {

--- 418 unchanged lines hidden (view full) ---

5105 if (cc_z | (cc_n ^ cc_v))
5106 pc = DIF_INSTR_LABEL(instr);
5107 break;
5108 case DIF_OP_BLEU:
5109 if (cc_c | cc_z)
5110 pc = DIF_INSTR_LABEL(instr);
5111 break;
5112 case DIF_OP_RLDSB:
5113 if (!dtrace_canstore(regs[r1], 1, mstate, vstate)) {
5114 *flags |= CPU_DTRACE_KPRIV;
5115 *illval = regs[r1];
5116 break;
5117 }
5118 /*FALLTHROUGH*/
5119 case DIF_OP_LDSB:
5120 regs[rd] = (int8_t)dtrace_load8(regs[r1]);
5121 break;
5122 case DIF_OP_RLDSH:
5123 if (!dtrace_canstore(regs[r1], 2, mstate, vstate)) {
5124 *flags |= CPU_DTRACE_KPRIV;
5125 *illval = regs[r1];
5126 break;
5127 }
5128 /*FALLTHROUGH*/
5129 case DIF_OP_LDSH:
5130 regs[rd] = (int16_t)dtrace_load16(regs[r1]);
5131 break;
5132 case DIF_OP_RLDSW:
5133 if (!dtrace_canstore(regs[r1], 4, mstate, vstate)) {
5134 *flags |= CPU_DTRACE_KPRIV;
5135 *illval = regs[r1];
5136 break;
5137 }
5138 /*FALLTHROUGH*/
5139 case DIF_OP_LDSW:
5140 regs[rd] = (int32_t)dtrace_load32(regs[r1]);
5141 break;
5142 case DIF_OP_RLDUB:
5143 if (!dtrace_canstore(regs[r1], 1, mstate, vstate)) {
5144 *flags |= CPU_DTRACE_KPRIV;
5145 *illval = regs[r1];
5146 break;
5147 }
5148 /*FALLTHROUGH*/
5149 case DIF_OP_LDUB:
5150 regs[rd] = dtrace_load8(regs[r1]);
5151 break;
5152 case DIF_OP_RLDUH:
5153 if (!dtrace_canstore(regs[r1], 2, mstate, vstate)) {
5154 *flags |= CPU_DTRACE_KPRIV;
5155 *illval = regs[r1];
5156 break;
5157 }
5158 /*FALLTHROUGH*/
5159 case DIF_OP_LDUH:
5160 regs[rd] = dtrace_load16(regs[r1]);
5161 break;
5162 case DIF_OP_RLDUW:
5163 if (!dtrace_canstore(regs[r1], 4, mstate, vstate)) {
5164 *flags |= CPU_DTRACE_KPRIV;
5165 *illval = regs[r1];
5166 break;
5167 }
5168 /*FALLTHROUGH*/
5169 case DIF_OP_LDUW:
5170 regs[rd] = dtrace_load32(regs[r1]);
5171 break;
5172 case DIF_OP_RLDX:
5173 if (!dtrace_canstore(regs[r1], 8, mstate, vstate)) {
5174 *flags |= CPU_DTRACE_KPRIV;
5175 *illval = regs[r1];
5176 break;
5177 }
5178 /*FALLTHROUGH*/
5179 case DIF_OP_LDX:
5180 regs[rd] = dtrace_load64(regs[r1]);
5181 break;
5182 case DIF_OP_ULDSB:
5183 regs[rd] = (int8_t)
5184 dtrace_fuword8((void *)(uintptr_t)regs[r1]);
5185 break;
5186 case DIF_OP_ULDSH:
5187 regs[rd] = (int16_t)
5188 dtrace_fuword16((void *)(uintptr_t)regs[r1]);
5189 break;
5190 case DIF_OP_ULDSW:
5191 regs[rd] = (int32_t)
5192 dtrace_fuword32((void *)(uintptr_t)regs[r1]);
5193 break;
5194 case DIF_OP_ULDUB:
5195 regs[rd] =
5196 dtrace_fuword8((void *)(uintptr_t)regs[r1]);
5197 break;
5198 case DIF_OP_ULDUH:
5199 regs[rd] =
5200 dtrace_fuword16((void *)(uintptr_t)regs[r1]);
5201 break;
5202 case DIF_OP_ULDUW:
5203 regs[rd] =
5204 dtrace_fuword32((void *)(uintptr_t)regs[r1]);
5205 break;
5206 case DIF_OP_ULDX:
5207 regs[rd] =
5208 dtrace_fuword64((void *)(uintptr_t)regs[r1]);
5209 break;
5210 case DIF_OP_RET:
5211 rval = regs[rd];
5212 pc = textlen;
5213 break;
5214 case DIF_OP_NOP:
5215 break;
5216 case DIF_OP_SETX:

--- 665 unchanged lines hidden (view full) ---

5882 cpu_t *cpu = CPU;
5883#else
5884 cpu_t *cpu = &solaris_cpu[curcpu];
5885#endif
5886
5887 if (dtrace_destructive_disallow)
5888 return;
5889
5890 flags = (volatile uint16_t *)&cpu_core[cpu->cpu_id].cpuc_dtrace_flags;
5891
5892 now = dtrace_gethrtime();
5893
5894 if (now - cpu->cpu_dtrace_chillmark > dtrace_chill_interval) {
5895 /*
5896 * We need to advance the mark to the current time.
5897 */
5898 cpu->cpu_dtrace_chillmark = now;

--- 131 unchanged lines hidden (view full) ---

6030
6031 while (offs < strsize)
6032 str[offs++] = '\0';
6033
6034out:
6035 mstate->dtms_scratch_ptr = old;
6036}
6037
6038/*
6039 * If you're looking for the epicenter of DTrace, you just found it. This
6040 * is the function called by the provider to fire a probe -- from which all
6041 * subsequent probe-context DTrace activity emanates.
6042 */
6043void
6044dtrace_probe(dtrace_id_t id, uintptr_t arg0, uintptr_t arg1,
6045 uintptr_t arg2, uintptr_t arg3, uintptr_t arg4)

--- 86 unchanged lines hidden (view full) ---

6132 * the action processing loop.) However, it must be declared
6133 * out of that scope because in the case of DIF expression
6134 * arguments to aggregating actions, one iteration of the
6135 * action loop will use the last iteration's value.
6136 */
6137 uint64_t val = 0;
6138
6139 mstate.dtms_present = DTRACE_MSTATE_ARGS | DTRACE_MSTATE_PROBE;
6140 *flags &= ~CPU_DTRACE_ERROR;
6141
6142 if (prov == dtrace_provider) {
6143 /*
6144 * If dtrace itself is the provider of this probe,
6145 * we're only going to continue processing the ECB if
6146 * arg0 (the dtrace_state_t) is equal to the ECB's
6147 * creating state. (This prevents disjoint consumers

--- 517 unchanged lines hidden (view full) ---

6665
6666 break;
6667 }
6668
6669 default:
6670 ASSERT(0);
6671 }
6672
6673 if (dp->dtdo_rtype.dtdt_flags & DIF_TF_BYREF) {
6674 uintptr_t end = valoffs + size;
6675
6676 if (tracememsize != 0 &&
6677 valoffs + tracememsize < end) {
6678 end = valoffs + tracememsize;
6679 tracememsize = 0;
6680 }
6681
6682 if (!dtrace_vcanload((void *)(uintptr_t)val,
6683 &dp->dtdo_rtype, &mstate, vstate))
6684 continue;
6685
6686 /*
6687 * If this is a string, we're going to only
6688 * load until we find the zero byte -- after
6689 * which we'll store zero bytes.
6690 */
6691 if (dp->dtdo_rtype.dtdt_kind ==
6692 DIF_TYPE_STRING) {
6693 char c = '\0' + 1;
6694 int intuple = act->dta_intuple;
6695 size_t s;
6696
6697 for (s = 0; s < size; s++) {
6698 if (c != '\0')
6699 c = dtrace_load8(val++);
6700
6701 DTRACE_STORE(uint8_t, tomax,
6702 valoffs++, c);
6703
6704 if (c == '\0' && intuple)
6705 break;
6706 }
6707
6708 continue;
6709 }
6710
6711 while (valoffs < end) {
6712 DTRACE_STORE(uint8_t, tomax, valoffs++,
6713 dtrace_load8(val++));
6714 }
6715
6716 continue;
6717 }
6718
6719 switch (size) {
6720 case 0:
6721 break;
6722
6723 case sizeof (uint8_t):

--- 2081 unchanged lines hidden (view full) ---

8805 err += efunc(pc, "invalid register %u\n", rd);
8806 if (rd == 0)
8807 err += efunc(pc, "cannot write to %r0\n");
8808
8809 if (subr == DIF_SUBR_COPYOUT ||
8810 subr == DIF_SUBR_COPYOUTSTR) {
8811 dp->dtdo_destructive = 1;
8812 }
8813 break;
8814 case DIF_OP_PUSHTR:
8815 if (type != DIF_TYPE_STRING && type != DIF_TYPE_CTF)
8816 err += efunc(pc, "invalid ref type %u\n", type);
8817 if (r2 >= nregs)
8818 err += efunc(pc, "invalid register %u\n", r2);
8819 if (rs >= nregs)
8820 err += efunc(pc, "invalid register %u\n", rs);

--- 13 unchanged lines hidden (view full) ---

8834 }
8835
8836 if (dp->dtdo_len != 0 &&
8837 DIF_INSTR_OP(dp->dtdo_buf[dp->dtdo_len - 1]) != DIF_OP_RET) {
8838 err += efunc(dp->dtdo_len - 1,
8839 "expected 'ret' as last DIF instruction\n");
8840 }
8841
8842 if (!(dp->dtdo_rtype.dtdt_flags & DIF_TF_BYREF)) {
8843 /*
8844 * If we're not returning by reference, the size must be either
8845 * 0 or the size of one of the base types.
8846 */
8847 switch (dp->dtdo_rtype.dtdt_size) {
8848 case 0:
8849 case sizeof (uint8_t):
8850 case sizeof (uint16_t):

--- 233 unchanged lines hidden (view full) ---

9084 subr == DIF_SUBR_BCOPY ||
9085 subr == DIF_SUBR_COPYIN ||
9086 subr == DIF_SUBR_COPYINTO ||
9087 subr == DIF_SUBR_COPYINSTR ||
9088 subr == DIF_SUBR_INDEX ||
9089 subr == DIF_SUBR_INET_NTOA ||
9090 subr == DIF_SUBR_INET_NTOA6 ||
9091 subr == DIF_SUBR_INET_NTOP ||
9092 subr == DIF_SUBR_LLTOSTR ||
9093 subr == DIF_SUBR_RINDEX ||
9094 subr == DIF_SUBR_STRCHR ||
9095 subr == DIF_SUBR_STRJOIN ||
9096 subr == DIF_SUBR_STRRCHR ||
9097 subr == DIF_SUBR_STRSTR ||
9098 subr == DIF_SUBR_HTONS ||
9099 subr == DIF_SUBR_HTONL ||
9100 subr == DIF_SUBR_HTONLL ||

--- 4628 unchanged lines hidden (view full) ---

13729 callout_reset(&state->dts_cleaner, hz * opt[DTRACEOPT_CLEANRATE] / NANOSEC,
13730 dtrace_state_clean, state);
13731 callout_reset(&state->dts_deadman, hz * dtrace_deadman_interval / NANOSEC,
13732 dtrace_state_deadman, state);
13733#endif
13734
13735 state->dts_activity = DTRACE_ACTIVITY_WARMUP;
13736
13737 /*
13738 * Now it's time to actually fire the BEGIN probe. We need to disable
13739 * interrupts here both to record the CPU on which we fired the BEGIN
13740 * probe (the data from this CPU will be processed first at user
13741 * level) and to manually activate the buffer for this CPU.
13742 */
13743 cookie = dtrace_interrupt_disable();
13744 *cpu = curcpu;

--- 100 unchanged lines hidden (view full) ---

13845 *cpu = curcpu;
13846 dtrace_probe(dtrace_probeid_end,
13847 (uint64_t)(uintptr_t)state, 0, 0, 0, 0);
13848 dtrace_interrupt_enable(cookie);
13849
13850 state->dts_activity = DTRACE_ACTIVITY_STOPPED;
13851 dtrace_sync();
13852
13853 return (0);
13854}
13855
13856static int
13857dtrace_state_option(dtrace_state_t *state, dtrace_optid_t option,
13858 dtrace_optval_t val)
13859{
13860 ASSERT(MUTEX_HELD(&dtrace_lock));

--- 1653 unchanged lines hidden (view full) ---

15514 ASSERT(dtrace_toxrange[dtrace_toxranges].dtt_base == 0);
15515 ASSERT(dtrace_toxrange[dtrace_toxranges].dtt_limit == 0);
15516
15517 dtrace_toxrange[dtrace_toxranges].dtt_base = base;
15518 dtrace_toxrange[dtrace_toxranges].dtt_limit = limit;
15519 dtrace_toxranges++;
15520}
15521
15522/*
15523 * DTrace Driver Cookbook Functions
15524 */
15525#if defined(sun)
15526/*ARGSUSED*/
15527static int
15528dtrace_attach(dev_info_t *devi, ddi_attach_cmd_t cmd)
15529{

--- 1247 unchanged lines hidden (view full) ---

16777 dtrace_helpers_fork = NULL;
16778 dtrace_cpustart_init = NULL;
16779 dtrace_cpustart_fini = NULL;
16780 dtrace_debugger_init = NULL;
16781 dtrace_debugger_fini = NULL;
16782 dtrace_modload = NULL;
16783 dtrace_modunload = NULL;
16784
16785 mutex_exit(&cpu_lock);
16786
16787 if (dtrace_helptrace_enabled) {
16788 kmem_free(dtrace_helptrace_buffer, dtrace_helptrace_bufsize);
16789 dtrace_helptrace_buffer = NULL;
16790 }
16791
16792 kmem_free(dtrace_probes, dtrace_nprobes * sizeof (dtrace_probe_t *));

--- 191 unchanged lines hidden ---