/*
- * Copyright (c) 2005-2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2005-2018 Apple Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_END@
*/
-#define MACH__POSIX_C_SOURCE_PRIVATE 1 /* pulls in suitable savearea from mach/ppc/thread_status.h */
#include <kern/thread.h>
#include <mach/thread_status.h>
#include <kern/sched_prim.h>
#include <miscfs/devfs/devfs.h>
#include <mach/vm_param.h>
+#include <machine/pal_routines.h>
+#include <i386/mp.h>
/*
* APPLE NOTE: The regmap is used to decode which 64bit uregs[] register
/*
* MP coordination
*/
-
-extern void mp_broadcast(
- void (*action_func)(void *),
- void *arg);
-
typedef struct xcArg {
processorid_t cpu;
dtrace_xcall_t f;
}
}
+
/*
* dtrace_xcall() is not called from probe context.
*/
xcArg.f = f;
xcArg.arg = arg;
- mp_broadcast( xcRemote, (void *)&xcArg);
+ if (cpu == DTRACE_CPUALL) {
+ mp_cpus_call (CPUMASK_ALL, ASYNC, xcRemote, (void*)&xcArg);
+ }
+ else {
+ mp_cpus_call (cpu_to_cpumask((cpu_t)cpu), ASYNC, xcRemote, (void*)&xcArg);
+ }
}
/*
- * Runtime and ABI
+ * Initialization
*/
+void
+dtrace_isa_init(void)
+{
+ return;
+}
+/*
+ * Runtime and ABI
+ */
uint64_t
dtrace_getreg(struct regs *savearea, uint_t reg)
{
boolean_t is64Bit = proc_is64bit(current_proc());
x86_saved_state_t *regs = (x86_saved_state_t *)savearea;
+ if (regs == NULL) {
+ DTRACE_CPUFLAG_SET(CPU_DTRACE_ILLOP);
+ return (0);
+ }
+
if (is64Bit) {
if (reg <= SS) {
reg = regmap[reg];
if (thread == NULL)
goto zero;
+ pal_register_cache_state(thread, VALID);
regs = (x86_saved_state_t *)find_user_regs(thread);
if (regs == NULL)
goto zero;
- *pcstack++ = (uint64_t)proc_selfpid();
+ *pcstack++ = (uint64_t)dtrace_proc_selfpid();
pcstack_limit--;
if (pcstack_limit <= 0)
if (DTRACE_CPUFLAG_ISSET(CPU_DTRACE_FAULT))
return (-1);
+ pal_register_cache_state(thread, VALID);
regs = (x86_saved_state_t *)find_user_regs(thread);
if (regs == NULL)
return 0;
if (regs == NULL)
goto zero;
- *pcstack++ = (uint64_t)proc_selfpid();
+ *pcstack++ = (uint64_t)dtrace_proc_selfpid();
pcstack_limit--;
if (pcstack_limit <= 0)
while (depth < pcstack_limit) {
nextfp = *(struct frame **)fp;
-#if defined(__x86_64__)
pc = *(uintptr_t *)(((uintptr_t)fp) + RETURN_OFFSET64);
-#else
- pc = *(uintptr_t *)(((uintptr_t)fp) + RETURN_OFFSET);
-#endif
if (nextfp <= minfp || nextfp >= stacktop) {
if (on_intr) {
};
uint64_t
-dtrace_getarg(int arg, int aframes)
+dtrace_getarg(int arg, int aframes, dtrace_mstate_t *mstate, dtrace_vstate_t *vstate)
{
- uint64_t val;
+ uint64_t val = 0;
struct frame *fp = (struct frame *)__builtin_frame_address(0);
uintptr_t *stack;
uintptr_t pc;
int i;
-#if defined(__x86_64__)
/*
* A total of 6 arguments are passed via registers; any argument with
* index of 5 or lower is therefore in a register.
*/
int inreg = 5;
-#endif
for (i = 1; i <= aframes; i++) {
fp = fp->backchain;
pc = fp->retaddr;
- if (pc == (uintptr_t)dtrace_invop_callsite) {
-#if defined(__i386__)
- /*
- * If we pass through the invalid op handler, we will
- * use the pointer that it passed to the stack as the
- * second argument to dtrace_invop() as the pointer to
- * the frame we're hunting for.
- */
-
- stack = (uintptr_t *)&fp[1]; /* Find marshalled arguments */
- fp = (struct frame *)stack[1]; /* Grab *second* argument */
- stack = (uintptr_t *)&fp[1]; /* Find marshalled arguments */
-#elif defined(__x86_64__)
+ if (dtrace_invop_callsite_pre != NULL
+ && pc > (uintptr_t)dtrace_invop_callsite_pre
+ && pc <= (uintptr_t)dtrace_invop_callsite_post) {
/*
* In the case of x86_64, we will use the pointer to the
* save area structure that was pushed when we took the
x86_saved_state64_t *saved_state = saved_state64(tagged_regs);
if (arg <= inreg) {
- stack = (uintptr_t *)&saved_state->rdi;
+ stack = (uintptr_t *)(void*)&saved_state->rdi;
} else {
- stack = (uintptr_t *)(saved_state->isf.rsp);
- arg -= inreg;
+ fp = (struct frame *)(saved_state->isf.rsp);
+ stack = (uintptr_t *)&fp[1]; /* Find marshalled
+ arguments */
+ arg -= inreg + 1;
}
-#else
-#error Unknown arch
-#endif
goto load;
}
}
/*
- * Arrive here when provider has called dtrace_probe directly.
+ * We know that we did not come through a trap to get into
+ * dtrace_probe() -- We arrive here when the provider has
+ * called dtrace_probe() directly.
+ * The probe ID is the first argument to dtrace_probe().
+ * We must advance beyond that to get the argX.
*/
arg++; /* Advance past probeID */
-#if defined(__x86_64__)
if (arg <= inreg) {
/*
* This shouldn't happen. If the argument is passed in a
}
arg -= (inreg + 1);
-#endif
stack = (uintptr_t *)&fp[1]; /* Find marshalled arguments */
load:
- DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);
- val = *(((uint64_t *)stack) + arg); /* dtrace_probe arguments arg0 .. arg4 are 64bits wide */
- DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT);
+ if (dtrace_canload((uint64_t)(stack + arg), sizeof(uint64_t),
+ mstate, vstate)) {
+ /* dtrace_probe arguments arg0 ... arg4 are 64bits wide */
+ val = dtrace_load64((uint64_t)(stack + arg));
+ }
return (val);
}