Module Name:    src
Committed By:   darran
Date:           Mon Mar  1 21:10:19 UTC 2010

Modified Files:
        src/distrib/sets/lists/modules: mi
        src/external/cddl/osnet/dev/sdt: sdt.c
        src/sys/conf: Makefile.kern.inc files
        src/sys/kern: kern_exec.c kern_exit.c kern_fork.c kern_ksyms.c
            kern_lwp.c kern_sig.c
        src/sys/modules/dtrace: Makefile
        src/sys/sys: Makefile ksyms.h
Added Files:
        src/sys/kern: kern_sdt.c
        src/sys/modules/dtrace/sdt: Makefile
        src/sys/sys: sdt.h

Log Message:
DTrace: Add an SDT (Statically Defined Tracing) provider framework, and
implement most of the proc provider.  Adds proc:::create, exec,
exec_success, exec_faillure, signal_send, signal_discard, signal_handle,
lwp_create, lwp_start, lwp_exit.


To generate a diff of this commit:
cvs rdiff -u -r1.7 -r1.8 src/distrib/sets/lists/modules/mi
cvs rdiff -u -r1.2 -r1.3 src/external/cddl/osnet/dev/sdt/sdt.c
cvs rdiff -u -r1.125 -r1.126 src/sys/conf/Makefile.kern.inc
cvs rdiff -u -r1.977 -r1.978 src/sys/conf/files
cvs rdiff -u -r1.293 -r1.294 src/sys/kern/kern_exec.c
cvs rdiff -u -r1.225 -r1.226 src/sys/kern/kern_exit.c
cvs rdiff -u -r1.175 -r1.176 src/sys/kern/kern_fork.c
cvs rdiff -u -r1.53 -r1.54 src/sys/kern/kern_ksyms.c
cvs rdiff -u -r1.140 -r1.141 src/sys/kern/kern_lwp.c
cvs rdiff -u -r0 -r1.1 src/sys/kern/kern_sdt.c
cvs rdiff -u -r1.302 -r1.303 src/sys/kern/kern_sig.c
cvs rdiff -u -r1.1 -r1.2 src/sys/modules/dtrace/Makefile
cvs rdiff -u -r0 -r1.1 src/sys/modules/dtrace/sdt/Makefile
cvs rdiff -u -r1.125 -r1.126 src/sys/sys/Makefile
cvs rdiff -u -r1.23 -r1.24 src/sys/sys/ksyms.h
cvs rdiff -u -r0 -r1.1 src/sys/sys/sdt.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/distrib/sets/lists/modules/mi
diff -u src/distrib/sets/lists/modules/mi:1.7 src/distrib/sets/lists/modules/mi:1.8
--- src/distrib/sets/lists/modules/mi:1.7	Sun Feb 21 03:18:47 2010
+++ src/distrib/sets/lists/modules/mi	Mon Mar  1 21:10:19 2010
@@ -1,4 +1,4 @@
-# $NetBSD: mi,v 1.7 2010/02/21 03:18:47 darran Exp $
+# $NetBSD: mi,v 1.8 2010/03/01 21:10:19 darran Exp $
 #
 # Note: don't delete entries from here - mark them as "obsolete" instead.
 #
@@ -92,6 +92,8 @@
 ./@MODULEDIR@/puffs/puffs.kmod			base-kernel-modules	kmod
 ./@MODULEDIR@/putter				base-kernel-modules	kmod
 ./@MODULEDIR@/putter/putter.kmod		base-kernel-modules	kmod
+./@MODULEDIR@/sdt				base-kernel-modules	kmod,dtrace
+./@MODULEDIR@/sdt/sdt.kmod			base-kernel-modules	kmod,dtrace
 ./@MODULEDIR@/secmodel_bsd44			base-kernel-modules	kmod
 ./@MODULEDIR@/secmodel_bsd44/secmodel_bsd44.kmod	base-kernel-modules	kmod
 ./@MODULEDIR@/secmodel_overlay			base-kernel-modules	kmod
@@ -100,8 +102,8 @@
 ./@MODULEDIR@/securelevel/securelevel.kmod	base-kernel-modules	kmod
 ./@MODULEDIR@/smbfs				base-kernel-modules	kmod
 ./@MODULEDIR@/smbfs/smbfs.kmod			base-kernel-modules	kmod
-./@MODULEDIR@/solaris				base-kernel-modules     kmod,zfs
-./@MODULEDIR@/solaris/solaris.kmod		base-kernel-modules     kmod,zfs
+./@MODULEDIR@/solaris				base-kernel-modules     kmod,dtrace
+./@MODULEDIR@/solaris/solaris.kmod		base-kernel-modules     kmod,dtrace
 ./@MODULEDIR@/suser				base-kernel-modules	kmod
 ./@MODULEDIR@/suser/suser.kmod			base-kernel-modules	kmod
 ./@MODULEDIR@/sysvbfs				base-kernel-modules	kmod

Index: src/external/cddl/osnet/dev/sdt/sdt.c
diff -u src/external/cddl/osnet/dev/sdt/sdt.c:1.2 src/external/cddl/osnet/dev/sdt/sdt.c:1.3
--- src/external/cddl/osnet/dev/sdt/sdt.c:1.2	Sun Feb 21 01:46:33 2010
+++ src/external/cddl/osnet/dev/sdt/sdt.c	Mon Mar  1 21:10:19 2010
@@ -1,33 +1,38 @@
-/*	$NetBSD: sdt.c,v 1.2 2010/02/21 01:46:33 darran Exp $	*/
+/*	$NetBSD: sdt.c,v 1.3 2010/03/01 21:10:19 darran Exp $	*/
 
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
+/*-
+ * Copyright (c) 2010 The NetBSD Foundation, Inc.
+ * All rights reserved.
  *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by CoyotePoint Systems, Inc. It was developed under contract to 
+ * CoyotePoint by Darran Hunt.
  *
- * CDDL HEADER END
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
  *
- * Portions Copyright 2006-2008 John Birrell j...@freebsd.org
- *
- * $FreeBSD: src/sys/cddl/dev/sdt/sdt.c,v 1.1.4.1 2009/08/03 08:13:06 kensmith Exp $
  *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef KDTRACE_HOOKS
-#define KDTRACE_HOOKS
+#ifdef _KERNEL_OPT
+#include "opt_dtrace.h"
 #endif
 
 #include <sys/cdefs.h>
@@ -35,42 +40,34 @@
 #include <sys/systm.h>
 #include <sys/conf.h>
 #include <sys/kernel.h>
-#include <sys/limits.h>
-#include <sys/lock.h>
-#include <sys/linker.h>
 #include <sys/module.h>
 #include <sys/mutex.h>
 
 #include <sys/dtrace.h>
+
+#define KDTRACE_HOOKS
 #include <sys/sdt.h>
 
-#define SDT_ADDR2NDX(addr) (((uintptr_t)(addr)) >> 4)
+#undef SDT_DEBUG
+
+static dev_type_open(sdt_open);
 
-static d_open_t sdt_open;
 static int	sdt_unload(void);
 static void	sdt_getargdesc(void *, dtrace_id_t, void *, dtrace_argdesc_t *);
-static void	sdt_provide_probes(void *, dtrace_probedesc_t *);
+static void	sdt_provide(void *, dtrace_probedesc_t *);
 static void	sdt_destroy(void *, dtrace_id_t, void *);
 static void	sdt_enable(void *, dtrace_id_t, void *);
 static void	sdt_disable(void *, dtrace_id_t, void *);
 static void	sdt_load(void *);
 
-static struct cdevsw sdt_cdevsw = {
-	.d_version	= D_VERSION,
-	.d_open		= sdt_open,
-	.d_name		= "sdt",
-};
-
-static dtrace_pattr_t sdt_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 },
+static const struct cdevsw sdt_cdevsw = {
+	sdt_open, noclose, noread, nowrite, noioctl,
+	nostop, notty, nopoll, nommap, nokqfilter,
+	D_OTHER
 };
 
 static dtrace_pops_t sdt_pops = {
-	sdt_provide_probes,
+	sdt_provide,
 	NULL,
 	sdt_enable,
 	sdt_disable,
@@ -84,173 +81,396 @@
 
 static struct cdev		*sdt_cdev;
 
-static int
-sdt_argtype_callback(struct sdt_argtype *argtype, void *arg)
-{
-	dtrace_argdesc_t *desc = arg;
+/*
+ * Provider and probe definitions 
+ */
 
