# Copyright 2011 -- 2013 Oracle, Inc. All rights reserved.
# Use is subject to license terms.
-EXTRA_CFLAGS := -I$(src)/include -I$(src)/include/uapi
+EXTRA_CFLAGS := -I$(src)/include -I$(src)/include/uapi \
+ -I$(src)/include/$(ARCH)
obj-$(CONFIG_DT_CORE) += dtrace.o
obj-$(CONFIG_DT_FASTTRAP) += fasttrap.o
obj-$(CONFIG_DT_DT_PERF) += dt_perf.o
dtrace-y := dtrace_mod.o dtrace_dev.o \
- dtrace_asm.o dtrace_isa.o \
+ dtrace_asm_$(ARCH).o dtrace_isa_$(ARCH).o \
dtrace_actdesc.o dtrace_anon.o \
dtrace_buffer.o dtrace_dif.o dtrace_dof.o \
dtrace_ecb.o dtrace_enable.o \
- dtrace_fmt.o dtrace_hash.o \
+ dtrace_fmt.o dtrace_hash.o dtrace_isa.o \
dtrace_match.o dtrace_priv.o \
dtrace_probe.o dtrace_probe_ctx.o \
dtrace_ptofapi.o dtrace_predicate.o \
dtrace_spec.o dtrace_state.o dtrace_util.o
fasttrap-y := fasttrap_mod.o fasttrap_dev.o
profile-y := profile_mod.o profile_dev.o
-sdt-y := sdt_mod.o sdt_dev.o
+sdt-y := sdt_mod.o sdt_dev.o sdt_$(ARCH).o
systrace-y := systrace_mod.o systrace_dev.o
dt_test-y := dt_test_mod.o dt_test_dev.o
dt_perf-y := dt_perf_mod.o dt_perf_dev.o
*
* CDDL HEADER END
*
- * Copyright 2011, 2012 Oracle, Inc. All rights reserved.
+ * Copyright 2011-2014 Oracle, Inc. All rights reserved.
* Use is subject to license terms.
*/
return;
pid = dtrace_probe_create(dt_test_id,
- "dt_test", NULL, "test", 0, NULL);
+ "dt_test", NULL, "test", 1, NULL);
}
int _dt_test_enable(void *arg, dtrace_id_t id, void *parg)
{
}
-static long dt_test_ioctl(struct file *file,
- unsigned int cmd, unsigned long arg)
+/*
+ * Direct calling into dtrace_probe() when passing more than 5 parameters to
+ * the probe requires a stub function. Otherwise we may not be able to get
+ * to the value of all arguments correctly.
+ */
+void dt_test_probe(uintptr_t arg0, uintptr_t arg1, uintptr_t arg2,
+ uintptr_t arg3, uintptr_t arg4, uintptr_t arg5,
+ uintptr_t arg6, uintptr_t arg7, uintptr_t arg8,
+ uintptr_t arg9)
{
/*
* Yes, this is not nice.
- * Not at all.
+ * Not at all...
* But we're doing it anyway...
*/
- void (*dt_test_probe)(dtrace_id_t, uintptr_t, uintptr_t, uintptr_t,
- uintptr_t, uintptr_t, uintptr_t, uintptr_t,
- uintptr_t, uintptr_t, uintptr_t);
+ void (*probe_fn)() = (void *)&dtrace_probe;
+ probe_fn(pid, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8,
+ arg9);
+}
+
+static long dt_test_ioctl(struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
if (enabled) {
- dt_test_probe = (void *)&dtrace_probe;
- dt_test_probe(pid, cmd, arg, 2ULL, 3ULL, 4ULL, 5ULL,
- 6ULL, 7ULL, 8ULL, 9ULL);
+ dt_test_probe(cmd, arg, 2ULL, 3ULL, 4ULL, 5ULL, 6ULL, 7ULL,
+ 8ULL, 9ULL);
return 0;
}
*
* CDDL HEADER END
*
- * Copyright 2010, 2011, 2012 Oracle, Inc. All rights reserved.
+ * Copyright 2010-2014 Oracle, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <linux/slab.h>
+#include <linux/vmalloc.h>
#include "dtrace.h"
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2010-2014 Oracle, Inc. All rights reserved.
* Use is subject to license terms.
*/
*
* CDDL HEADER END
*
- * Copyright 2010, 2011, 2012, 2013 Oracle, Inc. All rights reserved.
+ * Copyright 2010-2014 Oracle, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <linux/kernel.h>
#include <linux/miscdevice.h>
#include <linux/slab.h>
+#include <linux/vmalloc.h>
#include <asm/uaccess.h>
#include "ctf_api.h"
DEFINE_MUTEX(dtrace_lock);
-void (*dtrace_modload)(struct module *);
-void (*dtrace_modunload)(struct module *);
-
void dtrace_nullop(void)
{
}
register_module_notifier(&dtrace_modmgmt);
-#ifdef FIXME
- dtrace_modload = dtrace_module_loaded;
- dtrace_modunload = dtrace_module_unloaded;
-#endif
+#if defined(CONFIG_DT_FASTTRAP) || defined(CONFIG_DT_FASTTRAP_MODULE)
dtrace_helpers_cleanup = dtrace_helpers_destroy;
dtrace_helpers_fork = dtrace_helpers_duplicate;
+#endif
#ifdef FIXME
dtrace_cpu_init = dtrace_cpu_setup_initial;
dtrace_cpustart_init = dtrace_suspend;
NULL, "END", 0, NULL);
dtrace_probeid_error = dtrace_probe_create(
(dtrace_provider_id_t)dtrace_provider, NULL,
- NULL, "ERROR", 0, NULL);
+ NULL, "ERROR", 1, NULL);
dtrace_anon_property();
unregister_module_notifier(&dtrace_modmgmt);
-#ifdef FIXME
- dtrace_modload = NULL;
- dtrace_modunload = NULL;
-#endif
+#if defined(CONFIG_DT_FASTTRAP) || defined(CONFIG_DT_FASTTRAP_MODULE)
dtrace_helpers_cleanup = NULL;
dtrace_helpers_fork = NULL;
+#endif
#ifdef FIXME
dtrace_cpu_init = NULL;
dtrace_cpustart_init = NULL;
*
* CDDL HEADER END
*
- * Copyright 2010, 2011, 2012, 2013 Oracle, Inc. All rights reserved.
+ * Copyright 2010-2014 Oracle, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <linux/kdev_t.h>
#include <linux/slab.h>
#include <linux/socket.h>
+#include <linux/vmalloc.h>
#include <net/ipv6.h>
+#include <asm/byteorder.h>
#include <linux/mount.h>
dtrace_dstate_percpu_t *dcpu = &dstate->dtds_percpu[me];
size_t bucket, ksize;
size_t chunksize = dstate->dtds_chunksize;
- uintptr_t kdata, lock, nstate;
+ uintptr_t kdata, lock;
+ dtrace_dstate_state_t nstate;
uint_t i;
ASSERT(nkeys != 0);
*/
switch (dstate->dtds_state) {
case DTRACE_DSTATE_CLEAN: {
- uintptr_t *sp =
- (uintptr_t *)
+ dtrace_dstate_state_t *sp =
+ (dtrace_dstate_state_t *)
&dstate->dtds_state;
if (++cpu >= NR_CPUS)
if (ndx >=
sizeof(mstate->dtms_arg) / sizeof(mstate->dtms_arg[0])) {
int aframes =
- mstate->dtms_probe->dtpr_aframes + 3;
+ mstate->dtms_probe->dtpr_aframes + 2;
dtrace_provider_t *pv;
uint64_t val;
if (!dtrace_priv_kernel(state))
return 0;
if (!(mstate->dtms_present & DTRACE_MSTATE_STACKDEPTH)) {
- int aframes = mstate->dtms_probe->dtpr_aframes + 3;
+ int aframes = mstate->dtms_probe->dtpr_aframes + 2;
- mstate->dtms_stackdepth = dtrace_getstackdepth(aframes);
+ mstate->dtms_stackdepth = dtrace_getstackdepth(
+ mstate, aframes);
mstate->dtms_present |= DTRACE_MSTATE_STACKDEPTH;
}
return 0;
if (!(mstate->dtms_present & DTRACE_MSTATE_CALLER)) {
- int aframes = mstate->dtms_probe->dtpr_aframes + 3;
+ int aframes = mstate->dtms_probe->dtpr_aframes + 2;
if (!DTRACE_ANCHORED(mstate->dtms_probe)) {
/*
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;
case DIF_SUBR_HTONS:
case DIF_SUBR_NTOHS:
-#ifndef __LITTLE_ENDIAN
+#ifdef __BIG_ENDIAN
regs[rd] = (uint16_t)tupregs[0].dttk_value;
#else
regs[rd] = DT_BSWAP_16((uint16_t)tupregs[0].dttk_value);
case DIF_SUBR_HTONL:
case DIF_SUBR_NTOHL:
-#ifndef __LITTLE_ENDIAN
+#ifdef __BIG_ENDIAN
regs[rd] = (uint32_t)tupregs[0].dttk_value;
#else
regs[rd] = DT_BSWAP_32((uint32_t)tupregs[0].dttk_value);
case DIF_SUBR_HTONLL:
case DIF_SUBR_NTOHLL:
-#ifndef __LITTLE_ENDIAN
+#ifdef __BIG_ENDIAN
regs[rd] = (uint64_t)tupregs[0].dttk_value;
#else
regs[rd] = DT_BSWAP_64((uint64_t)tupregs[0].dttk_value);
*
* CDDL HEADER END
*
- * Copyright 2010, 2011, 2012, 2013 Oracle, Inc. All rights reserved.
+ * Copyright 2010-2014 Oracle, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <linux/slab.h>
#include <linux/types.h>
+#include <linux/vmalloc.h>
#include <asm/uaccess.h>
#include "dtrace.h"
*
* CDDL HEADER END
*
- * Copyright 2010, 2011, 2012 Oracle, Inc. All rights reserved.
+ * Copyright 2010-2014 Oracle, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <linux/slab.h>
+#include <linux/vmalloc.h>
#include "dtrace.h"
*
* CDDL HEADER END
*
- * Copyright 2010, 2011, 2012 Oracle, Inc. All rights reserved.
+ * Copyright 2010-2014 Oracle, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <linux/kernel.h>
#include <linux/mutex.h>
#include <linux/slab.h>
+#include <linux/vmalloc.h>
#include "dtrace.h"
*
* CDDL HEADER END
*
- * Copyright 2010, 2011 Oracle, Inc. All rights reserved.
+ * Copyright 2010-2014 Oracle, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <linux/slab.h>
+#include <linux/vmalloc.h>
#include "dtrace.h"
*
* CDDL HEADER END
*
- * Copyright 2010, 2011 Oracle, Inc. All rights reserved.
+ * Copyright 2010-2014 Oracle, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <linux/slab.h>
+#include <linux/vmalloc.h>
#include "dtrace.h"
#include <linux/mm.h>
#include <linux/smp.h>
#include <linux/uaccess.h>
+#include <asm/cacheflush.h>
#include <asm/stacktrace.h>
#include "dtrace.h"
-/* FIXME */
-uintptr_t _userlimit = 0x00007fffffffffffLL;
-uintptr_t kernelbase = 0xffff880000000000LL;
-
EXPORT_SYMBOL(dtrace_getfp);
DEFINE_MUTEX(cpu_lock);
EXPORT_SYMBOL(cpu_lock);
-extern void dtrace_copy(uintptr_t, uintptr_t, size_t);
-extern void dtrace_copystr(uintptr_t, uintptr_t, size_t,
- volatile uint16_t *);
-
-static int dtrace_copycheck(uintptr_t uaddr, uintptr_t kaddr, size_t size)
-{
-#ifdef FIXME
- ASSERT(kaddr >= kernelbase && kaddr + size >= kaddr);
-#else
- if (kaddr < kernelbase || kaddr + size < kaddr) {
- DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
- this_cpu_core->cpuc_dtrace_illval = kaddr;
- return 0;
- }
-#endif
-
- if (uaddr + size >= kernelbase || uaddr + size < uaddr) {
- DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
- this_cpu_core->cpuc_dtrace_illval = uaddr;
- return 0;
- }
-
- return 1;
-}
-
-void dtrace_copyin(uintptr_t uaddr, uintptr_t kaddr, size_t size,
- volatile uint16_t *flags)
-{
- if (dtrace_copycheck(uaddr, kaddr, size))
- dtrace_copy(uaddr, kaddr, size);
-}
-
-void dtrace_copyout(uintptr_t uaddr, uintptr_t kaddr, size_t size,
- volatile uint16_t *flags)
-{
- if (dtrace_copycheck(uaddr, kaddr, size))
- dtrace_copy(kaddr, uaddr, size);
-}
-
-void dtrace_copyinstr(uintptr_t uaddr, uintptr_t kaddr, size_t size,
- volatile uint16_t *flags)
-{
- if (dtrace_copycheck(uaddr, kaddr, size))
- dtrace_copystr(uaddr, kaddr, size, flags);
-}
-
-void dtrace_copyoutstr(uintptr_t uaddr, uintptr_t kaddr, size_t size,
- volatile uint16_t *flags)
-{
- if (dtrace_copycheck(uaddr, kaddr, size))
- dtrace_copystr(kaddr, uaddr, size, flags);
-}
-
-#define DTRACE_FUWORD(bits) \
- uint##bits##_t dtrace_fuword##bits(void *uaddr) \
- { \
- extern uint##bits##_t dtrace_fuword##bits##_nocheck(void *);\
- \
- if ((uintptr_t)uaddr > _userlimit) { \
- DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR); \
- this_cpu_core->cpuc_dtrace_illval = (uintptr_t)uaddr; \
- return 0; \
- } \
- \
- return dtrace_fuword##bits##_nocheck(uaddr); \
- }
-
-DTRACE_FUWORD(8)
-DTRACE_FUWORD(16)
-DTRACE_FUWORD(32)
-DTRACE_FUWORD(64)
-
-uint64_t dtrace_getarg(int argno, int aframes)
-{
- unsigned long bp;
- uint64_t *st;
- uint64_t val;
- int i;
-
- asm volatile("movq %%rbp,%0" : "=m"(bp));
-
- for (i = 0; i < aframes; i++)
- bp = *((unsigned long *)bp);
-
- ASSERT(argno >= 5);
-
- /*
- * The first 5 arguments (arg0 through arg4) are passed in registers
- * to dtrace_probe(). The remaining arguments (arg5 through arg9) are
- * passed on the stack.
- *
- * Stack layout:
- * bp[0] = pushed bp from caller
- * bp[1] = return address
- * bp[2] = 6th argument (arg5 -> argno = 5)
- * bp[3] = 7th argument (arg6 -> argno = 6)
- * ...
- */
- DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);
- st = (uint64_t *)bp;
- val = st[2 + (argno - 5)];
- DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT);
-
- return val;
-}
-
int dtrace_getipl(void)
{
return in_interrupt();
}
-ulong_t dtrace_getreg(struct task_struct *task, uint_t reg)
-{
- struct pt_regs *rp = task_pt_regs(task);
-
- int regmap[] = {
- REG_RBX, /* 0 -> EBX */
- REG_RCX, /* 1 -> ECX */
- REG_RDX, /* 2 -> EDX */
- REG_RSI, /* 3 -> ESI */
- REG_RDI, /* 4 -> EDI */
- REG_RBP, /* 5 -> EBP */
- REG_RAX, /* 6 -> EAX */
- REG_DS, /* 7 -> DS */
- REG_ES, /* 8 -> ES */
- REG_FS, /* 9 -> FS */
- REG_GS, /* 10 -> GS */
- REG_TRAPNO, /* 11 -> TRAPNO */
- REG_RIP, /* 12 -> EIP */
- REG_CS, /* 13 -> CS */
- REG_RFL, /* 14 -> EFL */
- REG_RSP, /* 15 -> UESP */
- REG_SS, /* 16 -> SS */
- };
- if (reg > REG_TRAPNO) {
- /*
- * Convert register alias index into register mapping index.
- */
- reg -= REG_TRAPNO + 1;
-
- if (reg >= sizeof(regmap) / sizeof(int)) {
- DTRACE_CPUFLAG_SET(CPU_DTRACE_ILLOP);
- return 0;
- }
-
- reg = regmap[reg];
- }
-
- /*
- * Most common case: direct index into pt_regs structure.
- */
- if (reg <= REG_SS)
- return (&rp->r15)[reg];
-
- switch (reg) {
- case REG_DS:
- return task->thread.ds;
- case REG_ES:
- return task->thread.es;
- case REG_FS:
- return task->thread.fs;
- case REG_GS:
- return task->thread.gs;
- case REG_TRAPNO:
- return task->thread.trap_nr;
- default:
- DTRACE_CPUFLAG_SET(CPU_DTRACE_ILLOP);
- return 0;
- }
-}
-
static void dtrace_sync_func(void)
{
}
-void dtrace_sync(void)
-{
- dtrace_xcall(DTRACE_CPUALL, (dtrace_xcall_t)dtrace_sync_func, NULL);
-}
-
void dtrace_xcall(processorid_t cpu, dtrace_xcall_t func, void *arg)
{
if (cpu == DTRACE_CPUALL) {
smp_call_function_single(cpu, func, arg, 1);
}
+void dtrace_sync(void)
+{
+ dtrace_xcall(DTRACE_CPUALL, (dtrace_xcall_t)dtrace_sync_func, NULL);
+}
+
void dtrace_toxic_ranges(void (*func)(uintptr_t, uintptr_t))
{
/* FIXME */
pcstack,
NULL,
pcstack_limit,
- 0,
+ aframes,
STACKTRACE_KERNEL
};
goto out;
atomic_inc(&mm->mm_users);
+#ifdef CONFIG_X86_64
tos = current_user_stack_pointer();
+#else
+ tos = user_stack_pointer(current_pt_regs());
+#endif
stack_vma = find_user_vma(p, mm, NULL, (unsigned long) tos, 0);
if (!stack_vma ||
stack_vma->vm_start > (unsigned long) tos)
dtrace_getufpstack(pcstack, NULL, pcstack_limit);
}
-int dtrace_getstackdepth(int aframes)
+int dtrace_getstackdepth(dtrace_mstate_t *mstate, int aframes)
{
+ uintptr_t old = mstate->dtms_scratch_ptr;
+ size_t size;
struct stacktrace_state st = {
NULL,
NULL,
0,
- 0,
+ aframes,
STACKTRACE_KERNEL
};
+ st.pcs = (uint64_t *)P2ROUNDUP(mstate->dtms_scratch_ptr, 8);
+ size = (uintptr_t)st.pcs - mstate->dtms_scratch_ptr +
+ aframes * sizeof(uint64_t);
+ if (mstate->dtms_scratch_ptr + size >
+ mstate->dtms_scratch_base + mstate->dtms_scratch_size) {
+ DTRACE_CPUFLAG_SET(CPU_DTRACE_NOSCRATCH);
+ return 0;
+ }
+
dtrace_stacktrace(&st);
- if (st.depth <= aframes)
- return 0;
+ mstate->dtms_scratch_ptr = old;
- return st.depth - aframes;
+ return st.depth;
}
int dtrace_getustackdepth(void)
--- /dev/null
+/*
+ * FILE: dtrace_isa_x86_64.c
+ * DESCRIPTION: Dynamic Tracing: x86_64 architecture specific support functions
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ * Copyright 2010-2014 Oracle, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#include <linux/dtrace_cpu.h>
+
+#include "dtrace.h"
+
+/* Register indices */
+#define REG_TRAPNO 25
+#define REG_GS 24
+#define REG_FS 23
+#define REG_ES 22
+#define REG_DS 21
+#define REG_SS 20
+#define REG_RSP 19
+#define REG_RFL 18
+#define REG_CS 17
+#define REG_RIP 16
+#define REG_ERR 15
+#define REG_RDI 14
+#define REG_RSI 13
+#define REG_RDX 12
+#define REG_RCX 11
+#define REG_RAX 10
+#define REG_R8 9
+#define REG_R9 8
+#define REG_R10 7
+#define REG_R11 6
+#define REG_RBX 5
+#define REG_RBP 4
+#define REG_R12 3
+#define REG_R13 2
+#define REG_R14 1
+#define REG_R15 0
+
+extern void dtrace_copy(uintptr_t, uintptr_t, size_t);
+extern void dtrace_copystr(uintptr_t, uintptr_t, size_t,
+ volatile uint16_t *);
+
+uintptr_t _userlimit = 0x00007fffffffffffLL;
+uintptr_t kernelbase = 0xffff880000000000LL;
+
+static int dtrace_copycheck(uintptr_t uaddr, uintptr_t kaddr, size_t size)
+{
+#ifdef FIXME
+ ASSERT(kaddr >= kernelbase && kaddr + size >= kaddr);
+#else
+ if (kaddr < kernelbase || kaddr + size < kaddr) {
+ DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
+ this_cpu_core->cpuc_dtrace_illval = kaddr;
+ return 0;
+ }
+#endif
+
+ if (uaddr + size >= kernelbase || uaddr + size < uaddr) {
+ DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR);
+ this_cpu_core->cpuc_dtrace_illval = uaddr;
+ return 0;
+ }
+
+ return 1;
+}
+
+void dtrace_copyin(uintptr_t uaddr, uintptr_t kaddr, size_t size,
+ volatile uint16_t *flags)
+{
+ if (dtrace_copycheck(uaddr, kaddr, size))
+ dtrace_copy(uaddr, kaddr, size);
+}
+
+void dtrace_copyout(uintptr_t uaddr, uintptr_t kaddr, size_t size,
+ volatile uint16_t *flags)
+{
+ if (dtrace_copycheck(uaddr, kaddr, size))
+ dtrace_copy(kaddr, uaddr, size);
+}
+
+void dtrace_copyinstr(uintptr_t uaddr, uintptr_t kaddr, size_t size,
+ volatile uint16_t *flags)
+{
+ if (dtrace_copycheck(uaddr, kaddr, size))
+ dtrace_copystr(uaddr, kaddr, size, flags);
+}
+
+void dtrace_copyoutstr(uintptr_t uaddr, uintptr_t kaddr, size_t size,
+ volatile uint16_t *flags)
+{
+ if (dtrace_copycheck(uaddr, kaddr, size))
+ dtrace_copystr(kaddr, uaddr, size, flags);
+}
+
+#define DTRACE_FUWORD(bits) \
+ uint##bits##_t dtrace_fuword##bits(void *uaddr) \
+ { \
+ extern uint##bits##_t dtrace_fuword##bits##_nocheck(void *);\
+ \
+ if ((uintptr_t)uaddr > _userlimit) { \
+ DTRACE_CPUFLAG_SET(CPU_DTRACE_BADADDR); \
+ this_cpu_core->cpuc_dtrace_illval = (uintptr_t)uaddr; \
+ return 0; \
+ } \
+ \
+ return dtrace_fuword##bits##_nocheck(uaddr); \
+ }
+
+DTRACE_FUWORD(8)
+DTRACE_FUWORD(16)
+DTRACE_FUWORD(32)
+DTRACE_FUWORD(64)
+
+uint64_t dtrace_getarg(int argno, int aframes)
+{
+ unsigned long bp;
+ uint64_t *st;
+ uint64_t val;
+ int i;
+
+ asm volatile("movq %%rbp,%0" : "=m"(bp));
+
+ for (i = 0; i < aframes; i++)
+ bp = *((unsigned long *)bp);
+
+ ASSERT(argno >= 5);
+
+ /*
+ * The first 5 arguments (arg0 through arg4) are passed in registers
+ * to dtrace_probe(). The remaining arguments (arg5 through arg9) are
+ * passed on the stack.
+ *
+ * Stack layout:
+ * bp[0] = pushed bp from caller
+ * bp[1] = return address
+ * bp[2] = 6th argument (arg5 -> argno = 5)
+ * bp[3] = 7th argument (arg6 -> argno = 6)
+ * ...
+ */
+ DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);
+ st = (uint64_t *)bp;
+ val = st[2 + (argno - 5)];
+ DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT);
+
+ return val;
+}
+
+ulong_t dtrace_getreg(struct task_struct *task, uint_t reg)
+{
+ struct pt_regs *rp = task_pt_regs(task);
+
+ int regmap[] = {
+ REG_RBX, /* 0 -> EBX */
+ REG_RCX, /* 1 -> ECX */
+ REG_RDX, /* 2 -> EDX */
+ REG_RSI, /* 3 -> ESI */
+ REG_RDI, /* 4 -> EDI */
+ REG_RBP, /* 5 -> EBP */
+ REG_RAX, /* 6 -> EAX */
+ REG_DS, /* 7 -> DS */
+ REG_ES, /* 8 -> ES */
+ REG_FS, /* 9 -> FS */
+ REG_GS, /* 10 -> GS */
+ REG_TRAPNO, /* 11 -> TRAPNO */
+ REG_RIP, /* 12 -> EIP */
+ REG_CS, /* 13 -> CS */
+ REG_RFL, /* 14 -> EFL */
+ REG_RSP, /* 15 -> UESP */
+ REG_SS, /* 16 -> SS */
+ };
+
+ if (reg > REG_TRAPNO) {
+ /*
+ * Convert register alias index into register mapping index.
+ */
+ reg -= REG_TRAPNO + 1;
+
+ if (reg >= sizeof(regmap) / sizeof(int)) {
+ DTRACE_CPUFLAG_SET(CPU_DTRACE_ILLOP);
+ return 0;
+ }
+
+ reg = regmap[reg];
+ }
+
+ /*
+ * Most common case: direct index into pt_regs structure.
+ */
+ if (reg <= REG_SS)
+ return (&rp->r15)[reg];
+
+ switch (reg) {
+ case REG_DS:
+ return task->thread.ds;
+ case REG_ES:
+ return task->thread.es;
+ case REG_FS:
+ return task->thread.fs;
+ case REG_GS:
+ return task->thread.gs;
+ case REG_TRAPNO:
+ return task->thread.trap_nr;
+ default:
+ DTRACE_CPUFLAG_SET(CPU_DTRACE_ILLOP);
+ return 0;
+ }
+}
*
* CDDL HEADER END
*
- * Copyright 2010, 2011, 2012, 2013 Oracle, Inc. All rights reserved.
+ * Copyright 2010-2014 Oracle, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <linux/idr.h>
#include <linux/module.h>
#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <asm/pgtable.h>
#include <asm/cmpxchg.h>
#include "dtrace.h"
-#include "sdt_impl.h"
ktime_t dtrace_chill_interval =
KTIME_INIT(1, 0);
* raise() has a queue depth of 1 -- we ignore all subsequent
* invocations of the raise() action.
*/
-#if 0
-
- sigaddset(¤t->pending.signal, sig);
- set_thread_flag(TIF_SIGPENDING);
-#else
if (current->dtrace_sig == 0)
current->dtrace_sig = (uint8_t)sig;
-#endif
}
static void dtrace_action_stop(void)
dtrace_probe_error(
state, ecb->dte_epid, ndx,
(mstate.dtms_present & DTRACE_MSTATE_FLTOFFS)
- ? mstate.dtms_fltoffs
+ ? mstate.dtms_fltoffs
: -1,
DTRACE_FLAGS2FLT(*flags),
this_cpu_core->cpuc_dtrace_illval);
*
* CDDL HEADER END
*
- * Copyright 2010, 2011, 2012 Oracle, Inc. All rights reserved.
+ * Copyright 2010-2014 Oracle, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <linux/dtrace_cpu.h>
#include <linux/vmalloc.h>
+#include <asm/pgtable.h>
#include "dtrace.h"
*
* CDDL HEADER END
*
- * Copyright 2009 -- 2013 Oracle, Inc. All rights reserved.
+ * Copyright 2009-2014 Oracle, Inc. All rights reserved.
* Use is subject to license terms.
*/
extern void ctf_forceload(void);
-#define dtrace_membar_producer() wmb()
-#define dtrace_membar_consumer() rmb()
+#define dtrace_membar_producer() smp_wmb()
+#define dtrace_membar_consumer() smp_rmb()
typedef unsigned long dtrace_icookie_t;
extern void dtrace_xcall(processorid_t, dtrace_xcall_t, void *);
+extern uintptr_t dtrace_fulword(void *);
extern uint8_t dtrace_fuword8(void *);
extern uint16_t dtrace_fuword16(void *);
extern uint32_t dtrace_fuword32(void *);
extern unsigned long dtrace_getufpstack(uint64_t *, uint64_t *, int);
extern uintptr_t dtrace_getfp(void);
extern uint64_t dtrace_getarg(int, int);
-extern int dtrace_getstackdepth(int);
+extern int dtrace_getstackdepth(dtrace_mstate_t *, int);
extern int dtrace_getustackdepth(void);
extern ulong_t dtrace_getreg(struct task_struct *, uint_t);
extern void dtrace_copyin(uintptr_t, uintptr_t, size_t, volatile uint16_t *);
*
* CDDL HEADER END
*
- * Copyright 2009 -- 2013 Oracle, Inc. All rights reserved.
+ * Copyright 2009-2014 Oracle, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <linux/preempt.h>
#include <asm/ptrace.h>
-typedef typeof(((struct pt_regs *)0)->ip) pc_t;
+typedef typeof(instruction_pointer((struct pt_regs *)0)) pc_t;
typedef enum dtrace_activity {
DTRACE_ACTIVITY_INACTIVE = 0,
#define KERNELBASE (uintptr_t)_text
-/*
- * regset.h information
- */
-#define REG_TRAPNO 25
-#define REG_GS 24
-#define REG_FS 23
-#define REG_ES 22
-#define REG_DS 21
-#define REG_SS 20
-#define REG_RSP 19
-#define REG_RFL 18
-#define REG_CS 17
-#define REG_RIP 16
-#define REG_ERR 15
-#define REG_RDI 14
-#define REG_RSI 13
-#define REG_RDX 12
-#define REG_RCX 11
-#define REG_RAX 10
-#define REG_R8 9
-#define REG_R9 8
-#define REG_R10 7
-#define REG_R11 6
-#define REG_RBX 5
-#define REG_RBP 4
-#define REG_R12 3
-#define REG_R13 2
-#define REG_R14 1
-#define REG_R15 0
-
#if defined(__i386__) || defined(__x86_64__)
# define DTRACE_INVOP_PUSHL_EBP 1
# define DTRACE_INVOP_POPL_EBP 2
--- /dev/null
+#ifndef _X86_64_SDT_ARCH_H
+#define _X86_64_SDT_ARCH_H
+
+/*
+ * Statically Defined Tracing Implementation defines
+ *
+ * Note: The contents of this file are private to the implementation of the
+ * DTrace subsystem and are subject to change at any time without notice.
+ */
+
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ * Copyright 2009-2014 Oracle, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+#define SDT_AFRAMES 4
+
+#endif /* _X86_64_SDT_ARCH_H */
*
* CDDL HEADER END
*
- * Copyright 2010, 2011, 2012 Oracle, Inc. All rights reserved.
+ * Copyright 2010-2014 Oracle, Inc. All rights reserved.
* Use is subject to license terms.
*/
dtrace_getpcstack(stack, 8, 0, NULL);
pc = stack[7];
} else if (user_mode(regs))
- upc = GET_IP(regs);
+ upc = instruction_pointer(regs);
else
- pc = GET_IP(regs);
+ pc = instruction_pointer(regs);
dtrace_probe(prof->prof_id, pc, upc, 0, 0, 0);
}
dtrace_getpcstack(stack, 8, 0, NULL);
pc = stack[7];
} else if (user_mode(regs))
- upc = GET_IP(regs);
+ upc = instruction_pointer(regs);
else
- pc = GET_IP(regs);
+ pc = instruction_pointer(regs);
dtrace_probe(prof->prof_id, pc, upc, ktime_to_ns(late), 0, 0);
}
*
* CDDL HEADER END
*
- * Copyright 2010, 2011, 2012 Oracle, Inc. All rights reserved.
+ * Copyright 2010-2014 Oracle, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <linux/sdt.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
+#include <linux/vmalloc.h>
#include "dtrace.h"
#include "dtrace_dev.h"
#include "sdt_impl.h"
-#define SDT_PATCHVAL 0xf0
-#define SDT_ADDR2NDX(addr) ((((uintptr_t)(addr)) >> 4) & sdt_probetab_mask)
#define SDT_PROBETAB_SIZE 0x1000 /* 4k entries -- 16K total */
-static sdt_probe_t **sdt_probetab;
-static int sdt_probetab_size;
-static int sdt_probetab_mask;
+sdt_probe_t **sdt_probetab;
+int sdt_probetab_size;
+int sdt_probetab_mask;
static sdt_argdesc_t sdt_args[] = {
/*
{ NULL, }
};
-static uint8_t sdt_invop(struct pt_regs *regs)
-{
- sdt_probe_t *sdt = sdt_probetab[SDT_ADDR2NDX(regs->ip)];
-
- for (; sdt != NULL; sdt = sdt->sdp_hashnext) {
- if ((uintptr_t)sdt->sdp_patchpoint == regs->ip) {
- this_cpu_core->cpu_dtrace_regs = regs;
-
- dtrace_probe(sdt->sdp_id, regs->di, regs->si,
- regs->dx, regs->cx, regs->r8);
-
- this_cpu_core->cpu_dtrace_regs = NULL;
-
- return DTRACE_INVOP_NOP;
- }
- }
-
- return 0;
-}
-
void sdt_provide_module(void *arg, struct module *mp)
{
char *modname = mp->name;
return;
}
+ if (!sdt_provide_module_arch(arg, mp))
+ return;
+
for (idx = 0, sdpd = mp->sdt_probes; idx < mp->num_dtrace_probes;
idx++, sdpd++) {
char *name = sdpd->sdpd_name, *nname;
sdp->sdp_id = dtrace_probe_create(prov->dtmp_id,
modname,
sdpd->sdpd_func,
- nname, 3, sdp);
+ nname, SDT_AFRAMES,
+ sdp);
mp->sdt_nprobes++;
}
SDT_ADDR2NDX(sdpd->sdpd_offset)];
sdt_probetab[SDT_ADDR2NDX(sdpd->sdpd_offset)] = sdp;
- sdp->sdp_patchval = SDT_PATCHVAL;
- sdp->sdp_patchpoint = (uint8_t *)sdpd->sdpd_offset;
- sdp->sdp_savedval = *sdp->sdp_patchpoint;
+ sdp->sdp_patchpoint = (sdt_instr_t *)sdpd->sdpd_offset;
+
+ sdt_provide_probe_arch(sdp, mp, idx);
}
}
module_put(sdp->sdp_module);
while (sdp != NULL) {
- dtrace_invop_enable(sdp->sdp_patchpoint);
+ sdt_enable_arch(sdp, id, arg);
sdp = sdp->sdp_next;
}
module_put(sdp->sdp_module);
while (sdp != NULL) {
- dtrace_invop_disable(sdp->sdp_patchpoint, sdp->sdp_savedval);
+ sdt_disable_arch(sdp, id, arg);
sdp = sdp->sdp_next;
}
}
desc->dtargd_ndx = DTRACE_ARGNONE;
}
-uint64_t sdt_getarg(void *arg, dtrace_id_t id, void *parg, int argno,
- int aframes)
-{
- struct pt_regs *regs = this_cpu_core->cpu_dtrace_regs;
- uint64_t *st;
- uint64_t val;
-
- if (regs == NULL)
- return 0;
-
- switch (argno) {
- case 0:
- return regs->di;
- case 1:
- return regs->si;
- case 2:
- return regs->dx;
- case 3:
- return regs->cx;
- case 4:
- return regs->r8;
- case 5:
- return regs->r9;
- }
-
- ASSERT(argno > 5);
-
- st = (uint64_t *)regs->sp;
- DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);
- __copy_from_user_inatomic_nocache(&val, (void *)&st[argno - 6],
- sizeof(st[0]));
- DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT);
-
- return val;
-}
-
void sdt_destroy(void *arg, dtrace_id_t id, void *parg)
{
sdt_probe_t *sdp = parg;
if (sdt_probetab == NULL)
return -ENOMEM;
- ret = dtrace_invop_add(sdt_invop);
+ sdt_dev_init_arch();
return ret;
}
void sdt_dev_exit(void)
{
- dtrace_invop_remove(sdt_invop);
+ sdt_dev_exit_arch();
+
vfree(sdt_probetab);
misc_deregister(&sdt_dev);
#define _SDT_IMPL_H_
#include <linux/sdt.h>
+#include <asm/dtrace_sdt.h>
+#include <dtrace/sdt_arch.h>
extern struct module *dtrace_kmod;
char *sda_xlate;
} sdt_argdesc_t;
-extern dtrace_mprovider_t sdt_providers[];
+extern dtrace_mprovider_t sdt_providers[];
+extern sdt_probe_t **sdt_probetab;
+extern int sdt_probetab_size;
+extern int sdt_probetab_mask;
+
+#define SDT_ADDR2NDX(addr) ((((uintptr_t)(addr)) >> 4) & \
+ sdt_probetab_mask)
+
+extern void sdt_provide_probe_arch(sdt_probe_t *, struct module *, int);
+extern int sdt_provide_module_arch(void *, struct module *);
+extern void sdt_enable_arch(sdt_probe_t *, dtrace_id_t, void *);
+extern void sdt_disable_arch(sdt_probe_t *, dtrace_id_t, void *);
extern void sdt_provide_module(void *, struct module *);
extern int _sdt_enable(void *, dtrace_id_t, void *);
extern int sdt_dev_init(void);
extern void sdt_dev_exit(void);
+extern int sdt_dev_init_arch(void);
+extern void sdt_dev_exit_arch(void);
+
#endif /* _SDT_IMPL_H_ */
*
* CDDL HEADER END
*
- * Copyright 2010, 2011, 2012 Oracle, Inc. All rights reserved.
+ * Copyright 2010-2014 Oracle, Inc. All rights reserved.
* Use is subject to license terms.
*/
NULL,
NULL,
sdt_getargdesc,
+#ifdef CONFIG_X86_64
sdt_getarg,
+#else
+ NULL,
+#endif
NULL,
sdt_destroy,
};
--- /dev/null
+/*
+ * FILE: sdt_dev.c
+ * DESCRIPTION: Statically Defined Tracing: device file handling
+ *
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ * Copyright 2010-2014 Oracle, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#include <linux/sdt.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+#include <linux/vmalloc.h>
+
+#include "dtrace.h"
+#include "dtrace_dev.h"
+#include "sdt_impl.h"
+
+#define SDT_PATCHVAL 0xf0
+
+static uint8_t sdt_invop(struct pt_regs *regs)
+{
+ sdt_probe_t *sdt = sdt_probetab[SDT_ADDR2NDX(regs->ip)];
+
+ for (; sdt != NULL; sdt = sdt->sdp_hashnext) {
+ if ((uintptr_t)sdt->sdp_patchpoint == regs->ip) {
+ this_cpu_core->cpu_dtrace_regs = regs;
+
+ dtrace_probe(sdt->sdp_id, regs->di, regs->si,
+ regs->dx, regs->cx, regs->r8);
+
+ this_cpu_core->cpu_dtrace_regs = NULL;
+
+ return DTRACE_INVOP_NOP;
+ }
+ }
+
+ return 0;
+}
+
+void sdt_provide_probe_arch(sdt_probe_t *sdp, struct module *mp, int idx)
+{
+ sdp->sdp_patchval = SDT_PATCHVAL;
+ sdp->sdp_savedval = *sdp->sdp_patchpoint;
+}
+
+int sdt_provide_module_arch(void *arg, struct module *mp)
+{
+ return 1;
+}
+
+void sdt_enable_arch(sdt_probe_t *sdp, dtrace_id_t id, void *arg)
+{
+ dtrace_invop_enable((uint8_t *)sdp->sdp_patchpoint);
+}
+
+void sdt_disable_arch(sdt_probe_t *sdp, dtrace_id_t id, void *arg)
+{
+ dtrace_invop_disable((uint8_t *)sdp->sdp_patchpoint,
+ sdp->sdp_savedval);
+}
+
+uint64_t sdt_getarg(void *arg, dtrace_id_t id, void *parg, int argno,
+ int aframes)
+{
+ struct pt_regs *regs = this_cpu_core->cpu_dtrace_regs;
+ uint64_t *st;
+ uint64_t val;
+
+ if (regs == NULL)
+ return 0;
+
+ switch (argno) {
+ case 0:
+ return regs->di;
+ case 1:
+ return regs->si;
+ case 2:
+ return regs->dx;
+ case 3:
+ return regs->cx;
+ case 4:
+ return regs->r8;
+ case 5:
+ return regs->r9;
+ }
+
+ ASSERT(argno > 5);
+
+ st = (uint64_t *)regs->sp;
+ DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);
+ __copy_from_user_inatomic_nocache(&val, (void *)&st[argno - 6],
+ sizeof(st[0]));
+ DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT);
+
+ return val;
+}
+
+int sdt_dev_init_arch(void)
+{
+ return dtrace_invop_add(sdt_invop);
+}
+
+void sdt_dev_exit_arch(void)
+{
+ dtrace_invop_remove(sdt_invop);
+}
*
* CDDL HEADER END
*
- * Copyright 2010, 2011 Oracle, Inc. All rights reserved.
+ * Copyright 2010-2014 Oracle, Inc. All rights reserved.
* Use is subject to license terms.
*/
+#include <linux/dtrace_syscall.h>
#include <linux/fs.h>
#include <linux/miscdevice.h>
#include <asm/unistd.h>
#include "dtrace_dev.h"
#include "systrace.h"
-#define SYSTRACE_ARTIFICIAL_FRAMES 0
+#define SYSTRACE_ARTIFICIAL_FRAMES 1
#define SYSTRACE_SHIFT 16
#define SYSTRACE_ENTRY(id) ((1 << SYSTRACE_SHIFT) | (id))
switch (sysnum) {
default:
return systrace_info->syscall;
- case __NR_clone:
- return systrace_info->stubs[SCE_CLONE];
- case __NR_fork:
- return systrace_info->stubs[SCE_FORK];
- case __NR_vfork:
- return systrace_info->stubs[SCE_VFORK];
- case __NR_iopl:
- return systrace_info->stubs[SCE_IOPL];
- case __NR_execve:
- return systrace_info->stubs[SCE_EXECVE];
- case __NR_rt_sigreturn:
- return systrace_info->stubs[SCE_RT_SIGRETURN];
+#define DTRACE_SYSCALL_STUB(t, n) \
+ case __NR_##n: \
+ return systrace_info->stubs[SCE_##t];
+#include <asm/dtrace_syscall.h>
+#undef DTRACE_SYSCALL_STUB
}
}
int _systrace_enable(void *arg, dtrace_id_t id, void *parg)
{
- int sysnum = SYSTRACE_SYSNUM((uintptr_t)parg);
- int enabled =
- systrace_info->sysent[sysnum].stsy_entry != DTRACE_IDNONE ||
- systrace_info->sysent[sysnum].stsy_return != DTRACE_IDNONE;
- dt_sys_call_t intercept = get_intercept(sysnum);
+ int sysnum = SYSTRACE_SYSNUM((uintptr_t)parg);
+ dtrace_syscalls_t *sc = &systrace_info->sysent[sysnum];
+ int enabled = sc->stsy_entry != DTRACE_IDNONE ||
+ sc->stsy_return != DTRACE_IDNONE;
+ dt_sys_call_t intercept = get_intercept(sysnum);
if (!enabled) {
- if (cmpxchg(systrace_info->sysent[sysnum].stsy_tblent,
- systrace_info->sysent[sysnum].stsy_underlying,
- intercept) !=
- systrace_info->sysent[sysnum].stsy_underlying)
- return 0;
+ if (cmpxchg((uint32_t *)sc->stsy_tblent,
+ (uint32_t)sc->stsy_underlying,
+ (uint32_t)intercept) !=
+ (uint32_t)sc->stsy_underlying)
+ return 1;
} else
- ASSERT((void *)*(systrace_info->sysent[sysnum].stsy_tblent) ==
- (void *)intercept);
+ ASSERT(*(uint32_t *)sc->stsy_tblent == (uint32_t)intercept);
if (SYSTRACE_ISENTRY((uintptr_t)parg))
- systrace_info->sysent[sysnum].stsy_entry = id;
+ sc->stsy_entry = id;
else
- systrace_info->sysent[sysnum].stsy_return = id;
+ sc->stsy_return = id;
return 0;
}
void _systrace_disable(void *arg, dtrace_id_t id, void *parg)
{
- int sysnum = SYSTRACE_SYSNUM((uintptr_t)parg);
- int enabled =
- systrace_info->sysent[sysnum].stsy_entry != DTRACE_IDNONE ||
- systrace_info->sysent[sysnum].stsy_return != DTRACE_IDNONE;
- dt_sys_call_t intercept = get_intercept(sysnum);
+ int sysnum = SYSTRACE_SYSNUM((uintptr_t)parg);
+ dtrace_syscalls_t *sc = &systrace_info->sysent[sysnum];
+ int enabled = sc->stsy_entry != DTRACE_IDNONE ||
+ sc->stsy_return != DTRACE_IDNONE;
+ dt_sys_call_t intercept = get_intercept(sysnum);
if (enabled)
- (void)cmpxchg(systrace_info->sysent[sysnum].stsy_tblent,
- intercept,
- systrace_info->sysent[sysnum].stsy_underlying);
+ (void)cmpxchg((uint32_t *)sc->stsy_tblent, (uint32_t)intercept,
+ (uint32_t)sc->stsy_underlying);
if (SYSTRACE_ISENTRY((uintptr_t)parg))
- systrace_info->sysent[sysnum].stsy_entry = DTRACE_IDNONE;
+ sc->stsy_entry = DTRACE_IDNONE;
else
- systrace_info->sysent[sysnum].stsy_return = DTRACE_IDNONE;
+ sc->stsy_return = DTRACE_IDNONE;
}
void systrace_destroy(void *arg, dtrace_id_t id, void *parg)