]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/dev/dtrace/systrace.c
xnu-7195.101.1.tar.gz
[apple/xnu.git] / bsd / dev / dtrace / systrace.c
index 6761beec99c3d04066d44b58f0e784c32c8f0e80..1342e7785875b4d3a1cf25f8662cfc431bda6ba9 100644 (file)
  * Use is subject to license terms.
  */
 
-/* #pragma ident       "@(#)systrace.c 1.6     06/09/19 SMI" */
+#include <ptrauth.h>
 
-#if !defined(__APPLE__)
-#include <sys/dtrace.h>
-#include <sys/systrace.h>
-#include <sys/stat.h>
-#include <sys/systm.h>
-#include <sys/conf.h>
-#include <sys/ddi.h>
-#include <sys/sunddi.h>
-#include <sys/atomic.h>
-#define        SYSTRACE_ARTIFICIAL_FRAMES      1
-#else
-
-#ifdef KERNEL
-#ifndef _KERNEL
-#define _KERNEL /* Solaris vs. Darwin */
-#endif
-#endif
-
-#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>
+
 /* XXX All of these should really be derived from syscall_sw.h */
-#if defined(__i386__) || defined (__x86_64__)
+#if defined (__x86_64__)
 #define SYSCALL_CLASS_SHIFT 24
 #define SYSCALL_CLASS_MASK  (0xFF << SYSCALL_CLASS_SHIFT)
 #define SYSCALL_NUMBER_MASK (~SYSCALL_CLASS_MASK)
 #define I386_SYSCALL_NUMBER_MASK (0xFFFF)
-
-typedef x86_saved_state_t savearea_t;
 #endif
 
 #include <sys/param.h>
@@ -63,10 +43,12 @@ typedef x86_saved_state_t savearea_t;
 #include <sys/ioctl.h>
 #include <sys/conf.h>
 #include <sys/fcntl.h>
+#include <sys/syscall.h>
 #include <miscfs/devfs/devfs.h>
 
 #include <sys/dtrace.h>
 #include <sys/dtrace_impl.h>
+#include <sys/systrace_args.h>
 #include "systrace.h"
 #include <sys/stat.h>
 #include <sys/systm.h>
@@ -75,13 +57,18 @@ typedef x86_saved_state_t savearea_t;
 
 #include <machine/pal_routines.h>
 
-#if defined(__i386__) || defined (__x86_64__)
-#define        SYSTRACE_ARTIFICIAL_FRAMES      2
+#if defined (__x86_64__)
+#define SYSTRACE_ARTIFICIAL_FRAMES      2
+#define MACHTRACE_ARTIFICIAL_FRAMES 3
+#elif defined(__arm__) || defined(__arm64__)
+#define SYSTRACE_ARTIFICIAL_FRAMES  2
 #define MACHTRACE_ARTIFICIAL_FRAMES 3
 #else
 #error Unknown Architecture
 #endif
 
+#define SYSTRACE_NARGS (int)(sizeof(((uthread_t)NULL)->uu_arg) / sizeof(((uthread_t)NULL)->uu_arg[0]))
+
 #include <sys/sysent.h>
 #define sy_callc sy_call /* Map Solaris slot name to Darwin's */
 #define NSYSCALL nsysent /* and is less than 500 or so */
@@ -95,14 +82,14 @@ extern const char *syscallnames[];
 #define LOADABLE_SYSCALL(a) 0 /* Not pertinent to Darwin. */
 #define LOADED_SYSCALL(a) 1 /* Not pertinent to Darwin. */
 
-extern lck_attr_t* dtrace_lck_attr;
-extern lck_grp_t* dtrace_lck_grp;
-static lck_mtx_t       dtrace_systrace_lock;           /* probe state lock */
+static LCK_MTX_DECLARE_ATTR(dtrace_systrace_lock,
+    &dtrace_lck_grp, &dtrace_lck_attr);           /* probe state lock */
 
 systrace_sysent_t *systrace_sysent = NULL;
 void (*systrace_probe)(dtrace_id_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t);
 