-	if (desc->dtargd_ndx == argtype->ndx) {
-		desc->dtargd_mapping = desc->dtargd_ndx; /* XXX */
-		strlcpy(desc->dtargd_native, argtype->type,
-		    sizeof(desc->dtargd_native));
-		desc->dtargd_xlate[0] = '\0'; /* XXX */
-	}
+/*
+ * proc provider
+ */
 
-	return (0);
-}
+/* declare all probes belonging to the provider */
+SDT_PROBE_DECLARE(proc,,,create);
+SDT_PROBE_DECLARE(proc,,,exec);
+SDT_PROBE_DECLARE(proc,,,exec_success);
+SDT_PROBE_DECLARE(proc,,,exec_failure);
+SDT_PROBE_DECLARE(proc,,,signal_send);
+SDT_PROBE_DECLARE(proc,,,signal_discard);
+SDT_PROBE_DECLARE(proc,,,signal_clear);
+SDT_PROBE_DECLARE(proc,,,signal_handle);
+SDT_PROBE_DECLARE(proc,,,lwp_create);
+SDT_PROBE_DECLARE(proc,,,lwp_start);
+SDT_PROBE_DECLARE(proc,,,lwp_exit);
+
+/* define the provider */
+static sdt_provider_t l7_provider = {
+    "proc",	/* provider name */
+    0,		/* registered ID - leave as 0 */
+    {
+	{ 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 },
+    },
+
+    /* list all probes belonging to the provider */
+    { 
+	&SDT_NAME(proc,,,create),
+	&SDT_NAME(proc,,,exec),
+	&SDT_NAME(proc,,,exec_success),
+	&SDT_NAME(proc,,,exec_failure),
+	&SDT_NAME(proc,,,signal_send),
+	&SDT_NAME(proc,,,signal_discard),
+	&SDT_NAME(proc,,,signal_clear),
+	&SDT_NAME(proc,,,signal_handle),
+	&SDT_NAME(proc,,,lwp_create),
+	&SDT_NAME(proc,,,lwp_start),
+	&SDT_NAME(proc,,,lwp_exit),
+	NULL					/* NULL terminated list */
+    }
+};
+
+/* list of local providers to register with DTrace */
+static sdt_provider_t *sdt_providers[] = {
+    &l7_provider,
+    NULL		/* NULL terminated list */
+};
+
+static sdt_provider_t **sdt_list = NULL;	/* registered provider list */
+static kmutex_t sdt_mutex;
+static int sdt_count = 0;	/* number of registered providers */
 
 static void
 sdt_getargdesc(void *arg, dtrace_id_t id, void *parg, dtrace_argdesc_t *desc)
 {
-	struct sdt_probe *probe = parg;
+    	sdt_provider_t *sprov = arg;
+	sdt_probe_t *sprobe = parg;
+	int res;
+	int ind;
+
+#ifdef SDT_DEBUG
+	printf("sdt: %s probe %d\n", __func__, id);
+	printf("%s: probe %d (%s:%s:%s:%s).%d\n",
+		__func__, id,
+		sprobe->provider,
+		sprobe->module,
+		sprobe->function,
+		sprobe->name,
+		desc->dtargd_ndx);
+#endif
 
-	if (desc->dtargd_ndx < probe->n_args)
-		(void) (sdt_argtype_listall(probe, sdt_argtype_callback, desc));
-	else
+	/* provide up to 5 arguments  */
+	if ((desc->dtargd_ndx < SDT_MAX_ARGS) &&
+		(sprobe->argv[desc->dtargd_ndx] != NULL)) {
+		strncpy(desc->dtargd_native, sprobe->argv[desc->dtargd_ndx],
+			sizeof(desc->dtargd_native));
+		desc->dtargd_mapping = desc->dtargd_ndx;
+		if (sprobe->argx[desc->dtargd_ndx] != NULL) {
+		    strncpy(desc->dtargd_xlate, sprobe->argx[desc->dtargd_ndx],
+			    sizeof(desc->dtargd_xlate));
+		}
+#ifdef SDT_DEBUG
+		printf("%s: probe %d (%s:%s:%s:%s).%d = %s\n",
+			__func__, id,
+			sprobe->provider,
+			sprobe->module,
+			sprobe->function,
+			sprobe->name,
+			desc->dtargd_ndx,
+			sprobe->argv[desc->dtargd_ndx]);
+#endif
+	} else {
+#ifdef SDT_DEBUG
+		printf("%s: probe %d (%s:%s:%s:%s).%d = NULL\n",
+			__func__, id,
+			sprobe->provider,
+			sprobe->module,
+			sprobe->function,
+			sprobe->name,
+			desc->dtargd_ndx);
 		desc->dtargd_ndx = DTRACE_ARGNONE;
-
-	return;
+#endif
+	}
 }
 
-static int
-sdt_probe_callback(struct sdt_probe *probe, void *arg __unused)
+static void
+sdt_provide(void *arg, dtrace_probedesc_t *desc)
 {
-	struct sdt_provider *prov = probe->prov;
-	char mod[64];
-	char func[64];
-	char name[64];
-
-	/*
-	 * Unfortunately this is necessary because the Solaris DTrace
-	 * code mixes consts and non-consts with casts to override
-	 * the incompatibilies. On FreeBSD, we use strict warnings
-	 * in gcc, so we have to respect const vs non-const.
-	 */
-	strlcpy(mod, probe->mod, sizeof(mod));
-	strlcpy(func, probe->func, sizeof(func));
-	strlcpy(name, probe->name, sizeof(name));
-
-	if (dtrace_probe_lookup(prov->id, mod, func, name) != 0)
-		return (0);
+    	sdt_provider_t *sprov = arg;
+	int res;
+	int ind;
+	int num_probes=0;
+
+#ifdef SDT_DEBUG
+	if (desc == NULL) {
+		printf("sdt: provide null\n");
+	} else {
+	    printf("sdt: provide %d %02x:%02x:%02x:%02x\n",
+		    desc->dtpd_id,
+		    desc->dtpd_provider[0],
+		    desc->dtpd_mod[0],
+		    desc->dtpd_func[0],
+		    desc->dtpd_name[0]);
+	}
+#endif
 
-	(void) dtrace_probe_create(prov->id, probe->mod, probe->func,
-	    probe->name, 0, probe);
+	for (ind=0; sprov->probes[ind] != NULL; ind++) {
+	    	if (sprov->probes[ind]->created == 0) {
+			res = dtrace_probe_create(sprov->id,
+				sprov->probes[ind]->module,
+				sprov->probes[ind]->function,
+				sprov->probes[ind]->name,
+				0, sprov->probes[ind]);
+			sprov->probes[ind]->id = res;
+#ifdef SDT_DEBUG
+			printf("%s: dtrace_probe_create[%d] res=%d\n",
+				__func__, ind, res);
+#endif
+			sprov->probes[ind]->created = 1;
+			num_probes++;
+		}
+	}
 
-	return (0);
-}
+#ifdef SDT_DEBUG
+	printf("sdt: %s num_probes %d\n", __func__, ind);
+#endif
 
-static int
-sdt_provider_entry(struct sdt_provider *prov, void *arg)
-{
-	return (sdt_probe_listall(prov, sdt_probe_callback, NULL));
 }
 
 static void
-sdt_provide_probes(void *arg, dtrace_probedesc_t *desc)
+sdt_destroy(void *arg, dtrace_id_t id, void *parg)
 {
-	if (desc != NULL)
-		return;
+    	sdt_provider_t *sprov = arg;
+    	int ind;
 
-	(void) sdt_provider_listall(sdt_provider_entry, NULL);
-}
+#ifdef SDT_DEBUG
+	printf("sdt: %s\n", __func__);
+#endif
 
-static void
-sdt_destroy(void *arg, dtrace_id_t id, void *parg)
-{
-	/* Nothing to do here. */
+	for (ind=0; sprov->probes[ind] != NULL; ind++) {
+	    	if (sprov->probes[ind]->id == id) {
+#ifdef SDT_DEBUG
+		    	printf("%s: destroying probe %d (%s:%s:%s:%s)\n",
+				__func__, id,
+				sprov->probes[ind]->provider,
+				sprov->probes[ind]->module,
+				sprov->probes[ind]->function,
+				sprov->probes[ind]->name);
+#endif
+			sprov->probes[ind]->enabled = 0;
+			sprov->probes[ind]->created = 0;
+			sprov->probes[ind]->id = 0;
+			break;
+		}
+	}
 }
 
 static void
 sdt_enable(void *arg, dtrace_id_t id, void *parg)
 {
-	struct sdt_probe *probe = parg;
+    	sdt_provider_t *sprov = arg;
+    	int ind;
+
+#ifdef SDT_DEBUG
+	printf("sdt: %s\n", __func__);
+#endif
 
-	probe->id = id;
+	for (ind=0; sprov->probes[ind] != NULL; ind++) {
+	    	if (sprov->probes[ind]->id == id) {
+#ifdef SDT_DEBUG
+		    	printf("%s: enabling probe %d (%s:%s:%s:%s)\n",
+				__func__, id,
+				sprov->probes[ind]->provider,
+				sprov->probes[ind]->module,
+				sprov->probes[ind]->function,
+				sprov->probes[ind]->name);
+#endif
+			sprov->probes[ind]->enabled = 1;
+			break;
+		}
+	}
 }
 
 static void
 sdt_disable(void *arg, dtrace_id_t id, void *parg)
 {
-	struct sdt_probe *probe = parg;
+    	sdt_provider_t *sprov = arg;
+    	int ind;
 
-	probe->id = 0;
+#ifdef SDT_DEBUG
+	printf("sdt: %s\n", __func__);
+#endif
+
+	for (ind=0; sprov->probes[ind] != NULL; ind++) {
+	    	if (sprov->probes[ind]->id == id) {
+#ifdef SDT_DEBUG
+		    	printf("%s: disabling probe %d (%s:%s:%s:%s)\n",
+				__func__, id,
+				sprov->probes[ind]->provider,
+				sprov->probes[ind]->module,
+				sprov->probes[ind]->function,
+				sprov->probes[ind]->name);
+#endif
+			sprov->probes[ind]->enabled = 0;
+			break;
+		}
+	}
 }
 
-static int
-sdt_provider_reg_callback(struct sdt_provider *prov, void *arg __unused)
+int
+sdt_register(sdt_provider_t *prov)
 {
-	return (dtrace_register(prov->name, &sdt_attr, DTRACE_PRIV_USER,
-	    NULL, &sdt_pops, NULL, (dtrace_provider_id_t *) &prov->id));
+	int ind;
+	int res;
+
+	/* make sure the provider is not already registered */
+	for (ind=0; ind < sdt_count; ind++) {
+	    if (strncmp(sdt_list[ind]->name, prov->name,
+			SDT_MAX_NAME_SIZE) == 0) {
+		printf("sdt: provider %s already registered\n", prov->name);
+		return -1;
+	    }
+	}
+
+	/* register the new provider */
+	if ((res = dtrace_register(prov->name, 
+			    &prov->attr, DTRACE_PRIV_USER,
+			    NULL, &sdt_pops, prov,
+			    &(prov->id))) != 0) {
+		printf("sdt: failed to register %s res = %d\n",
+			prov->name, res);
+		return -1;
+	}
+
+	sdt_list[sdt_count++] = prov;
+
+	return 0;
 }
 
-static void
-sdt_load(void *dummy)
+int
+sdt_unregister(sdt_provider_t *prov)
 {
-	/* Create the /dev/dtrace/sdt entry. */
-	sdt_cdev = make_dev(&sdt_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600,
-	    "dtrace/sdt");
+	int ind;
+	int res;
+
+	/* find the provider reference */
+	for (ind=0; ind < sdt_count; ind++) {
+		if (sdt_list[ind] == prov) {
+			res = dtrace_unregister(sdt_list[ind]->id);
+			if (res != 0) {
+			        printf(
+				    "sdt: failed to unregister provider %s\n",
+				    sdt_list[ind]->name);
+			}
+			/* remove provider from list */
+			sdt_list[ind] = sdt_list[--sdt_count];
+			return 0;;
+		}
+	}
 
-	sdt_probe_func = dtrace_probe;
+	/* provider not found */
+	printf("sdt: provider %s not found\n", prov->name);
 
-	(void) sdt_provider_listall(sdt_provider_reg_callback, NULL);
+	return 0;
 }
 
-static int
-sdt_provider_unreg_callback(struct sdt_provider *prov, void *arg __unused)
+static void
+sdt_load(void *dummy)
 {
-	return (dtrace_unregister(prov->id));
+    	int ind;
+	int res;
+
+#ifdef SDT_DEBUG
+	printf("sdt: %s\n", __func__);
+#endif
+
+	sdt_init(dtrace_probe);
+
+	sdt_list = (sdt_provider_t **)kmem_alloc(
+			    sizeof(sdt_provider_t *) * SDT_MAX_PROVIDER);
+
+	mutex_init(&sdt_mutex, "sdt_mutex", MUTEX_DEFAULT, NULL);
+
+	sdt_count = 0;
+
+	if (sdt_list == NULL) {
+	    printf("sdt: failed to alloc provider list\n");
+	    return;
+	}
+
+	for (ind=0; sdt_providers[ind] != NULL; ind++) {
+	    	if (sdt_count >= SDT_MAX_PROVIDER) {
+		    printf("sdt: too many providers\n");
+		    break;
+		}
+		sdt_register(sdt_providers[ind]);
+
+#ifdef SDT_DEBUG
+		printf("sdt: registered %s id = 0x%x\n",
+			sdt_providers[ind]->name,
+			sdt_providers[ind]->id);
+#endif
+	}
 }
 
+
 static int
 sdt_unload()
 {
 	int error = 0;
+	int res = 0;
+	int ind;
 
-	sdt_probe_func = sdt_probe_stub;
+#ifdef SDT_DEBUG
+	printf("sdt: %s\n", __func__);
+#endif
 
-	(void) sdt_provider_listall(sdt_provider_unreg_callback, NULL);
-	
-	destroy_dev(sdt_cdev);
+	for (ind=0; ind < sdt_count; ind++) {
+	    if ((res = dtrace_unregister(sdt_list[ind]->id)) != 0) {
+#ifdef SDT_DEBUG
+		    printf("%s: failed to unregister %s error = %d\n",
+			    sdt_list[ind]->name, res);
+#endif
+		    error = res;
+	    } else {
+#ifdef SDT_DEBUG
+		printf("sdt: unregistered %s id = %d\n",
+			sdt_list[ind]->name,
+			sdt_list[ind]->id);
+#endif
+	    }
+	}
 
+	kmem_free(sdt_list, sizeof(sdt_provider_t *) * SDT_MAX_PROVIDER);
+	mutex_destroy(&sdt_mutex);
+	sdt_exit();
 	return (error);
 }
 
-/* ARGSUSED */
 static int
