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