-static uint64_t systrace_getarg(void *, dtrace_id_t, void *, int, int);        
+static uint64_t systrace_getargval(void *, dtrace_id_t, void *, int, int);
+static void systrace_getargdesc(void *, dtrace_id_t, void *, dtrace_argdesc_t *);
 
 void
 systrace_stub(dtrace_id_t id, uint64_t arg0, uint64_t arg1,
@@ -114,19 +101,15 @@ systrace_stub(dtrace_id_t id, uint64_t arg0, uint64_t arg1,
 int32_t
 dtrace_systrace_syscall(struct proc *pp, void *uap, int *rv)
 {
-       boolean_t           flavor;
-       unsigned short      code;
+       unsigned short      code;       /* The system call number */
 
        systrace_sysent_t *sy;
        dtrace_id_t id;
        int32_t rval;
-#if 0 /* XXX */
-       proc_t *p;
-#endif
        syscall_arg_t *ip = (syscall_arg_t *)uap;
+       uint64_t uargs[SYSTRACE_NARGS] = {0};
 
-#if defined(__i386__) || defined (__x86_64__)
-#pragma unused(flavor)
+#if defined (__x86_64__)
        {
                pal_register_cache_state(current_thread(), VALID);
                x86_saved_state_t   *tagged_regs = (x86_saved_state_t *)find_user_regs(current_thread());
@@ -145,34 +128,83 @@ dtrace_systrace_syscall(struct proc *pp, void *uap, int *rv)
                        code = saved_state32(tagged_regs)->eax & I386_SYSCALL_NUMBER_MASK;
 
                        if (code == 0) {
-                               vm_offset_t params = (vm_offset_t) (saved_state32(tagged_regs)->uesp + sizeof (int));
+                               vm_offset_t params = (vm_offset_t) (saved_state32(tagged_regs)->uesp + sizeof(int));
                                code = fuword(params);
                        }
                }
        }
+#elif defined(__arm__)
+       {
+               /*
+                * On arm, syscall numbers depend on a flavor (indirect or not)
+                * and can be in either r0 or r12  (always u32)
+                */
+
+               /* See bsd/dev/arm/systemcalls.c:arm_get_syscall_number */
+               arm_saved_state_t *arm_regs = (arm_saved_state_t *) find_user_regs(current_thread());
+
+               /* Check for indirect system call */
+               if (arm_regs->r[12] != 0) {
+                       code = arm_regs->r[12];
+               } else {
+                       code = arm_regs->r[0];
+               }
+       }
+#elif defined(__arm64__)
+       {
+               /*
+                * On arm64, syscall numbers depend on a flavor (indirect or not)
+                * ... and for u32 can be in either r0 or r12
+                * ... and for u64 can be in either x0 or x16
+                */
+
+               /* see bsd/dev/arm/systemcalls.c:arm_get_syscall_number */
+               arm_saved_state_t *arm_regs = (arm_saved_state_t *) find_user_regs(current_thread());
+
+               if (is_saved_state32(arm_regs)) {
+                       /* Check for indirect system call */
+                       if (saved_state32(arm_regs)->r[12] != 0) {
+                               code = saved_state32(arm_regs)->r[12];
+                       } else {
+                               code = saved_state32(arm_regs)->r[0];
+                       }
+               } else {
+                       /* Check for indirect system call */
+                       if (saved_state64(arm_regs)->x[ARM64_SYSCALL_CODE_REG_NUM] != 0) {
+                               code = saved_state64(arm_regs)->x[ARM64_SYSCALL_CODE_REG_NUM];
+                       } else {
+                               code = saved_state64(arm_regs)->x[0];
+                       }
+               }
+       }
 #else
 #error Unknown Architecture
 #endif
 
        // Bounds "check" the value of code a la unix_syscall
-       sy = (code >= NUM_SYSENT) ? &systrace_sysent[63] : &systrace_sysent[code];
+       sy = (code >= nsysent) ? &systrace_sysent[SYS_invalid] : &systrace_sysent[code];
+
+       systrace_args(code, ip, uargs);
 
        if ((id = sy->stsy_entry) != DTRACE_IDNONE) {
-               uthread_t uthread = (uthread_t)get_bsdthread_info(current_thread());            
-               if (uthread)
-                       uthread->t_dtrace_syscall_args = (void *)ip;
-               
-               if (ip)
-                       (*systrace_probe)(id, *ip, *(ip+1), *(ip+2), *(ip+3), *(ip+4));
-               else
-                       (*systrace_probe)(id, 0, 0, 0, 0, 0);
-               
-               if (uthread)
-                       uthread->t_dtrace_syscall_args = (void *)0;
+               uthread_t uthread = (uthread_t)get_bsdthread_info(current_thread());
+               if (uthread) {
+                       uthread->t_dtrace_syscall_args = uargs;
+               }
+
+               static_assert(SYSTRACE_NARGS >= 5, "not enough system call arguments");
+               (*systrace_probe)(id, uargs[0], uargs[1], uargs[2], uargs[3], uargs[4]);
+
+               if (uthread) {
+                       uthread->t_dtrace_syscall_args = NULL;
+               }
        }
 
+
+
 #if 0 /* XXX */
        /*
+        * APPLE NOTE: Not implemented.
         * We want to explicitly allow DTrace consumers to stop a process
         * before it actually executes the meat of the syscall.
         */
@@ -189,14 +221,14 @@ dtrace_systrace_syscall(struct proc *pp, void *uap, int *rv)
 
        if ((id = sy->stsy_return) != DTRACE_IDNONE) {
                uint64_t munged_rv0, munged_rv1;
-       uthread_t uthread = (uthread_t)get_bsdthread_info(current_thread());
+               uthread_t uthread = (uthread_t)get_bsdthread_info(current_thread());
 
-               if (uthread)
+               if (uthread) {
                        uthread->t_dtrace_errno = rval; /* Establish t_dtrace_errno now in case this enabling refers to it. */
-
+               }
                /*
-                * "Decode" rv for use in the call to dtrace_probe()
-                */
+                * "Decode" rv for use in the call to dtrace_probe()
+                */
                if (rval == ERESTART) {
                        munged_rv0 = -1LL; /* System call will be reissued in user mode. Make DTrace report a -1 return. */
                        munged_rv1 = -1LL;
@@ -246,20 +278,20 @@ dtrace_systrace_syscall(struct proc *pp, void *uap, int *rv)
                 * "This is a bit of an historical artifact. At first, the syscall provider just
                 * had its return value in arg0, and the fbt and pid providers had their return
                 * values in arg1 (so that we could use arg0 for the offset of the return site).
-                * 
+                *
                 * We inevitably started writing scripts where we wanted to see the return
                 * values from probes in all three providers, and we made this script easier
                 * to write by replicating the syscall return values in arg1 to match fbt and
                 * pid. We debated briefly about removing the return value from arg0, but
                 * decided that it would be less confusing to have the same data in two places
                 * than to have some non-helpful, non-intuitive value in arg0.
-                * 
+                *
                 * This change was made 4/23/2003 according to the DTrace project's putback log."
-                */ 
+                */
                (*systrace_probe)(id, munged_rv0, munged_rv0, munged_rv1, (uint64_t)rval, 0);
        }
 
-       return (rval);
+       return rval;
 }
 
 void
@@ -269,18 +301,18 @@ dtrace_systrace_syscall_return(unsigned short code, int rval, int *rv)
        dtrace_id_t id;
 
        // Bounds "check" the value of code a la unix_syscall_return
-       sy = (code >= NUM_SYSENT) ? &systrace_sysent[63] : &systrace_sysent[code];
+       sy = (code >= nsysent) ? &systrace_sysent[SYS_invalid] : &systrace_sysent[code];
 
        if ((id = sy->stsy_return) != DTRACE_IDNONE) {
                uint64_t munged_rv0, munged_rv1;
-       uthread_t uthread = (uthread_t)get_bsdthread_info(current_thread());
+               uthread_t uthread = (uthread_t)get_bsdthread_info(current_thread());
 
-               if (uthread)
+               if (uthread) {
                        uthread->t_dtrace_errno = rval; /* Establish t_dtrace_errno now in case this enabling refers to it. */
-
+               }
                /*
-                * "Decode" rv for use in the call to dtrace_probe()
-                */
+                * "Decode" rv for use in the call to dtrace_probe()
+                */
                if (rval == ERESTART) {
                        munged_rv0 = -1LL; /* System call will be reissued in user mode. Make DTrace report a -1 return. */
                        munged_rv1 = -1LL;
@@ -327,111 +359,77 @@ dtrace_systrace_syscall_return(unsigned short code, int rval, int *rv)
                (*systrace_probe)(id, munged_rv0, munged_rv0, munged_rv1, (uint64_t)rval, 0);
        }
 }
-#endif /* __APPLE__ */
 
-#define        SYSTRACE_SHIFT                  16
-#define        SYSTRACE_ISENTRY(x)             ((int)(x) >> SYSTRACE_SHIFT)
-#define        SYSTRACE_SYSNUM(x)              ((int)(x) & ((1 << SYSTRACE_SHIFT) - 1))
-#define        SYSTRACE_ENTRY(id)              ((1 << SYSTRACE_SHIFT) | (id))
-#define        SYSTRACE_RETURN(id)             (id)
+#define SYSTRACE_SHIFT                  16
+#define SYSTRACE_ISENTRY(x)             ((int)(x) >> SYSTRACE_SHIFT)
+#define SYSTRACE_SYSNUM(x)              ((int)(x) & ((1 << SYSTRACE_SHIFT) - 1))
+#define SYSTRACE_ENTRY(id)              ((1 << SYSTRACE_SHIFT) | (id))
+#define SYSTRACE_RETURN(id)             (id)
 
 #if ((1 << SYSTRACE_SHIFT) <= NSYSCALL)
 #error 1 << SYSTRACE_SHIFT must exceed number of system calls
 #endif
 
-static dev_info_t *systrace_devi;
 static dtrace_provider_id_t systrace_id;
 
-#if !defined (__APPLE__)
-static void
-systrace_init(struct sysent *actual, systrace_sysent_t **interposed)
-{
-       systrace_sysent_t *sysent = *interposed;
-       int i;
-
-       if (sysent == NULL) {
-               *interposed = sysent = kmem_zalloc(sizeof (systrace_sysent_t) *
-                   NSYSCALL, KM_SLEEP);
-       }
-
-       for (i = 0; i < NSYSCALL; i++) {
-               struct sysent *a = &actual[i];
-               systrace_sysent_t *s = &sysent[i];
-
-               if (LOADABLE_SYSCALL(a) && !LOADED_SYSCALL(a))
-                       continue;
-
-               if (a->sy_callc == dtrace_systrace_syscall)
-                       continue;
-
-#ifdef _SYSCALL32_IMPL
-               if (a->sy_callc == dtrace_systrace_syscall32)
-                       continue;
-#endif
+/*
+ * APPLE NOTE: Avoid name clash with Darwin automagic conf symbol.
+ * See balanced undef below.
+ */
+#define systrace_init _systrace_init
 
-               s->stsy_underlying = a->sy_callc;
-       }
-}
-#else
-#define systrace_init _systrace_init /* Avoid name clash with Darwin automagic conf symbol */
 static void
-systrace_init(struct sysent *actual, systrace_sysent_t **interposed)
+systrace_init(const struct sysent *actual, systrace_sysent_t **interposed)
 {
-
        systrace_sysent_t *ssysent = *interposed;  /* Avoid sysent shadow warning
-                                                          from bsd/sys/sysent.h */
-       int i;
+                                                   *       from bsd/sys/sysent.h */
+       unsigned int i;
 
        if (ssysent == NULL) {
-               *interposed = ssysent = kmem_zalloc(sizeof (systrace_sysent_t) *
+               *interposed = ssysent = kmem_zalloc(sizeof(systrace_sysent_t) *
                    NSYSCALL, KM_SLEEP);
        }
 
        for (i = 0; i < NSYSCALL; i++) {
-               struct sysent *a = &actual[i];
+               const struct sysent *a = &actual[i];
                systrace_sysent_t *s = &ssysent[i];
 
-               if (LOADABLE_SYSCALL(a) && !LOADED_SYSCALL(a))
-                       continue;
-
-               if (a->sy_callc == dtrace_systrace_syscall)
+               if (LOADABLE_SYSCALL(a) && !LOADED_SYSCALL(a)) {
                        continue;
+               }
 
-#ifdef _SYSCALL32_IMPL
-               if (a->sy_callc == dtrace_systrace_syscall32)
+               if (a->sy_callc == dtrace_systrace_syscall) {
                        continue;
-#endif
+               }
 
                s->stsy_underlying = a->sy_callc;
                s->stsy_return_type = a->sy_return_type;
        }
-       lck_mtx_init(&dtrace_systrace_lock, dtrace_lck_grp, dtrace_lck_attr);
 }
 
-#endif /* __APPLE__ */
 
 /*ARGSUSED*/
 static void
 systrace_provide(void *arg, const dtrace_probedesc_t *desc)
 {
 #pragma unused(arg) /* __APPLE__ */
-       int i;
+       unsigned int i;
 
-       if (desc != NULL)
+       if (desc != NULL) {
                return;
+       }
 
        systrace_init(sysent, &systrace_sysent);
-#ifdef _SYSCALL32_IMPL
-       systrace_init(sysent32, &systrace_sysent32);
-#endif
 
        for (i = 0; i < NSYSCALL; i++) {
-               if (systrace_sysent[i].stsy_underlying == NULL)
+               if (systrace_sysent[i].stsy_underlying == NULL) {
                        continue;
+               }
 
                if (dtrace_probe_lookup(systrace_id, NULL,
-                   syscallnames[i], "entry") != 0)
+                   syscallnames[i], "entry") != 0) {
                        continue;
+               }
 
                (void) dtrace_probe_create(systrace_id, NULL, syscallnames[i],
                    "entry", SYSTRACE_ARTIFICIAL_FRAMES,
@@ -442,15 +440,9 @@ systrace_provide(void *arg, const dtrace_probedesc_t *desc)
 
                systrace_sysent[i].stsy_entry = DTRACE_IDNONE;
                systrace_sysent[i].stsy_return = DTRACE_IDNONE;
-#ifdef _SYSCALL32_IMPL
-               systrace_sysent32[i].stsy_entry = DTRACE_IDNONE;
-               systrace_sysent32[i].stsy_return = DTRACE_IDNONE;
-#endif
        }
 }
-#if defined(__APPLE__)
 #undef systrace_init
-#endif
 
 /*ARGSUSED*/
 static void
@@ -467,14 +459,8 @@ systrace_destroy(void *arg, dtrace_id_t id, void *parg)
         */
        if (SYSTRACE_ISENTRY((uintptr_t)parg)) {
                ASSERT(systrace_sysent[sysnum].stsy_entry == DTRACE_IDNONE);
-#ifdef _SYSCALL32_IMPL
-               ASSERT(systrace_sysent32[sysnum].stsy_entry == DTRACE_IDNONE);
-#endif
        } else {
                ASSERT(systrace_sysent[sysnum].stsy_return == DTRACE_IDNONE);
-#ifdef _SYSCALL32_IMPL
-               ASSERT(systrace_sysent32[sysnum].stsy_return == DTRACE_IDNONE);
-#endif
        }
 }
 
@@ -483,40 +469,31 @@ static int
 systrace_enable(void *arg, dtrace_id_t id, void *parg)
 {
 #pragma unused(arg) /* __APPLE__ */
-    
+
        int sysnum = SYSTRACE_SYSNUM((uintptr_t)parg);
        int enabled = (systrace_sysent[sysnum].stsy_entry != DTRACE_IDNONE ||
            systrace_sysent[sysnum].stsy_return != DTRACE_IDNONE);
 
        if (SYSTRACE_ISENTRY((uintptr_t)parg)) {
                systrace_sysent[sysnum].stsy_entry = id;
-#ifdef _SYSCALL32_IMPL
-               systrace_sysent32[sysnum].stsy_entry = id;
-#endif
        } else {
                systrace_sysent[sysnum].stsy_return = id;
-#ifdef _SYSCALL32_IMPL
-               systrace_sysent32[sysnum].stsy_return = id;
-#endif
        }
 
        if (enabled) {
                ASSERT(sysent[sysnum].sy_callc == dtrace_systrace_syscall);
-               return(0);
+               return 0;
        }
-#ifdef _SYSCALL32_IMPL
-       (void) casptr(&sysent32[sysnum].sy_callc,
-           (void *)systrace_sysent32[sysnum].stsy_underlying,
-           (void *)dtrace_systrace_syscall32);
-#endif
 
        lck_mtx_lock(&dtrace_systrace_lock);
        if (sysent[sysnum].sy_callc == systrace_sysent[sysnum].stsy_underlying) {
-               vm_offset_t dss = (vm_offset_t)&dtrace_systrace_syscall;
+               /* It is not possible to write to sysent[] directly because it is const. */
+               vm_offset_t dss = ptrauth_nop_cast(vm_offset_t, &dtrace_systrace_syscall);
                ml_nofault_copy((vm_offset_t)&dss, (vm_offset_t)&sysent[sysnum].sy_callc, sizeof(vm_offset_t));
        }
        lck_mtx_unlock(&dtrace_systrace_lock);
-       return (0);
+
+       return 0;
 }
 
 /*ARGSUSED*/
@@ -524,84 +501,62 @@ static void
 systrace_disable(void *arg, dtrace_id_t id, void *parg)
 {
 #pragma unused(arg,id) /* __APPLE__ */
-    
+
        int sysnum = SYSTRACE_SYSNUM((uintptr_t)parg);
        int disable = (systrace_sysent[sysnum].stsy_entry == DTRACE_IDNONE ||
            systrace_sysent[sysnum].stsy_return == DTRACE_IDNONE);
 
        if (disable) {
+               /*
+                * Usage of volatile protects the if statement below from being optimized away.
+                *
+                * Compilers are clever and know that const array values can't change in time
+                * and the if below is always false. That is because it can't see that DTrace
+                * injects dtrace_systrace_syscall dynamically and violates constness of the
+                * array.
+                */
+               volatile const struct sysent *syscallent = &sysent[sysnum];
+
                lck_mtx_lock(&dtrace_systrace_lock);
-               if (sysent[sysnum].sy_callc == dtrace_systrace_syscall)
-                       ml_nofault_copy((vm_offset_t)&systrace_sysent[sysnum].stsy_underlying, (vm_offset_t)&sysent[sysnum].sy_callc, sizeof(systrace_sysent[sysnum].stsy_underlying));
+               if (syscallent->sy_callc == dtrace_systrace_syscall) {
+                       ml_nofault_copy((vm_offset_t)&systrace_sysent[sysnum].stsy_underlying,
+                           (vm_offset_t)&syscallent->sy_callc, sizeof(vm_offset_t));
+               }
                lck_mtx_unlock(&dtrace_systrace_lock);
-
-#ifdef _SYSCALL32_IMPL
-               (void) casptr(&sysent32[sysnum].sy_callc,
-                   (void *)dtrace_systrace_syscall32,
-                   (void *)systrace_sysent32[sysnum].stsy_underlying);
-#endif
        }
 
        if (SYSTRACE_ISENTRY((uintptr_t)parg)) {
                systrace_sysent[sysnum].stsy_entry = DTRACE_IDNONE;
-#ifdef _SYSCALL32_IMPL
-               systrace_sysent32[sysnum].stsy_entry = DTRACE_IDNONE;
-#endif
        } else {
                systrace_sysent[sysnum].stsy_return = DTRACE_IDNONE;
-#ifdef _SYSCALL32_IMPL
-               systrace_sysent32[sysnum].stsy_return = DTRACE_IDNONE;
-#endif
        }
 }
 
 static dtrace_pattr_t systrace_attr = {
-{ DTRACE_STABILITY_EVOLVING, DTRACE_STABILITY_EVOLVING, DTRACE_CLASS_COMMON },
-{ DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_UNKNOWN },
-{ DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_ISA },
-{ DTRACE_STABILITY_EVOLVING, DTRACE_STABILITY_EVOLVING, DTRACE_CLASS_COMMON },
-{ DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_ISA },
+       { DTRACE_STABILITY_EVOLVING, DTRACE_STABILITY_EVOLVING, DTRACE_CLASS_COMMON },
+       { DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_UNKNOWN },
+       { DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_ISA },
+       { DTRACE_STABILITY_EVOLVING, DTRACE_STABILITY_EVOLVING, DTRACE_CLASS_COMMON },
+       { DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_ISA },
 };
 
 static dtrace_pops_t systrace_pops = {
-       systrace_provide,
-       NULL,
-       systrace_enable,
-       systrace_disable,
-       NULL,
-       NULL,
-       NULL,
-       systrace_getarg,
-       NULL,
-       systrace_destroy
+       .dtps_provide =         systrace_provide,
+       .dtps_provide_module =  NULL,
+       .dtps_enable =          systrace_enable,
+       .dtps_disable =         systrace_disable,
+       .dtps_suspend =         NULL,
+       .dtps_resume =          NULL,
+       .dtps_getargdesc =      systrace_getargdesc,
+       .dtps_getargval =       systrace_getargval,
+       .dtps_usermode =        NULL,
+       .dtps_destroy =         systrace_destroy
 };
 
 static int
-systrace_attach(dev_info_t *devi, ddi_attach_cmd_t cmd)
+systrace_attach(dev_info_t *devi)
 {
-       switch (cmd) {
-       case DDI_ATTACH:
-               break;
-       case DDI_RESUME:
-               return (DDI_SUCCESS);
-       default:
-               return (DDI_FAILURE);
-       }
-
-#if !defined(__APPLE__)        
-       systrace_probe = (void (*)())dtrace_probe;
-       membar_enter();
-
-       if (ddi_create_minor_node(devi, "systrace", S_IFCHR, 0,
-           DDI_PSEUDO, NULL) == DDI_FAILURE ||
-           dtrace_register("syscall", &systrace_attr, DTRACE_PRIV_USER, NULL,
-           &systrace_pops, NULL, &systrace_id) != 0) {
-               systrace_probe = systrace_stub;
-               ddi_remove_minor_node(devi, NULL);
-               return (DDI_FAILURE);
-       }
-#else
-       systrace_probe = (void(*))&dtrace_probe;
+       systrace_probe = (void*)&dtrace_probe;
        membar_enter();
 
        if (ddi_create_minor_node(devi, "systrace", S_IFCHR, 0,
@@ -610,16 +565,16 @@ systrace_attach(dev_info_t *devi, ddi_attach_cmd_t cmd)
            &systrace_pops, NULL, &systrace_id) != 0) {
                systrace_probe = systrace_stub;
                ddi_remove_minor_node(devi, NULL);
-               return (DDI_FAILURE);
+               return DDI_FAILURE;
        }
-#endif /* __APPLE__ */
-
-       ddi_report_dev(devi);
-       systrace_devi = devi;
 
-       return (DDI_SUCCESS);
+       return DDI_SUCCESS;
 }
 
+
+/*
+ * APPLE NOTE:  systrace_detach not implemented
+ */
 #if !defined(__APPLE__)
 static int
 systrace_detach(dev_info_t *devi, ddi_detach_cmd_t cmd)
@@ -628,145 +583,55 @@ systrace_detach(dev_info_t *devi, ddi_detach_cmd_t cmd)
        case DDI_DETACH:
                break;
        case DDI_SUSPEND:
-               return (DDI_SUCCESS);
+               return DDI_SUCCESS;
        default:
-               return (DDI_FAILURE);
+               return DDI_FAILURE;
        }
 
-       if (dtrace_unregister(systrace_id) != 0)
-               return (DDI_FAILURE);
+       if (dtrace_unregister(systrace_id) != 0) {
+               return DDI_FAILURE;
+       }
 
        ddi_remove_minor_node(devi, NULL);
        systrace_probe = systrace_stub;
-       return (DDI_SUCCESS);
-}
-
-/*ARGSUSED*/
-static int
-systrace_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result)
-{
-       int error;
-
-       switch (infocmd) {
-       case DDI_INFO_DEVT2DEVINFO:
-               *result = (void *)systrace_devi;
-               error = DDI_SUCCESS;
-               break;
-       case DDI_INFO_DEVT2INSTANCE:
-               *result = (void *)0;
-               error = DDI_SUCCESS;
-               break;
-       default:
-               error = DDI_FAILURE;
-       }
-       return (error);
-}
-
-/*ARGSUSED*/
-static int
-systrace_open(dev_t *devp, int flag, int otyp, cred_t *cred_p)
-{
-       return (0);
-}
-
-static struct cb_ops systrace_cb_ops = {
-       systrace_open,          /* open */
-       nodev,                  /* close */
-       nulldev,                /* strategy */
-       nulldev,                /* print */
-       nodev,                  /* dump */
-       nodev,                  /* read */
-       nodev,                  /* write */
-       nodev,                  /* ioctl */
-       nodev,                  /* devmap */
-       nodev,                  /* mmap */
-       nodev,                  /* segmap */
-       nochpoll,               /* poll */
-       ddi_prop_op,            /* cb_prop_op */
-       0,                      /* streamtab  */
-       D_NEW | D_MP            /* Driver compatibility flag */
-};
-
-static struct dev_ops systrace_ops = {
-       DEVO_REV,               /* devo_rev, */
-       0,                      /* refcnt  */
-       systrace_info,          /* get_dev_info */
-       nulldev,                /* identify */
-       nulldev,                /* probe */
-       systrace_attach,        /* attach */
-       systrace_detach,        /* detach */
-       nodev,                  /* reset */
-       &systrace_cb_ops,       /* driver operations */
-       NULL,                   /* bus operations */
-       nodev                   /* dev power */
-};
-
-/*
- * Module linkage information for the kernel.
- */
-static struct modldrv modldrv = {
-       &mod_driverops,         /* module type (this is a pseudo driver) */
-       "System Call Tracing",  /* name of module */
-       &systrace_ops,          /* driver ops */
-};
-
-static struct modlinkage modlinkage = {
-       MODREV_1,
-       (void *)&modldrv,
-       NULL
-};
-
-int
-_init(void)
-{
-       return (mod_install(&modlinkage));
+       return DDI_SUCCESS;
 }
