191eaf3e1SJohn Birrell /* 291eaf3e1SJohn Birrell * CDDL HEADER START 391eaf3e1SJohn Birrell * 491eaf3e1SJohn Birrell * The contents of this file are subject to the terms of the 591eaf3e1SJohn Birrell * Common Development and Distribution License (the "License"). 691eaf3e1SJohn Birrell * You may not use this file except in compliance with the License. 791eaf3e1SJohn Birrell * 891eaf3e1SJohn Birrell * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 991eaf3e1SJohn Birrell * or http://www.opensolaris.org/os/licensing. 1091eaf3e1SJohn Birrell * See the License for the specific language governing permissions 1191eaf3e1SJohn Birrell * and limitations under the License. 1291eaf3e1SJohn Birrell * 1391eaf3e1SJohn Birrell * When distributing Covered Code, include this CDDL HEADER in each 1491eaf3e1SJohn Birrell * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 1591eaf3e1SJohn Birrell * If applicable, add the following below this CDDL HEADER, with the 1691eaf3e1SJohn Birrell * fields enclosed by brackets "[]" replaced with your own identifying 1791eaf3e1SJohn Birrell * information: Portions Copyright [yyyy] [name of copyright owner] 1891eaf3e1SJohn Birrell * 1991eaf3e1SJohn Birrell * CDDL HEADER END 2091eaf3e1SJohn Birrell * 2191eaf3e1SJohn Birrell * Portions Copyright 2006-2008 John Birrell jb@freebsd.org 2291eaf3e1SJohn Birrell */ 2391eaf3e1SJohn Birrell 2491eaf3e1SJohn Birrell /* 2591eaf3e1SJohn Birrell * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 2691eaf3e1SJohn Birrell * Use is subject to license terms. 2791eaf3e1SJohn Birrell */ 2891eaf3e1SJohn Birrell 2991eaf3e1SJohn Birrell #include <sys/param.h> 3091eaf3e1SJohn Birrell #include <sys/systm.h> 3191eaf3e1SJohn Birrell #include <sys/conf.h> 3291eaf3e1SJohn Birrell #include <sys/cpuvar.h> 338ff6d9ddSMark Johnston #include <sys/dtrace.h> 3491eaf3e1SJohn Birrell #include <sys/fcntl.h> 3591eaf3e1SJohn Birrell #include <sys/filio.h> 3691eaf3e1SJohn Birrell #include <sys/kdb.h> 3791eaf3e1SJohn Birrell #include <sys/kernel.h> 3891eaf3e1SJohn Birrell #include <sys/kmem.h> 3991eaf3e1SJohn Birrell #include <sys/kthread.h> 4091eaf3e1SJohn Birrell #include <sys/limits.h> 4191eaf3e1SJohn Birrell #include <sys/linker.h> 4291eaf3e1SJohn Birrell #include <sys/lock.h> 4391eaf3e1SJohn Birrell #include <sys/malloc.h> 4491eaf3e1SJohn Birrell #include <sys/module.h> 4591eaf3e1SJohn Birrell #include <sys/mutex.h> 4691eaf3e1SJohn Birrell #include <sys/poll.h> 4791eaf3e1SJohn Birrell #include <sys/proc.h> 4891eaf3e1SJohn Birrell #include <sys/selinfo.h> 4991eaf3e1SJohn Birrell #include <sys/smp.h> 50f5a97d1bSCraig Rodrigues #include <sys/sysent.h> 51feea5135SMark Johnston #include <sys/sysproto.h> 5291eaf3e1SJohn Birrell #include <sys/uio.h> 5391eaf3e1SJohn Birrell #include <sys/unistd.h> 5491eaf3e1SJohn Birrell 558ff6d9ddSMark Johnston #include <cddl/dev/dtrace/dtrace_cddl.h> 568ff6d9ddSMark Johnston 578ff6d9ddSMark Johnston #include <machine/stdarg.h> 5891eaf3e1SJohn Birrell 59f5a97d1bSCraig Rodrigues #ifdef LINUX_SYSTRACE 60308bce2aSAndriy Gapon #if defined(__amd64__) 612f99bcceSJohn Baldwin #include <amd64/linux/linux.h> 622f99bcceSJohn Baldwin #include <amd64/linux/linux_proto.h> 632f99bcceSJohn Baldwin #include <amd64/linux/linux_syscalls.c> 642f99bcceSJohn Baldwin #include <amd64/linux/linux_systrace_args.c> 65308bce2aSAndriy Gapon #elif defined(__i386__) 66308bce2aSAndriy Gapon #include <i386/linux/linux.h> 67308bce2aSAndriy Gapon #include <i386/linux/linux_proto.h> 68308bce2aSAndriy Gapon #include <i386/linux/linux_syscalls.c> 69308bce2aSAndriy Gapon #include <i386/linux/linux_systrace_args.c> 70308bce2aSAndriy Gapon #else 71308bce2aSAndriy Gapon #error Only i386 and amd64 are supported. 72308bce2aSAndriy Gapon #endif 732f99bcceSJohn Baldwin #define MODNAME "linux" 74f5a97d1bSCraig Rodrigues extern struct sysent linux_sysent[]; 75f5a97d1bSCraig Rodrigues #define MAXSYSCALL LINUX_SYS_MAXSYSCALL 76f5a97d1bSCraig Rodrigues #define SYSCALLNAMES linux_syscallnames 77f5a97d1bSCraig Rodrigues #define SYSENT linux_sysent 782f99bcceSJohn Baldwin #elif defined(LINUX32_SYSTRACE) 792f99bcceSJohn Baldwin #if defined(__amd64__) 802f99bcceSJohn Baldwin #include <amd64/linux32/linux.h> 812f99bcceSJohn Baldwin #include <amd64/linux32/linux32_proto.h> 822f99bcceSJohn Baldwin #include <amd64/linux32/linux32_syscalls.c> 832f99bcceSJohn Baldwin #include <amd64/linux32/linux32_systrace_args.c> 842f99bcceSJohn Baldwin #else 852f99bcceSJohn Baldwin #error Only amd64 is supported. 862f99bcceSJohn Baldwin #endif 872f99bcceSJohn Baldwin #define MODNAME "linux32" 882f99bcceSJohn Baldwin extern struct sysent linux32_sysent[]; 892f99bcceSJohn Baldwin #define MAXSYSCALL LINUX32_SYS_MAXSYSCALL 902f99bcceSJohn Baldwin #define SYSCALLNAMES linux32_syscallnames 912f99bcceSJohn Baldwin #define SYSENT linux32_sysent 92308bce2aSAndriy Gapon #elif defined(FREEBSD32_SYSTRACE) 93308bce2aSAndriy Gapon /* 94308bce2aSAndriy Gapon * The syscall arguments are processed into a DTrace argument array 95*913bfd86SBrooks Davis * using a generated function. See sys/tools/syscalls/README.md. 96308bce2aSAndriy Gapon */ 97308bce2aSAndriy Gapon #include <compat/freebsd32/freebsd32_proto.h> 98308bce2aSAndriy Gapon #include <compat/freebsd32/freebsd32_util.h> 99308bce2aSAndriy Gapon #include <compat/freebsd32/freebsd32_syscall.h> 100308bce2aSAndriy Gapon #include <compat/freebsd32/freebsd32_systrace_args.c> 101308bce2aSAndriy Gapon extern const char *freebsd32_syscallnames[]; 102308bce2aSAndriy Gapon #define MODNAME "freebsd32" 103308bce2aSAndriy Gapon #define MAXSYSCALL FREEBSD32_SYS_MAXSYSCALL 104308bce2aSAndriy Gapon #define SYSCALLNAMES freebsd32_syscallnames 105308bce2aSAndriy Gapon #define SYSENT freebsd32_sysent 106f5a97d1bSCraig Rodrigues #else 107f5a97d1bSCraig Rodrigues /* 108f5a97d1bSCraig Rodrigues * The syscall arguments are processed into a DTrace argument array 109*913bfd86SBrooks Davis * using a generated function. See sys/tools/syscalls/README.md. 110f5a97d1bSCraig Rodrigues */ 111f5a97d1bSCraig Rodrigues #include <sys/syscall.h> 112f5a97d1bSCraig Rodrigues #include <kern/systrace_args.c> 113308bce2aSAndriy Gapon #define MODNAME "freebsd" 114f5a97d1bSCraig Rodrigues #define MAXSYSCALL SYS_MAXSYSCALL 115f5a97d1bSCraig Rodrigues #define SYSCALLNAMES syscallnames 116f5a97d1bSCraig Rodrigues #define SYSENT sysent 1172f99bcceSJohn Baldwin #define NATIVE_ABI 118f5a97d1bSCraig Rodrigues #endif 119f5a97d1bSCraig Rodrigues 120308bce2aSAndriy Gapon #define PROVNAME "syscall" 121308bce2aSAndriy Gapon #define DEVNAME "dtrace/systrace/" MODNAME 122308bce2aSAndriy Gapon 12391eaf3e1SJohn Birrell #define SYSTRACE_ARTIFICIAL_FRAMES 1 12491eaf3e1SJohn Birrell 12591eaf3e1SJohn Birrell #define SYSTRACE_SHIFT 16 12691eaf3e1SJohn Birrell #define SYSTRACE_ISENTRY(x) ((int)(x) >> SYSTRACE_SHIFT) 12791eaf3e1SJohn Birrell #define SYSTRACE_SYSNUM(x) ((int)(x) & ((1 << SYSTRACE_SHIFT) - 1)) 12891eaf3e1SJohn Birrell #define SYSTRACE_ENTRY(id) ((1 << SYSTRACE_SHIFT) | (id)) 12991eaf3e1SJohn Birrell #define SYSTRACE_RETURN(id) (id) 13091eaf3e1SJohn Birrell 131f5a97d1bSCraig Rodrigues #if ((1 << SYSTRACE_SHIFT) <= MAXSYSCALL) 13291eaf3e1SJohn Birrell #error 1 << SYSTRACE_SHIFT must exceed number of system calls 13391eaf3e1SJohn Birrell #endif 13491eaf3e1SJohn Birrell 1359d68f774SMateusz Guzik static int systrace_enabled_count; 1369d68f774SMateusz Guzik 137feea5135SMark Johnston static void systrace_load(void *); 138feea5135SMark Johnston static void systrace_unload(void *); 139feea5135SMark Johnston 140feea5135SMark Johnston static void systrace_getargdesc(void *, dtrace_id_t, void *, 141feea5135SMark Johnston dtrace_argdesc_t *); 1428ff6d9ddSMark Johnston static uint64_t systrace_getargval(void *, dtrace_id_t, void *, int, int); 14391eaf3e1SJohn Birrell static void systrace_provide(void *, dtrace_probedesc_t *); 14491eaf3e1SJohn Birrell static void systrace_destroy(void *, dtrace_id_t, void *); 14591eaf3e1SJohn Birrell static void systrace_enable(void *, dtrace_id_t, void *); 14691eaf3e1SJohn Birrell static void systrace_disable(void *, dtrace_id_t, void *); 14791eaf3e1SJohn Birrell 148f5a97d1bSCraig Rodrigues static union { 149f5a97d1bSCraig Rodrigues const char **p_constnames; 150f5a97d1bSCraig Rodrigues char **pp_syscallnames; 151f5a97d1bSCraig Rodrigues } uglyhack = { SYSCALLNAMES }; 152f5a97d1bSCraig Rodrigues 15391eaf3e1SJohn Birrell static dtrace_pattr_t systrace_attr = { 15491eaf3e1SJohn Birrell { DTRACE_STABILITY_EVOLVING, DTRACE_STABILITY_EVOLVING, DTRACE_CLASS_COMMON }, 15591eaf3e1SJohn Birrell { DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_UNKNOWN }, 15691eaf3e1SJohn Birrell { DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_ISA }, 15791eaf3e1SJohn Birrell { DTRACE_STABILITY_EVOLVING, DTRACE_STABILITY_EVOLVING, DTRACE_CLASS_COMMON }, 15891eaf3e1SJohn Birrell { DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_ISA }, 15991eaf3e1SJohn Birrell }; 16091eaf3e1SJohn Birrell 16191eaf3e1SJohn Birrell static dtrace_pops_t systrace_pops = { 16247f11baaSMark Johnston .dtps_provide = systrace_provide, 16347f11baaSMark Johnston .dtps_provide_module = NULL, 16447f11baaSMark Johnston .dtps_enable = systrace_enable, 16547f11baaSMark Johnston .dtps_disable = systrace_disable, 16647f11baaSMark Johnston .dtps_suspend = NULL, 16747f11baaSMark Johnston .dtps_resume = NULL, 16847f11baaSMark Johnston .dtps_getargdesc = systrace_getargdesc, 16947f11baaSMark Johnston .dtps_getargval = systrace_getargval, 17047f11baaSMark Johnston .dtps_usermode = NULL, 17147f11baaSMark Johnston .dtps_destroy = systrace_destroy 17291eaf3e1SJohn Birrell }; 17391eaf3e1SJohn Birrell 17491eaf3e1SJohn Birrell static dtrace_provider_id_t systrace_id; 17591eaf3e1SJohn Birrell 1762f99bcceSJohn Baldwin #ifdef NATIVE_ABI 17791eaf3e1SJohn Birrell /* 178f5a97d1bSCraig Rodrigues * Probe callback function. 179f5a97d1bSCraig Rodrigues * 180f5a97d1bSCraig Rodrigues * Note: This function is called for _all_ syscalls, regardless of which sysent 181f5a97d1bSCraig Rodrigues * array the syscall comes from. It could be a standard syscall or a 182f5a97d1bSCraig Rodrigues * compat syscall from something like Linux. 18391eaf3e1SJohn Birrell */ 18491eaf3e1SJohn Birrell static void 1858ff6d9ddSMark Johnston systrace_probe(struct syscall_args *sa, enum systrace_probe_t type, int retval) 18691eaf3e1SJohn Birrell { 1878ff6d9ddSMark Johnston uint64_t uargs[nitems(sa->args)]; 1888ff6d9ddSMark Johnston dtrace_id_t id; 1898ff6d9ddSMark Johnston int n_args, sysnum; 19091eaf3e1SJohn Birrell 1918ff6d9ddSMark Johnston sysnum = sa->code; 192c6f5742fSRui Paulo memset(uargs, 0, sizeof(uargs)); 193feea5135SMark Johnston 1948ff6d9ddSMark Johnston if (type == SYSTRACE_ENTRY) { 19536f5d077SMark Johnston if ((id = sa->callp->sy_entry) == DTRACE_IDNONE) 19636f5d077SMark Johnston return; 1978ff6d9ddSMark Johnston 1988ff6d9ddSMark Johnston if (sa->callp->sy_systrace_args_func != NULL) 19991eaf3e1SJohn Birrell /* 20091eaf3e1SJohn Birrell * Convert the syscall parameters using the registered 20191eaf3e1SJohn Birrell * function. 20291eaf3e1SJohn Birrell */ 2038ff6d9ddSMark Johnston (*sa->callp->sy_systrace_args_func)(sysnum, sa->args, 2048ff6d9ddSMark Johnston uargs, &n_args); 2058ff6d9ddSMark Johnston else 20691eaf3e1SJohn Birrell /* 20791eaf3e1SJohn Birrell * Use the built-in system call argument conversion 20891eaf3e1SJohn Birrell * function to translate the syscall structure fields 2098ff6d9ddSMark Johnston * into the array of 64-bit values that DTrace expects. 21091eaf3e1SJohn Birrell */ 2118ff6d9ddSMark Johnston systrace_args(sysnum, sa->args, uargs, &n_args); 212c6f5742fSRui Paulo /* 2138ff6d9ddSMark Johnston * Save probe arguments now so that we can retrieve them if 2148ff6d9ddSMark Johnston * the getargval method is called from further down the stack. 215c6f5742fSRui Paulo */ 2168ff6d9ddSMark Johnston curthread->t_dtrace_systrace_args = uargs; 2178ff6d9ddSMark Johnston } else { 21836f5d077SMark Johnston if ((id = sa->callp->sy_return) == DTRACE_IDNONE) 21936f5d077SMark Johnston return; 2208ff6d9ddSMark Johnston 2218ff6d9ddSMark Johnston curthread->t_dtrace_systrace_args = NULL; 2228ff6d9ddSMark Johnston /* Set arg0 and arg1 as the return value of this syscall. */ 2238ff6d9ddSMark Johnston uargs[0] = uargs[1] = retval; 224c6f5742fSRui Paulo } 22591eaf3e1SJohn Birrell 22691eaf3e1SJohn Birrell /* Process the probe using the converted argments. */ 2278ff6d9ddSMark Johnston dtrace_probe(id, uargs[0], uargs[1], uargs[2], uargs[3], uargs[4]); 22891eaf3e1SJohn Birrell } 229f5a97d1bSCraig Rodrigues #endif 23091eaf3e1SJohn Birrell 23191eaf3e1SJohn Birrell static void 232feea5135SMark Johnston systrace_getargdesc(void *arg, dtrace_id_t id, void *parg, 233feea5135SMark Johnston dtrace_argdesc_t *desc) 23491eaf3e1SJohn Birrell { 23591eaf3e1SJohn Birrell int sysnum = SYSTRACE_SYSNUM((uintptr_t)parg); 23691eaf3e1SJohn Birrell 237493b584dSRyan Stone if (SYSTRACE_ISENTRY((uintptr_t)parg)) 238493b584dSRyan Stone systrace_entry_setargdesc(sysnum, desc->dtargd_ndx, 239493b584dSRyan Stone desc->dtargd_native, sizeof(desc->dtargd_native)); 240493b584dSRyan Stone else 241493b584dSRyan Stone systrace_return_setargdesc(sysnum, desc->dtargd_ndx, 242493b584dSRyan Stone desc->dtargd_native, sizeof(desc->dtargd_native)); 24391eaf3e1SJohn Birrell 24491eaf3e1SJohn Birrell if (desc->dtargd_native[0] == '\0') 24591eaf3e1SJohn Birrell desc->dtargd_ndx = DTRACE_ARGNONE; 24691eaf3e1SJohn Birrell } 24791eaf3e1SJohn Birrell 2488ff6d9ddSMark Johnston static uint64_t 2498ff6d9ddSMark Johnston systrace_getargval(void *arg __unused, dtrace_id_t id __unused, 2508ff6d9ddSMark Johnston void *parg __unused, int argno, int aframes __unused) 2518ff6d9ddSMark Johnston { 2528ff6d9ddSMark Johnston uint64_t *uargs; 2538ff6d9ddSMark Johnston 2548ff6d9ddSMark Johnston uargs = curthread->t_dtrace_systrace_args; 2558ff6d9ddSMark Johnston if (uargs == NULL) 2568ff6d9ddSMark Johnston /* This is a return probe. */ 2578ff6d9ddSMark Johnston return (0); 2588ff6d9ddSMark Johnston if (argno >= nitems(((struct syscall_args *)NULL)->args)) 2598ff6d9ddSMark Johnston return (0); 2608ff6d9ddSMark Johnston return (uargs[argno]); 2618ff6d9ddSMark Johnston } 2628ff6d9ddSMark Johnston 26391eaf3e1SJohn Birrell static void 26491eaf3e1SJohn Birrell systrace_provide(void *arg, dtrace_probedesc_t *desc) 26591eaf3e1SJohn Birrell { 26691eaf3e1SJohn Birrell int i; 26791eaf3e1SJohn Birrell 26891eaf3e1SJohn Birrell if (desc != NULL) 26991eaf3e1SJohn Birrell return; 27091eaf3e1SJohn Birrell 271f5a97d1bSCraig Rodrigues for (i = 0; i < MAXSYSCALL; i++) { 272308bce2aSAndriy Gapon if (dtrace_probe_lookup(systrace_id, MODNAME, 273f5a97d1bSCraig Rodrigues uglyhack.pp_syscallnames[i], "entry") != 0) 27491eaf3e1SJohn Birrell continue; 27591eaf3e1SJohn Birrell 276feea5135SMark Johnston (void)dtrace_probe_create(systrace_id, MODNAME, 277feea5135SMark Johnston uglyhack.pp_syscallnames[i], "entry", 278feea5135SMark Johnston SYSTRACE_ARTIFICIAL_FRAMES, 27991eaf3e1SJohn Birrell (void *)((uintptr_t)SYSTRACE_ENTRY(i))); 280feea5135SMark Johnston (void)dtrace_probe_create(systrace_id, MODNAME, 281feea5135SMark Johnston uglyhack.pp_syscallnames[i], "return", 282feea5135SMark Johnston SYSTRACE_ARTIFICIAL_FRAMES, 28391eaf3e1SJohn Birrell (void *)((uintptr_t)SYSTRACE_RETURN(i))); 28491eaf3e1SJohn Birrell } 28591eaf3e1SJohn Birrell } 28691eaf3e1SJohn Birrell 28791eaf3e1SJohn Birrell static void 28891eaf3e1SJohn Birrell systrace_destroy(void *arg, dtrace_id_t id, void *parg) 28991eaf3e1SJohn Birrell { 2909e5787d2SMatt Macy #ifdef SYSTRACE_DEBUG 29191eaf3e1SJohn Birrell int sysnum = SYSTRACE_SYSNUM((uintptr_t)parg); 29291eaf3e1SJohn Birrell 29391eaf3e1SJohn Birrell /* 29491eaf3e1SJohn Birrell * There's nothing to do here but assert that we have actually been 29591eaf3e1SJohn Birrell * disabled. 29691eaf3e1SJohn Birrell */ 29791eaf3e1SJohn Birrell if (SYSTRACE_ISENTRY((uintptr_t)parg)) { 298a7261520SMark Johnston ASSERT(sysent[sysnum].sy_entry == DTRACE_IDNONE); 29991eaf3e1SJohn Birrell } else { 300a7261520SMark Johnston ASSERT(sysent[sysnum].sy_return == DTRACE_IDNONE); 30191eaf3e1SJohn Birrell } 30291eaf3e1SJohn Birrell #endif 30391eaf3e1SJohn Birrell } 30491eaf3e1SJohn Birrell 30591eaf3e1SJohn Birrell static void 30691eaf3e1SJohn Birrell systrace_enable(void *arg, dtrace_id_t id, void *parg) 30791eaf3e1SJohn Birrell { 30891eaf3e1SJohn Birrell int sysnum = SYSTRACE_SYSNUM((uintptr_t)parg); 30991eaf3e1SJohn Birrell 310f5a97d1bSCraig Rodrigues SYSENT[sysnum].sy_systrace_args_func = systrace_args; 311f5a97d1bSCraig Rodrigues 31291eaf3e1SJohn Birrell if (SYSTRACE_ISENTRY((uintptr_t)parg)) 313f5a97d1bSCraig Rodrigues SYSENT[sysnum].sy_entry = id; 31491eaf3e1SJohn Birrell else 315f5a97d1bSCraig Rodrigues SYSENT[sysnum].sy_return = id; 3169d68f774SMateusz Guzik systrace_enabled_count++; 3179d68f774SMateusz Guzik if (systrace_enabled_count == 1) 3189d68f774SMateusz Guzik systrace_enabled = true; 31991eaf3e1SJohn Birrell } 32091eaf3e1SJohn Birrell 32191eaf3e1SJohn Birrell static void 32291eaf3e1SJohn Birrell systrace_disable(void *arg, dtrace_id_t id, void *parg) 32391eaf3e1SJohn Birrell { 32491eaf3e1SJohn Birrell int sysnum = SYSTRACE_SYSNUM((uintptr_t)parg); 32591eaf3e1SJohn Birrell 326a7261520SMark Johnston SYSENT[sysnum].sy_systrace_args_func = NULL; 327a7261520SMark Johnston SYSENT[sysnum].sy_entry = DTRACE_IDNONE; 328a7261520SMark Johnston SYSENT[sysnum].sy_return = DTRACE_IDNONE; 3299d68f774SMateusz Guzik systrace_enabled_count--; 3309d68f774SMateusz Guzik if (systrace_enabled_count == 0) 3319d68f774SMateusz Guzik systrace_enabled = false; 33291eaf3e1SJohn Birrell } 33391eaf3e1SJohn Birrell 33491eaf3e1SJohn Birrell static void 335feea5135SMark Johnston systrace_load(void *dummy __unused) 33691eaf3e1SJohn Birrell { 33791eaf3e1SJohn Birrell 338feea5135SMark Johnston if (dtrace_register(PROVNAME, &systrace_attr, DTRACE_PRIV_USER, NULL, 339feea5135SMark Johnston &systrace_pops, NULL, &systrace_id) != 0) 34091eaf3e1SJohn Birrell return; 34191eaf3e1SJohn Birrell 3422f99bcceSJohn Baldwin #ifdef NATIVE_ABI 34391eaf3e1SJohn Birrell systrace_probe_func = systrace_probe; 344f5a97d1bSCraig Rodrigues #endif 34591eaf3e1SJohn Birrell } 34691eaf3e1SJohn Birrell 347feea5135SMark Johnston static void 348feea5135SMark Johnston systrace_unload(void *dummy __unused) 34991eaf3e1SJohn Birrell { 35091eaf3e1SJohn Birrell 3512f99bcceSJohn Baldwin #ifdef NATIVE_ABI 35291eaf3e1SJohn Birrell systrace_probe_func = NULL; 353f5a97d1bSCraig Rodrigues #endif 35491eaf3e1SJohn Birrell 355feea5135SMark Johnston if (dtrace_unregister(systrace_id) != 0) 356feea5135SMark Johnston return; 35791eaf3e1SJohn Birrell } 35891eaf3e1SJohn Birrell 35991eaf3e1SJohn Birrell static int 36091eaf3e1SJohn Birrell systrace_modevent(module_t mod __unused, int type, void *data __unused) 36191eaf3e1SJohn Birrell { 362feea5135SMark Johnston int error; 36391eaf3e1SJohn Birrell 364feea5135SMark Johnston error = 0; 36591eaf3e1SJohn Birrell switch (type) { 36691eaf3e1SJohn Birrell case MOD_LOAD: 36791eaf3e1SJohn Birrell break; 36891eaf3e1SJohn Birrell 36991eaf3e1SJohn Birrell case MOD_UNLOAD: 37091eaf3e1SJohn Birrell break; 37191eaf3e1SJohn Birrell 37291eaf3e1SJohn Birrell case MOD_SHUTDOWN: 37391eaf3e1SJohn Birrell break; 37491eaf3e1SJohn Birrell 37591eaf3e1SJohn Birrell default: 37691eaf3e1SJohn Birrell error = EOPNOTSUPP; 37791eaf3e1SJohn Birrell break; 37891eaf3e1SJohn Birrell 37991eaf3e1SJohn Birrell } 38091eaf3e1SJohn Birrell return (error); 38191eaf3e1SJohn Birrell } 38291eaf3e1SJohn Birrell 383feea5135SMark Johnston SYSINIT(systrace_load, SI_SUB_DTRACE_PROVIDER, SI_ORDER_ANY, 384feea5135SMark Johnston systrace_load, NULL); 385feea5135SMark Johnston SYSUNINIT(systrace_unload, SI_SUB_DTRACE_PROVIDER, SI_ORDER_ANY, 386feea5135SMark Johnston systrace_unload, NULL); 38791eaf3e1SJohn Birrell 388f5a97d1bSCraig Rodrigues #ifdef LINUX_SYSTRACE 3892f99bcceSJohn Baldwin DEV_MODULE(systrace_linux, systrace_modevent, NULL); 3902f99bcceSJohn Baldwin MODULE_VERSION(systrace_linux, 1); 3912f99bcceSJohn Baldwin #ifdef __amd64__ 3922f99bcceSJohn Baldwin MODULE_DEPEND(systrace_linux, linux64, 1, 1, 1); 3932f99bcceSJohn Baldwin #else 3942f99bcceSJohn Baldwin MODULE_DEPEND(systrace_linux, linux, 1, 1, 1); 3952f99bcceSJohn Baldwin #endif 3962f99bcceSJohn Baldwin MODULE_DEPEND(systrace_linux, dtrace, 1, 1, 1); 3972f99bcceSJohn Baldwin MODULE_DEPEND(systrace_linux, opensolaris, 1, 1, 1); 3982f99bcceSJohn Baldwin #elif defined(LINUX32_SYSTRACE) 399308bce2aSAndriy Gapon DEV_MODULE(systrace_linux32, systrace_modevent, NULL); 400308bce2aSAndriy Gapon MODULE_VERSION(systrace_linux32, 1); 401308bce2aSAndriy Gapon MODULE_DEPEND(systrace_linux32, linux, 1, 1, 1); 402308bce2aSAndriy Gapon MODULE_DEPEND(systrace_linux32, dtrace, 1, 1, 1); 403308bce2aSAndriy Gapon MODULE_DEPEND(systrace_linux32, opensolaris, 1, 1, 1); 404308bce2aSAndriy Gapon #elif defined(FREEBSD32_SYSTRACE) 405308bce2aSAndriy Gapon DEV_MODULE(systrace_freebsd32, systrace_modevent, NULL); 406308bce2aSAndriy Gapon MODULE_VERSION(systrace_freebsd32, 1); 407308bce2aSAndriy Gapon MODULE_DEPEND(systrace_freebsd32, dtrace, 1, 1, 1); 408308bce2aSAndriy Gapon MODULE_DEPEND(systrace_freebsd32, opensolaris, 1, 1, 1); 409f5a97d1bSCraig Rodrigues #else 41091eaf3e1SJohn Birrell DEV_MODULE(systrace, systrace_modevent, NULL); 41191eaf3e1SJohn Birrell MODULE_VERSION(systrace, 1); 41291eaf3e1SJohn Birrell MODULE_DEPEND(systrace, dtrace, 1, 1, 1); 41391eaf3e1SJohn Birrell MODULE_DEPEND(systrace, opensolaris, 1, 1, 1); 414f5a97d1bSCraig Rodrigues #endif 415