-sdt_modevent(module_t mod __unused, int type, void *data __unused)
+sdt_modcmd(modcmd_t cmd, void *data)
 {
+	int bmajor = -1, cmajor = -1;
 	int error = 0;
 
-	switch (type) {
-	case MOD_LOAD:
-		break;
-
-	case MOD_UNLOAD:
-		break;
-
-	case MOD_SHUTDOWN:
-		break;
-
+	switch (cmd) {
+	case MODULE_CMD_INIT:
+		sdt_load(NULL);
+		return devsw_attach("sdt", NULL, &bmajor,
+		    &sdt_cdevsw, &cmajor);
+	case MODULE_CMD_FINI:
+		sdt_unload();
+		return devsw_detach(NULL, &sdt_cdevsw);
 	default:
-		error = EOPNOTSUPP;
-		break;
-
+		return ENOTTY;
 	}
-
-	return (error);
 }
 
-/* ARGSUSED */
 static int
-sdt_open(struct cdev *dev __unused, int oflags __unused, int devtype __unused, struct thread *td __unused)
+sdt_open(dev_t dev, int flags, int mode, struct lwp *l)
 {
 	return (0);
 }
 
-SYSINIT(sdt_load, SI_SUB_DTRACE_PROVIDER, SI_ORDER_ANY, sdt_load, NULL);
-SYSUNINIT(sdt_unload, SI_SUB_DTRACE_PROVIDER, SI_ORDER_ANY, sdt_unload, NULL);
-
-DEV_MODULE(sdt, sdt_modevent, NULL);
-MODULE_VERSION(sdt, 1);
-MODULE_DEPEND(sdt, dtrace, 1, 1, 1);
-MODULE_DEPEND(sdt, opensolaris, 1, 1, 1);
+MODULE(MODULE_CLASS_MISC, sdt, NULL);

Index: src/sys/conf/Makefile.kern.inc
diff -u src/sys/conf/Makefile.kern.inc:1.125 src/sys/conf/Makefile.kern.inc:1.126
--- src/sys/conf/Makefile.kern.inc:1.125	Tue Nov 10 20:24:50 2009
+++ src/sys/conf/Makefile.kern.inc	Mon Mar  1 21:10:14 2010
@@ -1,4 +1,4 @@
-#	$NetBSD: Makefile.kern.inc,v 1.125 2009/11/10 20:24:50 tron Exp $
+#	$NetBSD: Makefile.kern.inc,v 1.126 2010/03/01 21:10:14 darran Exp $
 #
 # This file contains common `MI' targets and definitions and it is included
 # at the bottom of each `MD' ${MACHINE}/conf/Makefile.${MACHINE}.
@@ -120,16 +120,27 @@
 #
 COPTS.debugsyms.c+=	-g
 
+# Add CTF sections for DTrace
+.if defined(CTFCONVERT)
+COMPILE_CTFCONVERT=	${_MKSHECHO}\
+			${CTFCONVERT} ${CTFFLAGS} ${.TARGET}; \
+			${CTFCONVERT} ${CTFFLAGS} ${.TARGET}
+.else
+COMPILE_CTFCONVERT=	${_MKSHECHO}
+.endif
+
 # compile rules: rules are named ${TYPE}_${SUFFIX} where TYPE is NORMAL or
 # NOPROF and SUFFIX is the file suffix, capitalized (e.g. C for a .c file).
 NORMAL_C?=	@${_MKSHMSG} "compile  ${.CURDIR:T}/${.TARGET}"; \
 		${_MKSHECHO}\
 		${CC} ${CFLAGS} ${CPPFLAGS} ${PROF} -c $<; \
-		${CC} ${CFLAGS} ${CPPFLAGS} ${PROF} -c $<
+		${CC} ${CFLAGS} ${CPPFLAGS} ${PROF} -c $<; \
+		${COMPILE_CTFCONVERT}
 NOPROF_C?=	@${_MKSHMSG} "compile  ${.CURDIR:T}/${.TARGET}"; \
 		${_MKSHECHO}\
 		${CC} ${CFLAGS} ${CPPFLAGS} -c $<; \
-		${CC} ${CFLAGS} ${CPPFLAGS} -c $<
+		${CC} ${CFLAGS} ${CPPFLAGS} -c $<; \
+		${COMPILE_CTFCONVERT}
 NORMAL_S?=	@${_MKSHMSG} "compile  ${.CURDIR:T}/${.TARGET}"; \
 		${_MKSHECHO}\
 		${CC} ${AFLAGS} ${CPPFLAGS} -c $<; \
@@ -199,13 +210,19 @@
 #	${SYSTEM_LD_TAIL}
 SYSTEM_OBJ?=	${MD_OBJS} ${MI_OBJS} ${OBJS:O} ${SYSLIBCOMPAT} ${LIBKERN}
 SYSTEM_DEP?=	Makefile ${SYSTEM_OBJ:O} .gdbinit
+.if defined(CTFMERGE)
+SYSTEM_CTFMERGE= ${CTFMERGE} ${CTFFLAGS} -o ${.TARGET} ${SYSTEM_OBJ} ${EXTRA_OBJ} vers.o
+.else
+SYSTEM_CTFMERGE= ${_MKSHECHO}
+.endif
 system_ld_hea...@rm -f $@
 SYSTEM_LD?=	@${_MKSHMSG} "   link  ${.CURDIR:T}/${.TARGET}"; \
 		${_MKSHECHO}\
 		${LD} -Map $...@.map --cref ${LINKFLAGS} -o $@ '$${SYSTEM_OBJ}' '$${EXTRA_OBJ}' vers.o; \
 		${LD} -Map $...@.map --cref ${LINKFLAGS} -o $@ ${SYSTEM_OBJ} ${EXTRA_OBJ} vers.o
 system_ld_tai...@${tool_sed} '/const char sccs/!d;s/.*@(.)//;s/\\.*//' vers.c; \
-		${SIZE} $@; chmod 755 $@
+		${SIZE} $@; chmod 755 $@; \
+		${SYSTEM_CTFMERGE}
 
 TEXTADDR?=	${LOADADDRESS}			# backwards compatibility
 LINKTEXT?=	${TEXTADDR:C/.+/-Ttext &/}
@@ -228,6 +245,7 @@
 SYSTEM_LD_TAIL+=${SYSTEM_LD_TAIL_DEBUG}
 LINKFLAGS+=	${LINKFLAGS_DEBUG}
 EXTRA_KERNELS+= ${KERNELS:@.kern...@${.kernel.}.gdb@}
+CTFFLAGS+=	-g
 .elifndef PROF
 LINKFLAGS+=	${LINKFLAGS_NORMAL}
 .endif

Index: src/sys/conf/files
diff -u src/sys/conf/files:1.977 src/sys/conf/files:1.978
--- src/sys/conf/files:1.977	Tue Feb 23 22:21:25 2010
+++ src/sys/conf/files	Mon Mar  1 21:10:14 2010
@@ -1,4 +1,4 @@
-#	$NetBSD: files,v 1.977 2010/02/23 22:21:25 darran Exp $
+#	$NetBSD: files,v 1.978 2010/03/01 21:10:14 darran Exp $
 #	@(#)files.newconf	7.5 (Berkeley) 5/10/93
 
 version 	20090313
@@ -1456,6 +1456,7 @@
 file	kern/kern_runq.c
 file	kern/kern_rwlock.c
 file	kern/kern_rwlock_obj.c
+file	kern/kern_sdt.c			kdtrace_hooks
 file	kern/kern_sig.c
 file	kern/kern_sleepq.c
 file	kern/kern_softint.c

Index: src/sys/kern/kern_exec.c
diff -u src/sys/kern/kern_exec.c:1.293 src/sys/kern/kern_exec.c:1.294
--- src/sys/kern/kern_exec.c:1.293	Fri Jan  8 11:35:10 2010
+++ src/sys/kern/kern_exec.c	Mon Mar  1 21:10:15 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: kern_exec.c,v 1.293 2010/01/08 11:35:10 pooka Exp $	*/
+/*	$NetBSD: kern_exec.c,v 1.294 2010/03/01 21:10:15 darran Exp $	*/
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -59,7 +59,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_exec.c,v 1.293 2010/01/08 11:35:10 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_exec.c,v 1.294 2010/03/01 21:10:15 darran Exp $");
 
 #include "opt_ktrace.h"
 #include "opt_modular.h"
@@ -101,6 +101,7 @@
 #if NVERIEXEC > 0
 #include <sys/verified_exec.h>
 #endif /* NVERIEXEC > 0 */
+#include <sys/sdt.h>
 
 #include <uvm/uvm_extern.h>
 
@@ -117,6 +118,22 @@
 #endif /* DEBUG_EXEC */
 
 /*
+ * DTrace SDT provider definitions
+ */
+SDT_PROBE_DEFINE(proc,,,exec, 
+	    "char *", NULL,
+	    NULL, NULL, NULL, NULL,
+	    NULL, NULL, NULL, NULL);
+SDT_PROBE_DEFINE(proc,,,exec_success, 
+	    "char *", NULL,
+	    NULL, NULL, NULL, NULL,
+	    NULL, NULL, NULL, NULL);
+SDT_PROBE_DEFINE(proc,,,exec_failure, 
+	    "int", NULL,
+	    NULL, NULL, NULL, NULL,
+	    NULL, NULL, NULL, NULL);
+
+/*
  * Exec function switch:
  *
  * Note that each makecmds function is responsible for loading the
@@ -520,6 +537,8 @@
 	p = l->l_proc;
  	modgen = 0;
 
+	SDT_PROBE(proc,,,exec, path, 0, 0, 0, 0);
+
 	/*
 	 * Check if we have exceeded our number of processes limit.
 	 * This is so that we handle the case where a root daemon
@@ -1063,6 +1082,8 @@
 
 	kmem_free(pack.ep_hdr, pack.ep_hdrlen);
 
+	SDT_PROBE(proc,,,exec_success, path, 0, 0, 0, 0);
+
 	/* The emulation root will usually have been found when we looked
 	 * for the elf interpreter (or similar), if not look now. */
 	if (pack.ep_esch->es_emul->e_path != NULL && pack.ep_emul_root == NULL)
@@ -1181,9 +1202,11 @@
 		goto retry;
 	}
 