+#endif /* __APPLE__ */
 
-int
-_info(struct modinfo *modinfop)
-{
-       return (mod_info(&modlinkage, modinfop));
-}
 
-int
-_fini(void)
-{
-       return (mod_remove(&modlinkage));
-}
-#else
 typedef kern_return_t (*mach_call_t)(void *);
 
-/* XXX From #include <kern/syscall_sw.h> which may be changed for 64 bit! */
-typedef void    mach_munge_t(const void *, void *);
+/* APPLE NOTE: From #include <kern/syscall_sw.h> which may be changed for 64 bit! */
+typedef void    mach_munge_t(void *);
 
 typedef struct {
-       int                     mach_trap_arg_count;
-       kern_return_t           (*mach_trap_function)(void *);
-#if 0 /* no active architectures use mungers for mach traps */
-       mach_munge_t            *mach_trap_arg_munge32; /* system call arguments for 32-bit */
-       mach_munge_t            *mach_trap_arg_munge64; /* system call arguments for 64-bit */
+       int                     mach_trap_arg_count;
+       kern_return_t           (*mach_trap_function)(void *);
+#if defined(__arm64__) || defined(__x86_64__)
+       mach_munge_t            *mach_trap_arg_munge32; /* system call arguments for 32-bit */
 #endif
-#if    MACH_ASSERT
-       const char*             mach_trap_name;
+       int                     mach_trap_u32_words;
+#if     MACH_ASSERT
+       const char*             mach_trap_name;
 #endif /* MACH_ASSERT */
 } mach_trap_t;
 
