]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/dev/i386/dtrace_isa.c
xnu-6153.61.1.tar.gz
[apple/xnu.git] / bsd / dev / i386 / dtrace_isa.c
index 65749f9df84120df35cd9e2631675c43dc8816d4..6785dc53650866ce0735d343c38c444a06af77b3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005-2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2005-2018 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  * 
@@ -26,7 +26,6 @@
  * @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>
 
@@ -48,6 +47,8 @@ typedef x86_saved_state_t savearea_t;
 #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
@@ -126,11 +127,6 @@ dtrace_getipl(void)
 /*
  * MP coordination
  */
-
-extern void mp_broadcast(
-       void (*action_func)(void *),
-       void *arg);
-
 typedef struct xcArg {
        processorid_t cpu;
        dtrace_xcall_t f;
@@ -147,6 +143,7 @@ xcRemote( void *foo )
        }
 }
 
+
 /*
  * dtrace_xcall() is not called from probe context.
  */
@@ -159,19 +156,37 @@ dtrace_xcall(processorid_t cpu, dtrace_xcall_t f, void *arg)
        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];
@@ -420,11 +435,12 @@ dtrace_getupcstack(uint64_t *pcstack, int pcstack_limit)
        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)
@@ -483,6 +499,7 @@ dtrace_getustackdepth(void)
        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;
@@ -550,7 +567,7 @@ dtrace_getufpstack(uint64_t *pcstack, uint64_t *fpstack, int pcstack_limit)
        if (regs == NULL)
                goto zero;
                
-       *pcstack++ = (uint64_t)proc_selfpid();
+       *pcstack++ = (uint64_t)dtrace_proc_selfpid();
        pcstack_limit--;
 
        if (pcstack_limit <= 0)
@@ -666,11 +683,7 @@ dtrace_getpcstack(pc_t *pcstack, int pcstack_limit, int aframes,
 
        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) {
@@ -725,40 +738,28 @@ struct frame {
 };
 
 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
@@ -781,24 +782,26 @@ dtrace_getarg(int arg, int aframes)
                        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
@@ -810,13 +813,14 @@ dtrace_getarg(int arg, int aframes)
        }
 
        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);
 }