+	SDT_PROBE(proc,,,exec_failure, error, 0, 0, 0, 0);
 	return error;
 
  exec_abort:
+	SDT_PROBE(proc,,,exec_failure, error, 0, 0, 0, 0);
 	PNBUF_PUT(pathbuf);
 	rw_exit(&p->p_reflock);
 	rw_exit(&exec_lock);

Index: src/sys/kern/kern_exit.c
diff -u src/sys/kern/kern_exit.c:1.225 src/sys/kern/kern_exit.c:1.226
--- src/sys/kern/kern_exit.c:1.225	Wed Nov  4 21:23:02 2009
+++ src/sys/kern/kern_exit.c	Mon Mar  1 21:10:15 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: kern_exit.c,v 1.225 2009/11/04 21:23:02 rmind Exp $	*/
+/*	$NetBSD: kern_exit.c,v 1.226 2010/03/01 21:10:15 darran Exp $	*/
 
 /*-
  * Copyright (c) 1998, 1999, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -67,7 +67,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_exit.c,v 1.225 2009/11/04 21:23:02 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_exit.c,v 1.226 2010/03/01 21:10:15 darran Exp $");
 
 #include "opt_ktrace.h"
 #include "opt_perfctrs.h"
@@ -109,6 +109,7 @@
 #include <sys/cpu.h>
 #include <sys/lwpctl.h>
 #include <sys/atomic.h>
+#include <sys/sdt.h>
 
 #include <uvm/uvm_extern.h>
 
@@ -123,6 +124,13 @@
 static void proc_free(struct proc *, struct rusage *);
 
 /*
+ * DTrace SDT provider definitions
+ */
+SDT_PROBE_DEFINE(proc,,,exit, 
+	    "int", NULL, 		/* reason */
+	    NULL, NULL, NULL, NULL,
+	    NULL, NULL, NULL, NULL);
+/*
  * Fill in the appropriate signal information, and signal the parent.
  */
 static void
@@ -402,6 +410,11 @@
 	 */
 	KNOTE(&p->p_klist, NOTE_EXIT);
 
+	SDT_PROBE(proc,,,exit, 
+		(WCOREDUMP(rv) ? CLD_DUMPED :
+		 (WIFSIGNALED(rv) ? CLD_KILLED : CLD_EXITED)),
+		0,0,0,0);
+
 #if PERFCTRS
 	/*
 	 * Save final PMC information in parent process & clean up.

Index: src/sys/kern/kern_fork.c
diff -u src/sys/kern/kern_fork.c:1.175 src/sys/kern/kern_fork.c:1.176
--- src/sys/kern/kern_fork.c:1.175	Fri Jan  8 11:35:10 2010
+++ src/sys/kern/kern_fork.c	Mon Mar  1 21:10:16 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: kern_fork.c,v 1.175 2010/01/08 11:35:10 pooka Exp $	*/
+/*	$NetBSD: kern_fork.c,v 1.176 2010/03/01 21:10:16 darran Exp $	*/
 
 /*-
  * Copyright (c) 1999, 2001, 2004, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -67,7 +67,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_fork.c,v 1.175 2010/01/08 11:35:10 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_fork.c,v 1.176 2010/03/01 21:10:16 darran Exp $");
 
 #include "opt_ktrace.h"
 
@@ -91,9 +91,19 @@
 #include <sys/atomic.h>
 #include <sys/syscallargs.h>
 #include <sys/uidinfo.h>
+#include <sys/sdt.h>
 
 #include <uvm/uvm_extern.h>
 
+/*
+ * DTrace SDT provider definitions
+ */
+SDT_PROBE_DEFINE(proc,,,create, 
+	    "struct proc *", NULL,	/* new process */
+	    "struct proc *", NULL,	/* parent process */
+	    "int", NULL,		/* flags */
+	    NULL, NULL, NULL, NULL);
+
 u_int	nprocs = 1;		/* process 0 */
 
 /*
@@ -416,6 +426,8 @@
 
 	uvm_proc_fork(p1, p2, (flags & FORK_SHAREVM) ? true : false);
 
+	SDT_PROBE(proc,,,create, p2, p1, flags, 0, 0);
+
 	/*
 	 * Finish creating the child process.
 	 * It will return through a different path later.

Index: src/sys/kern/kern_ksyms.c
diff -u src/sys/kern/kern_ksyms.c:1.53 src/sys/kern/kern_ksyms.c:1.54
--- src/sys/kern/kern_ksyms.c:1.53	Sun Jan 31 00:43:37 2010
+++ src/sys/kern/kern_ksyms.c	Mon Mar  1 21:10:16 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: kern_ksyms.c,v 1.53 2010/01/31 00:43:37 hubertf Exp $	*/
+/*	$NetBSD: kern_ksyms.c,v 1.54 2010/03/01 21:10:16 darran Exp $	*/
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -71,7 +71,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_ksyms.c,v 1.53 2010/01/31 00:43:37 hubertf Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_ksyms.c,v 1.54 2010/03/01 21:10:16 darran Exp $");
 
 #if defined(_KERNEL) && defined(_KERNEL_OPT)
 #include "opt_ddb.h"
@@ -124,6 +124,7 @@
 
 int ksyms_symsz;
 int ksyms_strsz;
+int ksyms_ctfsz = 0;
 TAILQ_HEAD(, ksyms_symtab) ksyms_symtabs =
     TAILQ_HEAD_INITIALIZER(ksyms_symtabs);
 static struct ksyms_symtab kernel_symtab;