-extern mach_trap_t              mach_trap_table[];
-extern int                      mach_trap_count;
+extern const mach_trap_t mach_trap_table[]; /* syscall_sw.h now declares this as const */
+extern const int         mach_trap_count;
 
-extern const char *mach_syscall_name_table[];
+extern const char *const mach_syscall_name_table[];
 
 /* XXX From osfmk/i386/bsd_i386.c */
 struct mach_call_args {
-        syscall_arg_t arg1;
-        syscall_arg_t arg2;
-        syscall_arg_t arg3;
-        syscall_arg_t arg4;
-        syscall_arg_t arg5;
-        syscall_arg_t arg6;
-        syscall_arg_t arg7;
-        syscall_arg_t arg8;
-        syscall_arg_t arg9;
+       syscall_arg_t arg1;
+       syscall_arg_t arg2;
+       syscall_arg_t arg3;
+       syscall_arg_t arg4;
+       syscall_arg_t arg5;
+       syscall_arg_t arg6;
+       syscall_arg_t arg7;
+       syscall_arg_t arg8;
+       syscall_arg_t arg9;
 };
 
 #undef NSYSCALL
@@ -777,10 +642,10 @@ struct mach_call_args {
 #endif
 
 typedef struct machtrace_sysent {
-       dtrace_id_t     stsy_entry;
-       dtrace_id_t     stsy_return;
-       kern_return_t   (*stsy_underlying)(void *);
-       int32_t         stsy_return_type;
+       dtrace_id_t     stsy_entry;
+       dtrace_id_t     stsy_return;
+       kern_return_t   (*stsy_underlying)(void *);
+       int32_t         stsy_return_type;
 } machtrace_sysent_t;
 
 static machtrace_sysent_t *machtrace_sysent = NULL;
@@ -788,16 +653,14 @@ static machtrace_sysent_t *machtrace_sysent = NULL;
 void (*machtrace_probe)(dtrace_id_t, uint64_t, uint64_t,
     uint64_t, uint64_t, uint64_t);
 
-static uint64_t machtrace_getarg(void *, dtrace_id_t, void *, int, int);       
+static uint64_t machtrace_getarg(void *, dtrace_id_t, void *, int, int);
 
-static dev_info_t *machtrace_devi;
 static dtrace_provider_id_t machtrace_id;
 
 static kern_return_t
 dtrace_machtrace_syscall(struct mach_call_args *args)
 {
-       boolean_t           flavor;
-       unsigned short      code;
+       int code;       /* The mach call number */
 
        machtrace_sysent_t *sy;
        dtrace_id_t id;
@@ -808,8 +671,7 @@ dtrace_machtrace_syscall(struct mach_call_args *args)
        syscall_arg_t *ip = (syscall_arg_t *)args;
        mach_call_t mach_call;
 
-#if defined(__i386__) || defined (__x86_64__)
-#pragma unused(flavor)
+#if defined (__x86_64__)
        {
                pal_register_cache_state(current_thread(), VALID);
                x86_saved_state_t   *tagged_regs = (x86_saved_state_t *)find_user_regs(current_thread());
@@ -820,6 +682,28 @@ dtrace_machtrace_syscall(struct mach_call_args *args)
                        code = -saved_state32(tagged_regs)->eax;
                }
        }
+#elif defined(__arm__)
+       {
+               /* r12 has the machcall number, but it is -ve */
+               arm_saved_state_t *arm_regs = (arm_saved_state_t *) find_user_regs(current_thread());
+               code = (int)arm_regs->r[12];
+               ASSERT(code < 0);    /* Otherwise it would be a Unix syscall */
+               code = -code;
+       }
+#elif defined(__arm64__)
+       {
+               /* From arm/thread_status.h:get_saved_state_svc_number */
+               arm_saved_state_t *arm_regs = (arm_saved_state_t *) find_user_regs(current_thread());
+               if (is_saved_state32(arm_regs)) {
+                       code = (int)saved_state32(arm_regs)->r[12];
+               } else {
+                       code = (int)saved_state64(arm_regs)->x[ARM64_SYSCALL_CODE_REG_NUM];
+               }
+
+               /* From bsd/arm64.c:mach_syscall */
+               ASSERT(code < 0);    /* Otherwise it would be a Unix syscall */
+               code = -code;
+       }
 #else
 #error Unknown Architecture
 #endif
@@ -827,19 +711,22 @@ dtrace_machtrace_syscall(struct mach_call_args *args)
        sy = &machtrace_sysent[code];
 
        if ((id = sy->stsy_entry) != DTRACE_IDNONE) {
-               uthread_t uthread = (uthread_t)get_bsdthread_info(current_thread());    
+               uthread_t uthread = (uthread_t)get_bsdthread_info(current_thread());
 
-               if (uthread)
+               if (uthread) {
                        uthread->t_dtrace_syscall_args = (void *)ip;
-               
-               (*machtrace_probe)(id, *ip, *(ip+1), *(ip+2), *(ip+3), *(ip+4));
-               
-               if (uthread)
-                       uthread->t_dtrace_syscall_args = (void *)0;             
+               }
+
+               (*machtrace_probe)(id, *ip, *(ip + 1), *(ip + 2), *(ip + 3), *(ip + 4));
+
+               if (uthread) {
+                       uthread->t_dtrace_syscall_args = (void *)0;
+               }
        }
 
 #if 0 /* XXX */
        /*
+        * APPLE NOTE:  Not implemented.
         * We want to explicitly allow DTrace consumers to stop a process
         * before it actually executes the meat of the syscall.
         */
@@ -855,32 +742,35 @@ dtrace_machtrace_syscall(struct mach_call_args *args)
        mach_call = (mach_call_t)(*sy->stsy_underlying);
        rval = mach_call(args);
 
-       if ((id = sy->stsy_return) != DTRACE_IDNONE)
+       if ((id = sy->stsy_return) != DTRACE_IDNONE) {
                (*machtrace_probe)(id, (uint64_t)rval, 0, 0, 0, 0);
+       }
 
-       return (rval);
+       return rval;
 }
 
 static void
