14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync/*
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * CDDL HEADER START
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync *
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * The contents of this file are subject to the terms of the
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * Common Development and Distribution License (the "License").
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * You may not use this file except in compliance with the License.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync *
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * or http://www.opensolaris.org/os/licensing.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * See the License for the specific language governing permissions
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * and limitations under the License.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync *
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * When distributing Covered Code, include this CDDL HEADER in each
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * If applicable, add the following below this CDDL HEADER, with the
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * fields enclosed by brackets "[]" replaced with your own identifying
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * information: Portions Copyright [yyyy] [name of copyright owner]
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync *
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * CDDL HEADER END
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync */
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync/*
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * Use is subject to license terms.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync */
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync#include <sys/dtrace.h>
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync#include <sys/systrace.h>
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync#include <sys/stat.h>
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync#include <sys/systm.h>
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync#include <sys/conf.h>
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync#include <sys/ddi.h>
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync#include <sys/sunddi.h>
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync#include <sys/atomic.h>
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync#define SYSTRACE_ARTIFICIAL_FRAMES 1
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync#define SYSTRACE_SHIFT 16
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync#define SYSTRACE_ISENTRY(x) ((int)(x) >> SYSTRACE_SHIFT)
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync#define SYSTRACE_SYSNUM(x) ((int)(x) & ((1 << SYSTRACE_SHIFT) - 1))
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync#define SYSTRACE_ENTRY(id) ((1 << SYSTRACE_SHIFT) | (id))
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync#define SYSTRACE_RETURN(id) (id)
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync#if ((1 << SYSTRACE_SHIFT) <= NSYSCALL)
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync#error 1 << SYSTRACE_SHIFT must exceed number of system calls
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync#endif
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncstatic dev_info_t *systrace_devi;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncstatic dtrace_provider_id_t systrace_id;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncstatic void
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncsystrace_init(struct sysent *actual, systrace_sysent_t **interposed)
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync{
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync systrace_sysent_t *sysent = *interposed;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync int i;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync if (sysent == NULL) {
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync *interposed = sysent = kmem_zalloc(sizeof (systrace_sysent_t) *
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync NSYSCALL, KM_SLEEP);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync }
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync for (i = 0; i < NSYSCALL; i++) {
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync struct sysent *a = &actual[i];
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync systrace_sysent_t *s = &sysent[i];
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync if (LOADABLE_SYSCALL(a) && !LOADED_SYSCALL(a))
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync continue;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync if (a->sy_callc == dtrace_systrace_syscall)
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync continue;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync#ifdef _SYSCALL32_IMPL
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync if (a->sy_callc == dtrace_systrace_syscall32)
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync continue;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync#endif
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync s->stsy_underlying = a->sy_callc;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync }
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync}
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync/*ARGSUSED*/
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncstatic void
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncsystrace_provide(void *arg, const dtrace_probedesc_t *desc)
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync{
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync int i;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync if (desc != NULL)
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync return;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync systrace_init(sysent, &systrace_sysent);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync#ifdef _SYSCALL32_IMPL
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync systrace_init(sysent32, &systrace_sysent32);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync#endif
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync for (i = 0; i < NSYSCALL; i++) {
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync if (systrace_sysent[i].stsy_underlying == NULL)
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync continue;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync if (dtrace_probe_lookup(systrace_id, NULL,
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync syscallnames[i], "entry") != 0)
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync continue;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync (void) dtrace_probe_create(systrace_id, NULL, syscallnames[i],
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync "entry", SYSTRACE_ARTIFICIAL_FRAMES,
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync (void *)((uintptr_t)SYSTRACE_ENTRY(i)));
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync (void) dtrace_probe_create(systrace_id, NULL, syscallnames[i],
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync "return", SYSTRACE_ARTIFICIAL_FRAMES,
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync (void *)((uintptr_t)SYSTRACE_RETURN(i)));
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync systrace_sysent[i].stsy_entry = DTRACE_IDNONE;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync systrace_sysent[i].stsy_return = DTRACE_IDNONE;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync#ifdef _SYSCALL32_IMPL
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync systrace_sysent32[i].stsy_entry = DTRACE_IDNONE;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync systrace_sysent32[i].stsy_return = DTRACE_IDNONE;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync#endif
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync }
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync}
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync/*ARGSUSED*/
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncstatic void
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncsystrace_destroy(void *arg, dtrace_id_t id, void *parg)
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync{
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync int sysnum = SYSTRACE_SYSNUM((uintptr_t)parg);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync /*
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * There's nothing to do here but assert that we have actually been
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * disabled.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync */
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync if (SYSTRACE_ISENTRY((uintptr_t)parg)) {
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync ASSERT(systrace_sysent[sysnum].stsy_entry == DTRACE_IDNONE);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync#ifdef _SYSCALL32_IMPL
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync ASSERT(systrace_sysent32[sysnum].stsy_entry == DTRACE_IDNONE);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync#endif
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync } else {
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync ASSERT(systrace_sysent[sysnum].stsy_return == DTRACE_IDNONE);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync#ifdef _SYSCALL32_IMPL
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync ASSERT(systrace_sysent32[sysnum].stsy_return == DTRACE_IDNONE);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync#endif
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync }
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync}
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync/*ARGSUSED*/
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncstatic int
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncsystrace_enable(void *arg, dtrace_id_t id, void *parg)
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync{
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync int sysnum = SYSTRACE_SYSNUM((uintptr_t)parg);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync int enabled = (systrace_sysent[sysnum].stsy_entry != DTRACE_IDNONE ||
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync systrace_sysent[sysnum].stsy_return != DTRACE_IDNONE);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync if (SYSTRACE_ISENTRY((uintptr_t)parg)) {
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync systrace_sysent[sysnum].stsy_entry = id;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync#ifdef _SYSCALL32_IMPL
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync systrace_sysent32[sysnum].stsy_entry = id;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync#endif
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync } else {
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync systrace_sysent[sysnum].stsy_return = id;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync#ifdef _SYSCALL32_IMPL
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync systrace_sysent32[sysnum].stsy_return = id;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync#endif
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync }
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync if (enabled) {
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync ASSERT(sysent[sysnum].sy_callc == dtrace_systrace_syscall);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync return (0);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync }
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync (void) casptr(&sysent[sysnum].sy_callc,
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync (void *)systrace_sysent[sysnum].stsy_underlying,
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync (void *)dtrace_systrace_syscall);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync#ifdef _SYSCALL32_IMPL
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync (void) casptr(&sysent32[sysnum].sy_callc,
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync (void *)systrace_sysent32[sysnum].stsy_underlying,
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync (void *)dtrace_systrace_syscall32);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync#endif
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync return (0);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync}
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync/*ARGSUSED*/
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncstatic void
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncsystrace_disable(void *arg, dtrace_id_t id, void *parg)
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync{
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync int sysnum = SYSTRACE_SYSNUM((uintptr_t)parg);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync int disable = (systrace_sysent[sysnum].stsy_entry == DTRACE_IDNONE ||
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync systrace_sysent[sysnum].stsy_return == DTRACE_IDNONE);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync if (disable) {
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync (void) casptr(&sysent[sysnum].sy_callc,
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync (void *)dtrace_systrace_syscall,
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync (void *)systrace_sysent[sysnum].stsy_underlying);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync#ifdef _SYSCALL32_IMPL
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync (void) casptr(&sysent32[sysnum].sy_callc,
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync (void *)dtrace_systrace_syscall32,
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync (void *)systrace_sysent32[sysnum].stsy_underlying);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync#endif
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync }
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync if (SYSTRACE_ISENTRY((uintptr_t)parg)) {
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync systrace_sysent[sysnum].stsy_entry = DTRACE_IDNONE;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync#ifdef _SYSCALL32_IMPL
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync systrace_sysent32[sysnum].stsy_entry = DTRACE_IDNONE;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync#endif
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync } else {
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync systrace_sysent[sysnum].stsy_return = DTRACE_IDNONE;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync#ifdef _SYSCALL32_IMPL
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync systrace_sysent32[sysnum].stsy_return = DTRACE_IDNONE;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync#endif
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync }
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync}
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncstatic dtrace_pattr_t systrace_attr = {
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync{ DTRACE_STABILITY_EVOLVING, DTRACE_STABILITY_EVOLVING, DTRACE_CLASS_COMMON },
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync{ DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_UNKNOWN },
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync{ DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_ISA },
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync{ DTRACE_STABILITY_EVOLVING, DTRACE_STABILITY_EVOLVING, DTRACE_CLASS_COMMON },
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync{ DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_ISA },
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync};
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncstatic dtrace_pops_t systrace_pops = {
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync systrace_provide,
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync NULL,
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync systrace_enable,
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync systrace_disable,
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync NULL,
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync NULL,
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync NULL,
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync NULL,
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync NULL,
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync systrace_destroy
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync};
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncstatic int
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncsystrace_attach(dev_info_t *devi, ddi_attach_cmd_t cmd)
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync{
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync switch (cmd) {
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync case DDI_ATTACH:
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync break;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync case DDI_RESUME:
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync return (DDI_SUCCESS);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync default:
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync return (DDI_FAILURE);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync }
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync systrace_probe = (void (*)())dtrace_probe;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync membar_enter();
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync if (ddi_create_minor_node(devi, "systrace", S_IFCHR, 0,
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync DDI_PSEUDO, NULL) == DDI_FAILURE ||
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync dtrace_register("syscall", &systrace_attr, DTRACE_PRIV_USER, NULL,
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync &systrace_pops, NULL, &systrace_id) != 0) {
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync systrace_probe = systrace_stub;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync ddi_remove_minor_node(devi, NULL);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync return (DDI_FAILURE);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync }
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync ddi_report_dev(devi);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync systrace_devi = devi;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync return (DDI_SUCCESS);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync}
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncstatic int
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncsystrace_detach(dev_info_t *devi, ddi_detach_cmd_t cmd)
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync{
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync switch (cmd) {
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync case DDI_DETACH:
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync break;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync case DDI_SUSPEND:
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync return (DDI_SUCCESS);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync default:
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync return (DDI_FAILURE);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync }
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync if (dtrace_unregister(systrace_id) != 0)
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync return (DDI_FAILURE);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync ddi_remove_minor_node(devi, NULL);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync systrace_probe = systrace_stub;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync return (DDI_SUCCESS);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync}
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync/*ARGSUSED*/
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncstatic int
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncsystrace_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result)
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync{
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync int error;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync switch (infocmd) {
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync case DDI_INFO_DEVT2DEVINFO:
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync *result = (void *)systrace_devi;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync error = DDI_SUCCESS;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync break;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync case DDI_INFO_DEVT2INSTANCE:
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync *result = (void *)0;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync error = DDI_SUCCESS;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync break;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync default:
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync error = DDI_FAILURE;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync }
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync return (error);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync}
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync/*ARGSUSED*/
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncstatic int
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncsystrace_open(dev_t *devp, int flag, int otyp, cred_t *cred_p)
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync{
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync return (0);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync}
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncstatic struct cb_ops systrace_cb_ops = {
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync systrace_open, /* open */
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync nodev, /* close */
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync nulldev, /* strategy */
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync nulldev, /* print */
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync nodev, /* dump */
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync nodev, /* read */
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync nodev, /* write */
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync nodev, /* ioctl */
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync nodev, /* devmap */
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync nodev, /* mmap */
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync nodev, /* segmap */
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync nochpoll, /* poll */
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync ddi_prop_op, /* cb_prop_op */
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync 0, /* streamtab */
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync D_NEW | D_MP /* Driver compatibility flag */
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync};
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncstatic struct dev_ops systrace_ops = {
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync DEVO_REV, /* devo_rev, */
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync 0, /* refcnt */
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync systrace_info, /* get_dev_info */
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync nulldev, /* identify */
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync nulldev, /* probe */
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync systrace_attach, /* attach */
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync systrace_detach, /* detach */
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync nodev, /* reset */
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync &systrace_cb_ops, /* driver operations */
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync NULL, /* bus operations */
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync nodev, /* dev power */
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync ddi_quiesce_not_needed, /* quiesce */
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync};
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync/*
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * Module linkage information for the kernel.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync */
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncstatic struct modldrv modldrv = {
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync &mod_driverops, /* module type (this is a pseudo driver) */
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync "System Call Tracing", /* name of module */
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync &systrace_ops, /* driver ops */
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync};
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncstatic struct modlinkage modlinkage = {
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync MODREV_1,
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync (void *)&modldrv,
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync NULL
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync};
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncint
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync_init(void)
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync{
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync return (mod_install(&modlinkage));
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync}
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncint
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync_info(struct modinfo *modinfop)
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync{
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync return (mod_info(&modlinkage, modinfop));
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync}
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncint
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync_fini(void)
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync{
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync return (mod_remove(&modlinkage));
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync}