summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorjb <jb@FreeBSD.org>2008-05-22 07:33:39 +0000
committerjb <jb@FreeBSD.org>2008-05-22 07:33:39 +0000
commit5788c140d796d33530527e138c61b21303e8d006 (patch)
tree13c8247575459ee7fadf40737cff3eb883067b6c /sys
parent60b4eaf522405eafec6ba998afa8f7eaa4919166 (diff)
downloadFreeBSD-src-5788c140d796d33530527e138c61b21303e8d006.zip
FreeBSD-src-5788c140d796d33530527e138c61b21303e8d006.tar.gz
FreeBSD changes to vendor source.
Diffstat (limited to 'sys')
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c1288
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/dtrace/fasttrap.c41
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/sys/cpuvar.h2
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/sys/ctf.h2
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/sys/ctf_api.h6
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/sys/debug.h6
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h103
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/sys/dtrace_impl.h30
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/sys/isa_defs.h52
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
OpenPOWER on IntegriCloud