-machtrace_init(mach_trap_t *actual, machtrace_sysent_t **interposed)
+machtrace_init(const mach_trap_t *actual, machtrace_sysent_t **interposed)
 {
        machtrace_sysent_t *msysent = *interposed;
        int i;
 
        if (msysent == NULL) {
-               *interposed = msysent = kmem_zalloc(sizeof (machtrace_sysent_t) *
-                               NSYSCALL, KM_SLEEP);
+               *interposed = msysent = kmem_zalloc(sizeof(machtrace_sysent_t) *
+                   NSYSCALL, KM_SLEEP);
        }
 
        for (i = 0; i < NSYSCALL; i++) {
-               mach_trap_t *a = &actual[i];
+               const mach_trap_t *a = &actual[i];
                machtrace_sysent_t *s = &msysent[i];
 
-               if (LOADABLE_SYSCALL(a) && !LOADED_SYSCALL(a))
+               if (LOADABLE_SYSCALL(a) && !LOADED_SYSCALL(a)) {
                        continue;
+               }
 
-               if (a->mach_trap_function == (mach_call_t)(dtrace_machtrace_syscall))
+               if (a->mach_trap_function == (mach_call_t)(dtrace_machtrace_syscall)) {
                        continue;
+               }
 
                s->stsy_underlying = a->mach_trap_function;
        }
@@ -891,29 +781,31 @@ static void
 machtrace_provide(void *arg, const dtrace_probedesc_t *desc)
 {
 #pragma unused(arg) /* __APPLE__ */
-    
+
        int i;
 
-       if (desc != NULL)
+       if (desc != NULL) {
                return;
+       }
 
        machtrace_init(mach_trap_table, &machtrace_sysent);
 
        for (i = 0; i < NSYSCALL; i++) {
-               
-               if (machtrace_sysent[i].stsy_underlying == NULL)
+               if (machtrace_sysent[i].stsy_underlying == NULL) {
                        continue;
+               }
 
                if (dtrace_probe_lookup(machtrace_id, NULL,
-                                       mach_syscall_name_table[i], "entry") != 0)
+                   mach_syscall_name_table[i], "entry") != 0) {
                        continue;
+               }
 
                (void) dtrace_probe_create(machtrace_id, NULL, mach_syscall_name_table[i],
-                                          "entry", MACHTRACE_ARTIFICIAL_FRAMES,
-                                          (void *)((uintptr_t)SYSTRACE_ENTRY(i)));
+                   "entry", MACHTRACE_ARTIFICIAL_FRAMES,
+                   (void *)((uintptr_t)SYSTRACE_ENTRY(i)));
                (void) dtrace_probe_create(machtrace_id, NULL, mach_syscall_name_table[i],
-                                          "return", MACHTRACE_ARTIFICIAL_FRAMES,
-                                          (void *)((uintptr_t)SYSTRACE_RETURN(i)));
+                   "return", MACHTRACE_ARTIFICIAL_FRAMES,
+                   (void *)((uintptr_t)SYSTRACE_RETURN(i)));
 
                machtrace_sysent[i].stsy_entry = DTRACE_IDNONE;
                machtrace_sysent[i].stsy_return = DTRACE_IDNONE;
