diff options
author | jb <jb@FreeBSD.org> | 2008-05-22 07:33:39 +0000 |
---|---|---|
committer | jb <jb@FreeBSD.org> | 2008-05-22 07:33:39 +0000 |
commit | 5788c140d796d33530527e138c61b21303e8d006 (patch) | |
tree | 13c8247575459ee7fadf40737cff3eb883067b6c /sys/cddl/contrib/opensolaris | |
parent | 60b4eaf522405eafec6ba998afa8f7eaa4919166 (diff) | |
download | FreeBSD-src-5788c140d796d33530527e138c61b21303e8d006.zip FreeBSD-src-5788c140d796d33530527e138c61b21303e8d006.tar.gz |
FreeBSD changes to vendor source.
Diffstat (limited to 'sys/cddl/contrib/opensolaris')
9 files changed, 1290 insertions, 240 deletions
diff --git a/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c b/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c index 35971db..c85f7b1 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c +++ b/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c @@ -66,34 +66,66 @@ * on capital-f functions. */ #include <sys/errno.h> +#if !defined(sun) +#include <sys/time.h> +#endif #include <sys/stat.h> #include <sys/modctl.h> #include <sys/conf.h> #include <sys/systm.h> +#if defined(sun) #include <sys/ddi.h> #include <sys/sunddi.h> +#endif #include <sys/cpuvar.h> #include <sys/kmem.h> +#if defined(sun) #include <sys/strsubr.h> +#endif #include <sys/sysmacros.h> #include <sys/dtrace_impl.h> #include <sys/atomic.h> #include <sys/cmn_err.h> +#if defined(sun) #include <sys/mutex_impl.h> #include <sys/rwlock_impl.h> +#endif #include <sys/ctf_api.h> +#if defined(sun) #include <sys/panic.h> #include <sys/priv_impl.h> +#endif #include <sys/policy.h> +#if defined(sun) #include <sys/cred_impl.h> #include <sys/procfs_isa.h> +#endif #include <sys/taskq.h> +#if defined(sun) #include <sys/mkdev.h> #include <sys/kdi.h> +#endif #include <sys/zone.h> #include <sys/socket.h> #include <netinet/in.h> +/* FreeBSD includes: */ +#if !defined(sun) +#include <sys/ctype.h> +#include <sys/limits.h> +#include <sys/kdb.h> +#include <sys/kernel.h> +#include <sys/malloc.h> +#include <sys/sysctl.h> +#include <sys/lock.h> +#include <sys/mutex.h> +#include <sys/sx.h> +#include <sys/dtrace_bsd.h> +#include <netinet/in.h> +#include "dtrace_cddl.h" +#include "dtrace_debug.c" +#endif + /* * DTrace Tunable Variables * @@ -161,17 +193,25 @@ const char dtrace_zero[256] = { 0 }; /* zero-filled memory */ /* * DTrace Internal Variables */ +#if defined(sun) static dev_info_t *dtrace_devi; /* device info */ +#endif +#if defined(sun) static vmem_t *dtrace_arena; /* probe ID arena */ static vmem_t *dtrace_minor; /* minor number arena */ static taskq_t *dtrace_taskq; /* task queue */ +#else +static struct unrhdr *dtrace_arena; /* Probe ID number. */ +#endif static dtrace_probe_t **dtrace_probes; /* array of all probes */ static int dtrace_nprobes; /* number of probes */ static dtrace_provider_t *dtrace_provider; /* provider list */ static dtrace_meta_t *dtrace_meta_pid; /* user-land meta provider */ static int dtrace_opens; /* number of opens */ static int dtrace_helpers; /* number of helpers */ +#if defined(sun) static void *dtrace_softstate; /* softstate pointer */ +#endif static dtrace_hash_t *dtrace_bymod; /* probes hashed by module */ static dtrace_hash_t *dtrace_byfunc; /* probes hashed by function */ static dtrace_hash_t *dtrace_byname; /* probes hashed by name */ @@ -187,6 +227,14 @@ static dtrace_genid_t dtrace_probegen; /* current probe generation */ static dtrace_helpers_t *dtrace_deferred_pid; /* deferred helper list */ static dtrace_enabling_t *dtrace_retained; /* list of retained enablings */ static dtrace_dynvar_t dtrace_dynhash_sink; /* end of dynamic hash chains */ +#if !defined(sun) +static struct mtx dtrace_unr_mtx; +MTX_SYSINIT(dtrace_unr_mtx, &dtrace_unr_mtx, "Unique resource identifier", MTX_DEF); +int dtrace_in_probe; /* non-zero if executing a probe */ +#if defined(__i386__) || defined(__amd64__) +uintptr_t dtrace_in_probe_addr; /* Address of invop when already in probe */ +#endif +#endif /* * DTrace Locking @@ -222,6 +270,37 @@ static kmutex_t dtrace_lock; /* probe state lock */ static kmutex_t dtrace_provider_lock; /* provider state lock */ static kmutex_t dtrace_meta_lock; /* meta-provider state lock */ +#if !defined(sun) +/* XXX FreeBSD hacks. */ +static kmutex_t mod_lock; + +#define cr_suid cr_svuid +#define cr_sgid cr_svgid +#define ipaddr_t in_addr_t +#define mod_modname pathname +#define vuprintf vprintf +#define ttoproc(_a) ((_a)->td_proc) +#define crgetzoneid(_a) 0 +#define NCPU MAXCPU +#define SNOCD 0 +#define CPU_ON_INTR(_a) 0 + +#define PRIV_EFFECTIVE (1 << 0) +#define PRIV_DTRACE_KERNEL (1 << 1) +#define PRIV_DTRACE_PROC (1 << 2) +#define PRIV_DTRACE_USER (1 << 3) +#define PRIV_PROC_OWNER (1 << 4) +#define PRIV_PROC_ZONE (1 << 5) +#define PRIV_ALL ~0 + +SYSCTL_NODE(_debug, OID_AUTO, dtrace, CTLFLAG_RD, 0, "DTrace Information"); +#endif + +#if defined(sun) +#define curcpu CPU->cpu_id +#endif + + /* * DTrace Provider Variables * @@ -241,8 +320,8 @@ dtrace_nullop(void) {} static dtrace_pops_t dtrace_provider_ops = { - (void (*)(void *, const dtrace_probedesc_t *))dtrace_nullop, - (void (*)(void *, struct modctl *))dtrace_nullop, + (void (*)(void *, dtrace_probedesc_t *))dtrace_nullop, + (void (*)(void *, modctl_t *))dtrace_nullop, (void (*)(void *, dtrace_id_t, void *))dtrace_nullop, (void (*)(void *, dtrace_id_t, void *))dtrace_nullop, (void (*)(void *, dtrace_id_t, void *))dtrace_nullop, @@ -327,6 +406,7 @@ static kmutex_t dtrace_errlock; * no way for a global variable key signature to match a thread-local key * signature. */ +#if defined(sun) #define DTRACE_TLS_THRKEY(where) { \ uint_t intr = 0; \ uint_t actv = CPU->cpu_intr_actv >> (LOCK_LEVEL + 1); \ @@ -336,6 +416,18 @@ static kmutex_t dtrace_errlock; (where) = ((curthread->t_did + DIF_VARIABLE_MAX) & \ (((uint64_t)1 << 61) - 1)) | ((uint64_t)intr << 61); \ } +#else +#define DTRACE_TLS_THRKEY(where) { \ + solaris_cpu_t *_c = &solaris_cpu[curcpu]; \ + uint_t intr = 0; \ + uint_t actv = _c->cpu_intr_actv; \ + for (; actv; actv >>= 1) \ + intr++; \ + ASSERT(intr < (1 << 3)); \ + (where) = ((curthread->td_tid + DIF_VARIABLE_MAX) & \ + (((uint64_t)1 << 61) - 1)) | ((uint64_t)intr << 61); \ +} +#endif #define DT_BSWAP_8(x) ((x) & 0xff) #define DT_BSWAP_16(x) ((DT_BSWAP_8(x) << 8) | DT_BSWAP_8((x) >> 8)) @@ -351,7 +443,7 @@ static kmutex_t dtrace_errlock; #define DTRACE_ALIGNCHECK(addr, size, flags) \ if (addr & (size - 1)) { \ *flags |= CPU_DTRACE_BADALIGN; \ - cpu_core[CPU->cpu_id].cpuc_dtrace_illval = addr; \ + cpu_core[curcpu].cpuc_dtrace_illval = addr; \ return (0); \ } #else @@ -390,7 +482,7 @@ dtrace_load##bits(uintptr_t addr) \ uint##bits##_t rval; \ int i; \ volatile uint16_t *flags = (volatile uint16_t *) \ - &cpu_core[CPU->cpu_id].cpuc_dtrace_flags; \ + &cpu_core[curcpu].cpuc_dtrace_flags; \ \ DTRACE_ALIGNCHECK(addr, size, flags); \ \ @@ -405,7 +497,7 @@ dtrace_load##bits(uintptr_t addr) \ * This address falls within a toxic region; return 0. \ */ \ *flags |= CPU_DTRACE_BADADDR; \ - cpu_core[CPU->cpu_id].cpuc_dtrace_illval = addr; \ + cpu_core[curcpu].cpuc_dtrace_illval = addr; \ return (0); \ } \ \ @@ -448,22 +540,35 @@ dtrace_load##bits(uintptr_t addr) \ ((act)->dta_kind == DTRACEACT_DIFEXPR && \ (act)->dta_difo->dtdo_rtype.dtdt_kind == DIF_TYPE_STRING) +/* Function prototype definitions: */ static size_t dtrace_strlen(const char *, size_t); static dtrace_probe_t *dtrace_probe_lookup_id(dtrace_id_t id); static void dtrace_enabling_provide(dtrace_provider_t *); static int dtrace_enabling_match(dtrace_enabling_t *, int *); static void dtrace_enabling_matchall(void); static dtrace_state_t *dtrace_anon_grab(void); +#if defined(sun) static uint64_t dtrace_helper(int, dtrace_mstate_t *, dtrace_state_t *, uint64_t, uint64_t); static dtrace_helpers_t *dtrace_helpers_create(proc_t *); +#endif static void dtrace_buffer_drop(dtrace_buffer_t *); static intptr_t dtrace_buffer_reserve(dtrace_buffer_t *, size_t, size_t, dtrace_state_t *, dtrace_mstate_t *); static int dtrace_state_option(dtrace_state_t *, dtrace_optid_t, dtrace_optval_t); static int dtrace_ecb_create_enable(dtrace_probe_t *, void *); +#if defined(sun) static void dtrace_helper_provider_destroy(dtrace_helper_provider_t *); +#endif +uint16_t dtrace_load16(uintptr_t); +uint32_t dtrace_load32(uintptr_t); +uint64_t dtrace_load64(uintptr_t); +uint8_t dtrace_load8(uintptr_t); +void dtrace_dynvar_clean(dtrace_dstate_t *); +dtrace_dynvar_t *dtrace_dynvar(dtrace_dstate_t *, uint_t, dtrace_key_t *, + size_t, dtrace_dynvar_op_t, dtrace_mstate_t *, dtrace_vstate_t *); +uintptr_t dtrace_dif_varstr(uintptr_t, dtrace_state_t *, dtrace_mstate_t *); /* * DTrace Probe Context Functions @@ -674,7 +779,7 @@ static int dtrace_canload(uint64_t addr, size_t sz, dtrace_mstate_t *mstate, dtrace_vstate_t *vstate) { - volatile uintptr_t *illval = &cpu_core[CPU->cpu_id].cpuc_dtrace_illval; + volatile uintptr_t *illval = &cpu_core[curcpu].cpuc_dtrace_illval; /* * If we hold the privilege to read from kernel memory, then @@ -766,7 +871,7 @@ dtrace_strncmp(char *s1, char *s2, size_t limit) if (s1 == s2 || limit == 0) return (0); - flags = (volatile uint16_t *)&cpu_core[CPU->cpu_id].cpuc_dtrace_flags; + flags = (volatile uint16_t *)&cpu_core[curcpu].cpuc_dtrace_flags; do { if (s1 == NULL) { @@ -820,13 +925,13 @@ dtrace_istoxic(uintptr_t kaddr, size_t size) if (kaddr - taddr < tsize) { DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR); - cpu_core[CPU->cpu_id].cpuc_dtrace_illval = kaddr; + cpu_core[curcpu].cpuc_dtrace_illval = kaddr; return (1); } if (taddr - kaddr < size) { DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR); - cpu_core[CPU->cpu_id].cpuc_dtrace_illval = taddr; + cpu_core[curcpu].cpuc_dtrace_illval = taddr; return (1); } } @@ -910,7 +1015,7 @@ dtrace_bcmp(const void *s1, const void *s2, size_t len) { volatile uint16_t *flags; - flags = (volatile uint16_t *)&cpu_core[CPU->cpu_id].cpuc_dtrace_flags; + flags = (volatile uint16_t *)&cpu_core[curcpu].cpuc_dtrace_flags; if (s1 == s2) return (0); @@ -1066,6 +1171,7 @@ dtrace_priv_proc_common_user(dtrace_state_t *state) static int dtrace_priv_proc_common_zone(dtrace_state_t *state) { +#if defined(sun) cred_t *cr, *s_cr = state->dts_cred.dcr_cred; /* @@ -1079,6 +1185,9 @@ dtrace_priv_proc_common_zone(dtrace_state_t *state) return (1); return (0); +#else + return (1); +#endif } /* @@ -1086,7 +1195,7 @@ dtrace_priv_proc_common_zone(dtrace_state_t *state) * verify that the process has not setuid or changed credentials. */ static int -dtrace_priv_proc_common_nocd() +dtrace_priv_proc_common_nocd(void) { proc_t *proc; @@ -1117,7 +1226,7 @@ dtrace_priv_proc_destructive(dtrace_state_t *state) return (1); bad: - cpu_core[CPU->cpu_id].cpuc_dtrace_flags |= CPU_DTRACE_UPRIV; + cpu_core[curcpu].cpuc_dtrace_flags |= CPU_DTRACE_UPRIV; return (0); } @@ -1133,7 +1242,7 @@ dtrace_priv_proc_control(dtrace_state_t *state) dtrace_priv_proc_common_nocd()) return (1); - cpu_core[CPU->cpu_id].cpuc_dtrace_flags |= CPU_DTRACE_UPRIV; + cpu_core[curcpu].cpuc_dtrace_flags |= CPU_DTRACE_UPRIV; return (0); } @@ -1144,7 +1253,7 @@ dtrace_priv_proc(dtrace_state_t *state) if (state->dts_cred.dcr_action & DTRACE_CRA_PROC) return (1); - cpu_core[CPU->cpu_id].cpuc_dtrace_flags |= CPU_DTRACE_UPRIV; + cpu_core[curcpu].cpuc_dtrace_flags |= CPU_DTRACE_UPRIV; return (0); } @@ -1155,7 +1264,7 @@ dtrace_priv_kernel(dtrace_state_t *state) if (state->dts_cred.dcr_action & DTRACE_CRA_KERNEL) return (1); - cpu_core[CPU->cpu_id].cpuc_dtrace_flags |= CPU_DTRACE_KPRIV; + cpu_core[curcpu].cpuc_dtrace_flags |= CPU_DTRACE_KPRIV; return (0); } @@ -1166,7 +1275,7 @@ dtrace_priv_kernel_destructive(dtrace_state_t *state) if (state->dts_cred.dcr_action & DTRACE_CRA_KERNEL_DESTRUCTIVE) return (1); - cpu_core[CPU->cpu_id].cpuc_dtrace_flags |= CPU_DTRACE_KPRIV; + cpu_core[curcpu].cpuc_dtrace_flags |= CPU_DTRACE_KPRIV; return (0); } @@ -1277,7 +1386,7 @@ dtrace_dynvar(dtrace_dstate_t *dstate, uint_t nkeys, uint64_t hashval = DTRACE_DYNHASH_VALID; dtrace_dynhash_t *hash = dstate->dtds_hash; dtrace_dynvar_t *free, *new_free, *next, *dvar, *start, *prev = NULL; - processorid_t me = CPU->cpu_id, cpu = me; + processorid_t me = curcpu, cpu = me; dtrace_dstate_percpu_t *dcpu = &dstate->dtds_percpu[me]; size_t bucket, ksize; size_t chunksize = dstate->dtds_chunksize; @@ -1368,8 +1477,8 @@ dtrace_dynvar(dtrace_dstate_t *dstate, uint_t nkeys, while ((lock = *lockp) & 1) continue; - if (dtrace_casptr((void *)lockp, - (void *)lock, (void *)(lock + 1)) == (void *)lock) + if (dtrace_casptr((volatile void *)lockp, + (volatile void *)lock, (volatile void *)(lock + 1)) == (void *)lock) break; } @@ -2165,7 +2274,7 @@ dtrace_speculation_commit(dtrace_state_t *state, processorid_t cpu, dtrace_speculation_t *spec; dtrace_buffer_t *src, *dest; uintptr_t daddr, saddr, dlimit; - dtrace_speculation_state_t current, new; + dtrace_speculation_state_t current, new = 0; intptr_t offs; if (which == 0) @@ -2301,7 +2410,7 @@ dtrace_speculation_discard(dtrace_state_t *state, processorid_t cpu, dtrace_specid_t which) { dtrace_speculation_t *spec; - dtrace_speculation_state_t current, new; + dtrace_speculation_state_t current, new = 0; dtrace_buffer_t *buf; if (which == 0) @@ -2359,7 +2468,7 @@ static void dtrace_speculation_clean_here(dtrace_state_t *state) { dtrace_icookie_t cookie; - processorid_t cpu = CPU->cpu_id; + processorid_t cpu = curcpu; dtrace_buffer_t *dest = &state->dts_buffer[cpu]; dtrace_specid_t i; @@ -2463,7 +2572,7 @@ dtrace_speculation_buffer(dtrace_state_t *state, processorid_t cpuid, dtrace_specid_t which) { dtrace_speculation_t *spec; - dtrace_speculation_state_t current, new; + dtrace_speculation_state_t current, new = 0; dtrace_buffer_t *buf; if (which == 0) @@ -2556,7 +2665,7 @@ dtrace_dif_varstr(uintptr_t addr, dtrace_state_t *state, if (mstate->dtms_scratch_ptr + strsz > mstate->dtms_scratch_base + mstate->dtms_scratch_size) { DTRACE_CPUFLAG_SET(CPU_DTRACE_NOSCRATCH); - return (NULL); + return (0); } dtrace_strcpy((const void *)addr, (void *)mstate->dtms_scratch_ptr, @@ -2567,6 +2676,44 @@ dtrace_dif_varstr(uintptr_t addr, dtrace_state_t *state, } /* + * Return a string from a memoy address which is known to have one or + * more concatenated, individually zero terminated, sub-strings. + * In the event that the user lacks the privilege to access + * arbitrary kernel memory, we copy the string out to scratch memory so that we + * don't fail access checking. + * + * dtrace_dif_variable() uses this routine as a helper for various + * builtin values such as 'execargs'. + */ +static uintptr_t +dtrace_dif_varstrz(uintptr_t addr, size_t strsz, dtrace_state_t *state, + dtrace_mstate_t *mstate) +{ + char *p; + size_t i; + uintptr_t ret; + + if (mstate->dtms_scratch_ptr + strsz > + mstate->dtms_scratch_base + mstate->dtms_scratch_size) { + DTRACE_CPUFLAG_SET(CPU_DTRACE_NOSCRATCH); + return (0); + } + + dtrace_bcopy((const void *)addr, (void *)mstate->dtms_scratch_ptr, + strsz); + + /* Replace sub-string termination characters with a space. */ + for (p = (char *) mstate->dtms_scratch_ptr, i = 0; i < strsz - 1; + p++, i++) + if (*p == '\0') + *p = ' '; + + ret = mstate->dtms_scratch_ptr; + mstate->dtms_scratch_ptr += strsz; + return (ret); +} + +/* * This function implements the DIF emulator's variable lookups. The emulator * passes a reserved variable identifier and optional built-in array index. */ @@ -2617,6 +2764,7 @@ dtrace_dif_variable(dtrace_mstate_t *mstate, dtrace_state_t *state, uint64_t v, return (mstate->dtms_arg[ndx]); +#if defined(sun) case DIF_VAR_UREGS: { klwp_t *lwp; @@ -2625,12 +2773,14 @@ dtrace_dif_variable(dtrace_mstate_t *mstate, dtrace_state_t *state, uint64_t v, if ((lwp = curthread->t_lwp) == NULL) { DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR); - cpu_core[CPU->cpu_id].cpuc_dtrace_illval = NULL; + cpu_core[curcpu].cpuc_dtrace_illval = NULL; return (0); } return (dtrace_getreg(lwp->lwp_regs, ndx)); + return (0); } +#endif case DIF_VAR_CURTHREAD: if (!dtrace_priv_kernel(state)) @@ -2655,6 +2805,7 @@ dtrace_dif_variable(dtrace_mstate_t *mstate, dtrace_state_t *state, uint64_t v, } return (mstate->dtms_walltimestamp); +#if defined(sun) case DIF_VAR_IPL: if (!dtrace_priv_kernel(state)) return (0); @@ -2663,6 +2814,7 @@ dtrace_dif_variable(dtrace_mstate_t *mstate, dtrace_state_t *state, uint64_t v, mstate->dtms_present |= DTRACE_MSTATE_IPL; } return (mstate->dtms_ipl); +#endif case DIF_VAR_EPID: ASSERT(mstate->dtms_present & DTRACE_MSTATE_EPID); @@ -2683,6 +2835,7 @@ dtrace_dif_variable(dtrace_mstate_t *mstate, dtrace_state_t *state, uint64_t v, } return (mstate->dtms_stackdepth); +#if defined(sun) case DIF_VAR_USTACKDEPTH: if (!dtrace_priv_proc(state)) return (0); @@ -2702,6 +2855,7 @@ dtrace_dif_variable(dtrace_mstate_t *mstate, dtrace_state_t *state, uint64_t v, mstate->dtms_present |= DTRACE_MSTATE_USTACKDEPTH; } return (mstate->dtms_ustackdepth); +#endif case DIF_VAR_CALLER: if (!dtrace_priv_kernel(state)) @@ -2716,7 +2870,7 @@ dtrace_dif_variable(dtrace_mstate_t *mstate, dtrace_state_t *state, uint64_t v, * dtrace_caller() only guarantees correct * results for anchored probes. */ - pc_t caller[2]; + pc_t caller[2] = {0, 0}; dtrace_getpcstack(caller, 2, aframes, (uint32_t *)(uintptr_t)mstate->dtms_arg[0]); @@ -2728,7 +2882,7 @@ dtrace_dif_variable(dtrace_mstate_t *mstate, dtrace_state_t *state, uint64_t v, * we must resort to the slower approach of * calling dtrace_getpcstack(). */ - pc_t caller; + pc_t caller = 0; dtrace_getpcstack(&caller, 1, aframes, NULL); mstate->dtms_caller = caller; @@ -2738,6 +2892,7 @@ dtrace_dif_variable(dtrace_mstate_t *mstate, dtrace_state_t *state, uint64_t v, } return (mstate->dtms_caller); +#if defined(sun) case DIF_VAR_UCALLER: if (!dtrace_priv_proc(state)) return (0); @@ -2752,7 +2907,7 @@ dtrace_dif_variable(dtrace_mstate_t *mstate, dtrace_state_t *state, uint64_t v, * uint64_t will contain the caller, which is what * we're after. */ - ustack[2] = NULL; + ustack[2] = 0; DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT); dtrace_getupcstack(ustack, 3); DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT); @@ -2761,6 +2916,7 @@ dtrace_dif_variable(dtrace_mstate_t *mstate, dtrace_state_t *state, uint64_t v, } return (mstate->dtms_ucaller); +#endif case DIF_VAR_PROBEPROV: ASSERT(mstate->dtms_present & DTRACE_MSTATE_PROBE); @@ -2790,6 +2946,7 @@ dtrace_dif_variable(dtrace_mstate_t *mstate, dtrace_state_t *state, uint64_t v, if (!dtrace_priv_proc(state)) return (0); +#if defined(sun) /* * Note that we are assuming that an unanchored probe is * always due to a high-level interrupt. (And we're assuming @@ -2807,11 +2964,15 @@ dtrace_dif_variable(dtrace_mstate_t *mstate, dtrace_state_t *state, uint64_t v, * they leave that task to whomever reaps them.) */ return ((uint64_t)curthread->t_procp->p_pidp->pid_id); +#else + return ((uint64_t)curproc->p_pid); +#endif case DIF_VAR_PPID: if (!dtrace_priv_proc(state)) return (0); +#if defined(sun) /* * See comment in DIF_VAR_PID. */ @@ -2825,17 +2986,30 @@ dtrace_dif_variable(dtrace_mstate_t *mstate, dtrace_state_t *state, uint64_t v, * state -- they leave that task to whomever reaps them.) */ return ((uint64_t)curthread->t_procp->p_ppid); +#else + return ((uint64_t)curproc->p_pptr->p_pid); +#endif case DIF_VAR_TID: +#if defined(sun) /* * See comment in DIF_VAR_PID. */ if (DTRACE_ANCHORED(mstate->dtms_probe) && CPU_ON_INTR(CPU)) return (0); +#endif return ((uint64_t)curthread->t_tid); + case DIF_VAR_EXECARGS: { + struct pargs *p_args = curthread->td_proc->p_args; + + return (dtrace_dif_varstrz( + (uintptr_t) p_args->ar_args, p_args->ar_length, state, mstate)); + } + case DIF_VAR_EXECNAME: +#if defined(sun) if (!dtrace_priv_proc(state)) return (0); @@ -2854,8 +3028,13 @@ dtrace_dif_variable(dtrace_mstate_t *mstate, dtrace_state_t *state, uint64_t v, return (dtrace_dif_varstr( (uintptr_t)curthread->t_procp->p_user.u_comm, state, mstate)); +#else + return (dtrace_dif_varstr( + (uintptr_t) curthread->td_proc->p_comm, state, mstate)); +#endif case DIF_VAR_ZONENAME: +#if defined(sun) if (!dtrace_priv_proc(state)) return (0); @@ -2874,16 +3053,21 @@ dtrace_dif_variable(dtrace_mstate_t *mstate, dtrace_state_t *state, uint64_t v, return (dtrace_dif_varstr( (uintptr_t)curthread->t_procp->p_zone->zone_name, state, mstate)); +#else + return (0); +#endif case DIF_VAR_UID: if (!dtrace_priv_proc(state)) return (0); +#if defined(sun) /* * See comment in DIF_VAR_PID. */ if (DTRACE_ANCHORED(mstate->dtms_probe) && CPU_ON_INTR(CPU)) return ((uint64_t)p0.p_cred->cr_uid); +#endif /* * It is always safe to dereference one's own t_procp pointer: @@ -2900,11 +3084,13 @@ dtrace_dif_variable(dtrace_mstate_t *mstate, dtrace_state_t *state, uint64_t v, if (!dtrace_priv_proc(state)) return (0); +#if defined(sun) /* * See comment in DIF_VAR_PID. */ if (DTRACE_ANCHORED(mstate->dtms_probe) && CPU_ON_INTR(CPU)) return ((uint64_t)p0.p_cred->cr_gid); +#endif /* * It is always safe to dereference one's own t_procp pointer: @@ -2918,6 +3104,7 @@ dtrace_dif_variable(dtrace_mstate_t *mstate, dtrace_state_t *state, uint64_t v, return ((uint64_t)curthread->t_procp->p_cred->cr_gid); case DIF_VAR_ERRNO: { +#if defined(sun) klwp_t *lwp; if (!dtrace_priv_proc(state)) return (0); @@ -2938,6 +3125,9 @@ dtrace_dif_variable(dtrace_mstate_t *mstate, dtrace_state_t *state, uint64_t v, return (0); return ((uint64_t)lwp->lwp_errno); +#else + return (curthread->td_errno); +#endif } default: DTRACE_CPUFLAG_SET(CPU_DTRACE_ILLOP); @@ -2957,10 +3147,11 @@ dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs, dtrace_key_t *tupregs, int nargs, dtrace_mstate_t *mstate, dtrace_state_t *state) { - volatile uint16_t *flags = &cpu_core[CPU->cpu_id].cpuc_dtrace_flags; - volatile uintptr_t *illval = &cpu_core[CPU->cpu_id].cpuc_dtrace_illval; + volatile uint16_t *flags = &cpu_core[curcpu].cpuc_dtrace_flags; + volatile uintptr_t *illval = &cpu_core[curcpu].cpuc_dtrace_illval; dtrace_vstate_t *vstate = &state->dts_vstate; +#if defined(sun) union { mutex_impl_t mi; uint64_t mx; @@ -2970,16 +3161,27 @@ dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs, krwlock_t ri; uintptr_t rw; } r; +#else + union { + struct mtx *mi; + uintptr_t mx; + } m; + union { + struct sx *si; + uintptr_t sx; + } s; +#endif switch (subr) { case DIF_SUBR_RAND: regs[rd] = (dtrace_gethrtime() * 2416 + 374441) % 1771875; break; +#if defined(sun) case DIF_SUBR_MUTEX_OWNED: if (!dtrace_canload(tupregs[0].dttk_value, sizeof (kmutex_t), mstate, vstate)) { - regs[rd] = NULL; + regs[rd] = 0; break; } @@ -2993,7 +3195,7 @@ dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs, case DIF_SUBR_MUTEX_OWNER: if (!dtrace_canload(tupregs[0].dttk_value, sizeof (kmutex_t), mstate, vstate)) { - regs[rd] = NULL; + regs[rd] = 0; break; } @@ -3008,7 +3210,7 @@ dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs, case DIF_SUBR_MUTEX_TYPE_ADAPTIVE: if (!dtrace_canload(tupregs[0].dttk_value, sizeof (kmutex_t), mstate, vstate)) { - regs[rd] = NULL; + regs[rd] = 0; break; } @@ -3019,7 +3221,7 @@ dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs, case DIF_SUBR_MUTEX_TYPE_SPIN: if (!dtrace_canload(tupregs[0].dttk_value, sizeof (kmutex_t), mstate, vstate)) { - regs[rd] = NULL; + regs[rd] = 0; break; } @@ -3032,7 +3234,7 @@ dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs, if (!dtrace_canload(tupregs[0].dttk_value, sizeof (uintptr_t), mstate, vstate)) { - regs[rd] = NULL; + regs[rd] = 0; break; } @@ -3044,7 +3246,7 @@ dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs, case DIF_SUBR_RW_WRITE_HELD: if (!dtrace_canload(tupregs[0].dttk_value, sizeof (krwlock_t), mstate, vstate)) { - regs[rd] = NULL; + regs[rd] = 0; break; } @@ -3055,7 +3257,7 @@ dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs, case DIF_SUBR_RW_ISWRITER: if (!dtrace_canload(tupregs[0].dttk_value, sizeof (krwlock_t), mstate, vstate)) { - regs[rd] = NULL; + regs[rd] = 0; break; } @@ -3063,6 +3265,77 @@ dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs, regs[rd] = _RW_ISWRITER(&r.ri); break; +#else + /* + * XXX - The following code works because mutex, rwlocks, & sxlocks + * all have similar data structures in FreeBSD. This may not be + * good if someone changes one of the lock data structures. + * Ideally, it would be nice if all these shared a common lock + * object. + */ + case DIF_SUBR_MUTEX_OWNED: + /* XXX - need to use dtrace_canload() and dtrace_loadptr() */ + m.mx = tupregs[0].dttk_value; + + if (LO_CLASSINDEX(&(m.mi->lock_object)) < 2) { + regs[rd] = !(m.mi->mtx_lock & MTX_UNOWNED); + } else { + regs[rd] = !(m.mi->mtx_lock & SX_UNLOCKED); + } + break; + + case DIF_SUBR_MUTEX_OWNER: + /* XXX - need to use dtrace_canload() and dtrace_loadptr() */ + m.mx = tupregs[0].dttk_value; + + if (LO_CLASSINDEX(&(m.mi->lock_object)) < 2) { + regs[rd] = m.mi->mtx_lock & ~MTX_FLAGMASK; + } else { + if (!(m.mi->mtx_lock & SX_LOCK_SHARED)) + regs[rd] = SX_OWNER(m.mi->mtx_lock); + else + regs[rd] = 0; + } + break; + + case DIF_SUBR_MUTEX_TYPE_ADAPTIVE: + /* XXX - need to use dtrace_canload() and dtrace_loadptr() */ + m.mx = tupregs[0].dttk_value; + + regs[rd] = (LO_CLASSINDEX(&(m.mi->lock_object)) != 0); + break; + + case DIF_SUBR_MUTEX_TYPE_SPIN: + /* XXX - need to use dtrace_canload() and dtrace_loadptr() */ + m.mx = tupregs[0].dttk_value; + + regs[rd] = (LO_CLASSINDEX(&(m.mi->lock_object)) == 0); + break; + + case DIF_SUBR_RW_READ_HELD: + case DIF_SUBR_SX_SHARED_HELD: + /* XXX - need to use dtrace_canload() and dtrace_loadptr() */ + s.sx = tupregs[0].dttk_value; + regs[rd] = ((s.si->sx_lock & SX_LOCK_SHARED) && + (SX_OWNER(s.si->sx_lock) >> SX_SHARERS_SHIFT) != 0); + break; + + case DIF_SUBR_RW_WRITE_HELD: + case DIF_SUBR_SX_EXCLUSIVE_HELD: + /* XXX - need to use dtrace_canload() and dtrace_loadptr() */ + s.sx = tupregs[0].dttk_value; + regs[rd] = (SX_OWNER(s.si->sx_lock) == (uintptr_t) curthread); + break; + + case DIF_SUBR_RW_ISWRITER: + case DIF_SUBR_SX_ISEXCLUSIVE: + /* XXX - need to use dtrace_canload() and dtrace_loadptr() */ + s.sx = tupregs[0].dttk_value; + regs[rd] = ((s.si->sx_lock & SX_LOCK_EXCLUSIVE_WAITERS) || + !(s.si->sx_lock & SX_LOCK_SHARED)); + break; +#endif /* ! defined(sun) */ + case DIF_SUBR_BCOPY: { /* * We need to be sure that the destination is in the scratch @@ -3079,7 +3352,7 @@ dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs, } if (!dtrace_canload(src, size, mstate, vstate)) { - regs[rd] = NULL; + regs[rd] = 0; break; } @@ -3107,7 +3380,7 @@ dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs, if (scratch_size < size || !DTRACE_INSCRATCH(mstate, scratch_size)) { DTRACE_CPUFLAG_SET(CPU_DTRACE_NOSCRATCH); - regs[rd] = NULL; + regs[rd] = 0; break; } @@ -3157,7 +3430,7 @@ dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs, */ if (!DTRACE_INSCRATCH(mstate, size)) { DTRACE_CPUFLAG_SET(CPU_DTRACE_NOSCRATCH); - regs[rd] = NULL; + regs[rd] = 0; break; } @@ -3171,6 +3444,7 @@ dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs, break; } +#if defined(sun) case DIF_SUBR_MSGSIZE: case DIF_SUBR_MSGDSIZE: { uintptr_t baddr = tupregs[0].dttk_value, daddr; @@ -3178,11 +3452,11 @@ dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs, size_t count = 0; int cont = 0; - while (baddr != NULL && !(*flags & CPU_DTRACE_FAULT)) { + while (baddr != 0 && !(*flags & CPU_DTRACE_FAULT)) { if (!dtrace_canload(baddr, sizeof (mblk_t), mstate, vstate)) { - regs[rd] = NULL; + regs[rd] = 0; break; } @@ -3228,6 +3502,7 @@ dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs, break; } +#endif case DIF_SUBR_PROGENYOF: { pid_t pid = tupregs[0].dttk_value; @@ -3237,7 +3512,11 @@ dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs, DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT); for (p = curthread->t_procp; p != NULL; p = p->p_parent) { +#if defined(sun) if (p->p_pidp->pid_id == pid) { +#else + if (p->p_pid == pid) { +#endif rval = 1; break; } @@ -3290,7 +3569,7 @@ dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs, state->dts_options[DTRACEOPT_STRSIZE]); if (!dtrace_canload(addr, sz + 1, mstate, vstate)) { - regs[rd] = NULL; + regs[rd] = 0; break; } @@ -3313,7 +3592,7 @@ dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs, uintptr_t limit = addr + state->dts_options[DTRACEOPT_STRSIZE]; char c, target = (char)tupregs[1].dttk_value; - for (regs[rd] = NULL; addr < limit; addr++) { + for (regs[rd] = 0; addr < limit; addr++) { if ((c = dtrace_load8(addr)) == target) { regs[rd] = addr; @@ -3326,7 +3605,7 @@ dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs, } if (!dtrace_canload(saddr, addr - saddr, mstate, vstate)) { - regs[rd] = NULL; + regs[rd] = 0; break; } @@ -3357,13 +3636,13 @@ dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs, regs[rd] = notfound; if (!dtrace_canload((uintptr_t)addr, len + 1, mstate, vstate)) { - regs[rd] = NULL; + regs[rd] = 0; break; } if (!dtrace_canload((uintptr_t)substr, sublen + 1, mstate, vstate)) { - regs[rd] = NULL; + regs[rd] = 0; break; } @@ -3488,7 +3767,7 @@ dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs, uintptr_t tokaddr = tupregs[1].dttk_value; uint64_t size = state->dts_options[DTRACEOPT_STRSIZE]; uintptr_t limit, toklimit = tokaddr + size; - uint8_t c, tokmap[32]; /* 256 / 8 */ + uint8_t c = 0, tokmap[32]; /* 256 / 8 */ char *dest = (char *)mstate->dtms_scratch_ptr; int i; @@ -3497,17 +3776,17 @@ dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs, * since both could be non-scratch addresses. */ if (!dtrace_strcanload(tokaddr, size, mstate, vstate)) { - regs[rd] = NULL; + regs[rd] = 0; break; } if (!DTRACE_INSCRATCH(mstate, size)) { DTRACE_CPUFLAG_SET(CPU_DTRACE_NOSCRATCH); - regs[rd] = NULL; + regs[rd] = 0; break; } - if (addr == NULL) { + if (addr == 0) { /* * If the address specified is NULL, we use our saved * strtok pointer from the mstate. Note that this @@ -3526,7 +3805,7 @@ dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs, * would fail this access check. */ if (!dtrace_strcanload(addr, size, mstate, vstate)) { - regs[rd] = NULL; + regs[rd] = 0; break; } } @@ -3566,8 +3845,8 @@ dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs, * We return NULL in this case, and we set the saved * address to NULL as well. */ - regs[rd] = NULL; - mstate->dtms_strtok = NULL; + regs[rd] = 0; + mstate->dtms_strtok = 0; break; } @@ -3603,19 +3882,19 @@ dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs, int64_t i = 0; if (!dtrace_canload(s, len + 1, mstate, vstate)) { - regs[rd] = NULL; + regs[rd] = 0; break; } - if (nargs <= 2) - remaining = (int64_t)size; - if (!DTRACE_INSCRATCH(mstate, size)) { DTRACE_CPUFLAG_SET(CPU_DTRACE_NOSCRATCH); - regs[rd] = NULL; + regs[rd] = 0; break; } + if (nargs <= 2) + remaining = (int64_t)size; + if (index < 0) { index += len; @@ -3625,24 +3904,27 @@ dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs, } } - if (index >= len || index < 0) - index = len; - - for (d[0] = '\0'; remaining > 0; remaining--) { - if ((d[i++] = dtrace_load8(s++ + index)) == '\0') - break; + if (index >= len || index < 0) { + remaining = 0; + } else if (remaining < 0) { + remaining += len - index; + } else if (index + remaining > size) { + remaining = size - index; + } - if (i == size) { - d[i - 1] = '\0'; + for (i = 0; i < remaining; i++) { + if ((d[i] = dtrace_load8(s + index + i)) == '\0') break; - } } + d[i] = '\0'; + mstate->dtms_scratch_ptr += size; regs[rd] = (uintptr_t)d; break; } +#if defined(sun) case DIF_SUBR_GETMAJOR: #ifdef _LP64 regs[rd] = (tupregs[0].dttk_value >> NBITSMINOR64) & MAXMAJ64; @@ -3682,12 +3964,12 @@ dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs, if ((mstate->dtms_access & DTRACE_ACCESS_KERNEL) == 0) { *flags |= CPU_DTRACE_KPRIV; *illval = daddr; - regs[rd] = NULL; + regs[rd] = 0; } if (!DTRACE_INSCRATCH(mstate, size)) { DTRACE_CPUFLAG_SET(CPU_DTRACE_NOSCRATCH); - regs[rd] = NULL; + regs[rd] = 0; break; } @@ -3706,9 +3988,9 @@ dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs, * explained to them, and who can't even concisely describe * the conditions under which one would be forced to resort to * this technique. Needless to say, those conditions are - * found here -- and probably only here. Is this is the only - * use of this infamous trick in shipping, production code? - * If it isn't, it probably should be... + * found here -- and probably only here. Is this the only use + * of this infamous trick in shipping, production code? If it + * isn't, it probably should be... */ if (minor != -1) { uintptr_t maddr = dtrace_loadptr(daddr + @@ -3821,7 +4103,7 @@ dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs, * node), we're going to use the special path * "devices". */ - if (daddr == NULL) + if (daddr == 0) s = "devices"; len = dtrace_strlen(s, size); @@ -3844,13 +4126,14 @@ dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs, if (end < start) DTRACE_CPUFLAG_SET(CPU_DTRACE_NOSCRATCH); - if (daddr == NULL) { + if (daddr == 0) { regs[rd] = (uintptr_t)end; mstate->dtms_scratch_ptr += size; } break; } +#endif case DIF_SUBR_STRJOIN: { char *d = (char *)mstate->dtms_scratch_ptr; @@ -3861,20 +4144,20 @@ dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs, if (!dtrace_strcanload(s1, size, mstate, vstate) || !dtrace_strcanload(s2, size, mstate, vstate)) { - regs[rd] = NULL; + regs[rd] = 0; break; } if (!DTRACE_INSCRATCH(mstate, size)) { DTRACE_CPUFLAG_SET(CPU_DTRACE_NOSCRATCH); - regs[rd] = NULL; + regs[rd] = 0; break; } for (;;) { if (i >= size) { DTRACE_CPUFLAG_SET(CPU_DTRACE_NOSCRATCH); - regs[rd] = NULL; + regs[rd] = 0; break; } @@ -3887,7 +4170,7 @@ dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs, for (;;) { if (i >= size) { DTRACE_CPUFLAG_SET(CPU_DTRACE_NOSCRATCH); - regs[rd] = NULL; + regs[rd] = 0; break; } @@ -3911,7 +4194,7 @@ dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs, if (!DTRACE_INSCRATCH(mstate, size)) { DTRACE_CPUFLAG_SET(CPU_DTRACE_NOSCRATCH); - regs[rd] = NULL; + regs[rd] = 0; break; } @@ -3931,7 +4214,7 @@ dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs, case DIF_SUBR_HTONS: case DIF_SUBR_NTOHS: -#ifdef _BIG_ENDIAN +#if BYTE_ORDER == BIG_ENDIAN regs[rd] = (uint16_t)tupregs[0].dttk_value; #else regs[rd] = DT_BSWAP_16((uint16_t)tupregs[0].dttk_value); @@ -3941,7 +4224,7 @@ dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs, case DIF_SUBR_HTONL: case DIF_SUBR_NTOHL: -#ifdef _BIG_ENDIAN +#if BYTE_ORDER == BIG_ENDIAN regs[rd] = (uint32_t)tupregs[0].dttk_value; #else regs[rd] = DT_BSWAP_32((uint32_t)tupregs[0].dttk_value); @@ -3951,7 +4234,7 @@ dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs, case DIF_SUBR_HTONLL: case DIF_SUBR_NTOHLL: -#ifdef _BIG_ENDIAN +#if BYTE_ORDER == BIG_ENDIAN regs[rd] = (uint64_t)tupregs[0].dttk_value; #else regs[rd] = DT_BSWAP_64((uint64_t)tupregs[0].dttk_value); @@ -3969,13 +4252,13 @@ dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs, int start, end; if (!dtrace_canload(src, len + 1, mstate, vstate)) { - regs[rd] = NULL; + regs[rd] = 0; break; } if (!DTRACE_INSCRATCH(mstate, size)) { DTRACE_CPUFLAG_SET(CPU_DTRACE_NOSCRATCH); - regs[rd] = NULL; + regs[rd] = 0; break; } @@ -4097,13 +4380,13 @@ dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs, int i = 0, j = 0; if (!dtrace_strcanload(src, size, mstate, vstate)) { - regs[rd] = NULL; + regs[rd] = 0; break; } if (!DTRACE_INSCRATCH(mstate, size)) { DTRACE_CPUFLAG_SET(CPU_DTRACE_NOSCRATCH); - regs[rd] = NULL; + regs[rd] = 0; break; } @@ -4228,7 +4511,7 @@ next: size = INET_ADDRSTRLEN; if (!DTRACE_INSCRATCH(mstate, size)) { DTRACE_CPUFLAG_SET(CPU_DTRACE_NOSCRATCH); - regs[rd] = NULL; + regs[rd] = 0; break; } base = (char *)mstate->dtms_scratch_ptr; @@ -4283,7 +4566,7 @@ next: size = INET6_ADDRSTRLEN; if (!DTRACE_INSCRATCH(mstate, size)) { DTRACE_CPUFLAG_SET(CPU_DTRACE_NOSCRATCH); - regs[rd] = NULL; + regs[rd] = 0; break; } base = (char *)mstate->dtms_scratch_ptr; @@ -4298,14 +4581,22 @@ next: tryzero = -1; numzero = 1; for (i = 0; i < sizeof (struct in6_addr); i++) { +#if defined(sun) if (ip6._S6_un._S6_u8[i] == 0 && +#else + if (ip6.__u6_addr.__u6_addr8[i] == 0 && +#endif tryzero == -1 && i % 2 == 0) { tryzero = i; continue; } if (tryzero != -1 && +#if defined(sun) (ip6._S6_un._S6_u8[i] != 0 || +#else + (ip6.__u6_addr.__u6_addr8[i] != 0 || +#endif i == sizeof (struct in6_addr) - 1)) { if (i - tryzero <= numzero) { @@ -4317,7 +4608,11 @@ next: numzero = i - i % 2 - tryzero; tryzero = -1; +#if defined(sun) if (ip6._S6_un._S6_u8[i] == 0 && +#else + if (ip6.__u6_addr.__u6_addr8[i] == 0 && +#endif i == sizeof (struct in6_addr) - 1) numzero += 2; } @@ -4334,7 +4629,11 @@ next: i >= DTRACE_V4MAPPED_OFFSET; i--) { ASSERT(end >= base); +#if defined(sun) val = ip6._S6_un._S6_u8[i]; +#else + val = ip6.__u6_addr.__u6_addr8[i]; +#endif if (val == 0) { *end-- = '0'; @@ -4375,8 +4674,13 @@ next: if (i < 14 && i != firstzero - 2) *end-- = ':'; +#if defined(sun) val = (ip6._S6_un._S6_u8[i] << 8) + ip6._S6_un._S6_u8[i + 1]; +#else + val = (ip6.__u6_addr.__u6_addr8[i] << 8) + + ip6.__u6_addr.__u6_addr8[i + 1]; +#endif if (val == 0) { *end-- = '0'; @@ -4393,7 +4697,7 @@ next: * The user didn't use AH_INET or AH_INET6. */ DTRACE_CPUFLAG_SET(CPU_DTRACE_ILLOP); - regs[rd] = NULL; + regs[rd] = 0; break; } @@ -4402,6 +4706,35 @@ inetout: regs[rd] = (uintptr_t)end + 1; break; } + case DIF_SUBR_MEMREF: { + uintptr_t size = 2 * sizeof(uintptr_t); + uintptr_t *memref = (uintptr_t *) P2ROUNDUP(mstate->dtms_scratch_ptr, sizeof(uintptr_t)); + size_t scratch_size = ((uintptr_t) memref - mstate->dtms_scratch_ptr) + size; + + /* address and length */ + memref[0] = tupregs[0].dttk_value; + memref[1] = tupregs[1].dttk_value; + + regs[rd] = (uintptr_t) memref; + mstate->dtms_scratch_ptr += scratch_size; + break; + } + + case DIF_SUBR_TYPEREF: { + uintptr_t size = 4 * sizeof(uintptr_t); + uintptr_t *typeref = (uintptr_t *) P2ROUNDUP(mstate->dtms_scratch_ptr, sizeof(uintptr_t)); + size_t scratch_size = ((uintptr_t) typeref - mstate->dtms_scratch_ptr) + size; + + /* address, num_elements, type_str, type_len */ + typeref[0] = tupregs[0].dttk_value; + typeref[1] = tupregs[1].dttk_value; + typeref[2] = tupregs[2].dttk_value; + typeref[3] = tupregs[3].dttk_value; + + regs[rd] = (uintptr_t) typeref; + mstate->dtms_scratch_ptr += scratch_size; + break; + } } } @@ -4423,8 +4756,8 @@ dtrace_dif_emulate(dtrace_difo_t *difo, dtrace_mstate_t *mstate, dtrace_statvar_t *svar; dtrace_dstate_t *dstate = &vstate->dtvs_dynvars; dtrace_difv_t *v; - volatile uint16_t *flags = &cpu_core[CPU->cpu_id].cpuc_dtrace_flags; - volatile uintptr_t *illval = &cpu_core[CPU->cpu_id].cpuc_dtrace_illval; + volatile uint16_t *flags = &cpu_core[curcpu].cpuc_dtrace_flags; + volatile uintptr_t *illval = &cpu_core[curcpu].cpuc_dtrace_illval; dtrace_key_t tupregs[DIF_DTR_NREGS + 2]; /* +2 for thread and id */ uint64_t regs[DIF_DIR_NREGS]; @@ -4432,7 +4765,7 @@ dtrace_dif_emulate(dtrace_difo_t *difo, dtrace_mstate_t *mstate, uint8_t cc_n = 0, cc_z = 0, cc_v = 0, cc_c = 0; int64_t cc_r; - uint_t pc = 0, id, opc; + uint_t pc = 0, id, opc = 0; uint8_t ttop = 0; dif_instr_t instr; uint_t r1, r2, rd; @@ -4692,10 +5025,10 @@ dtrace_dif_emulate(dtrace_difo_t *difo, dtrace_mstate_t *mstate, uintptr_t s1 = regs[r1]; uintptr_t s2 = regs[r2]; - if (s1 != NULL && + if (s1 != 0 && !dtrace_strcanload(s1, sz, mstate, vstate)) break; - if (s2 != NULL && + if (s2 != 0 && !dtrace_strcanload(s2, sz, mstate, vstate)) break; @@ -4734,7 +5067,7 @@ dtrace_dif_emulate(dtrace_difo_t *difo, dtrace_mstate_t *mstate, * then this is to be treated as a * reference to a NULL variable. */ - regs[rd] = NULL; + regs[rd] = 0; } else { regs[rd] = a + sizeof (uint64_t); } @@ -4758,10 +5091,10 @@ dtrace_dif_emulate(dtrace_difo_t *difo, dtrace_mstate_t *mstate, if (v->dtdv_type.dtdt_flags & DIF_TF_BYREF) { uintptr_t a = (uintptr_t)svar->dtsv_data; - ASSERT(a != NULL); + ASSERT(a != 0); ASSERT(svar->dtsv_size != 0); - if (regs[rd] == NULL) { + if (regs[rd] == 0) { *(uint8_t *)a = UINT8_MAX; break; } else { @@ -4816,7 +5149,7 @@ dtrace_dif_emulate(dtrace_difo_t *difo, dtrace_mstate_t *mstate, sz += sizeof (uint64_t); ASSERT(svar->dtsv_size == NCPU * sz); - a += CPU->cpu_id * sz; + a += curcpu * sz; if (*(uint8_t *)a == UINT8_MAX) { /* @@ -4824,7 +5157,7 @@ dtrace_dif_emulate(dtrace_difo_t *difo, dtrace_mstate_t *mstate, * then this is to be treated as a * reference to a NULL variable. */ - regs[rd] = NULL; + regs[rd] = 0; } else { regs[rd] = a + sizeof (uint64_t); } @@ -4834,7 +5167,7 @@ dtrace_dif_emulate(dtrace_difo_t *difo, dtrace_mstate_t *mstate, ASSERT(svar->dtsv_size == NCPU * sizeof (uint64_t)); tmp = (uint64_t *)(uintptr_t)svar->dtsv_data; - regs[rd] = tmp[CPU->cpu_id]; + regs[rd] = tmp[curcpu]; break; case DIF_OP_STLS: @@ -4855,9 +5188,9 @@ dtrace_dif_emulate(dtrace_difo_t *difo, dtrace_mstate_t *mstate, sz += sizeof (uint64_t); ASSERT(svar->dtsv_size == NCPU * sz); - a += CPU->cpu_id * sz; + a += curcpu * sz; - if (regs[rd] == NULL) { + if (regs[rd] == 0) { *(uint8_t *)a = UINT8_MAX; break; } else { @@ -4877,7 +5210,7 @@ dtrace_dif_emulate(dtrace_difo_t *difo, dtrace_mstate_t *mstate, ASSERT(svar->dtsv_size == NCPU * sizeof (uint64_t)); tmp = (uint64_t *)(uintptr_t)svar->dtsv_data; - tmp[CPU->cpu_id] = regs[rd]; + tmp[curcpu] = regs[rd]; break; case DIF_OP_LDTS: { @@ -4938,7 +5271,7 @@ dtrace_dif_emulate(dtrace_difo_t *difo, dtrace_mstate_t *mstate, * Given that we're storing to thread-local data, * we need to flush our predicate cache. */ - curthread->t_predcache = NULL; + curthread->t_predcache = 0; if (dvar == NULL) break; @@ -5109,7 +5442,7 @@ dtrace_dif_emulate(dtrace_difo_t *difo, dtrace_mstate_t *mstate, if (size < regs[r1] || !DTRACE_INSCRATCH(mstate, size)) { DTRACE_CPUFLAG_SET(CPU_DTRACE_NOSCRATCH); - regs[rd] = NULL; + regs[rd] = 0; break; } @@ -5255,7 +5588,11 @@ dtrace_action_breakpoint(dtrace_ecb_t *ecb) c[i++] = ')'; c[i] = '\0'; +#if defined(sun) debug_enter(c); +#else + kdb_enter(KDB_WHY_DTRACE, "breakpoint action"); +#endif } static void @@ -5298,6 +5635,7 @@ dtrace_action_raise(uint64_t sig) return; } +#if defined(sun) /* * raise() has a queue depth of 1 -- we ignore all subsequent * invocations of the raise() action. @@ -5307,6 +5645,12 @@ dtrace_action_raise(uint64_t sig) curthread->t_sig_check = 1; aston(curthread); +#else + struct proc *p = curproc; + PROC_LOCK(p); + psignal(p, sig); + PROC_UNLOCK(p); +#endif } static void @@ -5315,11 +5659,18 @@ dtrace_action_stop(void) if (dtrace_destructive_disallow) return; +#if defined(sun) if (!curthread->t_dtrace_stop) { curthread->t_dtrace_stop = 1; curthread->t_sig_check = 1; aston(curthread); } +#else + struct proc *p = curproc; + PROC_LOCK(p); + psignal(p, SIGSTOP); + PROC_UNLOCK(p); +#endif } static void @@ -5327,7 +5678,11 @@ dtrace_action_chill(dtrace_mstate_t *mstate, hrtime_t val) { hrtime_t now; volatile uint16_t *flags; +#if defined(sun) cpu_t *cpu = CPU; +#else + cpu_t *cpu = &solaris_cpu[curcpu]; +#endif if (dtrace_destructive_disallow) return; @@ -5367,6 +5722,7 @@ dtrace_action_chill(dtrace_mstate_t *mstate, hrtime_t val) cpu->cpu_dtrace_chilled += val; } +#if defined(sun) static void dtrace_action_ustack(dtrace_mstate_t *mstate, dtrace_state_t *state, uint64_t *buf, uint64_t arg) @@ -5377,7 +5733,7 @@ dtrace_action_ustack(dtrace_mstate_t *mstate, dtrace_state_t *state, char *str = (char *)&pcs[nframes]; int size, offs = 0, i, j; uintptr_t old = mstate->dtms_scratch_ptr, saved; - uint16_t *flags = &cpu_core[CPU->cpu_id].cpuc_dtrace_flags; + uint16_t *flags = &cpu_core[curcpu].cpuc_dtrace_flags; char *sym; /* @@ -5479,6 +5835,7 @@ dtrace_action_ustack(dtrace_mstate_t *mstate, dtrace_state_t *state, out: mstate->dtms_scratch_ptr = old; } +#endif /* * If you're looking for the epicenter of DTrace, you just found it. This @@ -5501,6 +5858,7 @@ dtrace_probe(dtrace_id_t id, uintptr_t arg0, uintptr_t arg1, volatile uint16_t *flags; hrtime_t now; +#if defined(sun) /* * Kick out immediately if this CPU is still being born (in which case * curthread will be set to -1) or the current thread can't allow @@ -5508,10 +5866,11 @@ dtrace_probe(dtrace_id_t id, uintptr_t arg0, uintptr_t arg1, */ if (((uintptr_t)curthread & 1) || (curthread->t_flag & T_DONTDTRACE)) return; +#endif cookie = dtrace_interrupt_disable(); probe = dtrace_probes[id - 1]; - cpuid = CPU->cpu_id; + cpuid = curcpu; onintr = CPU_ON_INTR(CPU); if (!onintr && probe->dtpr_predcache != DTRACE_CACHEIDNONE && @@ -5524,7 +5883,11 @@ dtrace_probe(dtrace_id_t id, uintptr_t arg0, uintptr_t arg1, return; } +#if defined(sun) if (panic_quiesce) { +#else + if (panicstr != NULL) { +#endif /* * We don't trace anything if we're panicking. */ @@ -5540,7 +5903,7 @@ dtrace_probe(dtrace_id_t id, uintptr_t arg0, uintptr_t arg1, mstate.dtms_difo = NULL; mstate.dtms_probe = probe; - mstate.dtms_strtok = NULL; + mstate.dtms_strtok = 0; mstate.dtms_arg[0] = arg0; mstate.dtms_arg[1] = arg1; mstate.dtms_arg[2] = arg2; @@ -5569,11 +5932,7 @@ dtrace_probe(dtrace_id_t id, uintptr_t arg0, uintptr_t arg1, * arguments to aggregating actions, one iteration of the * action loop will use the last iteration's value. */ -#ifdef lint uint64_t val = 0; -#else - uint64_t val; -#endif mstate.dtms_present = DTRACE_MSTATE_ARGS | DTRACE_MSTATE_PROBE; *flags &= ~CPU_DTRACE_ERROR; @@ -5627,6 +5986,7 @@ dtrace_probe(dtrace_id_t id, uintptr_t arg0, uintptr_t arg1, probe->dtpr_id, probe->dtpr_arg) == 0) continue; +#if defined(sun) /* * This is more subtle than it looks. We have to be * absolutely certain that CRED() isn't going to @@ -5671,6 +6031,7 @@ dtrace_probe(dtrace_id_t id, uintptr_t arg0, uintptr_t arg1, cr->cr_zone->zone_id) continue; } +#endif } if (now - state->dts_alive > dtrace_deadman_timeout) { @@ -5795,9 +6156,9 @@ dtrace_probe(dtrace_id_t id, uintptr_t arg0, uintptr_t arg1, size / sizeof (pc_t), probe->dtpr_aframes, DTRACE_ANCHORED(probe) ? NULL : (uint32_t *)arg0); - continue; +#if defined(sun) case DTRACEACT_JSTACK: case DTRACEACT_USTACK: if (!dtrace_priv_proc(state)) @@ -5839,6 +6200,7 @@ dtrace_probe(dtrace_id_t id, uintptr_t arg0, uintptr_t arg1, DTRACE_USTACK_NFRAMES(rec->dtrd_arg) + 1); DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT); continue; +#endif default: break; @@ -5880,6 +6242,103 @@ dtrace_probe(dtrace_id_t id, uintptr_t arg0, uintptr_t arg1, ecb->dte_epid); continue; + case DTRACEACT_PRINTM: { + /* The DIF returns a 'memref'. */ + uintptr_t *memref = (uintptr_t *)(uintptr_t) val; + + /* Get the size from the memref. */ + size = memref[1]; + + /* + * Check if the size exceeds the allocated + * buffer size. + */ + if (size + sizeof(uintptr_t) > dp->dtdo_rtype.dtdt_size) { + /* Flag a drop! */ + *flags |= CPU_DTRACE_DROP; + continue; + } + + /* Store the size in the buffer first. */ + DTRACE_STORE(uintptr_t, tomax, + valoffs, size); + + /* + * Offset the buffer address to the start + * of the data. + */ + valoffs += sizeof(uintptr_t); + + /* + * Reset to the memory address rather than + * the memref array, then let the BYREF + * code below do the work to store the + * memory data in the buffer. + */ + val = memref[0]; + break; + } + + case DTRACEACT_PRINTT: { + /* The DIF returns a 'typeref'. */ + uintptr_t *typeref = (uintptr_t *)(uintptr_t) val; + char c = '\0' + 1; + size_t s; + + /* + * Get the type string length and round it + * up so that the data that follows is + * aligned for easy access. + */ + size_t typs = strlen((char *) typeref[2]) + 1; + typs = roundup(typs, sizeof(uintptr_t)); + + /* + *Get the size from the typeref using the + * number of elements and the type size. + */ + size = typeref[1] * typeref[3]; + + /* + * Check if the size exceeds the allocated + * buffer size. + */ + if (size + typs + 2 * sizeof(uintptr_t) > dp->dtdo_rtype.dtdt_size) { + /* Flag a drop! */ + *flags |= CPU_DTRACE_DROP; + + } + + /* Store the size in the buffer first. */ + DTRACE_STORE(uintptr_t, tomax, + valoffs, size); + valoffs += sizeof(uintptr_t); + + /* Store the type size in the buffer. */ + DTRACE_STORE(uintptr_t, tomax, + valoffs, typeref[3]); + valoffs += sizeof(uintptr_t); + + val = typeref[2]; + + for (s = 0; s < typs; s++) { + if (c != '\0') + c = dtrace_load8(val++); + + DTRACE_STORE(uint8_t, tomax, + valoffs++, c); + } + + /* + * Reset to the memory address rather than + * the typeref array, then let the BYREF + * code below do the work to store the + * memory data in the buffer. + */ + val = typeref[0]; + break; + } + case DTRACEACT_CHILL: if (dtrace_priv_kernel_destructive(state)) dtrace_action_chill(&mstate, val); @@ -5924,13 +6383,19 @@ dtrace_probe(dtrace_id_t id, uintptr_t arg0, uintptr_t arg1, case DTRACEACT_USYM: case DTRACEACT_UMOD: case DTRACEACT_UADDR: { +#if defined(sun) struct pid *pid = curthread->t_procp->p_pidp; +#endif if (!dtrace_priv_proc(state)) continue; DTRACE_STORE(uint64_t, tomax, +#if defined(sun) valoffs, (uint64_t)pid->pid_id); +#else + valoffs, (uint64_t) curproc->p_pid); +#endif DTRACE_STORE(uint64_t, tomax, valoffs + sizeof (uint64_t), val); @@ -6113,7 +6578,7 @@ dtrace_probe(dtrace_id_t id, uintptr_t arg0, uintptr_t arg1, * specified.) */ static uint_t -dtrace_hash_str(char *p) +dtrace_hash_str(const char *p) { unsigned int g; uint_t hval = 0; @@ -6257,7 +6722,7 @@ dtrace_hash_collisions(dtrace_hash_t *hash, dtrace_probe_t *template) return (bucket->dthb_len); } - return (NULL); + return (0); } static void @@ -6369,6 +6834,7 @@ dtrace_cred2priv(cred_t *cr, uint32_t *privp, uid_t *uidp, zoneid_t *zoneidp) { uint32_t priv; +#if defined(sun) if (cr == NULL || PRIV_POLICY_ONLY(cr, PRIV_ALL, B_FALSE)) { /* * For DTRACE_PRIV_ALL, the uid and zoneid don't matter. @@ -6390,6 +6856,9 @@ dtrace_cred2priv(cred_t *cr, uint32_t *privp, uid_t *uidp, zoneid_t *zoneidp) if (PRIV_POLICY_ONLY(cr, PRIV_PROC_ZONE, B_FALSE)) priv |= DTRACE_PRIV_ZONEOWNER; } +#else + priv = DTRACE_PRIV_ALL; +#endif *privp = priv; } @@ -6398,7 +6867,7 @@ dtrace_cred2priv(cred_t *cr, uint32_t *privp, uid_t *uidp, zoneid_t *zoneidp) static void dtrace_errdebug(const char *str) { - int hval = dtrace_hash_str((char *)str) % DTRACE_ERRHASHSZ; + int hval = dtrace_hash_str(str) % DTRACE_ERRHASHSZ; int occupied = 0; mutex_enter(&dtrace_errlock); @@ -6768,7 +7237,7 @@ dtrace_probekey_func(const char *p) * dtrace_match_nonzero(). */ static void -dtrace_probekey(const dtrace_probedesc_t *pdp, dtrace_probekey_t *pkp) +dtrace_probekey(dtrace_probedesc_t *pdp, dtrace_probekey_t *pkp) { pkp->dtpk_prov = pdp->dtpd_provider; pkp->dtpk_pmatch = dtrace_probekey_func(pdp->dtpd_provider); @@ -6871,13 +7340,13 @@ dtrace_register(const char *name, const dtrace_pattr_t *pap, uint32_t priv, if (pops->dtps_provide == NULL) { ASSERT(pops->dtps_provide_module != NULL); provider->dtpv_pops.dtps_provide = - (void (*)(void *, const dtrace_probedesc_t *))dtrace_nullop; + (void (*)(void *, dtrace_probedesc_t *))dtrace_nullop; } if (pops->dtps_provide_module == NULL) { ASSERT(pops->dtps_provide != NULL); provider->dtpv_pops.dtps_provide_module = - (void (*)(void *, struct modctl *))dtrace_nullop; + (void (*)(void *, modctl_t *))dtrace_nullop; } if (pops->dtps_suspend == NULL) { @@ -6959,7 +7428,9 @@ dtrace_unregister(dtrace_provider_id_t id) * already held. */ ASSERT(old == dtrace_provider); +#if defined(sun) ASSERT(dtrace_devi != NULL); +#endif ASSERT(MUTEX_HELD(&dtrace_provider_lock)); ASSERT(MUTEX_HELD(&dtrace_lock)); self = 1; @@ -7057,13 +7528,19 @@ dtrace_unregister(dtrace_provider_id_t id) kmem_free(probe->dtpr_mod, strlen(probe->dtpr_mod) + 1); kmem_free(probe->dtpr_func, strlen(probe->dtpr_func) + 1); kmem_free(probe->dtpr_name, strlen(probe->dtpr_name) + 1); +#if defined(sun) vmem_free(dtrace_arena, (void *)(uintptr_t)(probe->dtpr_id), 1); +#else + free_unr(dtrace_arena, probe->dtpr_id); +#endif kmem_free(probe, sizeof (dtrace_probe_t)); } if ((prev = dtrace_provider) == old) { +#if defined(sun) ASSERT(self || dtrace_devi == NULL); ASSERT(old->dtpv_next == NULL || dtrace_devi == NULL); +#endif dtrace_provider = old->dtpv_next; } else { while (prev != NULL && prev->dtpv_next != old) @@ -7170,7 +7647,11 @@ dtrace_condense(dtrace_provider_id_t id) kmem_free(probe->dtpr_func, strlen(probe->dtpr_func) + 1); kmem_free(probe->dtpr_name, strlen(probe->dtpr_name) + 1); kmem_free(probe, sizeof (dtrace_probe_t)); +#if defined(sun) vmem_free(dtrace_arena, (void *)((uintptr_t)i + 1), 1); +#else + free_unr(dtrace_arena, i + 1); +#endif } mutex_exit(&dtrace_lock); @@ -7206,8 +7687,12 @@ dtrace_probe_create(dtrace_provider_id_t prov, const char *mod, mutex_enter(&dtrace_lock); } +#if defined(sun) id = (dtrace_id_t)(uintptr_t)vmem_alloc(dtrace_arena, 1, VM_BESTFIT | VM_SLEEP); +#else + id = alloc_unr(dtrace_arena); +#endif probe = kmem_zalloc(sizeof (dtrace_probe_t), KM_SLEEP); probe->dtpr_id = id; @@ -7292,8 +7777,8 @@ dtrace_probe_lookup_match(dtrace_probe_t *probe, void *arg) * name and probe name. */ dtrace_id_t -dtrace_probe_lookup(dtrace_provider_id_t prid, const char *mod, - const char *func, const char *name) +dtrace_probe_lookup(dtrace_provider_id_t prid, char *mod, + char *func, char *name) { dtrace_probekey_t pkey; dtrace_id_t id; @@ -7355,6 +7840,19 @@ dtrace_probe_description(const dtrace_probe_t *prp, dtrace_probedesc_t *pdp) (void) strncpy(pdp->dtpd_name, prp->dtpr_name, DTRACE_NAMELEN - 1); } +#if !defined(sun) +static int +dtrace_probe_provide_cb(linker_file_t lf, void *arg) +{ + dtrace_provider_t *prv = (dtrace_provider_t *) arg; + + prv->dtpv_pops.dtps_provide_module(prv->dtpv_arg, lf); + + return(0); +} +#endif + + /* * Called to indicate that a probe -- or probes -- should be provided by a * specfied provider. If the specified description is NULL, the provider will @@ -7373,7 +7871,9 @@ dtrace_probe_description(const dtrace_probe_t *prp, dtrace_probedesc_t *pdp) static void dtrace_probe_provide(dtrace_probedesc_t *desc, dtrace_provider_t *prv) { - struct modctl *ctl; +#if defined(sun) + modctl_t *ctl; +#endif int all = 0; ASSERT(MUTEX_HELD(&dtrace_provider_lock)); @@ -7397,6 +7897,7 @@ dtrace_probe_provide(dtrace_probedesc_t *desc, dtrace_provider_t *prv) */ mutex_enter(&mod_lock); +#if defined(sun) ctl = &modules; do { if (ctl->mod_busy || ctl->mod_mp == NULL) @@ -7405,11 +7906,15 @@ dtrace_probe_provide(dtrace_probedesc_t *desc, dtrace_provider_t *prv) prv->dtpv_pops.dtps_provide_module(prv->dtpv_arg, ctl); } while ((ctl = ctl->mod_next) != &modules); +#else + (void) linker_file_foreach(dtrace_probe_provide_cb, prv); +#endif mutex_exit(&mod_lock); } while (all && (prv = prv->dtpv_next) != NULL); } +#if defined(sun) /* * Iterate over each probe, and call the Framework-to-Provider API function * denoted by offs. @@ -7450,9 +7955,10 @@ dtrace_probe_foreach(uintptr_t offs) dtrace_interrupt_enable(cookie); } +#endif static int -dtrace_probe_enable(const dtrace_probedesc_t *desc, dtrace_enabling_t *enab) +dtrace_probe_enable(dtrace_probedesc_t *desc, dtrace_enabling_t *enab) { dtrace_probekey_t pkey; uint32_t priv; @@ -7621,6 +8127,7 @@ dtrace_helper_provide(dof_helper_t *dhp, pid_t pid) dtrace_enabling_matchall(); } +#if defined(sun) static void dtrace_helper_provider_remove_one(dof_helper_t *dhp, dof_sec_t *sec, pid_t pid) { @@ -7668,6 +8175,7 @@ dtrace_helper_provider_remove(dof_helper_t *dhp, pid_t pid) dtrace_helper_provider_remove_one(dhp, sec, pid); } } +#endif /* * DTrace Meta Provider-to-Framework API Functions @@ -8207,6 +8715,7 @@ dtrace_difo_validate(dtrace_difo_t *dp, dtrace_vstate_t *vstate, uint_t nregs, return (err); } +#if defined(sun) /* * Validate a DTrace DIF object that it is to be used as a helper. Helpers * are much more constrained than normal DIFOs. Specifically, they may @@ -8306,6 +8815,7 @@ dtrace_difo_validate_helper(dtrace_difo_t *dp) if (v == DIF_VAR_CURTHREAD || v == DIF_VAR_PID || v == DIF_VAR_PPID || v == DIF_VAR_TID || + v == DIF_VAR_EXECARGS || v == DIF_VAR_EXECNAME || v == DIF_VAR_ZONENAME || v == DIF_VAR_UID || v == DIF_VAR_GID) break; @@ -8347,7 +8857,9 @@ dtrace_difo_validate_helper(dtrace_difo_t *dp) subr == DIF_SUBR_HTONLL || subr == DIF_SUBR_NTOHS || subr == DIF_SUBR_NTOHL || - subr == DIF_SUBR_NTOHLL) + subr == DIF_SUBR_NTOHLL || + subr == DIF_SUBR_MEMREF || + subr == DIF_SUBR_TYPEREF) break; err += efunc(pc, "invalid subr %u\n", subr); @@ -8361,6 +8873,7 @@ dtrace_difo_validate_helper(dtrace_difo_t *dp) return (err); } +#endif /* * Returns 1 if the expression in the DIF object can be cached on a per-thread @@ -8384,6 +8897,7 @@ dtrace_difo_cacheable(dtrace_difo_t *dp) case DIF_VAR_CURTHREAD: case DIF_VAR_PID: case DIF_VAR_TID: + case DIF_VAR_EXECARGS: case DIF_VAR_EXECNAME: case DIF_VAR_ZONENAME: break; @@ -8446,7 +8960,7 @@ dtrace_difo_hold(dtrace_difo_t *dp) static void dtrace_difo_chunksize(dtrace_difo_t *dp, dtrace_vstate_t *vstate) { - uint64_t sval; + uint64_t sval = 0; dtrace_key_t tupregs[DIF_DTR_NREGS + 2]; /* +2 for thread and id */ const dif_instr_t *text = dp->dtdo_buf; uint_t pc, srd = 0; @@ -8460,7 +8974,7 @@ dtrace_difo_chunksize(dtrace_difo_t *dp, dtrace_vstate_t *vstate) uint_t rd = DIF_INSTR_RD(instr); uint_t r1 = DIF_INSTR_R1(instr); uint_t nkeys = 0; - uchar_t scope; + uchar_t scope = 0; dtrace_key_t *key = tupregs; @@ -8589,10 +9103,10 @@ dtrace_difo_init(dtrace_difo_t *dp, dtrace_vstate_t *vstate) for (i = 0; i < dp->dtdo_varlen; i++) { dtrace_difv_t *v = &dp->dtdo_vartab[i]; - dtrace_statvar_t *svar, ***svarp; + dtrace_statvar_t *svar, ***svarp = NULL; size_t dsize = 0; uint8_t scope = v->dtdv_scope; - int *np; + int *np = NULL; if ((id = v->dtdv_id) < DIF_VAR_OTHER_UBASE) continue; @@ -8691,6 +9205,7 @@ dtrace_difo_init(dtrace_difo_t *dp, dtrace_vstate_t *vstate) dtrace_difo_hold(dp); } +#if defined(sun) static dtrace_difo_t * dtrace_difo_duplicate(dtrace_difo_t *dp, dtrace_vstate_t *vstate) { @@ -8734,6 +9249,7 @@ dtrace_difo_duplicate(dtrace_difo_t *dp, dtrace_vstate_t *vstate) dtrace_difo_init(new, vstate); return (new); } +#endif static void dtrace_difo_destroy(dtrace_difo_t *dp, dtrace_vstate_t *vstate) @@ -8744,10 +9260,10 @@ dtrace_difo_destroy(dtrace_difo_t *dp, dtrace_vstate_t *vstate) for (i = 0; i < dp->dtdo_varlen; i++) { dtrace_difv_t *v = &dp->dtdo_vartab[i]; - dtrace_statvar_t *svar, **svarp; + dtrace_statvar_t *svar, **svarp = NULL; uint_t id; uint8_t scope = v->dtdv_scope; - int *np; + int *np = NULL; switch (scope) { case DIFV_SCOPE_THREAD: @@ -8781,7 +9297,7 @@ dtrace_difo_destroy(dtrace_difo_t *dp, dtrace_vstate_t *vstate) continue; if (svar->dtsv_size != 0) { - ASSERT(svar->dtsv_data != NULL); + ASSERT(svar->dtsv_data != 0); kmem_free((void *)(uintptr_t)svar->dtsv_data, svar->dtsv_size); } @@ -8790,10 +9306,14 @@ dtrace_difo_destroy(dtrace_difo_t *dp, dtrace_vstate_t *vstate) svarp[id] = NULL; } - kmem_free(dp->dtdo_buf, dp->dtdo_len * sizeof (dif_instr_t)); - kmem_free(dp->dtdo_inttab, dp->dtdo_intlen * sizeof (uint64_t)); - kmem_free(dp->dtdo_strtab, dp->dtdo_strlen); - kmem_free(dp->dtdo_vartab, dp->dtdo_varlen * sizeof (dtrace_difv_t)); + if (dp->dtdo_buf != NULL) + kmem_free(dp->dtdo_buf, dp->dtdo_len * sizeof (dif_instr_t)); + if (dp->dtdo_inttab != NULL) + kmem_free(dp->dtdo_inttab, dp->dtdo_intlen * sizeof (uint64_t)); + if (dp->dtdo_strtab != NULL) + kmem_free(dp->dtdo_strtab, dp->dtdo_strlen); + if (dp->dtdo_vartab != NULL) + kmem_free(dp->dtdo_vartab, dp->dtdo_varlen * sizeof (dtrace_difv_t)); kmem_free(dp, sizeof (dtrace_difo_t)); } @@ -8977,8 +9497,10 @@ dtrace_actdesc_create(dtrace_actkind_t kind, uint32_t ntuple, { dtrace_actdesc_t *act; +#if defined(sun) ASSERT(!DTRACEACT_ISPRINTFLIKE(kind) || (arg != NULL && arg >= KERNELBASE) || (arg == NULL && kind == DTRACEACT_PRINTA)); +#endif act = kmem_zalloc(sizeof (dtrace_actdesc_t), KM_SLEEP); act->dtad_kind = kind; @@ -9014,8 +9536,10 @@ dtrace_actdesc_release(dtrace_actdesc_t *act, dtrace_vstate_t *vstate) if (DTRACEACT_ISPRINTFLIKE(kind)) { char *str = (char *)(uintptr_t)act->dtad_arg; +#if defined(sun) ASSERT((str != NULL && (uintptr_t)str >= KERNELBASE) || (str == NULL && act->dtad_kind == DTRACEACT_PRINTA)); +#endif if (str != NULL) kmem_free(str, strlen(str) + 1); @@ -9169,7 +9693,7 @@ dtrace_ecb_resize(dtrace_ecb_t *ecb) */ diff = offs + sizeof (dtrace_aggid_t); - if (diff = (diff & (sizeof (uint64_t) - 1))) + if ((diff = (diff & (sizeof (uint64_t) - 1)))) offs += sizeof (uint64_t) - diff; aggbase = offs - sizeof (dtrace_aggid_t); @@ -9375,8 +9899,12 @@ success: /* * We need to allocate an id for this aggregation. */ +#if defined(sun) aggid = (dtrace_aggid_t)(uintptr_t)vmem_alloc(state->dts_aggid_arena, 1, VM_BESTFIT | VM_SLEEP); +#else + aggid = alloc_unr(state->dts_aggid_arena); +#endif if (aggid - 1 >= state->dts_naggregations) { dtrace_aggregation_t **oaggs = state->dts_aggregations; @@ -9425,7 +9953,11 @@ dtrace_ecb_aggregation_destroy(dtrace_ecb_t *ecb, dtrace_action_t *act) dtrace_aggid_t aggid = agg->dtag_id; ASSERT(DTRACEACT_ISAGG(act->dta_kind)); +#if defined(sun) vmem_free(state->dts_aggid_arena, (void *)(uintptr_t)aggid, 1); +#else + free_unr(state->dts_aggid_arena, aggid); +#endif ASSERT(state->dts_aggregations[aggid - 1] == agg); state->dts_aggregations[aggid - 1] = NULL; @@ -9442,7 +9974,7 @@ dtrace_ecb_action_add(dtrace_ecb_t *ecb, dtrace_actdesc_t *desc) uint16_t format = 0; dtrace_recdesc_t *rec; dtrace_state_t *state = ecb->dte_state; - dtrace_optval_t *opt = state->dts_options, nframes, strsize; + dtrace_optval_t *opt = state->dts_options, nframes = 0, strsize; uint64_t arg = desc->dtad_arg; ASSERT(MUTEX_HELD(&dtrace_lock)); @@ -9483,12 +10015,14 @@ dtrace_ecb_action_add(dtrace_ecb_t *ecb, dtrace_actdesc_t *desc) * We know that our arg is a string -- turn it into a * format. */ - if (arg == NULL) { + if (arg == 0) { ASSERT(desc->dtad_kind == DTRACEACT_PRINTA); format = 0; } else { - ASSERT(arg != NULL); + ASSERT(arg != 0); +#if defined(sun) ASSERT(arg > KERNELBASE); +#endif format = dtrace_format_add(state, (char *)(uintptr_t)arg); } @@ -9603,6 +10137,14 @@ dtrace_ecb_action_add(dtrace_ecb_t *ecb, dtrace_actdesc_t *desc) state->dts_speculates = 1; break; + case DTRACEACT_PRINTM: + size = dp->dtdo_rtype.dtdt_size; + break; + + case DTRACEACT_PRINTT: + size = dp->dtdo_rtype.dtdt_size; + break; + case DTRACEACT_COMMIT: { dtrace_action_t *act = ecb->dte_action; @@ -10005,7 +10547,7 @@ dtrace_buffer_activate(dtrace_state_t *state) dtrace_buffer_t *buf; dtrace_icookie_t cookie = dtrace_interrupt_disable(); - buf = &state->dts_buffer[CPU->cpu_id]; + buf = &state->dts_buffer[curcpu]; if (buf->dtb_tomax != NULL) { /* @@ -10025,9 +10567,14 @@ static int dtrace_buffer_alloc(dtrace_buffer_t *bufs, size_t size, int flags, processorid_t cpu) { +#if defined(sun) cpu_t *cp; +#else + struct pcpu *cp; +#endif dtrace_buffer_t *buf; +#if defined(sun) ASSERT(MUTEX_HELD(&cpu_lock)); ASSERT(MUTEX_HELD(&dtrace_lock)); @@ -10098,6 +10645,91 @@ err: } while ((cp = cp->cpu_next) != cpu_list); return (ENOMEM); +#else + int i; + +#if defined(__amd64__) + /* + * FreeBSD isn't good at limiting the amount of memory we + * ask to malloc, so let's place a limit here before trying + * to do something that might well end in tears at bedtime. + */ + if (size > physmem * PAGE_SIZE / (128 * (mp_maxid + 1))) + return(ENOMEM); +#endif + + ASSERT(MUTEX_HELD(&dtrace_lock)); + for (i = 0; i <= mp_maxid; i++) { + if ((cp = pcpu_find(i)) == NULL) + continue; + + if (cpu != DTRACE_CPUALL && cpu != i) + continue; + + buf = &bufs[i]; + + /* + * If there is already a buffer allocated for this CPU, it + * is only possible that this is a DR event. In this case, + * the buffer size must match our specified size. + */ + if (buf->dtb_tomax != NULL) { + ASSERT(buf->dtb_size == size); + continue; + } + + ASSERT(buf->dtb_xamot == NULL); + + if ((buf->dtb_tomax = kmem_zalloc(size, KM_NOSLEEP)) == NULL) + goto err; + + buf->dtb_size = size; + buf->dtb_flags = flags; + buf->dtb_offset = 0; + buf->dtb_drops = 0; + + if (flags & DTRACEBUF_NOSWITCH) + continue; + + if ((buf->dtb_xamot = kmem_zalloc(size, KM_NOSLEEP)) == NULL) + goto err; + } + + return (0); + +err: + /* + * Error allocating memory, so free the buffers that were + * allocated before the failed allocation. + */ + for (i = 0; i <= mp_maxid; i++) { + if ((cp = pcpu_find(i)) == NULL) + continue; + + if (cpu != DTRACE_CPUALL && cpu != i) + continue; + + buf = &bufs[i]; + + if (buf->dtb_xamot != NULL) { + ASSERT(buf->dtb_tomax != NULL); + ASSERT(buf->dtb_size == size); + kmem_free(buf->dtb_xamot, size); + } + + if (buf->dtb_tomax != NULL) { + ASSERT(buf->dtb_size == size); + kmem_free(buf->dtb_tomax, size); + } + + buf->dtb_tomax = NULL; + buf->dtb_xamot = NULL; + buf->dtb_size = 0; + + } + + return (ENOMEM); +#endif } /* @@ -10469,7 +11101,8 @@ dtrace_enabling_add(dtrace_enabling_t *enab, dtrace_ecbdesc_t *ecb) nsize = enab->dten_maxdesc * sizeof (dtrace_enabling_t *); ndesc = kmem_zalloc(nsize, KM_SLEEP); bcopy(enab->dten_desc, ndesc, osize); - kmem_free(enab->dten_desc, osize); + if (enab->dten_desc != NULL) + kmem_free(enab->dten_desc, osize); enab->dten_desc = ndesc; enab->dten_desc[enab->dten_ndesc++] = ecb; @@ -10543,8 +11176,9 @@ dtrace_enabling_destroy(dtrace_enabling_t *enab) kmem_free(ep, sizeof (dtrace_ecbdesc_t)); } - kmem_free(enab->dten_desc, - enab->dten_maxdesc * sizeof (dtrace_enabling_t *)); + if (enab->dten_desc != NULL) + kmem_free(enab->dten_desc, + enab->dten_maxdesc * sizeof (dtrace_enabling_t *)); /* * If this was a retained enabling, decrement the dts_nretained count @@ -10776,33 +11410,6 @@ dtrace_enabling_matchall(void) mutex_exit(&cpu_lock); } -static int -dtrace_enabling_matchstate(dtrace_state_t *state, int *nmatched) -{ - dtrace_enabling_t *enab; - int matched, total = 0, err; - - ASSERT(MUTEX_HELD(&cpu_lock)); - ASSERT(MUTEX_HELD(&dtrace_lock)); - - for (enab = dtrace_retained; enab != NULL; enab = enab->dten_next) { - ASSERT(enab->dten_vstate->dtvs_state != NULL); - - if (enab->dten_vstate->dtvs_state != state) - continue; - - if ((err = dtrace_enabling_match(enab, &matched)) != 0) - return (err); - - total += matched; - } - - if (nmatched != NULL) - *nmatched = total; - - return (0); -} - /* * If an enabling is to be enabled without having matched probes (that is, if * dtrace_state_go() is to be called on the underlying dtrace_state_t), the @@ -11004,6 +11611,41 @@ dtrace_dof_copyin(uintptr_t uarg, int *errp) return (dof); } +#if !defined(sun) +static __inline uchar_t +dtrace_dof_char(char c) { + switch (c) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + return (c - '0'); + case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + return (c - 'A' + 10); + case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + return (c - 'a' + 10); + } + /* Should not reach here. */ + return (0); +} +#endif + static dof_hdr_t * dtrace_dof_property(const char *name) { @@ -11012,6 +11654,7 @@ dtrace_dof_property(const char *name) unsigned int len, i; dof_hdr_t *dof; +#if defined(sun) /* * Unfortunately, array of values in .conf files are always (and * only) interpreted to be integer arrays. We must read our DOF @@ -11045,6 +11688,47 @@ dtrace_dof_property(const char *name) dof = kmem_alloc(loadsz, KM_SLEEP); bcopy(buf, dof, loadsz); ddi_prop_free(buf); +#else + char *p; + char *p_env; + + if ((p_env = getenv(name)) == NULL) + return (NULL); + + len = strlen(p_env) / 2; + + buf = kmem_alloc(len, KM_SLEEP); + + dof = (dof_hdr_t *) buf; + + p = p_env; + + for (i = 0; i < len; i++) { + buf[i] = (dtrace_dof_char(p[0]) << 4) | + dtrace_dof_char(p[1]); + p += 2; + } + + freeenv(p_env); + + if (len < sizeof (dof_hdr_t)) { + kmem_free(buf, 0); + dtrace_dof_error(NULL, "truncated header"); + return (NULL); + } + + if (len < (loadsz = dof->dofh_loadsz)) { + kmem_free(buf, 0); + dtrace_dof_error(NULL, "truncated DOF"); + return (NULL); + } + + if (loadsz >= dtrace_dof_maxsize) { + kmem_free(buf, 0); + dtrace_dof_error(NULL, "oversized DOF"); + return (NULL); + } +#endif return (dof); } @@ -11189,7 +11873,7 @@ dtrace_dof_difo(dof_hdr_t *dof, dof_sec_t *sec, dtrace_vstate_t *vstate, offsetof(dtrace_difo_t, dtdo_varlen), sizeof (dtrace_difv_t), sizeof (uint_t), "multiple variable tables" }, - { DOF_SECT_NONE, 0, 0, 0, NULL } + { DOF_SECT_NONE, 0, 0, 0, 0, NULL } }; if (sec->dofs_type != DOF_SECT_DIFOHDR) { @@ -11854,7 +12538,7 @@ dtrace_dof_options(dof_hdr_t *dof, dtrace_state_t *state) /* * DTrace Consumer State Functions */ -int +static int dtrace_dstate_init(dtrace_dstate_t *dstate, size_t size) { size_t hashsize, maxper, min, chunksize = dstate->dtds_chunksize; @@ -11915,6 +12599,10 @@ dtrace_dstate_init(dtrace_dstate_t *dstate, size_t size) maxper = (maxper / dstate->dtds_chunksize) * dstate->dtds_chunksize; for (i = 0; i < NCPU; i++) { +#if !defined(sun) + if (CPU_ABSENT(i)) + continue; +#endif dstate->dtds_percpu[i].dtdsc_free = dvar = start; /* @@ -11952,7 +12640,7 @@ dtrace_dstate_init(dtrace_dstate_t *dstate, size_t size) return (0); } -void +static void dtrace_dstate_fini(dtrace_dstate_t *dstate) { ASSERT(MUTEX_HELD(&cpu_lock)); @@ -12007,6 +12695,10 @@ dtrace_state_deadman(dtrace_state_t *state) dtrace_sync(); +#if !defined(sun) + dtrace_debug_output(); +#endif + now = dtrace_gethrtime(); if (state != dtrace_anon.dta_state && @@ -12027,11 +12719,20 @@ dtrace_state_deadman(dtrace_state_t *state) state->dts_alive = now; } -dtrace_state_t * +static dtrace_state_t * +#if defined(sun) dtrace_state_create(dev_t *devp, cred_t *cr) +#else +dtrace_state_create(struct cdev *dev) +#endif { +#if defined(sun) minor_t minor; major_t major; +#else + cred_t *cr = NULL; + int m = 0; +#endif char c[30]; dtrace_state_t *state; dtrace_optval_t *opt; @@ -12040,6 +12741,7 @@ dtrace_state_create(dev_t *devp, cred_t *cr) ASSERT(MUTEX_HELD(&dtrace_lock)); ASSERT(MUTEX_HELD(&cpu_lock)); +#if defined(sun) minor = (minor_t)(uintptr_t)vmem_alloc(dtrace_minor, 1, VM_BESTFIT | VM_SLEEP); @@ -12049,9 +12751,20 @@ dtrace_state_create(dev_t *devp, cred_t *cr) } state = ddi_get_soft_state(dtrace_softstate, minor); +#else + if (dev != NULL) { + cr = dev->si_cred; + m = minor(dev); + } + + /* Allocate memory for the state. */ + state = kmem_zalloc(sizeof(dtrace_state_t), KM_SLEEP); +#endif + state->dts_epid = DTRACE_EPIDNONE + 1; - (void) snprintf(c, sizeof (c), "dtrace_aggid_%d", minor); + (void) snprintf(c, sizeof (c), "dtrace_aggid_%d", m); +#if defined(sun) state->dts_aggid_arena = vmem_create(c, (void *)1, UINT32_MAX, 1, NULL, NULL, NULL, 0, VM_SLEEP | VMC_IDENTIFIER); @@ -12065,6 +12778,10 @@ dtrace_state_create(dev_t *devp, cred_t *cr) if (devp != NULL) *devp = state->dts_dev; +#else + state->dts_aggid_arena = new_unrhdr(1, INT_MAX, &dtrace_unr_mtx); + state->dts_dev = dev; +#endif /* * We allocate NCPU buffers. On the one hand, this can be quite @@ -12159,11 +12876,13 @@ dtrace_state_create(dev_t *devp, cred_t *cr) * we can do destructive things to processes which * have altered credentials. */ +#if defined(sun) if (priv_isequalset(priv_getset(cr, PRIV_EFFECTIVE), cr->cr_zone->zone_privset)) { state->dts_cred.dcr_action |= DTRACE_CRA_PROC_DESTRUCTIVE_CREDCHG; } +#endif } /* @@ -12199,6 +12918,7 @@ dtrace_state_create(dev_t *devp, cred_t *cr) state->dts_cred.dcr_action |= DTRACE_CRA_PROC_DESTRUCTIVE_ALLZONE; +#if defined(sun) /* * If we have all privs in whatever zone this is, * we can do destructive things to processes which @@ -12209,6 +12929,7 @@ dtrace_state_create(dev_t *devp, cred_t *cr) state->dts_cred.dcr_action |= DTRACE_CRA_PROC_DESTRUCTIVE_CREDCHG; } +#endif } /* @@ -12235,7 +12956,7 @@ static int dtrace_state_buffer(dtrace_state_t *state, dtrace_buffer_t *buf, int which) { dtrace_optval_t *opt = state->dts_options, size; - processorid_t cpu; + processorid_t cpu = 0;; int flags = 0, rval; ASSERT(MUTEX_HELD(&dtrace_lock)); @@ -12534,7 +13255,9 @@ dtrace_state_go(dtrace_state_t *state, processorid_t *cpu) hdlr.cyh_func = (cyc_func_t)dtrace_state_clean; hdlr.cyh_arg = state; +#if defined(sun) hdlr.cyh_level = CY_LOW_LEVEL; +#endif when.cyt_when = 0; when.cyt_interval = opt[DTRACEOPT_CLEANRATE]; @@ -12543,7 +13266,9 @@ dtrace_state_go(dtrace_state_t *state, processorid_t *cpu) hdlr.cyh_func = (cyc_func_t)dtrace_state_deadman; hdlr.cyh_arg = state; +#if defined(sun) hdlr.cyh_level = CY_LOW_LEVEL; +#endif when.cyt_when = 0; when.cyt_interval = dtrace_deadman_interval; @@ -12560,7 +13285,7 @@ dtrace_state_go(dtrace_state_t *state, processorid_t *cpu) * level) and to manually activate the buffer for this CPU. */ cookie = dtrace_interrupt_disable(); - *cpu = CPU->cpu_id; + *cpu = curcpu; ASSERT(state->dts_buffer[*cpu].dtb_flags & DTRACEBUF_INACTIVE); state->dts_buffer[*cpu].dtb_flags &= ~DTRACEBUF_INACTIVE; @@ -12661,7 +13386,7 @@ dtrace_state_stop(dtrace_state_t *state, processorid_t *cpu) state->dts_reserve = 0; cookie = dtrace_interrupt_disable(); - *cpu = CPU->cpu_id; + *cpu = curcpu; dtrace_probe(dtrace_probeid_end, (uint64_t)(uintptr_t)state, 0, 0, 0, 0); dtrace_interrupt_enable(cookie); @@ -12732,7 +13457,9 @@ dtrace_state_destroy(dtrace_state_t *state) { dtrace_ecb_t *ecb; dtrace_vstate_t *vstate = &state->dts_vstate; +#if defined(sun) minor_t minor = getminor(state->dts_dev); +#endif int i, bufsize = NCPU * sizeof (dtrace_buffer_t); dtrace_speculation_t *spec = state->dts_speculations; int nspec = state->dts_nspeculations; @@ -12816,7 +13543,8 @@ dtrace_state_destroy(dtrace_state_t *state) dtrace_dstate_fini(&vstate->dtvs_dynvars); dtrace_vstate_fini(vstate); - kmem_free(state->dts_ecbs, state->dts_necbs * sizeof (dtrace_ecb_t *)); + if (state->dts_ecbs != NULL) + kmem_free(state->dts_ecbs, state->dts_necbs * sizeof (dtrace_ecb_t *)); if (state->dts_aggregations != NULL) { #ifdef DEBUG @@ -12834,13 +13562,23 @@ dtrace_state_destroy(dtrace_state_t *state) for (i = 0; i < nspec; i++) kmem_free(spec[i].dtsp_buffer, bufsize); - kmem_free(spec, nspec * sizeof (dtrace_speculation_t)); + if (spec != NULL) + kmem_free(spec, nspec * sizeof (dtrace_speculation_t)); dtrace_format_destroy(state); - vmem_destroy(state->dts_aggid_arena); + if (state->dts_aggid_arena != NULL) { +#if defined(sun) + vmem_destroy(state->dts_aggid_arena); +#else + delete_unrhdr(state->dts_aggid_arena); +#endif + state->dts_aggid_arena = NULL; + } +#if defined(sun) ddi_soft_state_free(dtrace_softstate, minor); vmem_free(dtrace_minor, (void *)(uintptr_t)minor, 1); +#endif } /* @@ -12889,6 +13627,7 @@ dtrace_anon_property(void) break; } +#if defined(sun) /* * We want to create anonymous state, so we need to transition * the kernel debugger to indicate that DTrace is active. If @@ -12901,12 +13640,17 @@ dtrace_anon_property(void) dtrace_dof_destroy(dof); break; } +#endif /* * If we haven't allocated an anonymous state, we'll do so now. */ if ((state = dtrace_anon.dta_state) == NULL) { +#if defined(sun) state = dtrace_state_create(NULL, NULL); +#else + state = dtrace_state_create(NULL); +#endif dtrace_anon.dta_state = state; if (state == NULL) { @@ -12967,6 +13711,7 @@ dtrace_anon_property(void) } } +#if defined(sun) /* * DTrace Helper Functions */ @@ -12976,7 +13721,7 @@ dtrace_helper_trace(dtrace_helper_action_t *helper, { uint32_t size, next, nnext, i; dtrace_helptrace_t *ent; - uint16_t flags = cpu_core[CPU->cpu_id].cpuc_dtrace_flags; + uint16_t flags = cpu_core[curcpu].cpuc_dtrace_flags; if (!dtrace_helptrace_enabled) return; @@ -13017,7 +13762,7 @@ dtrace_helper_trace(dtrace_helper_action_t *helper, ent->dtht_fltoffs = (mstate->dtms_present & DTRACE_MSTATE_FLTOFFS) ? mstate->dtms_fltoffs : -1; ent->dtht_fault = DTRACE_FLAGS2FLT(flags); - ent->dtht_illval = cpu_core[CPU->cpu_id].cpuc_dtrace_illval; + ent->dtht_illval = cpu_core[curcpu].cpuc_dtrace_illval; for (i = 0; i < vstate->dtvs_nlocals; i++) { dtrace_statvar_t *svar; @@ -13027,15 +13772,17 @@ dtrace_helper_trace(dtrace_helper_action_t *helper, ASSERT(svar->dtsv_size >= NCPU * sizeof (uint64_t)); ent->dtht_locals[i] = - ((uint64_t *)(uintptr_t)svar->dtsv_data)[CPU->cpu_id]; + ((uint64_t *)(uintptr_t)svar->dtsv_data)[curcpu]; } } +#endif +#if defined(sun) static uint64_t dtrace_helper(int which, dtrace_mstate_t *mstate, dtrace_state_t *state, uint64_t arg0, uint64_t arg1) { - uint16_t *flags = &cpu_core[CPU->cpu_id].cpuc_dtrace_flags; + uint16_t *flags = &cpu_core[curcpu].cpuc_dtrace_flags; uint64_t sarg0 = mstate->dtms_arg[0]; uint64_t sarg1 = mstate->dtms_arg[1]; uint64_t rval; @@ -13119,7 +13866,7 @@ err: mstate->dtms_arg[0] = sarg0; mstate->dtms_arg[1] = sarg1; - return (NULL); + return (0); } static void @@ -13229,7 +13976,9 @@ dtrace_helper_destroygen(int gen) return (0); } +#endif +#if defined(sun) static int dtrace_helper_validate(dtrace_helper_action_t *helper) { @@ -13244,7 +13993,9 @@ dtrace_helper_validate(dtrace_helper_action_t *helper) return (err == 0); } +#endif +#if defined(sun) static int dtrace_helper_action_add(int which, dtrace_ecbdesc_t *ep) { @@ -13964,12 +14715,14 @@ dtrace_helpers_duplicate(proc_t *from, proc_t *to) if (hasprovs) dtrace_helper_provider_register(to, newhelp, NULL); } +#endif +#if defined(sun) /* * DTrace Hook Functions */ static void -dtrace_module_loaded(struct modctl *ctl) +dtrace_module_loaded(modctl_t *ctl) { dtrace_provider_t *prv; @@ -14022,7 +14775,7 @@ dtrace_module_loaded(struct modctl *ctl) } static void -dtrace_module_unloaded(struct modctl *ctl) +dtrace_module_unloaded(modctl_t *ctl) { dtrace_probe_t template, *probe, *first, *next; dtrace_provider_t *prov; @@ -14115,17 +14868,18 @@ dtrace_module_unloaded(struct modctl *ctl) mutex_exit(&dtrace_provider_lock); } -void +static void dtrace_suspend(void) { dtrace_probe_foreach(offsetof(dtrace_pops_t, dtps_suspend)); } -void +static void dtrace_resume(void) { dtrace_probe_foreach(offsetof(dtrace_pops_t, dtps_resume)); } +#endif static int dtrace_cpu_setup(cpu_setup_t what, processorid_t cpu) @@ -14186,11 +14940,13 @@ dtrace_cpu_setup(cpu_setup_t what, processorid_t cpu) return (0); } +#if defined(sun) static void dtrace_cpu_setup_initial(processorid_t cpu) { (void) dtrace_cpu_setup(CPU_CONFIG, cpu); } +#endif static void dtrace_toxrange_add(uintptr_t base, uintptr_t limit) @@ -14221,8 +14977,8 @@ dtrace_toxrange_add(uintptr_t base, uintptr_t limit) dtrace_toxrange = range; } - ASSERT(dtrace_toxrange[dtrace_toxranges].dtt_base == NULL); - ASSERT(dtrace_toxrange[dtrace_toxranges].dtt_limit == NULL); + ASSERT(dtrace_toxrange[dtrace_toxranges].dtt_base == 0); + ASSERT(dtrace_toxrange[dtrace_toxranges].dtt_limit == 0); dtrace_toxrange[dtrace_toxranges].dtt_base = base; dtrace_toxrange[dtrace_toxranges].dtt_limit = limit; @@ -14232,6 +14988,7 @@ dtrace_toxrange_add(uintptr_t base, uintptr_t limit) /* * DTrace Driver Cookbook Functions */ +#if defined(sun) /*ARGSUSED*/ static int dtrace_attach(dev_info_t *devi, ddi_attach_cmd_t cmd) @@ -14398,16 +15155,22 @@ dtrace_attach(dev_info_t *devi, ddi_attach_cmd_t cmd) return (DDI_SUCCESS); } +#endif /*ARGSUSED*/ static int +#if defined(sun) dtrace_open(dev_t *devp, int flag, int otyp, cred_t *cred_p) +#else +dtrace_open(struct cdev *dev, int oflags, int devtype, struct thread *td) +#endif { dtrace_state_t *state; uint32_t priv; uid_t uid; zoneid_t zoneid; +#if defined(sun) if (getminor(*devp) == DTRACEMNRN_HELPER) return (0); @@ -14416,14 +15179,41 @@ dtrace_open(dev_t *devp, int flag, int otyp, cred_t *cred_p) * the "dtrace" minor. */ ASSERT(getminor(*devp) == DTRACEMNRN_DTRACE); +#else + cred_t *cred_p = NULL; + + /* + * The first minor device is the one that is cloned so there is + * nothing more to do here. + */ + if (minor(dev) == 0) + return 0; + + /* + * Devices are cloned, so if the DTrace state has already + * been allocated, that means this device belongs to a + * different client. Each client should open '/dev/dtrace' + * to get a cloned device. + */ + if (dev->si_drv1 != NULL) + return (EBUSY); + + cred_p = dev->si_cred; +#endif /* * If no DTRACE_PRIV_* bits are set in the credential, then the * caller lacks sufficient permission to do anything with DTrace. */ dtrace_cred2priv(cred_p, &priv, &uid, &zoneid); - if (priv == DTRACE_PRIV_NONE) + if (priv == DTRACE_PRIV_NONE) { +#if !defined(sun) + /* Destroy the cloned device. */ + destroy_dev(dev); +#endif + return (EACCES); + } /* * Ask all providers to provide all their probes. @@ -14437,6 +15227,7 @@ dtrace_open(dev_t *devp, int flag, int otyp, cred_t *cred_p) dtrace_opens++; dtrace_membar_producer(); +#if defined(sun) /* * If the kernel debugger is active (that is, if the kernel debugger * modified text in some way), we won't allow the open. @@ -14449,12 +15240,25 @@ dtrace_open(dev_t *devp, int flag, int otyp, cred_t *cred_p) } state = dtrace_state_create(devp, cred_p); +#else + state = dtrace_state_create(dev); + dev->si_drv1 = state; +#endif + mutex_exit(&cpu_lock); if (state == NULL) { +#if defined(sun) if (--dtrace_opens == 0) (void) kdi_dtrace_set(KDI_DTSET_DTRACE_DEACTIVATE); +#else + --dtrace_opens; +#endif mutex_exit(&dtrace_lock); +#if !defined(sun) + /* Destroy the cloned device. */ + destroy_dev(dev); +#endif return (EAGAIN); } @@ -14465,8 +15269,13 @@ dtrace_open(dev_t *devp, int flag, int otyp, cred_t *cred_p) /*ARGSUSED*/ static int +#if defined(sun) dtrace_close(dev_t dev, int flag, int otyp, cred_t *cred_p) +#else +dtrace_close(struct cdev *dev, int flags, int fmt __unused, struct thread *td) +#endif { +#if defined(sun) minor_t minor = getminor(dev); dtrace_state_t *state; @@ -14474,29 +15283,53 @@ dtrace_close(dev_t dev, int flag, int otyp, cred_t *cred_p) return (0); state = ddi_get_soft_state(dtrace_softstate, minor); +#else + dtrace_state_t *state = dev->si_drv1; + + /* Check if this is not a cloned device. */ + if (minor(dev) == 0) + return (0); + +#endif mutex_enter(&cpu_lock); mutex_enter(&dtrace_lock); - if (state->dts_anon) { - /* - * There is anonymous state. Destroy that first. - */ - ASSERT(dtrace_anon.dta_state == NULL); - dtrace_state_destroy(state->dts_anon); + if (state != NULL) { + if (state->dts_anon) { + /* + * There is anonymous state. Destroy that first. + */ + ASSERT(dtrace_anon.dta_state == NULL); + dtrace_state_destroy(state->dts_anon); + } + + dtrace_state_destroy(state); + +#if !defined(sun) + kmem_free(state, 0); + dev->si_drv1 = NULL; +#endif } - dtrace_state_destroy(state); ASSERT(dtrace_opens > 0); +#if defined(sun) if (--dtrace_opens == 0) (void) kdi_dtrace_set(KDI_DTSET_DTRACE_DEACTIVATE); +#else + --dtrace_opens; +#endif mutex_exit(&dtrace_lock); mutex_exit(&cpu_lock); + /* Schedule this cloned device to be destroyed. */ + destroy_dev_sched(dev); + return (0); } +#if defined(sun) /*ARGSUSED*/ static int dtrace_ioctl_helper(int cmd, intptr_t arg, int *rv) @@ -14594,6 +15427,7 @@ dtrace_ioctl(dev_t dev, int cmd, intptr_t arg, int md, cred_t *cr, int *rv) bcopy(&pvp->dtpv_priv, &pvd.dtvd_priv, sizeof (dtrace_ppriv_t)); bcopy(&pvp->dtpv_attr, &pvd.dtvd_attr, sizeof (dtrace_pattr_t)); + if (copyout(&pvd, (void *)arg, sizeof (pvd)) != 0) return (EFAULT); @@ -14790,13 +15624,9 @@ dtrace_ioctl(dev_t dev, int cmd, intptr_t arg, int md, cred_t *cr, int *rv) * cue to reevaluate our enablings. */ if (arg == NULL) { - mutex_enter(&cpu_lock); - mutex_enter(&dtrace_lock); - err = dtrace_enabling_matchstate(state, rv); - mutex_exit(&dtrace_lock); - mutex_exit(&cpu_lock); + dtrace_enabling_matchall(); - return (err); + return (0); } if ((dof = dtrace_dof_copyin(arg, &rval)) == NULL) @@ -15436,7 +16266,9 @@ dtrace_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) return (DDI_SUCCESS); } +#endif +#if defined(sun) /*ARGSUSED*/ static int dtrace_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result) @@ -15457,7 +16289,9 @@ dtrace_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result) } return (error); } +#endif +#if defined(sun) static struct cb_ops dtrace_cb_ops = { dtrace_open, /* open */ dtrace_close, /* close */ @@ -15519,3 +16353,43 @@ _fini(void) { return (mod_remove(&modlinkage)); } +#else + +static d_ioctl_t dtrace_ioctl; +static void dtrace_load(void *); +static int dtrace_unload(void); +static void dtrace_clone(void *, struct ucred *, char *, int , struct cdev **); +static struct clonedevs *dtrace_clones; /* Ptr to the array of cloned devices. */ +static eventhandler_tag eh_tag; /* Event handler tag. */ + +void dtrace_invop_init(void); +void dtrace_invop_uninit(void); + +static struct cdevsw dtrace_cdevsw = { + .d_version = D_VERSION, + .d_close = dtrace_close, + .d_ioctl = dtrace_ioctl, + .d_open = dtrace_open, + .d_name = "dtrace", +}; + +#include <dtrace_anon.c> +#include <dtrace_clone.c> +#include <dtrace_ioctl.c> +#include <dtrace_load.c> +#include <dtrace_modevent.c> +#include <dtrace_sysctl.c> +#include <dtrace_unload.c> +#include <dtrace_vtime.c> +#include <dtrace_hacks.c> +#include <dtrace_isa.c> + +SYSINIT(dtrace_load, SI_SUB_DTRACE, SI_ORDER_FIRST, dtrace_load, NULL); +SYSUNINIT(dtrace_unload, SI_SUB_DTRACE, SI_ORDER_FIRST, dtrace_unload, NULL); +SYSINIT(dtrace_anon_init, SI_SUB_DTRACE_ANON, SI_ORDER_FIRST, dtrace_anon_init, NULL); + +DEV_MODULE(dtrace, dtrace_modevent, NULL); +MODULE_VERSION(dtrace, 1); +MODULE_DEPEND(dtrace, cyclic, 1, 1, 1); +MODULE_DEPEND(dtrace, opensolaris, 1, 1, 1); +#endif diff --git a/sys/cddl/contrib/opensolaris/uts/common/dtrace/fasttrap.c b/sys/cddl/contrib/opensolaris/uts/common/dtrace/fasttrap.c index dd78b48..b7ca92f 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/dtrace/fasttrap.c +++ b/sys/cddl/contrib/opensolaris/uts/common/dtrace/fasttrap.c @@ -20,7 +20,7 @@ */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -390,7 +390,7 @@ fasttrap_pid_cleanup(void) /* * This is called from cfork() via dtrace_fasttrap_fork(). The child - * process's address space is a (roughly) a copy of the parent process's so + * process's address space is (roughly) a copy of the parent process's so * we have to remove all the instrumentation we had previously enabled in the * parent. */ @@ -437,6 +437,15 @@ fasttrap_fork(proc_t *p, proc_t *cp) tp->ftt_proc->ftpc_acount != 0) { int ret = fasttrap_tracepoint_remove(cp, tp); ASSERT(ret == 0); + + /* + * The count of active providers can only be + * decremented (i.e. to zero) during exec, + * exit, and removal of a meta provider so it + * should be impossible to drop the count + * mid-fork. + */ + ASSERT(tp->ftt_proc->ftpc_acount != 0); } } mutex_exit(&bucket->ftb_mtx); @@ -517,6 +526,12 @@ fasttrap_tracepoint_enable(proc_t *p, fasttrap_probe_t *probe, uint_t index) again: mutex_enter(&bucket->ftb_mtx); for (tp = bucket->ftb_data; tp != NULL; tp = tp->ftt_next) { + /* + * Note that it's safe to access the active count on the + * associated proc structure because we know that at least one + * provider (this one) will still be around throughout this + * operation. + */ if (tp->ftt_pid != pid || tp->ftt_pc != pc || tp->ftt_proc->ftpc_acount == 0) continue; @@ -1157,6 +1172,7 @@ fasttrap_proc_lookup(pid_t pid) mutex_exit(&bucket->ftb_mtx); fprc->ftpc_rcount++; atomic_add_64(&fprc->ftpc_acount, 1); + ASSERT(fprc->ftpc_acount <= fprc->ftpc_rcount); mutex_exit(&fprc->ftpc_mtx); return (fprc); @@ -1186,6 +1202,7 @@ fasttrap_proc_lookup(pid_t pid) mutex_exit(&bucket->ftb_mtx); fprc->ftpc_rcount++; atomic_add_64(&fprc->ftpc_acount, 1); + ASSERT(fprc->ftpc_acount <= fprc->ftpc_rcount); mutex_exit(&fprc->ftpc_mtx); kmem_free(new_fprc, sizeof (fasttrap_proc_t)); @@ -1212,6 +1229,7 @@ fasttrap_proc_release(fasttrap_proc_t *proc) mutex_enter(&proc->ftpc_mtx); ASSERT(proc->ftpc_rcount != 0); + ASSERT(proc->ftpc_acount <= proc->ftpc_rcount); if (--proc->ftpc_rcount != 0) { mutex_exit(&proc->ftpc_mtx); @@ -1390,6 +1408,16 @@ fasttrap_provider_free(fasttrap_provider_t *provider) ASSERT(provider->ftp_ccount == 0); ASSERT(provider->ftp_mcount == 0); + /* + * If this provider hasn't been retired, we need to explicitly drop the + * count of active providers on the associated process structure. + */ + if (!provider->ftp_retired) { + atomic_add_64(&provider->ftp_proc->ftpc_acount, -1); + ASSERT(provider->ftp_proc->ftpc_acount < + provider->ftp_proc->ftpc_rcount); + } + fasttrap_proc_release(provider->ftp_proc); kmem_free(provider, sizeof (fasttrap_provider_t)); @@ -1461,6 +1489,8 @@ fasttrap_provider_retire(pid_t pid, const char *name, int mprov) * table. */ atomic_add_64(&fp->ftp_proc->ftpc_acount, -1); + ASSERT(fp->ftp_proc->ftpc_acount < fp->ftp_proc->ftpc_rcount); + fp->ftp_retired = 1; fp->ftp_marked = 1; provid = fp->ftp_provid; @@ -2014,6 +2044,13 @@ err: tp->ftt_proc->ftpc_acount != 0) break; + /* + * The count of active providers can only be + * decremented (i.e. to zero) during exec, exit, and + * removal of a meta provider so it should be + * impossible to drop the count during this operation(). + */ + ASSERT(tp->ftt_proc->ftpc_acount != 0); tp = tp->ftt_next; } diff --git a/sys/cddl/contrib/opensolaris/uts/common/sys/cpuvar.h b/sys/cddl/contrib/opensolaris/uts/common/sys/cpuvar.h index c7b76b3..cd0d027 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/sys/cpuvar.h +++ b/sys/cddl/contrib/opensolaris/uts/common/sys/cpuvar.h @@ -668,7 +668,7 @@ void cpu_destroy_bound_threads(cpu_t *cp); extern int cpu_bind_thread(kthread_t *tp, processorid_t bind, processorid_t *obind, int *error); -extern int cpu_unbind(processorid_t cpu_id); +extern int cpu_unbind(processorid_t cpu_id, boolean_t force); extern void thread_affinity_set(kthread_t *t, int cpu_id); extern void thread_affinity_clear(kthread_t *t); extern void affinity_set(int cpu_id); diff --git a/sys/cddl/contrib/opensolaris/uts/common/sys/ctf.h b/sys/cddl/contrib/opensolaris/uts/common/sys/ctf.h index 065e985..2d1987b 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/sys/ctf.h +++ b/sys/cddl/contrib/opensolaris/uts/common/sys/ctf.h @@ -27,7 +27,9 @@ #ifndef _CTF_H #define _CTF_H +#if defined(sun) #pragma ident "%Z%%M% %I% %E% SMI" +#endif #include <sys/types.h> diff --git a/sys/cddl/contrib/opensolaris/uts/common/sys/ctf_api.h b/sys/cddl/contrib/opensolaris/uts/common/sys/ctf_api.h index 17b0b72..cd4caaa 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/sys/ctf_api.h +++ b/sys/cddl/contrib/opensolaris/uts/common/sys/ctf_api.h @@ -65,10 +65,14 @@ typedef long ctf_id_t; * filling in ctf_sect_t structures and passing them to ctf_bufopen(): */ typedef struct ctf_sect { - const char *cts_name; /* section name (if any) */ + char *cts_name; /* section name (if any) */ ulong_t cts_type; /* section type (ELF SHT_... value) */ ulong_t cts_flags; /* section flags (ELF SHF_... value) */ +#if defined(sun) const void *cts_data; /* pointer to section data */ +#else + void *cts_data; /* pointer to section data */ +#endif size_t cts_size; /* size of data in bytes */ size_t cts_entsize; /* size of each section entry (symtab only) */ off64_t cts_offset; /* file offset of this section (if any) */ diff --git a/sys/cddl/contrib/opensolaris/uts/common/sys/debug.h b/sys/cddl/contrib/opensolaris/uts/common/sys/debug.h index c87c884..432e6be 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/sys/debug.h +++ b/sys/cddl/contrib/opensolaris/uts/common/sys/debug.h @@ -49,7 +49,7 @@ extern "C" { #if defined(__STDC__) extern int assfail(const char *, const char *, int); #define VERIFY(EX) ((void)((EX) || assfail(#EX, __FILE__, __LINE__))) -#if DEBUG +#ifdef DEBUG #define ASSERT(EX) VERIFY(EX) #else #define ASSERT(x) ((void)0) @@ -57,7 +57,7 @@ extern int assfail(const char *, const char *, int); #else /* defined(__STDC__) */ extern int assfail(); #define VERIFY(EX) ((void)((EX) || assfail("EX", __FILE__, __LINE__))) -#if DEBUG +#ifdef DEBUG #define ASSERT(EX) VERIFY(EX) #else #define ASSERT(x) ((void)0) @@ -97,7 +97,7 @@ _NOTE(CONSTCOND) } while (0) #define VERIFY3S(x, y, z) VERIFY3_IMPL(x, y, z, int64_t) #define VERIFY3U(x, y, z) VERIFY3_IMPL(x, y, z, uint64_t) #define VERIFY3P(x, y, z) VERIFY3_IMPL(x, y, z, uintptr_t) -#if DEBUG +#ifdef DEBUG #define ASSERT3S(x, y, z) VERIFY3S(x, y, z) #define ASSERT3U(x, y, z) VERIFY3U(x, y, z) #define ASSERT3P(x, y, z) VERIFY3P(x, y, z) diff --git a/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h b/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h index b6e52ec..82b97a3 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h +++ b/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h @@ -49,10 +49,22 @@ extern "C" { #include <sys/types.h> #include <sys/modctl.h> #include <sys/processor.h> +#if defined(sun) #include <sys/systm.h> +#else +#include <sys/param.h> +#include <sys/linker.h> +#include <sys/ioccom.h> +#include <sys/ucred.h> +typedef int model_t; +#endif #include <sys/ctf_api.h> #include <sys/cyclic.h> +#if defined(sun) #include <sys/int_limits.h> +#else +#include <sys/stdint.h> +#endif /* * DTrace Universal Constants and Typedefs @@ -237,6 +249,7 @@ typedef enum dtrace_probespec { #define DIF_VAR_UID 0x011e /* process user ID */ #define DIF_VAR_GID 0x011f /* process group ID */ #define DIF_VAR_ERRNO 0x0120 /* thread errno */ +#define DIF_VAR_EXECARGS 0x0121 /* process arguments */ #define DIF_SUBR_RAND 0 #define DIF_SUBR_MUTEX_OWNED 1 @@ -282,8 +295,13 @@ typedef enum dtrace_probespec { #define DIF_SUBR_INET_NTOP 41 #define DIF_SUBR_INET_NTOA 42 #define DIF_SUBR_INET_NTOA6 43 +#define DIF_SUBR_MEMREF 44 +#define DIF_SUBR_TYPEREF 45 +#define DIF_SUBR_SX_SHARED_HELD 46 +#define DIF_SUBR_SX_EXCLUSIVE_HELD 47 +#define DIF_SUBR_SX_ISEXCLUSIVE 48 -#define DIF_SUBR_MAX 43 /* max subroutine value */ +#define DIF_SUBR_MAX 48 /* max subroutine value */ typedef uint32_t dif_instr_t; @@ -392,6 +410,8 @@ typedef struct dtrace_difv { #define DTRACEACT_PRINTF 3 /* printf() action */ #define DTRACEACT_PRINTA 4 /* printa() action */ #define DTRACEACT_LIBACT 5 /* library-controlled action */ +#define DTRACEACT_PRINTM 6 /* printm() action */ +#define DTRACEACT_PRINTT 7 /* printt() action */ #define DTRACEACT_PROC 0x0100 #define DTRACEACT_USTACK (DTRACEACT_PROC + 1) @@ -497,7 +517,7 @@ typedef struct dtrace_difv { ((((uint64_t)(y)) << 32) | ((x) & UINT32_MAX)) #ifndef _LP64 -#ifndef _LITTLE_ENDIAN +#if BYTE_ORDER == _BIG_ENDIAN #define DTRACE_PTR(type, name) uint32_t name##pad; type *name #else #define DTRACE_PTR(type, name) type *name; uint32_t name##pad @@ -607,7 +627,7 @@ typedef struct dof_hdr { #define DOF_ENCODE_LSB 1 #define DOF_ENCODE_MSB 2 -#ifdef _BIG_ENDIAN +#if BYTE_ORDER == _BIG_ENDIAN #define DOF_ENCODE_NATIVE DOF_ENCODE_MSB #else #define DOF_ENCODE_NATIVE DOF_ENCODE_LSB @@ -1171,6 +1191,7 @@ typedef struct dtrace_providerdesc { * pseudodevice driver. These ioctls comprise the user-kernel interface to * DTrace. */ +#if defined(sun) #define DTRACEIOC (('d' << 24) | ('t' << 16) | ('r' << 8)) #define DTRACEIOC_PROVIDER (DTRACEIOC | 1) /* provider query */ #define DTRACEIOC_PROBES (DTRACEIOC | 2) /* probe query */ @@ -1188,6 +1209,44 @@ typedef struct dtrace_providerdesc { #define DTRACEIOC_FORMAT (DTRACEIOC | 16) /* get format str */ #define DTRACEIOC_DOFGET (DTRACEIOC | 17) /* get DOF */ #define DTRACEIOC_REPLICATE (DTRACEIOC | 18) /* replicate enab */ +#else +#define DTRACEIOC_PROVIDER _IOWR('x',1,dtrace_providerdesc_t) + /* provider query */ +#define DTRACEIOC_PROBES _IOWR('x',2,dtrace_probedesc_t) + /* probe query */ +#define DTRACEIOC_BUFSNAP _IOW('x',4,dtrace_bufdesc_t *) + /* snapshot buffer */ +#define DTRACEIOC_PROBEMATCH _IOWR('x',5,dtrace_probedesc_t) + /* match probes */ +typedef struct { + void *dof; /* DOF userland address written to driver. */ + int n_matched; /* # matches returned by driver. */ +} dtrace_enable_io_t; +#define DTRACEIOC_ENABLE _IOWR('x',6,dtrace_enable_io_t) + /* enable probes */ +#define DTRACEIOC_AGGSNAP _IOW('x',7,dtrace_bufdesc_t *) + /* snapshot agg. */ +#define DTRACEIOC_EPROBE _IOW('x',8,dtrace_eprobedesc_t) + /* get eprobe desc. */ +#define DTRACEIOC_PROBEARG _IOWR('x',9,dtrace_argdesc_t) + /* get probe arg */ +#define DTRACEIOC_CONF _IOR('x',10,dtrace_conf_t) + /* get config. */ +#define DTRACEIOC_STATUS _IOR('x',11,dtrace_status_t) + /* get status */ +#define DTRACEIOC_GO _IOR('x',12,processorid_t) + /* start tracing */ +#define DTRACEIOC_STOP _IOWR('x',13,processorid_t) + /* stop tracing */ +#define DTRACEIOC_AGGDESC _IOW('x',15,dtrace_aggdesc_t *) + /* get agg. desc. */ +#define DTRACEIOC_FORMAT _IOWR('x',16,dtrace_fmtdesc_t) + /* get format str */ +#define DTRACEIOC_DOFGET _IOW('x',17,dof_hdr_t *) + /* get DOF */ +#define DTRACEIOC_REPLICATE _IOW('x',18,dtrace_repldesc_t) + /* replicate enab */ +#endif /* * DTrace Helpers @@ -1350,7 +1409,7 @@ typedef struct dof_helper { * DTrace routines, including dtrace_probe_create(), dtrace_probe_lookup(), * and dtrace_probe_arg(). * - * 1.3 void dtps_provide_module(void *arg, struct modctl *mp) + * 1.3 void dtps_provide_module(void *arg, modctl_t *mp) * * 1.3.1 Overview * @@ -1955,8 +2014,8 @@ typedef struct dof_helper { * routines. */ typedef struct dtrace_pops { - void (*dtps_provide)(void *arg, const dtrace_probedesc_t *spec); - void (*dtps_provide_module)(void *arg, struct modctl *mp); + void (*dtps_provide)(void *arg, dtrace_probedesc_t *spec); + void (*dtps_provide_module)(void *arg, modctl_t *mp); void (*dtps_enable)(void *arg, dtrace_id_t id, void *parg); void (*dtps_disable)(void *arg, dtrace_id_t id, void *parg); void (*dtps_suspend)(void *arg, dtrace_id_t id, void *parg); @@ -1976,8 +2035,8 @@ extern int dtrace_register(const char *, const dtrace_pattr_t *, uint32_t, extern int dtrace_unregister(dtrace_provider_id_t); extern int dtrace_condense(dtrace_provider_id_t); extern void dtrace_invalidate(dtrace_provider_id_t); -extern dtrace_id_t dtrace_probe_lookup(dtrace_provider_id_t, const char *, - const char *, const char *); +extern dtrace_id_t dtrace_probe_lookup(dtrace_provider_id_t, char *, + char *, char *); extern dtrace_id_t dtrace_probe_create(dtrace_provider_id_t, const char *, const char *, const char *, int, void *); extern void *dtrace_probe_arg(dtrace_provider_id_t, dtrace_id_t); @@ -2150,7 +2209,9 @@ typedef enum dtrace_vtime_state { DTRACE_VTIME_ACTIVE_TNF /* DTrace virtual time _and_ TNF */ } dtrace_vtime_state_t; +#if defined(sun) extern dtrace_vtime_state_t dtrace_vtime_active; +#endif extern void dtrace_vtime_switch(kthread_t *next); extern void dtrace_vtime_enable_tnf(void); extern void dtrace_vtime_disable_tnf(void); @@ -2159,12 +2220,14 @@ extern void dtrace_vtime_disable(void); struct regs; +#if defined(sun) extern int (*dtrace_pid_probe_ptr)(struct regs *); extern int (*dtrace_return_probe_ptr)(struct regs *); extern void (*dtrace_fasttrap_fork_ptr)(proc_t *, proc_t *); extern void (*dtrace_fasttrap_exec_ptr)(proc_t *); extern void (*dtrace_fasttrap_exit_ptr)(proc_t *); extern void dtrace_fasttrap_fork(proc_t *, proc_t *); +#endif typedef uintptr_t dtrace_icookie_t; typedef void (*dtrace_xcall_t)(void *); @@ -2176,18 +2239,22 @@ extern void dtrace_membar_producer(void); extern void dtrace_membar_consumer(void); extern void (*dtrace_cpu_init)(processorid_t); -extern void (*dtrace_modload)(struct modctl *); -extern void (*dtrace_modunload)(struct modctl *); -extern void (*dtrace_helpers_cleanup)(); +extern void (*dtrace_modload)(modctl_t *); +extern void (*dtrace_modunload)(modctl_t *); +extern void (*dtrace_helpers_cleanup)(void); extern void (*dtrace_helpers_fork)(proc_t *parent, proc_t *child); -extern void (*dtrace_cpustart_init)(); -extern void (*dtrace_cpustart_fini)(); +extern void (*dtrace_cpustart_init)(void); +extern void (*dtrace_cpustart_fini)(void); -extern void (*dtrace_debugger_init)(); -extern void (*dtrace_debugger_fini)(); +extern void (*dtrace_debugger_init)(void); +extern void (*dtrace_debugger_fini)(void); extern dtrace_cacheid_t dtrace_predcache_id; +#if defined(sun) extern hrtime_t dtrace_gethrtime(void); +#else +void dtrace_debug_printf(const char *, ...) __printflike(1, 2); +#endif extern void dtrace_sync(void); extern void dtrace_toxic_ranges(void (*)(uintptr_t, uintptr_t)); extern void dtrace_xcall(processorid_t, dtrace_xcall_t, void *); @@ -2213,13 +2280,13 @@ extern void dtrace_getfsr(uint64_t *); #endif #define DTRACE_CPUFLAG_ISSET(flag) \ - (cpu_core[CPU->cpu_id].cpuc_dtrace_flags & (flag)) + (cpu_core[curcpu].cpuc_dtrace_flags & (flag)) #define DTRACE_CPUFLAG_SET(flag) \ - (cpu_core[CPU->cpu_id].cpuc_dtrace_flags |= (flag)) + (cpu_core[curcpu].cpuc_dtrace_flags |= (flag)) #define DTRACE_CPUFLAG_CLEAR(flag) \ - (cpu_core[CPU->cpu_id].cpuc_dtrace_flags &= ~(flag)) + (cpu_core[curcpu].cpuc_dtrace_flags &= ~(flag)) #endif /* _KERNEL */ diff --git a/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace_impl.h b/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace_impl.h index fed537e..1139073 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace_impl.h +++ b/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace_impl.h @@ -45,6 +45,14 @@ extern "C" { */ #include <sys/dtrace.h> +#if !defined(sun) +#ifdef __sparcv9 +typedef uint32_t pc_t; +#else +typedef uintptr_t pc_t; +#endif +typedef u_long greg_t; +#endif /* * DTrace Implementation Constants and Typedefs @@ -114,13 +122,13 @@ struct dtrace_probe { typedef int dtrace_probekey_f(const char *, const char *, int); typedef struct dtrace_probekey { - const char *dtpk_prov; /* provider name to match */ + char *dtpk_prov; /* provider name to match */ dtrace_probekey_f *dtpk_pmatch; /* provider matching function */ - const char *dtpk_mod; /* module name to match */ + char *dtpk_mod; /* module name to match */ dtrace_probekey_f *dtpk_mmatch; /* module matching function */ - const char *dtpk_func; /* func name to match */ + char *dtpk_func; /* func name to match */ dtrace_probekey_f *dtpk_fmatch; /* func matching function */ - const char *dtpk_name; /* name to match */ + char *dtpk_name; /* name to match */ dtrace_probekey_f *dtpk_nmatch; /* name matching function */ dtrace_id_t dtpk_id; /* identifier to match */ } dtrace_probekey_t; @@ -1099,7 +1107,11 @@ typedef struct dtrace_cred { * dtrace_state structure. */ struct dtrace_state { +#if defined(sun) dev_t dts_dev; /* device */ +#else + struct cdev *dts_dev; /* device */ +#endif int dts_necbs; /* total number of ECBs */ dtrace_ecb_t **dts_ecbs; /* array of ECBs */ dtrace_epid_t dts_epid; /* next EPID to allocate */ @@ -1113,7 +1125,11 @@ struct dtrace_state { int dts_nspeculations; /* number of speculations */ int dts_naggregations; /* number of aggregations */ dtrace_aggregation_t **dts_aggregations; /* aggregation array */ +#if defined(sun) vmem_t *dts_aggid_arena; /* arena for aggregation IDs */ +#else + struct unrhdr *dts_aggid_arena; /* arena for aggregation IDs */ +#endif uint64_t dts_errors; /* total number of errors */ uint32_t dts_speculations_busy; /* number of spec. busy */ uint32_t dts_speculations_unavail; /* number of spec unavail */ @@ -1238,7 +1254,7 @@ extern greg_t dtrace_getfp(void); extern int dtrace_getipl(void); extern uintptr_t dtrace_caller(int); extern uint32_t dtrace_cas32(uint32_t *, uint32_t, uint32_t); -extern void *dtrace_casptr(void *, void *, void *); +extern void *dtrace_casptr(volatile void *, volatile void *, volatile void *); extern void dtrace_copyin(uintptr_t, uintptr_t, size_t, volatile uint16_t *); extern void dtrace_copyinstr(uintptr_t, uintptr_t, size_t, volatile uint16_t *); extern void dtrace_copyout(uintptr_t, uintptr_t, size_t, volatile uint16_t *); @@ -1259,7 +1275,9 @@ extern void dtrace_probe_error(dtrace_state_t *, dtrace_epid_t, int, int, int, uintptr_t); extern int dtrace_assfail(const char *, const char *, int); extern int dtrace_attached(void); -extern hrtime_t dtrace_gethrestime(); +#if defined(sun) +extern hrtime_t dtrace_gethrestime(void); +#endif #ifdef __sparc extern void dtrace_flush_windows(void); diff --git a/sys/cddl/contrib/opensolaris/uts/common/sys/isa_defs.h b/sys/cddl/contrib/opensolaris/uts/common/sys/isa_defs.h index a65d16a..b1b99ad 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/sys/isa_defs.h +++ b/sys/cddl/contrib/opensolaris/uts/common/sys/isa_defs.h @@ -206,6 +206,9 @@ * This indicates that the implementation uses a dynamically * linked unix + krtld to form the core kernel image at boot * time, or (in the absence of this symbol) a prelinked kernel image. + * + * _OBP + * This indicates the firmware interface is OBP. */ #ifdef __cplusplus @@ -216,7 +219,7 @@ extern "C" { * The following set of definitions characterize Solaris on AMD's * 64-bit systems. */ -#if defined(__x86_64) || defined(__amd64) +#if defined(__x86_64) || defined(__amd64) || defined(__ia64__) #if !defined(__amd64) #define __amd64 /* preferred guard */ @@ -336,6 +339,51 @@ extern "C" { #define _DONT_USE_1275_GENERIC_NAMES #define _HAVE_CPUID_INSN +#elif defined(__arm__) + +/* + * Define the appropriate "processor characteristics" + */ +#define _STACK_GROWS_DOWNWARD +#define _LONG_LONG_LTOH +#define _BIT_FIELDS_LTOH +#define _IEEE_754 +#define _CHAR_IS_SIGNED +#define _BOOL_ALIGNMENT 1 +#define _CHAR_ALIGNMENT 1 +#define _SHORT_ALIGNMENT 2 +#define _INT_ALIGNMENT 4 +#define _FLOAT_ALIGNMENT 4 +#define _FLOAT_COMPLEX_ALIGNMENT 4 +#define _LONG_ALIGNMENT 4 +#define _LONG_LONG_ALIGNMENT 4 +#define _DOUBLE_ALIGNMENT 4 +#define _DOUBLE_COMPLEX_ALIGNMENT 4 +#define _LONG_DOUBLE_ALIGNMENT 4 +#define _LONG_DOUBLE_COMPLEX_ALIGNMENT 4 +#define _POINTER_ALIGNMENT 4 +#define _MAX_ALIGNMENT 4 +#define _ALIGNMENT_REQUIRED 0 + +#define _LONG_LONG_ALIGNMENT_32 _LONG_LONG_ALIGNMENT + +/* + * Define the appropriate "implementation choices". + */ +#define _ILP32 +#if !defined(_I32LPx) && defined(_KERNEL) +#define _I32LPx +#endif +#define _SUNOS_VTOC_16 +#define _DMA_USES_PHYSADDR +#define _FIRMWARE_NEEDS_FDISK +#define _PSM_MODULES +#define _RTC_CONFIG +#define _DONT_USE_1275_GENERIC_NAMES +#define _HAVE_CPUID_INSN + +#elif defined(__powerpc__) + /* * The following set of definitions characterize the Solaris on SPARC systems. * @@ -408,7 +456,7 @@ extern "C" { #define _DMA_USES_VIRTADDR #define _NO_FDISK_PRESENT #define _HAVE_TEM_FIRMWARE -#define _UNIX_KRTLD +#define _OBP /* * The following set of definitions characterize the implementation of |