In article <cakryomg6z8scuvmzqmfk+n09n+1xfniznc4fac59zxoaljo...@mail.gmail.com>,
Ryota Ozaki  <ozak...@netbsd.org> wrote:
>Anyway I updated my patches; they're based on latest -current.
>
>Changes since the previous are:
>- Remove an unexpected contribution comment from kern_dtrace.c
>  (thanks riastradh!)
>- Don't unload systrace.kmod when there are users using dtrace
>- Add "created from" line to *_systrace_args.c
>
>http://www.netbsd.org/~ozaki-r/systrace.diff
>http://www.netbsd.org/~ozaki-r/systrace-full.diff
>https://github.com/ozaki-r/netbsd-src/commits/dtrace-syscall-provider2

Thanks for working on this... I had done mostly the same, but with a few
differences:

        1. I named the module dtrace_systrace to match with the other
           dtrace modules.
        2. I did not create the args union to deal with signed/unsigned,
           chose to mimick what FreeBSD does. Do you prefer your way?
        3. I fixed the entry/exit probe functions to deal with the return
           value of the syscall, as well as the entry and exit argument
           descriptions.
        4. I am not sure if creating systrace_foo files in the emulations
           should be done right now, since we don't really load/use them.
           This should be a todo item, perhaps these functions should be
           the emulation structure and loaded with the emulation. But
           that should be phase II...
        5. I bumped the kernel because of struct sysent changes.

Anyway it works nicely, and I'd like to commit it if you don't mind
(or if you have any changes).

Thanks,

christos

Index: kern/Makefile
===================================================================
RCS file: /cvsroot/src/sys/kern/Makefile,v
retrieving revision 1.17
diff -u -u -r1.17 Makefile
--- kern/Makefile       16 Jan 2014 01:15:34 -0000      1.17
+++ kern/Makefile       6 Mar 2015 20:55:27 -0000
@@ -11,7 +11,7 @@
        @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: kern/makesyscalls.sh
===================================================================
RCS file: /cvsroot/src/sys/kern/makesyscalls.sh,v
retrieving revision 1.145
diff -u -u -r1.145 makesyscalls.sh
--- kern/makesyscalls.sh        24 Jul 2014 11:58:45 -0000      1.145
+++ kern/makesyscalls.sh        6 Mar 2015 20:55:28 -0000
@@ -61,6 +61,7 @@
 # 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 @@
 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 @@
        sysnumhdr = \"$sysnumhdr\"
        sysarghdr = \"$sysarghdr\"
        sysarghdrextra = \"$sysarghdrextra\"
+       systrace = \"$systrace\"
+       systracetmp = \"$systracetmp\"
+       systraceret = \"$systraceret\"
        rumpcalls = \"$rumpcalls\"
        rumpcallshdr = \"$rumpcallshdr\"
        rumpsysent = \"$rumpsysent\"
@@ -211,6 +217,10 @@
        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 @@
                "\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(int sysnum, void *params, uint64_t 
*uarg, int *n_args)\n{\n" > systrace
+       printf "\tint64_t *iarg  = (int64_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 @@
        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 @@
                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 +689,7 @@
                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
@@ -697,6 +721,40 @@
            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 (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 +766,7 @@
        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 +788,7 @@
        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
@@ -922,9 +981,9 @@
        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 +1048,9 @@
                        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 +1068,9 @@
        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 +1088,8 @@
 
 #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: sys/param.h
===================================================================
RCS file: /cvsroot/src/sys/sys/param.h,v
retrieving revision 1.465
diff -u -u -r1.465 param.h
--- sys/param.h 14 Feb 2015 12:59:02 -0000      1.465
+++ sys/param.h 6 Mar 2015 20:55:50 -0000
@@ -63,7 +63,7 @@
  *     2.99.9          (299000900)
  */
 
-#define        __NetBSD_Version__      799000500       /* NetBSD 7.99.5 */
+#define        __NetBSD_Version__      799000600       /* NetBSD 7.99.6 */
 
 #define __NetBSD_Prereq__(M,m,p) (((((M) * 100000000) + \
     (m) * 1000000) + (p) * 100) <= __NetBSD_Version__)
Index: sys/syscallvar.h
===================================================================
RCS file: /cvsroot/src/sys/sys/syscallvar.h,v
retrieving revision 1.9
diff -u -u -r1.9 syscallvar.h
--- sys/syscallvar.h    4 Mar 2014 03:24:03 -0000       1.9
+++ sys/syscallvar.h    6 Mar 2015 20:55:50 -0000
@@ -36,6 +36,10 @@
 #error nothing of interest to userspace here
 #endif
 
+#if defined(_KERNEL) && defined(_KERNEL_OPT)
+#include "opt_dtrace.h"
+#endif
+
 #include <sys/systm.h>
 #include <sys/proc.h>
 
@@ -72,6 +76,16 @@
            (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, 0);
+#endif
        if (__predict_true(!do_trace)
            || (error = trace_enter(code, uap, sy->sy_narg)) == 0) {
                rval[0] = 0;
@@ -85,6 +99,18 @@
                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, error ? -1 : rval[0]);
+#endif
+
        if (__predict_false(do_trace)) {
                trace_exit(code, rval, error);
        }
Index: sys/systm.h
===================================================================
RCS file: /cvsroot/src/sys/sys/systm.h,v
retrieving revision 1.266
diff -u -u -r1.266 systm.h
--- sys/systm.h 3 Aug 2014 12:49:32 -0000       1.266
+++ sys/systm.h 6 Mar 2015 20:55:50 -0000
@@ -57,6 +57,7 @@
 struct clockframe;
 struct lwp;
 struct proc;