@@ -926,7 +818,7 @@ machtrace_destroy(void *arg, dtrace_id_t id, void *parg)
 {
 #pragma unused(arg,id) /* __APPLE__ */
        int sysnum = SYSTRACE_SYSNUM((uintptr_t)parg);
-       
+
 #pragma unused(sysnum) /* __APPLE__ */
 
        /*
@@ -945,10 +837,10 @@ static int
 machtrace_enable(void *arg, dtrace_id_t id, void *parg)
 {
 #pragma unused(arg) /* __APPLE__ */
-    
+
        int sysnum = SYSTRACE_SYSNUM((uintptr_t)parg);
        int enabled = (machtrace_sysent[sysnum].stsy_entry != DTRACE_IDNONE ||
-                       machtrace_sysent[sysnum].stsy_return != DTRACE_IDNONE);
+           machtrace_sysent[sysnum].stsy_return != DTRACE_IDNONE);
 
        if (SYSTRACE_ISENTRY((uintptr_t)parg)) {
                machtrace_sysent[sysnum].stsy_entry = id;
@@ -957,20 +849,21 @@ machtrace_enable(void *arg, dtrace_id_t id, void *parg)
        }
 
        if (enabled) {
-           ASSERT(mach_trap_table[sysnum].mach_trap_function == (void *)dtrace_machtrace_syscall);
-           return(0);
+               ASSERT(mach_trap_table[sysnum].mach_trap_function == (void *)dtrace_machtrace_syscall);
+               return 0;
        }
 
        lck_mtx_lock(&dtrace_systrace_lock);
 
        if (mach_trap_table[sysnum].mach_trap_function == machtrace_sysent[sysnum].stsy_underlying) {
-               vm_offset_t dss = (vm_offset_t)&dtrace_machtrace_syscall;
+               /* It is not possible to write to mach_trap_table[] directly because it is const. */
+               vm_offset_t dss = ptrauth_nop_cast(vm_offset_t, &dtrace_machtrace_syscall);
                ml_nofault_copy((vm_offset_t)&dss, (vm_offset_t)&mach_trap_table[sysnum].mach_trap_function, sizeof(vm_offset_t));
        }
 
        lck_mtx_unlock(&dtrace_systrace_lock);
 
-       return(0);
+       return 0;
 }
 
 /*ARGSUSED*/
@@ -978,17 +871,26 @@ static void
 machtrace_disable(void *arg, dtrace_id_t id, void *parg)
 {
 #pragma unused(arg,id) /* __APPLE__ */
-      
+
        int sysnum = SYSTRACE_SYSNUM((uintptr_t)parg);
        int disable = (machtrace_sysent[sysnum].stsy_entry == DTRACE_IDNONE ||
-                       machtrace_sysent[sysnum].stsy_return == DTRACE_IDNONE);
+           machtrace_sysent[sysnum].stsy_return == DTRACE_IDNONE);
 
        if (disable) {
+               /*
+                * Usage of volatile protects the if statement below from being optimized away.
+                *
+                * Compilers are clever and know that const array values can't change in time
+                * and the if below is always false. That is because it can't see that DTrace
+                * injects dtrace_machtrace_syscall dynamically and violates constness of the
+                * array.
+                */
+               volatile const mach_trap_t *machtrap = &mach_trap_table[sysnum];
 
                lck_mtx_lock(&dtrace_systrace_lock);
-
-               if (mach_trap_table[sysnum].mach_trap_function == (mach_call_t)dtrace_machtrace_syscall) {
-                       ml_nofault_copy((vm_offset_t)&machtrace_sysent[sysnum].stsy_underlying, (vm_offset_t)&mach_trap_table[sysnum].mach_trap_function, sizeof(vm_offset_t));
+               if (machtrap->mach_trap_function == (mach_call_t)dtrace_machtrace_syscall) {
+                       ml_nofault_copy((vm_offset_t)&machtrace_sysent[sysnum].stsy_underlying,
+                           (vm_offset_t)&machtrap->mach_trap_function, sizeof(vm_offset_t));
                }
                lck_mtx_unlock(&dtrace_systrace_lock);
        }
@@ -1001,70 +903,48 @@ machtrace_disable(void *arg, dtrace_id_t id, void *parg)
 }
 
 static dtrace_pattr_t machtrace_attr = {
-{ DTRACE_STABILITY_EVOLVING, DTRACE_STABILITY_EVOLVING, DTRACE_CLASS_COMMON },
-{ DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_UNKNOWN },
-{ DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_ISA },
-{ DTRACE_STABILITY_EVOLVING, DTRACE_STABILITY_EVOLVING, DTRACE_CLASS_COMMON },
-{ DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_ISA },
+       { DTRACE_STABILITY_EVOLVING, DTRACE_STABILITY_EVOLVING, DTRACE_CLASS_COMMON },
+       { DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_UNKNOWN },
+       { DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_ISA },
+       { DTRACE_STABILITY_EVOLVING, DTRACE_STABILITY_EVOLVING, DTRACE_CLASS_COMMON },
+       { DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_ISA },
 };
 
 static dtrace_pops_t machtrace_pops = {
-       machtrace_provide,
-       NULL,
-       machtrace_enable,
-       machtrace_disable,
-       NULL,
-       NULL,
-       NULL,
-       machtrace_getarg,
-       NULL,
-       machtrace_destroy
+       .dtps_provide =         machtrace_provide,
+       .dtps_provide_module =  NULL,
+       .dtps_enable =          machtrace_enable,
+       .dtps_disable =         machtrace_disable,
+       .dtps_suspend =         NULL,
+       .dtps_resume =          NULL,
+       .dtps_getargdesc =      NULL,
+       .dtps_getargval =       machtrace_getarg,
+       .dtps_usermode =        NULL,
+       .dtps_destroy =         machtrace_destroy
 };
 
 static int
-machtrace_attach(dev_info_t *devi, ddi_attach_cmd_t cmd)
+machtrace_attach(dev_info_t *devi)
 {
-       switch (cmd) {
-               case DDI_ATTACH:
-                       break;
-               case DDI_RESUME:
-                       return (DDI_SUCCESS);
-               default:
-                       return (DDI_FAILURE);
-       }
-
-#if !defined(__APPLE__)
-       machtrace_probe = (void (*)())dtrace_probe;
-       membar_enter();
-
-       if (ddi_create_minor_node(devi, "machtrace", S_IFCHR, 0,
-                               DDI_PSEUDO, NULL) == DDI_FAILURE ||
-                       dtrace_register("mach_trap", &machtrace_attr, DTRACE_PRIV_USER, NULL,
-                               &machtrace_pops, NULL, &machtrace_id) != 0) {
-               machtrace_probe = systrace_stub;
-#else
        machtrace_probe = dtrace_probe;
        membar_enter();
-       
+
        if (ddi_create_minor_node(devi, "machtrace", S_IFCHR, 0,
-                               DDI_PSEUDO, 0) == DDI_FAILURE ||
-                       dtrace_register("mach_trap", &machtrace_attr, DTRACE_PRIV_USER, NULL,
-                               &machtrace_pops, NULL, &machtrace_id) != 0) {
-                machtrace_probe = (void (*))&systrace_stub;
-#endif /* __APPLE__ */         
+           DDI_PSEUDO, 0) == DDI_FAILURE ||
+           dtrace_register("mach_trap", &machtrace_attr, DTRACE_PRIV_USER, NULL,
+           &machtrace_pops, NULL, &machtrace_id) != 0) {
+               machtrace_probe = (void*)&systrace_stub;
                ddi_remove_minor_node(devi, NULL);
-               return (DDI_FAILURE);
+               return DDI_FAILURE;
        }
 
-       ddi_report_dev(devi);
-       machtrace_devi = devi;
-
-       return (DDI_SUCCESS);
+       return DDI_SUCCESS;
 }
 
 d_open_t _systrace_open;
 