@@ -264,7 +265,7 @@
 static void
 addsymtab(const char *name, void *symstart, size_t symsize,
 	  void *strstart, size_t strsize, struct ksyms_symtab *tab,
-	  void *newstart)
+	  void *newstart, void *ctfstart, size_t ctfsize)
 {
 	Elf_Sym *sym, *nsym, ts;
 	int i, j, n, nglob;
@@ -279,6 +280,8 @@
 	tab->sd_maxsym = 0;
 	tab->sd_usroffset = 0;
 	tab->sd_gone = false;
+	tab->sd_ctfstart = ctfstart;
+	tab->sd_ctfsize = ctfsize;
 #ifdef KSYMS_DEBUG
 	printf("newstart %p sym %p ksyms_symsz %d str %p strsz %d send %p\n",
 	    newstart, symstart, symsize, strstart, strsize,
@@ -353,6 +356,8 @@
 	char *symstart = NULL, *strstart = NULL;
 	size_t strsize = 0;
 	Elf_Ehdr *ehdr;
+	char *ctfstart = NULL;
+	size_t ctfsize = 0;
 
 	if (symsize <= 0) {
 		printf("[ Kernel symbol table missing! ]\n");
@@ -397,10 +402,26 @@
 		break;
 	}
 
+	/* Find the CTF section */
+	shdr = (Elf_Shdr *)((uint8_t *)start + ehdr->e_shoff);
+	for (i = 1; i < ehdr->e_shnum; i++) {
+		if (shdr[i].sh_type != SHT_PROGBITS)
+			continue;
+		if (strncmp(".SUNW_ctf", &strstart[shdr[i].sh_name] ,10) != 0)
+		    	continue;
+		ctfstart = (uint8_t *)start + shdr[i].sh_offset;
+		ctfsize = shdr[i].sh_size;
+		ksyms_ctfsz = ctfsize;
+		printf("%s: found CTF at 0x%x, size 0x%x\n",
+			__func__,
+			(uint32_t)ctfstart, ctfsize);
+		break;
+	}
+
 	if (!ksyms_verify(symstart, strstart))
 		return;
 	addsymtab("netbsd", symstart, symsize, strstart, strsize,
-	    &kernel_symtab, start);
+	    &kernel_symtab, start, ctfstart, ctfsize);
 
 #ifdef DEBUG
 	aprint_normal("Loaded initial symtab at %p, strtab at %p, # entries %ld\n",
@@ -427,7 +448,7 @@
 
 	ksyms_hdr_init(ehdr);
 	addsymtab("netbsd", symstart, symsize, strstart, strsize,
-	    &kernel_symtab, symstart);
+	    &kernel_symtab, symstart, NULL, 0);
 }
 
 /*
@@ -548,7 +569,8 @@
 
 	st = kmem_zalloc(sizeof(*st), KM_SLEEP);
 	mutex_enter(&ksyms_lock);
-	addsymtab(name, symstart, symsize, strstart, strsize, st, symstart);
+	addsymtab(name, symstart, symsize, strstart, strsize, st, symstart, 
+		NULL, 0);
 	mutex_exit(&ksyms_lock);
 }
 
@@ -716,12 +738,20 @@
 
 	/* Fifth section, ".bss". All symbols reside here. */
 	ksyms_hdr.kh_shdr[SHBSS].sh_name = 27; /* This section name offset */
-	ksyms_hdr.kh_shdr[SHBSS].sh_type = SHT_NOBITS;
+	ksyms_hdr.kh_shdr[SHBSS].sh_type = SHT_SYMTAB;
 	ksyms_hdr.kh_shdr[SHBSS].sh_offset = 0;
 	ksyms_hdr.kh_shdr[SHBSS].sh_size = (unsigned long)-1L;
 	ksyms_hdr.kh_shdr[SHBSS].sh_addralign = PAGE_SIZE;
 	ksyms_hdr.kh_shdr[SHBSS].sh_flags = SHF_ALLOC | SHF_EXECINSTR;
 
+	/* Sixth section, ".SUNW_ctf". CTF section for DTrace */
+	ksyms_hdr.kh_shdr[SHCTF].sh_name = 32; /* This section name offset */
+	ksyms_hdr.kh_shdr[SHCTF].sh_type = SHT_NOBITS;
+/*	ksyms_hdr.kh_shdr[SHCTF].sh_offset = filled at open; */
+/*	ksyms_hdr.kh_shdr[SHCTF].sh_size = filled at open; */
+	ksyms_hdr.kh_shdr[SHCTF].sh_addralign = PAGE_SIZE;
+	ksyms_hdr.kh_shdr[SHCTF].sh_flags = 0;
+
 	/* Set section names */
 	strlcpy(&ksyms_hdr.kh_strtab[1], ".symtab",
 	    sizeof(ksyms_hdr.kh_strtab) - 1);
@@ -731,6 +761,8 @@
 	    sizeof(ksyms_hdr.kh_strtab) - 17);
 	strlcpy(&ksyms_hdr.kh_strtab[27], ".bss",
 	    sizeof(ksyms_hdr.kh_strtab) - 27);
+	strlcpy(&ksyms_hdr.kh_strtab[32], ".SUNW_ctf",
+	    sizeof(ksyms_hdr.kh_strtab) - 32);
 }
 
 static int
@@ -747,8 +779,11 @@
 	mutex_enter(&ksyms_lock);
 	ksyms_hdr.kh_shdr[SYMTAB].sh_size = ksyms_symsz;
 	ksyms_hdr.kh_shdr[SYMTAB].sh_info = ksyms_symsz / sizeof(Elf_Sym);
-	ksyms_hdr.kh_shdr[STRTAB].sh_offset = ksyms_symsz +
+	ksyms_hdr.kh_shdr[SHCTF].sh_size = ksyms_ctfsz;
+	ksyms_hdr.kh_shdr[SHCTF].sh_offset = ksyms_symsz +
 	    ksyms_hdr.kh_shdr[SYMTAB].sh_offset;
+	ksyms_hdr.kh_shdr[STRTAB].sh_offset = 
+	    ksyms_hdr.kh_shdr[SHCTF].sh_offset + ksyms_ctfsz;
 	ksyms_hdr.kh_shdr[STRTAB].sh_size = ksyms_strsz;
 	ksyms_isopen = true;
 	mutex_exit(&ksyms_lock);
