diff --git a/distrib/sets/lists/modules/md.amd64 b/distrib/sets/lists/modules/md.amd64 index ce578c4..2a8833f 100644 --- a/distrib/sets/lists/modules/md.amd64 +++ b/distrib/sets/lists/modules/md.amd64 @@ -274,6 +274,8 @@ ./stand/amd64-xen/@OSRELEASE@/modules/dtrace_profile/dtrace_profile.kmod base-kernel-modules kmod,dtrace,compatmodules ./stand/amd64-xen/@OSRELEASE@/modules/dtrace_sdt base-kernel-modules kmod,dtrace,compatmodules ./stand/amd64-xen/@OSRELEASE@/modules/dtrace_sdt/dtrace_sdt.kmod base-kernel-modules kmod,dtrace,compatmodules +./stand/amd64-xen/@OSRELEASE@/modules/systrace base-kernel-modules kmod,dtrace,compatmodules +./stand/amd64-xen/@OSRELEASE@/modules/systrace/systrace.kmod base-kernel-modules kmod,dtrace,compatmodules ./stand/amd64-xen/@OSRELEASE@/modules/dtv base-kernel-modules kmod,compatmodules ./stand/amd64-xen/@OSRELEASE@/modules/dtv/dtv.kmod base-kernel-modules kmod,compatmodules ./stand/amd64-xen/@OSRELEASE@/modules/dtv_math base-kernel-modules kmod,compatmodules diff --git a/distrib/sets/lists/modules/md.i386 b/distrib/sets/lists/modules/md.i386 index 8acce74..8259a7a 100644 --- a/distrib/sets/lists/modules/md.i386 +++ b/distrib/sets/lists/modules/md.i386 @@ -304,6 +304,8 @@ ./stand/i386-xen/@OSRELEASE@/modules/dtrace_profile/dtrace_profile.kmod base-kernel-modules kmod,dtrace,compatmodules ./stand/i386-xen/@OSRELEASE@/modules/dtrace_sdt base-kernel-modules kmod,dtrace,compatmodules ./stand/i386-xen/@OSRELEASE@/modules/dtrace_sdt/dtrace_sdt.kmod base-kernel-modules kmod,dtrace,compatmodules +./stand/i386-xen/@OSRELEASE@/modules/systrace base-kernel-modules kmod,dtrace,compatmodules +./stand/i386-xen/@OSRELEASE@/modules/systrace/systrace.kmod base-kernel-modules kmod,dtrace,compatmodules ./stand/i386-xen/@OSRELEASE@/modules/dtv base-kernel-modules kmod,compatmodules ./stand/i386-xen/@OSRELEASE@/modules/dtv/dtv.kmod base-kernel-modules kmod,compatmodules ./stand/i386-xen/@OSRELEASE@/modules/dtv_math base-kernel-modules kmod,compatmodules @@ -703,6 +705,8 @@ ./stand/i386pae-xen/@OSRELEASE@/modules/dtrace_profile/dtrace_profile.kmod base-kernel-modules kmod,dtrace,compatmodules ./stand/i386pae-xen/@OSRELEASE@/modules/dtrace_sdt base-kernel-modules kmod,dtrace,compatmodules ./stand/i386pae-xen/@OSRELEASE@/modules/dtrace_sdt/dtrace_sdt.kmod base-kernel-modules kmod,dtrace,compatmodules +./stand/i386pae-xen/@OSRELEASE@/modules/systrace base-kernel-modules kmod,dtrace,compatmodules +./stand/i386pae-xen/@OSRELEASE@/modules/systrace/systrace.kmod base-kernel-modules kmod,dtrace,compatmodules ./stand/i386pae-xen/@OSRELEASE@/modules/dtv base-kernel-modules kmod,compatmodules ./stand/i386pae-xen/@OSRELEASE@/modules/dtv/dtv.kmod base-kernel-modules kmod,compatmodules ./stand/i386pae-xen/@OSRELEASE@/modules/dtv_math base-kernel-modules kmod,compatmodules diff --git a/distrib/sets/lists/modules/mi b/distrib/sets/lists/modules/mi index 957c3d9..0847b97 100644 --- a/distrib/sets/lists/modules/mi +++ b/distrib/sets/lists/modules/mi @@ -218,6 +218,8 @@ ./@MODULEDIR@/swcrypto/swcrypto.kmod base-kernel-modules kmod ./@MODULEDIR@/swsensor base-kernel-modules kmod ./@MODULEDIR@/swsensor/swsensor.kmod base-kernel-modules kmod +./@MODULEDIR@/systrace base-kernel-modules kmod,dtrace +./@MODULEDIR@/systrace/systrace.kmod base-kernel-modules kmod,dtrace ./@MODULEDIR@/sysvbfs base-kernel-modules kmod ./@MODULEDIR@/sysvbfs/sysvbfs.kmod base-kernel-modules kmod ./@MODULEDIR@/tmpfs base-kernel-modules kmod diff --git a/external/cddl/osnet/dev/systrace/systrace.c b/external/cddl/osnet/dev/systrace/systrace.c index 1b06b82..1f28842 100644 --- a/external/cddl/osnet/dev/systrace/systrace.c +++ b/external/cddl/osnet/dev/systrace/systrace.c @@ -371,8 +371,10 @@ systrace_modcmd(modcmd_t cmd, void *data) return 0; case MODULE_CMD_FINI: - systrace_unload(); - return 0; + return systrace_unload(); + + case MODULE_CMD_AUTOUNLOAD: + return EBUSY; default: return ENOTTY; diff --git a/sys/arch/amd64/amd64/netbsd32_syscall.c b/sys/arch/amd64/amd64/netbsd32_syscall.c index 7efbb5d..5cf6542 100644 --- a/sys/arch/amd64/amd64/netbsd32_syscall.c +++ b/sys/arch/amd64/amd64/netbsd32_syscall.c @@ -29,6 +29,10 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#if defined(_KERNEL) && defined(_KERNEL_OPT) +#include "opt_dtrace.h" +#endif + #include __KERNEL_RCSID(0, "$NetBSD: netbsd32_syscall.c,v 1.32 2014/05/16 12:55:43 njoly Exp $"); @@ -80,6 +84,18 @@ netbsd32_syscall(struct trapframe *frame) SYSCALL_COUNT(syscall_counts, code); SYSCALL_TIME_SYS_ENTRY(l, syscall_times, code); +#ifdef KDTRACE_HOOKS + /* + * If the systrace module has registered its probe + * callback and if there is a probe active for the + * syscall 'entry', process the probe. + */ + if (__predict_false(systrace_probe_func != NULL && + callp->sy_entry != 0)) + (*systrace_probe_func)(callp->sy_entry, code, callp, + args); +#endif + params = (char *)frame->tf_rsp + sizeof(int); if (callp->sy_argsize) { @@ -103,6 +119,18 @@ netbsd32_syscall(struct trapframe *frame) error = sy_call(callp, l, args, rval); out: +#ifdef KDTRACE_HOOKS + /* + * If the systrace module has registered its probe + * callback and if there is a probe active for the + * syscall 'return', process the probe. + */ + if (__predict_false(systrace_probe_func != NULL && + callp->sy_return != 0)) + (*systrace_probe_func)(callp->sy_return, code, callp, + args); +#endif + if (__predict_false(p->p_trace_enabled) && !__predict_false(callp->sy_flags & SYCALL_INDIRECT)) { trace_exit(code, rval, error); diff --git a/sys/compat/freebsd/syscalls.conf b/sys/compat/freebsd/syscalls.conf index d35f9a4..aea0ce5 100644 --- a/sys/compat/freebsd/syscalls.conf +++ b/sys/compat/freebsd/syscalls.conf @@ -4,6 +4,7 @@ sysnames="freebsd_syscalls.c" sysnumhdr="freebsd_syscall.h" syssw="freebsd_sysent.c" sysarghdr="freebsd_syscallargs.h" +systrace="freebsd_systrace_args.c" compatopts="" libcompatopts="" diff --git a/sys/compat/ibcs2/syscalls.conf b/sys/compat/ibcs2/syscalls.conf index c1628c8..d14df07 100644 --- a/sys/compat/ibcs2/syscalls.conf +++ b/sys/compat/ibcs2/syscalls.conf @@ -6,6 +6,7 @@ sysnames="ibcs2_syscalls.c" sysnumhdr="ibcs2_syscall.h" syssw="ibcs2_sysent.c" sysarghdr="ibcs2_syscallargs.h" +systrace="ibcs2_systrace_args.c" compatopts="" libcompatopts="" diff --git a/sys/compat/linux/arch/amd64/syscalls.conf b/sys/compat/linux/arch/amd64/syscalls.conf index e0dd425..752e9b8 100644 --- a/sys/compat/linux/arch/amd64/syscalls.conf +++ b/sys/compat/linux/arch/amd64/syscalls.conf @@ -4,6 +4,7 @@ sysnames="linux_syscalls.c" sysnumhdr="linux_syscall.h" syssw="linux_sysent.c" sysarghdr="linux_syscallargs.h" +systrace="linux_systrace_args.c" compatopts="" libcompatopts="" diff --git a/sys/compat/linux/arch/i386/syscalls.conf b/sys/compat/linux/arch/i386/syscalls.conf index 4c1a7b7..47fc08b 100644 --- a/sys/compat/linux/arch/i386/syscalls.conf +++ b/sys/compat/linux/arch/i386/syscalls.conf @@ -4,6 +4,7 @@ sysnames="linux_syscalls.c" sysnumhdr="linux_syscall.h" syssw="linux_sysent.c" sysarghdr="linux_syscallargs.h" +systrace="linux_systrace_args.c" compatopts="" libcompatopts="" diff --git a/sys/compat/linux32/arch/amd64/syscalls.conf b/sys/compat/linux32/arch/amd64/syscalls.conf index 644afc2..afb4cd6 100644 --- a/sys/compat/linux32/arch/amd64/syscalls.conf +++ b/sys/compat/linux32/arch/amd64/syscalls.conf @@ -4,6 +4,7 @@ sysnames="linux32_syscalls.c" sysnumhdr="linux32_syscall.h" syssw="linux32_sysent.c" sysarghdr="linux32_syscallargs.h" +systrace="linux32_systrace_args.c" compatopts="" libcompatopts="" diff --git a/sys/compat/netbsd32/syscalls.conf b/sys/compat/netbsd32/syscalls.conf index 1853179..25c3363 100644 --- a/sys/compat/netbsd32/syscalls.conf +++ b/sys/compat/netbsd32/syscalls.conf @@ -4,6 +4,7 @@ sysnames="netbsd32_syscalls.c" sysnumhdr="netbsd32_syscall.h" syssw="netbsd32_sysent.c" sysarghdr="netbsd32_syscallargs.h" +systrace="netbsd32_systrace_args.c" compatopts="compat_43 compat_09 compat_10 compat_11 compat_12 compat_13 compat_14 compat_15 compat_16 compat_20 compat_30 compat_40 compat_50 compat_60 compat_70" libcompatopts="" diff --git a/sys/compat/svr4/syscalls.conf b/sys/compat/svr4/syscalls.conf index f9a9561..bb02009 100644 --- a/sys/compat/svr4/syscalls.conf +++ b/sys/compat/svr4/syscalls.conf @@ -4,6 +4,7 @@ sysnames="svr4_syscalls.c" sysnumhdr="svr4_syscall.h" syssw="svr4_sysent.c" sysarghdr="svr4_syscallargs.h" +systrace="svr4_systrace_args.c" compatopts="" libcompatopts="" diff --git a/sys/kern/files.kern b/sys/kern/files.kern index fccd706..0389174 100644 --- a/sys/kern/files.kern +++ b/sys/kern/files.kern @@ -58,6 +58,7 @@ file kern/kern_core.c coredump file kern/kern_cpu.c kern file kern/kern_ctf.c kdtrace_hooks file kern/kern_descrip.c kern +file kern/kern_dtrace.c kdtrace_hooks file kern/kern_event.c kern file kern/kern_exec.c kern file kern/kern_exit.c kern @@ -168,7 +169,7 @@ file kern/sys_select.c kern file kern/sys_sig.c kern file kern/sys_sched.c kern file kern/sys_socket.c kern -file kern/syscalls.c syscall_debug +file kern/syscalls.c syscall_debug | kdtrace_hooks file kern/sysv_ipc.c sysvshm | sysvsem | sysvmsg file kern/sysv_msg.c sysvmsg file kern/sysv_sem.c sysvsem diff --git a/sys/kern/kern_dtrace.c b/sys/kern/kern_dtrace.c new file mode 100644 index 0000000..b97a58d --- /dev/null +++ b/sys/kern/kern_dtrace.c @@ -0,0 +1,36 @@ +/* $NetBSD$ */ + +/*- + * Copyright (c) 2015 The NetBSD Foundation, Inc. + * All rights reserved. + * + * 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. + */ + +#include + +/* + * This is a hook which is initialised by the systrace module + * when it is loaded. This keeps the DTrace syscall provider + * implementation opaque. + */ +systrace_probe_func_t systrace_probe_func; diff --git a/sys/kern/makesyscalls.sh b/sys/kern/makesyscalls.sh index ddc0ea4..7868a56 100644 --- a/sys/kern/makesyscalls.sh +++ b/sys/kern/makesyscalls.sh @@ -75,8 +75,9 @@ sysent="sysent.switch" sysnamesbottom="sysnames.bottom" rumptypes="rumphdr.types" rumpprotos="rumphdr.protos" +systracetmp="systrace" -trap "rm $sysdcl $sysprotos $sysent $sysnamesbottom $rumpsysent $rumptypes $rumpprotos" 0 +trap "rm $sysdcl $sysprotos $sysent $sysnamesbottom $rumpsysent $rumptypes $rumpprotos $systracetmp" 0 # Awk program (must support nawk extensions) # Use "awk" at Berkeley, "nawk" or "gawk" elsewhere. @@ -155,6 +156,8 @@ BEGIN { syscompat_pref = \"$syscompat_pref\" sysent = \"$sysent\" sysnamesbottom = \"$sysnamesbottom\" + systrace = \"$systrace\" + systracetmp = \"$systracetmp\" rumpprotos = \"$rumpprotos\" rumptypes = \"$rumptypes\" sys_nosys = \"$sys_nosys\" @@ -211,6 +214,10 @@ BEGIN { printf "/* %s */\n\n", tag > rumpcallshdr printf "/*\n * System call protos in rump namespace.\n *\n" > rumpcallshdr printf " * DO NOT EDIT-- this file is automatically generated.\n" > rumpcallshdr + + printf "/* %s */\n\n", tag > systrace + printf "/*\n * System call argument to DTrace register array conversion.\n *\n" > systrace + printf " * DO NOT EDIT-- this file is automatically generated.\n" > systrace } NR == 1 { sub(/ $/, "") @@ -324,6 +331,20 @@ NR == 1 { "\t\t<= %sMAXSYSARGS * sizeof (%s) ? 1 : -1];\n", \ constprefix, registertype) >sysarghdr + printf " * created from%s\n", $0 > systrace + printf " *\n" > systrace + printf " * This file is part of the DTrace syscall provider.\n */\n\n" > systrace + printf "#define SYSTRACE_INT_ARG(t, idx, var)\t" \ + "if (__type_is_signed(t)) \\\n\t\t\t\t\t" \ + "uarg[idx].s = SCARG(p, var); \\\n" \ + "\t\t\t\t\telse uarg[idx].u = SCARG(p, var)\n" > systrace + printf "#define SYSTRACE_PTR_ARG(t, idx, var)\tuarg[idx].u = (intptr_t) SCARG(p, var)\n\n" > systrace + printf "static void\nsystrace_args(int sysnum, const void *params, union systrace_probe_args_un *uarg, int *n_args)\n{\n" > systrace + printf "\tswitch (sysnum) {\n" > systrace + + printf "static void\nsystrace_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)\n{\n\tconst char *p = NULL;\n" > systracetmp + printf "\tswitch (sysnum) {\n" > systracetmp + # compat types from syscalls.master. this is slightly ugly, # but given that we have so few compats from over 17 years, # a more complicated solution is not currently warranted. @@ -376,6 +397,8 @@ $1 ~ /^#/ && intable { print > sysnumhdr print > sysprotos print > sysnamesbottom + print > systrace + print > systracetmp # XXX: technically we do not want to have conditionals in rump, # but it is easier to just let the cpp handle them than try to @@ -647,7 +670,7 @@ function printrumpsysent(insysent, compatwrap) { eno[1] = "rumpns_sys_nomodule" flags[0] = "SYCALL_NOSYS" flags[1] = "0" - printf("\t{ 0, 0, %s,\n\t (sy_call_t *)%s }, \t" \ + printf("\t{ 0, 0, %s,\n\t (sy_call_t *)%s, NULL, 0, 0 }, \t" \ "/* %d = %s */\n", \ flags[modular], eno[modular], syscall, funcalias) \ > rumpsysent @@ -665,7 +688,7 @@ function printrumpsysent(insysent, compatwrap) { fn="(sy_call_t *)rumpns_sys_nomodule" else fn="(sy_call_t *)rumpns_enosys" - printf("0,\n\t %s },", fn) > rumpsysent + printf("0,\n\t %s, NULL, 0, 0 },", fn) > rumpsysent for (i = 0; i < (33 - length(fn)) / 8; i++) printf("\t") > rumpsysent printf("/* %d = %s%s */\n", syscall, compatwrap_, funcalias) > rumpsysent @@ -729,7 +752,7 @@ function putent(type, compatwrap) { else wfn = compatwrap "(" funcname ")"; wfn_cast="(sy_call_t *)" wfn - printf("%s,\n\t %s },", sycall_flags, wfn_cast) > sysent + printf("%s,\n\t %s, NULL, 0, 0 },", sycall_flags, wfn_cast) > sysent for (i = 0; i < (33 - length(wfn_cast)) / 8; i++) printf("\t") > sysent printf("/* %d = %s%s */\n", syscall, compatwrap_, funcalias) > sysent @@ -750,6 +773,28 @@ function putent(type, compatwrap) { printproto(compatwrap_) } + # output systrace bits + printf("\t/* %s */\n\tcase %d: {\n", funcname, syscall) > systrace + printf("\t/* %s */\n\tcase %d:\n", funcname, syscall) > systracetmp + if (argc > 0) { + printf("\t\tswitch(ndx) {\n") > systracetmp + printf("\t\tstruct %s%s_args *p = params;\n", compatwrap_, funcname) > systrace + for (i = 1; i <= argc; i++) { + printf("\t\tcase %d:\n\t\t\tp = \"%s\";\n\t\t\tbreak;\n", i - 1, argtype[i]) > systracetmp + if (index(argtype[i], "*") > 0) + printf("\t\tSYSTRACE_PTR_ARG(%s, %d, %s);\n", \ + argtype[i], i - 1, \ + argname[i]) > systrace + else + printf("\t\tSYSTRACE_INT_ARG(%s, %d, %s);\n", \ + argtype[i], i - 1, \ + argname[i]) > systrace + } + printf("\t\tdefault:\n\t\t\tbreak;\n\t\t};\n") > systracetmp + } + printf("\t\t*n_args = %d;\n\t\tbreak;\n\t}\n", argc) > systrace + printf("\t\tbreak;\n") > systracetmp + # output syscall argument structure, if it has arguments if (argc != 0) { printf("\n") > sysarghdr @@ -922,9 +967,9 @@ $2 == "OBSOL" || $2 == "UNIMPL" || $2 == "EXCL" || $2 == "IGNORED" { else sys_stub = sys_nosys; - printf("\t{ 0, 0, 0,\n\t %s },\t\t\t/* %d = %s */\n", \ + printf("\t{ 0, 0, 0,\n\t %s, NULL, 0, 0 },\t\t\t/* %d = %s */\n", \ sys_stub, syscall, comment) > sysent - printf("\t{ 0, 0, SYCALL_NOSYS,\n\t %s },\t\t/* %d = %s */\n", \ + printf("\t{ 0, 0, SYCALL_NOSYS,\n\t %s, NULL, 0, 0 },\t\t/* %d = %s */\n", \ "(sy_call_t *)rumpns_enosys", syscall, comment) > rumpsysent printf("\t/* %3d */\t\"#%d (%s)\",\n", syscall, syscall, comment) \ > sysnamesbottom @@ -989,9 +1034,9 @@ END { exit 1 } while (syscall < nsysent) { - printf("\t{ 0, 0, 0,\n\t %s },\t\t\t/* %d = filler */\n", \ + printf("\t{ 0, 0, 0,\n\t %s, NULL, 0, 0 },\t\t\t/* %d = filler */\n", \ sys_nosys, syscall) > sysent - printf("\t{ 0, 0, SYCALL_NOSYS,\n\t %s },\t\t/* %d = filler */\n", \ + printf("\t{ 0, 0, SYCALL_NOSYS,\n\t %s, NULL, 0, 0 },\t\t/* %d = filler */\n", \ "(sy_call_t *)rumpns_enosys", syscall) > rumpsysent printf("\t/* %3d */\t\"# filler\",\n", syscall) \ > sysnamesbottom @@ -1009,6 +1054,8 @@ END { printf("#define\t%sMAXSYSCALL\t%d\n", constprefix, maxsyscall) > sysnumhdr if (nsysent) printf("#define\t%sNSYSENT\t%d\n", constprefix, nsysent) > sysnumhdr + printf "\tdefault:\n\t\t*n_args = 0;\n\t\tbreak;\n\t};\n}\n" > systrace + printf "\tdefault:\n\t\tbreak;\n\t};\n\tif (p != NULL)\n\t\tstrlcpy(desc, p, descsz);\n}\n" > systracetmp } ' cat $sysprotos >> $sysarghdr @@ -1024,6 +1071,7 @@ cat $rumptypes >> $rumpcallshdr echo >> $rumpcallshdr cat $rumpprotos >> $rumpcallshdr +cat $systracetmp >> $systrace #chmod 444 $sysnames $sysnumhdr $syssw echo Generated following files: diff --git a/sys/kern/syscalls.conf b/sys/kern/syscalls.conf index 9b26033..1a696a8 100644 --- a/sys/kern/syscalls.conf +++ b/sys/kern/syscalls.conf @@ -8,6 +8,7 @@ sysarghdrextra='#include \n#ifndef RUMP_CLIENT\n#include -SUBDIR= dtrace sdt fbt profile +SUBDIR= dtrace sdt fbt profile systrace .include diff --git a/sys/modules/dtrace/systrace/Makefile b/sys/modules/dtrace/systrace/Makefile new file mode 100644 index 0000000..2da6c2c --- /dev/null +++ b/sys/modules/dtrace/systrace/Makefile @@ -0,0 +1,16 @@ +# $NetBSD$ + +.include "../../Makefile.inc" + +.PATH: ${NETBSDSRCDIR}/external/cddl/osnet/dev/systrace + +WARNS=2 +KMOD= systrace +SRCS= systrace.c + +CPPFLAGS+= -I${NETBSDSRCDIR}/external/cddl/osnet/sys \ + -I${NETBSDSRCDIR}/external/cddl/osnet/dist/uts/common + +CPPFLAGS+= -Wno-unknown-pragmas + +.include diff --git a/sys/sys/syscallvar.h b/sys/sys/syscallvar.h index f396f88..b7e469d 100644 --- a/sys/sys/syscallvar.h +++ b/sys/sys/syscallvar.h @@ -36,6 +36,10 @@ #error nothing of interest to userspace here #endif +#if defined(_KERNEL) && defined(_KERNEL_OPT) +#include "opt_dtrace.h" +#endif + #include #include @@ -72,6 +76,17 @@ sy_invoke(const struct sysent *sy, struct lwp *l, const void *uap, (sy->sy_flags & SYCALL_INDIRECT) == 0; int error; +#ifdef KDTRACE_HOOKS + /* + * If the systrace module has registered its probe + * callback and if there is a probe active for the + * syscall 'entry', process the probe. + */ + if (__predict_false(systrace_probe_func != NULL && + sy->sy_entry != 0)) + (*systrace_probe_func)(sy->sy_entry, code, sy, + uap); +#endif if (__predict_true(!do_trace) || (error = trace_enter(code, uap, sy->sy_narg)) == 0) { rval[0] = 0; @@ -85,6 +100,18 @@ sy_invoke(const struct sysent *sy, struct lwp *l, const void *uap, error = sy_call(sy, l, uap, rval); } +#ifdef KDTRACE_HOOKS + /* + * If the systrace module has registered its probe + * callback and if there is a probe active for the + * syscall 'return', process the probe. + */ + if (__predict_false(systrace_probe_func != NULL && + sy->sy_return != 0)) + (*systrace_probe_func)(sy->sy_return, code, sy, + uap); +#endif + if (__predict_false(do_trace)) { trace_exit(code, rval, error); } diff --git a/sys/sys/systm.h b/sys/sys/systm.h index 201552f..9726267 100644 --- a/sys/sys/systm.h +++ b/sys/sys/systm.h @@ -57,6 +57,7 @@ struct clockframe; struct lwp; struct proc; +struct sysent; struct timeval; struct tty; struct uio; @@ -115,11 +116,32 @@ extern const dev_t zerodev; /* /dev/zero */ typedef int sy_call_t(struct lwp *, const void *, register_t *); +/* Used by the machine dependent syscall() code. */ +typedef void (*systrace_probe_func_t)(u_int32_t, int, + const struct sysent *, const void *); + +/* + * Used by loaded syscalls to convert arguments to a DTrace array + * of 64-bit arguments. + */ +union systrace_probe_args_un { + uint64_t u; + int64_t s; +}; +typedef void (*systrace_args_func_t)(int, const void *, + union systrace_probe_args_un *, int *); + +extern systrace_probe_func_t systrace_probe_func; + extern struct sysent { /* system call table */ short sy_narg; /* number of args */ short sy_argsize; /* total size of arguments */ int sy_flags; /* flags. see below */ sy_call_t *sy_call; /* implementing function */ + systrace_args_func_t sy_systrace_args_func; + /* optional argument conversion function. */ + u_int32_t sy_entry; /* DTrace entry ID for systrace. */ + u_int32_t sy_return; /* DTrace return ID for systrace. */ } sysent[]; extern int nsysent; #if BYTE_ORDER == BIG_ENDIAN