-int _systrace_open(dev_t dev, int flags, int devtype, struct proc *p)
+int
+_systrace_open(dev_t dev, int flags, int devtype, struct proc *p)
 {
 #pragma unused(dev,flags,devtype,p)
        return 0;
@@ -1072,75 +952,96 @@ int _systrace_open(dev_t dev, int flags, int devtype, struct proc *p)
 
 #define SYSTRACE_MAJOR  -24 /* let the kernel pick the device number */
 
-/*
- * A struct describing which functions will get invoked for certain
- * actions.
- */
 static struct cdevsw systrace_cdevsw =
 {
-       _systrace_open,         /* open */
-       eno_opcl,               /* close */
-       eno_rdwrt,                      /* read */
-       eno_rdwrt,                      /* write */
-       eno_ioctl,              /* ioctl */
-       (stop_fcn_t *)nulldev, /* stop */
-       (reset_fcn_t *)nulldev, /* reset */
-       NULL,                           /* tty's */
-       eno_select,                     /* select */
-       eno_mmap,                       /* mmap */
-       eno_strat,                      /* strategy */
-       eno_getc,                       /* getc */
-       eno_putc,                       /* putc */
-       0                                       /* type */
+       .d_open = _systrace_open,
+       .d_close = eno_opcl,
+       .d_read = eno_rdwrt,
+       .d_write = eno_rdwrt,
+       .d_ioctl = eno_ioctl,
+       .d_stop = (stop_fcn_t *)nulldev,
+       .d_reset = (reset_fcn_t *)nulldev,
+       .d_select = eno_select,
+       .d_mmap = eno_mmap,
+       .d_strategy = eno_strat,
+       .d_reserved_1 = eno_getc,
+       .d_reserved_2 = eno_putc,
 };
 
-static int gSysTraceInited = 0;
-
 void systrace_init( void );
 
-void systrace_init( void )
+void
+systrace_init( void )
 {
-       if (0 == gSysTraceInited) {
-               int majdevno = cdevsw_add(SYSTRACE_MAJOR, &systrace_cdevsw);
+       if (dtrace_sdt_probes_restricted()) {
+               return;
+       }
 
-               if (majdevno < 0) {
-                       printf("systrace_init: failed to allocate a major number!\n");
-                       gSysTraceInited = 0;
-                       return;
-               }
+       int majdevno = cdevsw_add(SYSTRACE_MAJOR, &systrace_cdevsw);
 
-               systrace_attach( (dev_info_t    *)(uintptr_t)majdevno, DDI_ATTACH );
-               machtrace_attach( (dev_info_t   *)(uintptr_t)majdevno, DDI_ATTACH );
+       if (majdevno < 0) {
+               printf("systrace_init: failed to allocate a major number!\n");
+               return;
+       }
 
-               gSysTraceInited = 1;
-       } else
-               panic("systrace_init: called twice!\n");
+       systrace_attach((dev_info_t*)(uintptr_t)majdevno);
+       machtrace_attach((dev_info_t*)(uintptr_t)majdevno);
 }
 #undef SYSTRACE_MAJOR
-#endif /* __APPLE__ */
 
 static uint64_t
-systrace_getarg(void *arg, dtrace_id_t id, void *parg, int argno, int aframes)
+systrace_getargval(void *arg, dtrace_id_t id, void *parg, int argno, int aframes)
 {
 #pragma unused(arg,id,parg,aframes)     /* __APPLE__ */
        uint64_t val = 0;
-       syscall_arg_t *stack = (syscall_arg_t *)NULL;
-
-       uthread_t uthread = (uthread_t)get_bsdthread_info(current_thread());    
+       uint64_t *uargs = NULL;
 
-       if (uthread)
-               stack = (syscall_arg_t *)uthread->t_dtrace_syscall_args;
+       uthread_t uthread = (uthread_t)get_bsdthread_info(current_thread());
 
-       if (!stack)
-               return(0);
+       if (uthread) {
+               uargs = uthread->t_dtrace_syscall_args;
+       }
+       if (!uargs) {
+               return 0;
+       }
+       if (argno < 0 || argno >= SYSTRACE_NARGS) {
+               return 0;
+       }
 
        DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);
-       /* dtrace_probe arguments arg0 .. arg4 are 64bits wide */
-       val = (uint64_t)*(stack+argno);
+       val = uargs[argno];
        DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT);
-       return (val);
+       return val;
 }
 
+static void
+systrace_getargdesc(void *arg, dtrace_id_t id, void *parg,
+    dtrace_argdesc_t *desc)
+{
+#pragma unused(arg, id)
+       int sysnum = SYSTRACE_SYSNUM(parg);
+       uthread_t uthread = (uthread_t)get_bsdthread_info(current_thread());
+       uint64_t *uargs = NULL;
+
+       if (!uthread) {
+               desc->dtargd_ndx = DTRACE_ARGNONE;
+               return;
+       }
+
+       uargs = uthread->t_dtrace_syscall_args;
+
+       if (SYSTRACE_ISENTRY((uintptr_t)parg)) {
+               systrace_entry_setargdesc(sysnum, desc->dtargd_ndx,
+                   desc->dtargd_native, sizeof(desc->dtargd_native));
+       } else {
+               systrace_return_setargdesc(sysnum, desc->dtargd_ndx,
+                   desc->dtargd_native, sizeof(desc->dtargd_native));
+       }
+
+       if (desc->dtargd_native[0] == '\0') {
+               desc->dtargd_ndx = DTRACE_ARGNONE;
+       }
+}
 
 static uint64_t
 machtrace_getarg(void *arg, dtrace_id_t id, void *parg, int argno, int aframes)
@@ -1150,17 +1051,18 @@ machtrace_getarg(void *arg, dtrace_id_t id, void *parg, int argno, int aframes)
        syscall_arg_t *stack = (syscall_arg_t *)NULL;
 
        uthread_t uthread = (uthread_t)get_bsdthread_info(current_thread());
-       
-       if (uthread)
+
+       if (uthread) {
                stack = (syscall_arg_t *)uthread->t_dtrace_syscall_args;
-       
-       if (!stack)
-               return(0);
+       }
+
+       if (!stack) {
+               return 0;
+       }
 
        DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);
        /* dtrace_probe arguments arg0 .. arg4 are 64bits wide */
-       val = (uint64_t)*(stack+argno); 
+       val = (uint64_t)*(stack + argno);
        DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT);
-       return (val);
+       return val;
 }
-