Module Name: src
Committed By: christos
Date: Sat Mar 7 16:38:08 UTC 2015
Modified Files:
src/sys/kern: Makefile kern_syscall.c makesyscalls.sh syscalls.conf
Log Message:
Adjust for systrace based on the FreeBSD code:
- create new file systrace_args.c that use used to convert the syscall
arguments to an array, and functions that print the types of the
entry and return arguments.
- call the systrace probe from the trace_enter and trace_exit functions
To generate a diff of this commit:
cvs rdiff -u -r1.17 -r1.18 src/sys/kern/Makefile
cvs rdiff -u -r1.9 -r1.10 src/sys/kern/kern_syscall.c
cvs rdiff -u -r1.145 -r1.146 src/sys/kern/makesyscalls.sh
cvs rdiff -u -r1.21 -r1.22 src/sys/kern/syscalls.conf
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/kern/Makefile
diff -u src/sys/kern/Makefile:1.17 src/sys/kern/Makefile:1.18
--- src/sys/kern/Makefile:1.17 Wed Jan 15 20:15:34 2014
+++ src/sys/kern/Makefile Sat Mar 7 11:38:07 2015
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.17 2014/01/16 01:15:34 christos Exp $
+# $NetBSD: Makefile,v 1.18 2015/03/07 16:38:07 christos Exp $
#
# from: @(#)Makefile 8.2 (Berkeley) 3/21/94
@@ -11,7 +11,7 @@ all:
@false
SYSCALLSRC = makesyscalls.sh syscalls.conf syscalls.master
-init_sysent.c syscalls.c ../sys/syscall.h ../sys/syscallargs.h: ${SYSCALLSRC}
+init_sysent.c syscalls.c systrace_args.c ../sys/syscall.h ../sys/syscallargs.h: ${SYSCALLSRC}
${HOST_SH} makesyscalls.sh syscalls.conf syscalls.master
VNODEIFSRC = vnode_if.sh vnode_if.src
Index: src/sys/kern/kern_syscall.c
diff -u src/sys/kern/kern_syscall.c:1.9 src/sys/kern/kern_syscall.c:1.10
--- src/sys/kern/kern_syscall.c:1.9 Sat Dec 14 01:27:57 2013
+++ src/sys/kern/kern_syscall.c Sat Mar 7 11:38:07 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: kern_syscall.c,v 1.9 2013/12/14 06:27:57 pgoyette Exp $ */
+/* $NetBSD: kern_syscall.c,v 1.10 2015/03/07 16:38:07 christos Exp $ */
/*-
* Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -30,13 +30,14 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_syscall.c,v 1.9 2013/12/14 06:27:57 pgoyette Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_syscall.c,v 1.10 2015/03/07 16:38:07 christos Exp $");
#ifdef _KERNEL_OPT
#include "opt_modular.h"
#include "opt_syscall_debug.h"
#include "opt_ktrace.h"
#include "opt_ptrace.h"
+#include "opt_dtrace.h"
#endif
/* XXX To get syscall prototypes. */
@@ -370,15 +371,22 @@ trace_is_enabled(struct proc *p)
* a system call is actually executed.
*/
int
-trace_enter(register_t code, const register_t *args, int narg)
+trace_enter(register_t code, const struct sysent *sy, const void *args)
{
int error = 0;
+#ifdef KDTRACE_HOOKS
+ if (sy->sy_entry) {
+ struct emul *e = curlwp->l_proc->p_emul;
+ (*e->e_dtrace_syscall)(sy->sy_entry, code, sy, args, NULL, 0);
+ }
+#endif
+
#ifdef SYSCALL_DEBUG
scdebug_call(code, args);
#endif /* SYSCALL_DEBUG */
- ktrsyscall(code, args, narg);
+ ktrsyscall(code, args, sy->sy_narg);
#ifdef PTRACE
if ((curlwp->l_proc->p_slflag & (PSL_SYSCALL|PSL_TRACED)) ==
@@ -401,12 +409,20 @@ trace_enter(register_t code, const regis
* system call number range for emulation the process runs under.
*/
void
-trace_exit(register_t code, register_t rval[], int error)
+trace_exit(register_t code, const struct sysent *sy, const void *args,
+ register_t rval[], int error)
{
-#ifdef PTRACE
+#if defined(PTRACE) || defined(KDTRACE_HOOKS)
struct proc *p = curlwp->l_proc;
#endif
+#ifdef KDTRACE_HOOKS
+ if (sy->sy_return) {
+ (*p->p_emul->e_dtrace_syscall)(sy->sy_return, code, sy, args,
+ rval, error);
+ }
+#endif
+
#ifdef SYSCALL_DEBUG
scdebug_ret(code, error, rval);
#endif /* SYSCALL_DEBUG */
Index: src/sys/kern/makesyscalls.sh
diff -u src/sys/kern/makesyscalls.sh:1.145 src/sys/kern/makesyscalls.sh:1.146
--- src/sys/kern/makesyscalls.sh:1.145 Thu Jul 24 07:58:45 2014
+++ src/sys/kern/makesyscalls.sh Sat Mar 7 11:38:07 2015
@@ -1,4 +1,4 @@
-# $NetBSD: makesyscalls.sh,v 1.145 2014/07/24 11:58:45 pooka Exp $
+# $NetBSD: makesyscalls.sh,v 1.146 2015/03/07 16:38:07 christos Exp $
#
# Copyright (c) 1994, 1996, 2000 Christopher G. Demetriou
# All rights reserved.
@@ -61,6 +61,7 @@ esac
# source the config file.
sys_nosys="sys_nosys" # default is sys_nosys(), if not specified otherwise
maxsysargs=8 # default limit is 8 (32bit) arguments
+systrace="/dev/null"
rumpcalls="/dev/null"
rumpcallshdr="/dev/null"
rumpsysmap="/dev/null"
@@ -75,15 +76,17 @@ sysent="sysent.switch"
sysnamesbottom="sysnames.bottom"
rumptypes="rumphdr.types"
rumpprotos="rumphdr.protos"
+systracetmp="systrace.$$"
+systraceret="systraceret.$$"
-trap "rm $sysdcl $sysprotos $sysent $sysnamesbottom $rumpsysent $rumptypes $rumpprotos" 0
+trap "rm $sysdcl $sysprotos $sysent $sysnamesbottom $rumpsysent $rumptypes $rumpprotos $systracetmp $systraceret" 0
# Awk program (must support nawk extensions)
# Use "awk" at Berkeley, "nawk" or "gawk" elsewhere.
awk=${AWK:-awk}
# Does this awk have a "toupper" function?
-have_toupper=`$awk 'BEGIN { print toupper("true"); exit; }' 2>/dev/null`
+have_toupper="$($awk 'BEGIN { print toupper("true"); exit; }' 2>/dev/null)"
# If this awk does not define "toupper" then define our own.
if [ "$have_toupper" = TRUE ] ; then
@@ -137,6 +140,9 @@ BEGIN {
sysnumhdr = \"$sysnumhdr\"
sysarghdr = \"$sysarghdr\"
sysarghdrextra = \"$sysarghdrextra\"
+ systrace = \"$systrace\"
+ systracetmp = \"$systracetmp\"
+ systraceret = \"$systraceret\"
rumpcalls = \"$rumpcalls\"
rumpcallshdr = \"$rumpcallshdr\"
rumpsysent = \"$rumpsysent\"
@@ -211,6 +217,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 converstion.\n *\n" > systrace
+ printf " * DO NOT EDIT-- this file is automatically generated.\n" > systrace
}
NR == 1 {
sub(/ $/, "")
@@ -324,6 +334,17 @@ NR == 1 {
"\t\t<= %sMAXSYSARGS * sizeof (%s) ? 1 : -1];\n", \
constprefix, registertype) >sysarghdr
+ printf " * This file is part of the DTrace syscall provider.\n */\n\n" > systrace
+ printf "static void\nsystrace_args(register_t sysnum, const void *params, uintptr_t *uarg, size_t *n_args)\n{\n" > systrace
+ printf "\tintptr_t *iarg = (intptr_t *)uarg;\n" > systrace
+ printf "\tswitch (sysnum) {\n" > systrace
+
+ printf "static void\nsystrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)\n{\n\tconst char *p = NULL;\n" > systracetmp
+ printf "\tswitch (sysnum) {\n" > systracetmp
+
+ printf "static void\nsystrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)\n{\n\tconst char *p = NULL;\n" > systraceret
+ printf "\tswitch (sysnum) {\n" > systraceret
+
# 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,9 @@ $1 ~ /^#/ && intable {
print > sysnumhdr
print > sysprotos
print > sysnamesbottom
+ print > systrace
+ print > systracetmp
+ print > systraceret
# 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 +671,7 @@ function printrumpsysent(insysent, compa
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, 0, 0 }, \t" \
"/* %d = %s */\n", \
flags[modular], eno[modular], syscall, funcalias) \
> rumpsysent
@@ -665,7 +689,7 @@ function printrumpsysent(insysent, compa
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, 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
@@ -697,6 +721,45 @@ function printrumpsysmap(syscall, wfn, f
syscall, wfn, funcalias, rumpentry) > rumpsysmap
}
+function putsystrace(type, compatwrap_) {
+ printf("\t/* %s */\n\tcase %d: {\n", funcname, syscall) > systrace
+ printf("\t/* %s */\n\tcase %d:\n", funcname, syscall) > systracetmp
+ printf("\t/* %s */\n\tcase %d:\n", funcname, syscall) > systraceret
+ 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++) {
+ arg = argtype[i]
+ sub("__restrict$", "", arg)
+ printf("\t\tcase %d:\n\t\t\tp = \"%s\";\n\t\t\tbreak;\n", i - 1, arg) > systracetmp
+ if (arg ~ /.*p_t$/ || arg ~ /.*p$/ || arg ~ /.*_t_p$/ ||
+ arg ~ /.*_pointer_t$/)
+ printf("\t\tuarg[%d] = (intptr_t) SCARG(p, %s).i32; /* %s */\n", \
+ i - 1, \
+ argname[i], arg) > systrace
+ else if (index(arg, "*") > 0 || arg == "caddr_t")
+ printf("\t\tuarg[%d] = (intptr_t) SCARG(p, %s); /* %s */\n", \
+ i - 1, \
+ argname[i], arg) > systrace
+ else if (substr(arg, 1, 1) == "u" || arg == "size_t")
+ printf("\t\tuarg[%d] = SCARG(p, %s); /* %s */\n", \
+ i - 1, \
+ argname[i], arg) > systrace
+ else
+ printf("\t\tiarg[%d] = SCARG(p, %s); /* %s */\n", \
+ i - 1, \
+ argname[i], arg) > systrace
+ }
+ printf("\t\tdefault:\n\t\t\tbreak;\n\t\t};\n") > systracetmp
+
+ printf("\t\tif (ndx == 0 || ndx == 1)\n") > systraceret
+ printf("\t\t\tp = \"%s\";\n", returntype) > systraceret
+ printf("\t\tbreak;\n") > systraceret
+ }
+ printf("\t\t*n_args = %d;\n\t\tbreak;\n\t}\n", argc) > systrace
+ printf("\t\tbreak;\n") > systracetmp
+}
+
function putent(type, compatwrap) {
# output syscall declaration for switch table.
if (compatwrap == "")
@@ -708,6 +771,7 @@ function putent(type, compatwrap) {
else {
arg_type = "struct " compatwrap_ funcname "_args";
}
+ putsystrace(type, compatwrap_)
proto = "int\t" compatwrap_ funcname "(struct lwp *, const " \
arg_type " *, register_t *);\n"
if (sysmap[proto] != 1) {
@@ -729,7 +793,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, 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
@@ -922,9 +986,9 @@ $2 == "OBSOL" || $2 == "UNIMPL" || $2 ==
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, 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, 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 +1053,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, 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, 0, 0 },\t\t/* %d = filler */\n", \
"(sy_call_t *)rumpns_enosys", syscall) > rumpsysent
printf("\t/* %3d */\t\"# filler\",\n", syscall) \
> sysnamesbottom
@@ -1009,6 +1073,9 @@ 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
+ printf "\tdefault:\n\t\tbreak;\n\t};\n\tif (p != NULL)\n\t\tstrlcpy(desc, p, descsz);\n}\n" > systraceret
} '
cat $sysprotos >> $sysarghdr
@@ -1026,5 +1093,8 @@ cat $rumpprotos >> $rumpcallshdr
#chmod 444 $sysnames $sysnumhdr $syssw
+cat $systracetmp >> $systrace
+cat $systraceret >> $systrace
+
echo Generated following files:
-echo $sysarghdr $sysnumhdr $syssw $sysnames $rumpcalls $rumpcallshdr $rumpsysmap
+echo $sysarghdr $sysnumhdr $syssw $sysnames $systrace $rumpcalls $rumpcallshdr $rumpsysmap
Index: src/sys/kern/syscalls.conf
diff -u src/sys/kern/syscalls.conf:1.21 src/sys/kern/syscalls.conf:1.22
--- src/sys/kern/syscalls.conf:1.21 Sat Aug 16 13:24:29 2014
+++ src/sys/kern/syscalls.conf Sat Mar 7 11:38:07 2015
@@ -1,8 +1,9 @@
-# $NetBSD: syscalls.conf,v 1.21 2014/08/16 17:24:29 apb Exp $
+# $NetBSD: syscalls.conf,v 1.22 2015/03/07 16:38:07 christos Exp $
sysnames="syscalls.c"
sysnumhdr="../sys/syscall.h"
syssw="init_sysent.c"
+systrace="systrace_args.c"
sysarghdr="../sys/syscallargs.h"
sysarghdrextra='#include <sys/mount.h>\n#ifndef RUMP_CLIENT\n#include <sys/sched.h>\n#endif\n#include <sys/socket.h>\n\n'
sysalign=1