@@ -784,7 +819,7 @@
 static int
 ksymsread(dev_t dev, struct uio *uio, int ioflag)
 {
-	struct ksyms_symtab *st;
+	struct ksyms_symtab *st, *cst;
 	size_t filepos, inpos, off;
 	int error;
 
@@ -818,10 +853,29 @@
 	}
 
 	/*
+	 * Copy out the CTF table.
+	 */
+	cst = TAILQ_FIRST(&ksyms_symtabs);
+	printf("%s: ctf start 0x%x size 0x%x\n",
+		__func__,
+		(uint32_t)cst->sd_ctfstart, cst->sd_ctfsize);
+	if (uio->uio_resid == 0)
+		return 0;
+	if (uio->uio_offset <= cst->sd_symsize + filepos) {
+		inpos = uio->uio_offset - filepos;
+		error = uiomove((char *)cst->sd_ctfstart + inpos,
+		   cst->sd_ctfsize - inpos, uio);
+		if (error != 0)
+			return error;
+	}
+	filepos += cst->sd_ctfsize;
+
+	/*
 	 * Copy out the string table
 	 */
 	KASSERT(filepos == sizeof(struct ksyms_hdr) +
-	    ksyms_hdr.kh_shdr[SYMTAB].sh_size);
+	    ksyms_hdr.kh_shdr[SYMTAB].sh_size +
+	    ksyms_hdr.kh_shdr[SHCTF].sh_size);
 	TAILQ_FOREACH(st, &ksyms_symtabs, sd_queue) {
 		if (uio->uio_resid == 0)
 			return 0;

Index: src/sys/kern/kern_lwp.c
diff -u src/sys/kern/kern_lwp.c:1.140 src/sys/kern/kern_lwp.c:1.141
--- src/sys/kern/kern_lwp.c:1.140	Tue Feb 23 22:19:27 2010
+++ src/sys/kern/kern_lwp.c	Mon Mar  1 21:10:17 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: kern_lwp.c,v 1.140 2010/02/23 22:19:27 darran Exp $	*/
+/*	$NetBSD: kern_lwp.c,v 1.141 2010/03/01 21:10:17 darran Exp $	*/
 
 /*-
  * Copyright (c) 2001, 2006, 2007, 2008, 2009 The NetBSD Foundation, Inc.
@@ -209,7 +209,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_lwp.c,v 1.140 2010/02/23 22:19:27 darran Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_lwp.c,v 1.141 2010/03/01 21:10:17 darran Exp $");
 
 #include "opt_ddb.h"
 #include "opt_lockdebug.h"
@@ -237,6 +237,7 @@
 #include <sys/atomic.h>
 #include <sys/filedesc.h>
 #include <sys/dtrace_bsd.h>
+#include <sys/sdt.h>
 
 #include <uvm/uvm_extern.h>
 #include <uvm/uvm_object.h>
@@ -248,6 +249,20 @@
 static pool_cache_t lwp_cache;
 static specificdata_domain_t lwp_specificdata_domain;
 
+/* DTrace proc provider probes */
+SDT_PROBE_DEFINE(proc,,,lwp_create,
+	"struct lwp *", NULL,
+	NULL, NULL, NULL, NULL,
+	NULL, NULL, NULL, NULL);
+SDT_PROBE_DEFINE(proc,,,lwp_start,
+	"struct lwp *", NULL,
+	NULL, NULL, NULL, NULL,
+	NULL, NULL, NULL, NULL);
+SDT_PROBE_DEFINE(proc,,,lwp_exit,
+	"struct lwp *", NULL,
+	NULL, NULL, NULL, NULL,
+	NULL, NULL, NULL, NULL);
+
 void
 lwpinit(void)
 {
@@ -681,6 +696,8 @@
 	}
 	mutex_exit(p2->p_lock);
 
+	SDT_PROBE(proc,,,lwp_create, l2, 0,0,0,0);
+
 	mutex_enter(proc_lock);
 	LIST_INSERT_HEAD(&alllwp, l2, l_list);
 	mutex_exit(proc_lock);
@@ -702,6 +719,8 @@
 lwp_startup(struct lwp *prev, struct lwp *new)
 {
 
+	SDT_PROBE(proc,,,lwp_start, new, 0,0,0,0);
+
 	KASSERT(kpreempt_disabled());
 	if (prev != NULL) {
 		/*
@@ -738,6 +757,8 @@
 	KASSERT(current || (l->l_stat == LSIDL && l->l_target_cpu == NULL));
 	KASSERT(p == curproc);
 
+	SDT_PROBE(proc,,,lwp_exit, l, 0,0,0,0);
+
 	/*
 	 * Verify that we hold no locks other than the kernel lock.
 	 */

Index: src/sys/kern/kern_sig.c
diff -u src/sys/kern/kern_sig.c:1.302 src/sys/kern/kern_sig.c:1.303
--- src/sys/kern/kern_sig.c:1.302	Wed Dec 30 23:31:56 2009
+++ src/sys/kern/kern_sig.c	Mon Mar  1 21:10:17 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: kern_sig.c,v 1.302 2009/12/30 23:31:56 rmind Exp $	*/
+/*	$NetBSD: kern_sig.c,v 1.303 2010/03/01 21:10:17 darran Exp $	*/
 
 /*-
  * Copyright (c) 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -66,7 +66,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_sig.c,v 1.302 2009/12/30 23:31:56 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_sig.c,v 1.303 2010/03/01 21:10:17 darran Exp $");
 
 #include "opt_ptrace.h"
 #include "opt_compat_sunos.h"
@@ -96,6 +96,7 @@
 #include <sys/atomic.h>
 #include <sys/cpu.h>
 #include <sys/module.h>
+#include <sys/sdt.h>
 
 #ifdef PAX_SEGVGUARD
 #include <sys/pax.h>
@@ -124,6 +125,30 @@
 int (*coredump_vec)(struct lwp *, const char *) =
     (int (*)(struct lwp *, const char *))enosys;
 
+/*
+ * DTrace SDT provider definitions
+ */
+SDT_PROBE_DEFINE(proc,,,signal_send, 
+	    "struct lwp *", NULL,	/* target thread */
+	    "struct proc *", NULL,	/* target process */
+	    "int", NULL, 		/* signal */
+	    NULL, NULL, NULL, NULL);
+SDT_PROBE_DEFINE(proc,,,signal_discard, 
+	    "struct lwp *", NULL,	/* target thread */
+	    "struct proc *", NULL,	/* target process */
+	    "int", NULL, 		/* signal */
+	    NULL, NULL, NULL, NULL);
+SDT_PROBE_DEFINE(proc,,,signal_clear, 
+	    "int", NULL,		/* signal */
+	    NULL, NULL, NULL, NULL,
+	    NULL, NULL, NULL, NULL);
+SDT_PROBE_DEFINE(proc,,,signal_handle, 
+	    "int", NULL,		/* signal */
+	    "ksiginfo_t *", NULL,
+	    "void (*)(void)", NULL,	/* handler address */
+	    NULL, NULL, NULL, NULL);
+
+
 static struct pool_allocator sigactspool_allocator = {
 	.pa_alloc = sigacts_poolpage_alloc,
 	.pa_free = sigacts_poolpage_free
@@ -1071,6 +1096,8 @@
 	if (l->l_refcnt == 0)
 		return 0;
 
+	SDT_PROBE(proc,,,signal_send, l, p, sig,  0, 0);
+
 	/*
 	 * Have the LWP check for signals.  This ensures that even if no LWP
 	 * is found to take the signal immediately, it should be taken soon.
@@ -1835,6 +1862,10 @@
 
 		prop = sigprop[signo];
 
+		/* XXX no siginfo? */
+		SDT_PROBE(proc,,,signal_handle, signo, 0, 
+			SIGACTION(p, signo).sa_handler, 0, 0);
+
 		/*
 		 * Decide whether the signal should be returned.
 		 */

Index: src/sys/modules/dtrace/Makefile
diff -u src/sys/modules/dtrace/Makefile:1.1 src/sys/modules/dtrace/Makefile:1.2
--- src/sys/modules/dtrace/Makefile:1.1	Sun Feb 21 11:16:19 2010
+++ src/sys/modules/dtrace/Makefile	Mon Mar  1 21:10:18 2010
@@ -1,8 +1,8 @@
-#	$NetBSD: Makefile,v 1.1 2010/02/21 11:16:19 darran Exp $
+#	$NetBSD: Makefile,v 1.2 2010/03/01 21:10:18 darran Exp $
 # $FreeBSD: src/sys/modules/dtrace/Makefile,v 1.6.2.1 2009/08/03 08:13:06 kensmith Exp $
 
 .include <bsd.own.mk>
 
-SUBDIR=		dtrace
+SUBDIR=		dtrace sdt
 
 .include <bsd.subdir.mk>

Index: src/sys/sys/Makefile
diff -u src/sys/sys/Makefile:1.125 src/sys/sys/Makefile:1.126
--- src/sys/sys/Makefile:1.125	Mon Mar  1 11:25:05 2010
+++ src/sys/sys/Makefile	Mon Mar  1 21:10:13 2010
@@ -1,4 +1,4 @@
-#	$NetBSD: Makefile,v 1.125 2010/03/01 11:25:05 darran Exp $
+#	$NetBSD: Makefile,v 1.126 2010/03/01 21:10:13 darran Exp $
 
 .include <bsd.sys.mk>
 
@@ -29,7 +29,7 @@
 	queue.h \
 	ras.h rb.h reboot.h radioio.h resource.h resourcevar.h rmd160.h \
 	rnd.h rwlock.h sa.h satypes.h \
-	scanio.h sched.h scsiio.h select.h selinfo.h sem.h sha1.h \
+	scanio.h sched.h scsiio.h sdt.h select.h selinfo.h sem.h sha1.h \
 	sha2.h shm.h siginfo.h signal.h signalvar.h sigtypes.h simplelock.h \
 	sleepq.h socket.h \
 	socketvar.h sockio.h specificdata.h stat.h statvfs.h \

Index: src/sys/sys/ksyms.h
diff -u src/sys/sys/ksyms.h:1.23 src/sys/sys/ksyms.h:1.24
--- src/sys/sys/ksyms.h:1.23	Sat Mar  7 21:59:25 2009
+++ src/sys/sys/ksyms.h	Mon Mar  1 21:10:13 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: ksyms.h,v 1.23 2009/03/07 21:59:25 ad Exp $	*/
+/*	$NetBSD: ksyms.h,v 1.24 2010/03/01 21:10:13 darran Exp $	*/
 
 /*
  * Copyright (c) 2001, 2003 Anders Magnusson (ra...@ludd.luth.se).
@@ -47,6 +47,8 @@
 	int sd_strsize;		/* Size of string table */
 	int sd_nglob;		/* Number of global symbols */
 	bool sd_gone;		/* dead but around for open() */
+	void *sd_ctfstart;	/* Address of CTF contents */
+	int sd_ctfsize;		/* Size in bytes of CTF contents */
 };
 
 /*
@@ -57,10 +59,11 @@
 #define	STRTAB		2
 #define	SHSTRTAB	3
 #define	SHBSS		4
-#define NSECHDR		5
+#define	SHCTF		5
+#define NSECHDR		6
 
 #define	NPRGHDR		1
-#define	SHSTRSIZ	32
+#define	SHSTRSIZ	42
 
 struct ksyms_hdr {
 	Elf_Ehdr	kh_ehdr;

Added files:

Index: src/sys/kern/kern_sdt.c
diff -u /dev/null src/sys/kern/kern_sdt.c:1.1
--- /dev/null	Mon Mar  1 21:10:20 2010
+++ src/sys/kern/kern_sdt.c	Mon Mar  1 21:10:17 2010
@@ -0,0 +1,110 @@
+/*	$NetBSD: kern_sdt.c,v 1.1 2010/03/01 21:10:17 darran Exp $	*/
+
+/*-
+ * Copyright (c) 2010 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by CoyotePoint Systems, Inc. It was developed under contract to 
+ * CoyotePoint by Darran Hunt.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*-
+ * Copyright 2006-2008 John Birrell <j...@freebsd.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD: src/sys/kern/kern_sdt.c,v 1.1.4.1 2009/08/03 08:13:06 kensmith Exp $
+ *
+ * Backend for the Statically Defined Tracing (SDT) kernel support. This is
+ * required to allow a module to load even though DTrace kernel support may
+ * not be present. A module may be built with SDT probes in it.
+ *
+ */
+
+#include <sys/cdefs.h>
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/sdt.h>
+
+void sdt_probe_stub(u_int32_t, uintptr_t, uintptr_t,
+	uintptr_t, uintptr_t, uintptr_t);
+
+/*
+ * Hook for the DTrace probe function. The 'sdt' provider will set this
+ * to dtrace_probe when it loads.
+ */
+sdt_probe_func_t sdt_probe_func = sdt_probe_stub;
+
+/*
+ * This is a stub for probe calls in case kernel DTrace support isn't
+ * compiled in. It should never get called because there is no DTrace
+ * support to enable it.
+ */
+void
+sdt_probe_stub(u_int32_t id, uintptr_t arg0, uintptr_t arg1,
+    uintptr_t arg2, uintptr_t arg3, uintptr_t arg4)
+{
+	printf("%s: XXX should not be called\n", __func__);
+}
+
+/*
+ * initialize the SDT dtrace probe function
+ */
+void
+sdt_init(void *dtrace_probe)
+{
+
+	sdt_probe_func = dtrace_probe;
+}
+
+/*
+ * Disable the SDT dtrace probe function
+ */
+void
+sdt_exit(void)
+{
+
+	sdt_probe_func = sdt_probe_stub;
+}

Index: src/sys/modules/dtrace/sdt/Makefile
diff -u /dev/null src/sys/modules/dtrace/sdt/Makefile:1.1
--- /dev/null	Mon Mar  1 21:10:20 2010
+++ src/sys/modules/dtrace/sdt/Makefile	Mon Mar  1 21:10:19 2010
@@ -0,0 +1,13 @@
+# $FreeBSD: src/sys/modules/dtrace/sdt/Makefile,v 1.1.4.1 2009/08/03 08:13:06 kensmith Exp $
+
+.PATH: ${NETBSDSRCDIR}/external/cddl/osnet/dev/sdt
+
+KMOD=		sdt
+SRCS=		sdt.c
+SRCS+=		vnode_if.h
+
+CPPFLAGS+=	-I${NETBSDSRCDIR}/external/cddl/osnet/sys \
+		-I${NETBSDSRCDIR}/external/cddl/osnet/dev/sdt \
+		-I${NETBSDSRCDIR}/external/cddl/osnet/dist/uts/common 
+
+.include <bsd.kmodule.mk>

Index: src/sys/sys/sdt.h
diff -u /dev/null src/sys/sys/sdt.h:1.1
--- /dev/null	Mon Mar  1 21:10:20 2010
+++ src/sys/sys/sdt.h	Mon Mar  1 21:10:13 2010
@@ -0,0 +1,128 @@
+/*	$NetBSD: sdt.h,v 1.1 2010/03/01 21:10:13 darran Exp $	*/
+
+/*-
+ * Copyright (c) 2010 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by CoyotePoint Systems, Inc. It was developed under contract to 
+ * CoyotePoint by Darran Hunt.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _SDT_H_
+#define _SDT_H_
+
+#if defined(_KERNEL_OPT)
+#include "opt_dtrace.h"
+#endif
+
+#define SDT_MAX_PROVIDER	1024	/* max number of SDT providers */
+#define SDT_MAX_ARGS		5	/* max number of probe arguments */
+#define SDT_MAX_NAME_SIZE	64	/* max size of provider name */
+
+typedef struct {
+    int		created;	/* boolean: probe created? */
+    int		enabled;	/* boolean: probe enabled? */
+    int		id;		/* dtrace provided probe id */
+    const char	*provider;	/* provider name */
+    const char	*module;	/* module name */
+    const char	*function;	/* function name */
+    const char	*name;		/* probe name */
+    const char	*argv[SDT_MAX_ARGS];	/* probe argument types */
+    const char	*argx[SDT_MAX_ARGS];	/* probe argument xlate types */
+} sdt_probe_t;
+
+
+/*
+ * This type definition must match that of dtrace_probe. It is defined this
+ * way to avoid having to rely on CDDL code.
+ */
+typedef	void (*sdt_probe_func_t)(u_int32_t, uintptr_t arg0, uintptr_t arg1,
+    uintptr_t arg2, uintptr_t arg3, uintptr_t arg4);
+
+/*
+ * The hook for the probe function. See kern_sdt.c which defaults this to
+ * it's own stub. The 'sdt' provider will set it to dtrace_probe when it
+ * loads.
+ */
+extern sdt_probe_func_t	sdt_probe_func;
+
+
+#define SDT_NAME(prov, mod, func, name) \
+    	prov##_##mod##_##func##_##name
+
+#ifdef KDTRACE_HOOKS
+/*
+ * SDT_PROBE_DEFINE(prov, mod, func, name,
+ *		    arg0, argx0, arg1, argx1,
+ *		    arg2, argx2, arg3, argx3, arg4, argx4)
+ *
+ * 	prov	- provider name
+ * 	mod	- module name
+ * 	func	- function name
+ * 	name	- probe name
+ * 	arg0 - arg4, argument types as strings, or NULL.
+ * 	argx0 - argx4, translation types for arg0 - arg4
+ *
+ * 	e.g. SDT_PROBE_DEFINE(l7, l7lb, l7lb_create_node, 
+ * 				"void *", NULL, 
+ * 				NULL, NULL, NULL, NULL,
+ * 				NULL, NULL, NULL NULL, )
+ *
+ *	This is used in the target module to define probes to be used.
+ *	The translation type should be set to NULL if not used.
+ */
+#define SDT_PROBE_DEFINE(prov, mod, func, name, \
+	    arg0, argx0, arg1, argx1, arg2, argx2, \
+	    arg3, argx3, arg4, argx4) \
+    	sdt_probe_t SDT_NAME(prov, mod, func, name) = { \
+	    0, 0, 0, #prov, #mod, #func, #name, \
+	    { arg0, arg1, arg2, arg3, arg4 }, \
+	    { NULL, NULL, NULL, NULL, NULL } \
+	}
+
+/* Use this in this module to declare probes defined in the kernel. */
+#define SDT_PROBE_DECLARE(prov, mod, func, name) \
+    	extern sdt_probe_t SDT_NAME(prov, mod, func, name);
+
+/* Use this in the target modules to provide instrumentation points */
+#define SDT_PROBE(prov, mod, func, name, arg0, arg1, arg2, arg3, arg4) \
+    	if (__predict_false(SDT_NAME(prov, mod, func, name).enabled)) { \
+	    	(*sdt_probe_func)(SDT_NAME(prov, mod, func, name).id, \
+		    (uintptr_t)(arg0), (uintptr_t)(arg1), (uintptr_t)(arg2), \
+		    (uintptr_t)(arg3), (uintptr_t)(arg4)); \
+	}
+#else
+#define SDT_PROBE_DEFINE(prov, mod, func, name, \
+	    arg0, argx0, arg1, argx1, arg2, argx2, \
+	    arg3, argx3, arg4, argx4)
+#define SDT_PROBE_DECLARE(prov, mod, func, name)
+#define SDT_PROBE(prov, mod, func, name, arg0, arg1, arg2, arg3, arg4) 
+#endif
+
+void sdt_init(void *);
+void sdt_exit(void);
+
+#endif

Reply via email to