+struct sysent;
 struct timeval;
 struct tty;
 struct uio;
@@ -115,11 +116,26 @@
 
 typedef int    sy_call_t(struct lwp *, const void *, register_t *);
 
+/* Used by the machine dependent syscall() code. */
+typedef        void (*systrace_probe_func_t)(uint32_t, int, const struct 
sysent *,
+    const void *, register_t);
+
+/*
+ * Used by loaded syscalls to convert arguments to a DTrace array
+ * of 64-bit arguments.
+ */
+typedef        void (*systrace_args_func_t)(int, void *, uint64_t *, 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;
+       uint32_t sy_entry;      /* DTrace entry ID for systrace. */
+       uint32_t sy_return;     /* DTrace return ID for systrace. */
 } sysent[];
 extern int nsysent;
 #if    BYTE_ORDER == BIG_ENDIAN
Index: dev/systrace/systrace.c
===================================================================
RCS file: /cvsroot/src/external/cddl/osnet/dev/systrace/systrace.c,v
retrieving revision 1.4
diff -u -u -r1.4 systrace.c
--- dev/systrace/systrace.c     12 Jan 2014 17:49:30 -0000      1.4
+++ dev/systrace/systrace.c     6 Mar 2015 21:00:41 -0000
@@ -169,7 +169,7 @@
 systrace_probe(u_int32_t id, int sysnum, struct sysent *se, void *params)
 {
        int             n_args  = 0;
-       union systrace_probe_args_un    uargs[SYS_MAXSYSARGS];
+       uint64_t        uargs[SYS_MAXSYSARGS];
 
        /*
         * Check if this syscall has an argument conversion function
@@ -191,8 +191,7 @@
                systrace_args(sysnum, params, uargs, &n_args);
 
        /* Process the probe using the converted argments. */
-       dtrace_probe(id, uargs[0].u, uargs[1].u, uargs[2].u, uargs[3].u,
-               uargs[4].u);
+       dtrace_probe(id, uargs[0], uargs[1], uargs[2], uargs[3], uargs[4]);
 }
 #endif
 
@@ -201,8 +200,12 @@
 {
        int sysnum = SYSTRACE_SYSNUM((uintptr_t)parg);
 
-       systrace_setargdesc(sysnum, desc->dtargd_ndx, desc->dtargd_native,
-           sizeof(desc->dtargd_native));
+       if (SYSTRACE_ISENTRY((uintptr_t)parg))
+               systrace_entry_setargdesc(sysnum, desc->dtargd_ndx, 
+                   desc->dtargd_native, sizeof(desc->dtargd_native));
+       else
+               systrace_return_setargdesc(sysnum, desc->dtargd_ndx, 
+                   desc->dtargd_native, sizeof(desc->dtargd_native));
 
        if (desc->dtargd_native[0] == '\0')
                desc->dtargd_ndx = DTRACE_ARGNONE;
@@ -371,8 +374,10 @@
                return 0;
 
        case MODULE_CMD_FINI:
-               systrace_unload();
-               return 0;
+               return systrace_unload();
+
+       case MODULE_CMD_AUTOUNLOAD:
+               return EBUSY;
 
        default:
                return ENOTTY;
Index: dist/uts/common/dtrace/dtrace.c
===================================================================
RCS file: /cvsroot/src/external/cddl/osnet/dist/uts/common/dtrace/dtrace.c,v
retrieving revision 1.29
diff -u -u -r1.29 dtrace.c
--- dist/uts/common/dtrace/dtrace.c     31 Jan 2015 13:36:29 -0000      1.29
+++ dist/uts/common/dtrace/dtrace.c     6 Mar 2015 21:00:43 -0000
@@ -7893,7 +7893,7 @@
  */
 dtrace_id_t
 dtrace_probe_lookup(dtrace_provider_id_t prid, char *mod,
-    char *func, char *name)
+    char *func, const char *name)
 {
        dtrace_probekey_t pkey;
        dtrace_id_t id;
@@ -7905,7 +7905,7 @@
        pkey.dtpk_mmatch = mod ? &dtrace_match_string : &dtrace_match_nul;
        pkey.dtpk_func = func;
        pkey.dtpk_fmatch = func ? &dtrace_match_string : &dtrace_match_nul;
-       pkey.dtpk_name = name;
+       pkey.dtpk_name = __UNCONST(name);
        pkey.dtpk_nmatch = name ? &dtrace_match_string : &dtrace_match_nul;
        pkey.dtpk_id = DTRACE_IDNONE;
 
Index: dist/uts/common/sys/dtrace.h
===================================================================
RCS file: /cvsroot/src/external/cddl/osnet/dist/uts/common/sys/dtrace.h,v
retrieving revision 1.10
diff -u -u -r1.10 dtrace.h
--- dist/uts/common/sys/dtrace.h        15 Mar 2014 08:00:19 -0000      1.10
+++ dist/uts/common/sys/dtrace.h        6 Mar 2015 21:00:43 -0000
@@ -2056,7 +2056,7 @@
 extern int dtrace_condense(dtrace_provider_id_t);
 extern void dtrace_invalidate(dtrace_provider_id_t);
 extern dtrace_id_t dtrace_probe_lookup(dtrace_provider_id_t, char *,
-    char *, char *);
+    char *, const char *);
 extern dtrace_id_t dtrace_probe_create(dtrace_provider_id_t, const char *,
     const char *, const char *, int, void *);
 extern void *dtrace_probe_arg(dtrace_provider_id_t, dtrace_id_t);

Reply via email to