As mentioned in the other thread here, I am trying to make ktrace output
working for netbsd32 emulated ktrace/kdump.

The patch below allows emulations to override the "msghdr" ktrace data
output by various variants of sendmsg/recvmsg. This is simmply done by
passing two new args to do_sys_sendmsg()/do_sys_recvmsg() and friends
which provide alternative  data to record in the ktrace record.

Since a full msgheader is not always conveniently available, it is also
possible to pass a NULL pointer and ~0U as size to skip this ktrace
record completely.

If passing NULL/0 as the new args, the native msghdr is output, which means
most callers simply needed adding "NULL, 0," in the argument list.

A few compat versions are missing here, but will be added before commit.

Any objections?

Martin
Index: compat/common/uipc_syscalls_43.c
===================================================================
RCS file: /cvsroot/src/sys/compat/common/uipc_syscalls_43.c,v
retrieving revision 1.46
diff -u -p -r1.46 uipc_syscalls_43.c
--- compat/common/uipc_syscalls_43.c    9 Nov 2014 17:48:07 -0000       1.46
+++ compat/common/uipc_syscalls_43.c    9 Sep 2016 07:54:37 -0000
@@ -216,7 +216,7 @@ compat_43_sys_recvmsg(struct lwp *l, con
        msg.msg_iov     = omsg.msg_iov;
        msg.msg_flags   = (SCARG(uap, flags) & MSG_USERFLAGS) | MSG_IOVUSRSPACE;
 
-       error = do_sys_recvmsg(l, SCARG(uap, s), &msg, &from,
+       error = do_sys_recvmsg(l, SCARG(uap, s), &msg, NULL, 0, &from,
            omsg.msg_accrights != NULL ? &control : NULL, retval);
        if (error != 0)
                return error;
@@ -361,7 +361,8 @@ compat_43_sys_sendmsg(struct lwp *l, con
        if (error != 0)
                goto bad;
 
-       return do_sys_sendmsg(l, SCARG(uap, s), &msg, SCARG(uap, flags), 
retval);
+       return do_sys_sendmsg(l, SCARG(uap, s), &msg, SCARG(uap, flags),
+           NULL, 0, retval);
 
     bad:
        if (nam != NULL)
Index: compat/linux/common/linux_socket.c
===================================================================
RCS file: /cvsroot/src/sys/compat/linux/common/linux_socket.c,v
retrieving revision 1.132
diff -u -p -r1.132 linux_socket.c
--- compat/linux/common/linux_socket.c  1 Aug 2016 03:15:30 -0000       1.132
+++ compat/linux/common/linux_socket.c  9 Sep 2016 07:54:37 -0000
@@ -428,7 +428,8 @@ linux_sys_sendto(struct lwp *l, const st
        aiov.iov_base = __UNCONST(SCARG(uap, msg));
        aiov.iov_len = SCARG(uap, len);
 
-       return do_sys_sendmsg(l, SCARG(uap, s), &msg, bflags, retval);
+       return do_sys_sendmsg(l, SCARG(uap, s), &msg, bflags,
+           NULL, 0, retval);
 }
 
 static void
@@ -617,7 +618,8 @@ linux_sys_sendmsg(struct lwp *l, const s
        }
 
 skipcmsg:
-       error = do_sys_sendmsg(l, SCARG(uap, s), &msg, bflags, retval);
+       error = do_sys_sendmsg(l, SCARG(uap, s), &msg, bflags,
+           NULL, 0, retval);
        /* Freed internally */
        ctl_mbuf = NULL;
 
@@ -779,7 +781,7 @@ linux_sys_recvmsg(struct lwp *l, const s
        }
        msg.msg_flags |= MSG_IOVUSRSPACE;
 
-       error = do_sys_recvmsg(l, SCARG(uap, s), &msg, &from,
+       error = do_sys_recvmsg(l, SCARG(uap, s), &msg, NULL, 0, &from,
            msg.msg_control != NULL ? &control : NULL, retval);
        if (error != 0)
                return error;
Index: compat/netbsd32/netbsd32_compat_43.c
===================================================================
RCS file: /cvsroot/src/sys/compat/netbsd32/netbsd32_compat_43.c,v
retrieving revision 1.53
diff -u -p -r1.53 netbsd32_compat_43.c
--- compat/netbsd32/netbsd32_compat_43.c        23 Apr 2010 23:05:40 -0000      
1.53
+++ compat/netbsd32/netbsd32_compat_43.c        9 Sep 2016 07:54:37 -0000
@@ -451,7 +451,7 @@ compat_43_netbsd32_orecvmsg(struct lwp *
        msg.msg_iov     = iov;
        msg.msg_flags   = SCARG(uap, flags) & MSG_USERFLAGS;
 
-       error = do_sys_recvmsg(l, SCARG(uap, s), &msg, &from,
+       error = do_sys_recvmsg(l, SCARG(uap, s), &msg, NULL, 0, &from,
            NETBSD32PTR64(omsg.msg_accrights) != NULL ? &control : NULL,
            retval);
        if (error != 0)
@@ -547,7 +547,8 @@ compat_43_netbsd32_osendmsg(struct lwp *
                goto out;
        }
 
-       error = do_sys_sendmsg(l, SCARG(uap, s), &msg, SCARG(uap, flags), 
retval);
+       error = do_sys_sendmsg(l, SCARG(uap, s), &msg, SCARG(uap, flags),
+           &omsg, sizeof(omsg), retval);
 
     out:
        if (iov != aiov)
Index: compat/netbsd32/netbsd32_socket.c
===================================================================
RCS file: /cvsroot/src/sys/compat/netbsd32/netbsd32_socket.c,v
retrieving revision 1.43
diff -u -p -r1.43 netbsd32_socket.c
--- compat/netbsd32/netbsd32_socket.c   8 Sep 2016 18:54:03 -0000       1.43
+++ compat/netbsd32/netbsd32_socket.c   9 Sep 2016 07:54:37 -0000
@@ -193,8 +193,8 @@ netbsd32_recvmsg(struct lwp *l, const st
        msg.msg_iov = iov;
        msg.msg_iovlen = msg32.msg_iovlen;
 
-       error = do_sys_recvmsg(l, SCARG(uap, s), &msg, &from,
-           msg.msg_control != NULL ? &control : NULL, retval);
+       error = do_sys_recvmsg(l, SCARG(uap, s), &msg, &msg32, sizeof(msg32),
+           &from, msg.msg_control != NULL ? &control : NULL, retval);
        if (error != 0)
                goto done;
 
@@ -367,7 +367,8 @@ netbsd32_sendmsg(struct lwp *l, const st
                goto out;
        msg.msg_iov = iov;
 
-       error = do_sys_sendmsg(l, SCARG(uap, s), &msg, SCARG(uap, flags), 
retval);
+       error = do_sys_sendmsg(l, SCARG(uap, s), &msg, SCARG(uap, flags),
+           &msg32, sizeof(msg32), retval);
        /* msg.msg_control freed by do_sys_sendmsg() */
 
        if (iov != aiov)
@@ -406,7 +407,8 @@ netbsd32_recvfrom(struct lwp *l, const s
        msg.msg_control = NULL;
        msg.msg_flags = SCARG(uap, flags) & MSG_USERFLAGS;
 
-       error = do_sys_recvmsg(l, SCARG(uap, s), &msg, &from, NULL, retval);
+       error = do_sys_recvmsg(l, SCARG(uap, s), &msg, NULL, ~0U,
+           &from, NULL, retval);
        if (error != 0)
                return error;
 
@@ -439,5 +441,6 @@ netbsd32_sendto(struct lwp *l, const str
        aiov.iov_base = SCARG_P32(uap, buf);    /* XXX kills const */
        aiov.iov_len = SCARG(uap, len);
        msg.msg_flags = 0;
-       return do_sys_sendmsg(l, SCARG(uap, s), &msg, SCARG(uap, flags), 
retval);
+       return do_sys_sendmsg(l, SCARG(uap, s), &msg, SCARG(uap, flags),
+           NULL, ~0U, retval);
 }
Index: kern/kern_ktrace.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_ktrace.c,v
retrieving revision 1.167
diff -u -p -r1.167 kern_ktrace.c
--- kern/kern_ktrace.c  7 Jul 2016 06:55:43 -0000       1.167
+++ kern/kern_ktrace.c  9 Sep 2016 07:54:37 -0000
@@ -938,7 +938,7 @@ ktruser(const char *id, void *addr, size
 }
 
 void
-ktr_kuser(const char *id, void *addr, size_t len)
+ktr_kuser(const char *id, const void *addr, size_t len)
 {
        struct ktrace_entry *kte;
        struct ktr_user *ktp;
Index: kern/uipc_syscalls.c
===================================================================
RCS file: /cvsroot/src/sys/kern/uipc_syscalls.c,v
retrieving revision 1.182
diff -u -p -r1.182 uipc_syscalls.c
--- kern/uipc_syscalls.c        7 Jul 2016 06:55:43 -0000       1.182
+++ kern/uipc_syscalls.c        9 Sep 2016 07:54:37 -0000
@@ -505,7 +505,8 @@ sys_sendto(struct lwp *l, const struct s
        msg.msg_flags = 0;
        aiov.iov_base = __UNCONST(SCARG(uap, buf)); /* XXXUNCONST kills const */
        aiov.iov_len = SCARG(uap, len);
-       return do_sys_sendmsg(l, SCARG(uap, s), &msg, SCARG(uap, flags), 
retval);
+       return do_sys_sendmsg(l, SCARG(uap, s), &msg, SCARG(uap, flags),
+           NULL, 0, retval);
 }
 
 int
@@ -525,12 +526,14 @@ sys_sendmsg(struct lwp *l, const struct 
                return (error);
 
        msg.msg_flags = MSG_IOVUSRSPACE;
-       return do_sys_sendmsg(l, SCARG(uap, s), &msg, SCARG(uap, flags), 
retval);
+       return do_sys_sendmsg(l, SCARG(uap, s), &msg, SCARG(uap, flags),
+           NULL, 0, retval);
 }
 
 static int
 do_sys_sendmsg_so(struct lwp *l, int s, struct socket *so, file_t *fp,
-    struct msghdr *mp, int flags, register_t *retsize)
+    struct msghdr *mp, int flags, const void *kthdr, size_t ktsize,
+    register_t *retsize)
 {
 
        struct iovec    aiov[UIO_SMALLIOV], *iov = aiov, *tiov, *ktriov = NULL;
@@ -540,7 +543,12 @@ do_sys_sendmsg_so(struct lwp *l, int s, 
        size_t          len, iovsz;
        int             i, error;
 
-       ktrkuser("msghdr", mp, sizeof *mp);
+       if (__predict_false(kthdr == NULL && ktsize == 0)) {
+               kthdr = mp;
+               ktsize = sizeof(*mp);
+       }
+       if (__predict_true(kthdr != NULL))
+               ktrkuser("msghdr", kthdr, ktsize);
 
        /* If the caller passed us stuff in mbufs, we must free them. */
        to = (mp->msg_flags & MSG_NAMEMBUF) ? mp->msg_name : NULL;
@@ -656,7 +664,7 @@ bad:
 
 int
 do_sys_sendmsg(struct lwp *l, int s, struct msghdr *mp, int flags,
-    register_t *retsize)
+    const void *kthdr, size_t ktsize, register_t *retsize)
 {
        int             error;
        struct socket   *so;
@@ -670,7 +678,8 @@ do_sys_sendmsg(struct lwp *l, int s, str
                        m_freem(mp->msg_control);
                return error;
        }
-       error = do_sys_sendmsg_so(l, s, so, fp, mp, flags, retsize);
+       error = do_sys_sendmsg_so(l, s, so, fp, mp, flags, kthdr, ktsize,
+           retsize);
        /* msg_name and msg_control freed */
        fd_putfile(s);
        return error;
@@ -701,7 +710,8 @@ sys_recvfrom(struct lwp *l, const struct
        msg.msg_control = NULL;
        msg.msg_flags = SCARG(uap, flags) & MSG_USERFLAGS;
 
-       error = do_sys_recvmsg(l, SCARG(uap, s), &msg, &from, NULL, retval);
+       error = do_sys_recvmsg(l, SCARG(uap, s), &msg, NULL, 0, &from,
+           NULL, retval);
        if (error != 0)
                return error;
 
@@ -731,7 +741,7 @@ sys_recvmsg(struct lwp *l, const struct 
 
        msg.msg_flags = (SCARG(uap, flags) & MSG_USERFLAGS) | MSG_IOVUSRSPACE;
 
-       error = do_sys_recvmsg(l, SCARG(uap, s), &msg, &from,
+       error = do_sys_recvmsg(l, SCARG(uap, s), &msg, NULL, 0, &from,
            msg.msg_control != NULL ? &control : NULL, retval);
        if (error != 0)
                return error;
@@ -786,7 +796,8 @@ sys_sendmmsg(struct lwp *l, const struct
 
                msg->msg_flags = flags;
 
-               error = do_sys_sendmsg_so(l, s, so, fp, msg, flags, retval);
+               error = do_sys_sendmsg_so(l, s, so, fp, msg, flags,
+                   &msg, sizeof(msg), retval);
                if (error)
                        break;
 
@@ -913,14 +924,20 @@ copyout_msg_control(struct lwp *l, struc
 
 static int
 do_sys_recvmsg_so(struct lwp *l, int s, struct socket *so, struct msghdr *mp,
-    struct mbuf **from, struct mbuf **control, register_t *retsize)
+    const void *ktrhdr, size_t ktsize, struct mbuf **from,
+    struct mbuf **control, register_t *retsize)
 {
        struct iovec    aiov[UIO_SMALLIOV], *iov = aiov, *tiov, *ktriov = NULL;
        struct uio      auio;
        size_t          len, iovsz;
        int             i, error;
 
-       ktrkuser("msghdr", mp, sizeof *mp);
+       if (__predict_false(ktrhdr == NULL && ktsize == 0)) {
+               ktrhdr = mp;
+               ktsize = sizeof *mp;
+       }
+       if (__predict_true(ktrhdr != NULL))
+               ktrkuser("msghdr", ktrhdr, ktsize);
 
        *from = NULL;
        if (control != NULL)
@@ -1002,15 +1019,17 @@ do_sys_recvmsg_so(struct lwp *l, int s, 
 
 
 int
-do_sys_recvmsg(struct lwp *l, int s, struct msghdr *mp, struct mbuf **from,
-    struct mbuf **control, register_t *retsize)
+do_sys_recvmsg(struct lwp *l, int s, struct msghdr *mp,
+    const void *ktrhdr, size_t ktrsize,
+    struct mbuf **from, struct mbuf **control, register_t *retsize)
 {
        int error;
        struct socket *so;
 
        if ((error = fd_getsock(s, &so)) != 0)
                return error;
-       error = do_sys_recvmsg_so(l, s, so, mp, from, control, retsize);
+       error = do_sys_recvmsg_so(l, s, so, mp, ktrhdr, ktrsize, from,
+           control, retsize);
        fd_putfile(s);
        return error;
 }
@@ -1064,7 +1083,7 @@ sys_recvmmsg(struct lwp *l, const struct
                        from = NULL;
                }
 
-               error = do_sys_recvmsg_so(l, s, so, msg, &from,
+               error = do_sys_recvmsg_so(l, s, so, msg, NULL, 0, &from,
                    msg->msg_control != NULL ? &control : NULL, retval);
                if (error) {
                        if (error == EAGAIN && dg > 0)
Index: sys/ktrace.h
===================================================================
RCS file: /cvsroot/src/sys/sys/ktrace.h,v
retrieving revision 1.63
diff -u -p -r1.63 ktrace.h
--- sys/ktrace.h        19 Mar 2016 17:04:12 -0000      1.63
+++ sys/ktrace.h        9 Sep 2016 07:54:37 -0000
@@ -296,7 +296,7 @@ void ktr_namei2(const char *, size_t, co
 void ktr_psig(int, sig_t, const sigset_t *, const ksiginfo_t *);
 void ktr_syscall(register_t, const register_t [], int);
 void ktr_sysret(register_t, int, register_t *);
-void ktr_kuser(const char *, void *, size_t);
+void ktr_kuser(const char *, const void *, size_t);
 void ktr_mib(const int *a , u_int b);
 void ktr_execarg(const void *, size_t);
 void ktr_execenv(const void *, size_t);
@@ -398,7 +398,7 @@ ktrsysret(register_t a, int b, register_
 }
 
 static inline void
-ktrkuser(const char *a, void *b, size_t c)
+ktrkuser(const char *a, const void *b, size_t c)
 {
        if (__predict_false(ktrace_on))
                ktr_kuser(a, b, c);
Index: sys/socketvar.h
===================================================================
RCS file: /cvsroot/src/sys/sys/socketvar.h,v
retrieving revision 1.140
diff -u -p -r1.140 socketvar.h
--- sys/socketvar.h     1 Jun 2016 04:15:54 -0000       1.140
+++ sys/socketvar.h     9 Sep 2016 07:54:37 -0000
@@ -351,9 +351,11 @@ void       free_control_mbuf(struct lwp *, str
 
 int    do_sys_getpeername(int, struct sockaddr *);
 int    do_sys_getsockname(int, struct sockaddr *);
-int    do_sys_sendmsg(struct lwp *, int, struct msghdr *, int, register_t *);
-int    do_sys_recvmsg(struct lwp *, int, struct msghdr *, struct mbuf **,
-           struct mbuf **, register_t *);
+int    do_sys_sendmsg(struct lwp *, int, struct msghdr *, int,
+           const void *, size_t, register_t *);
+int    do_sys_recvmsg(struct lwp *, int, struct msghdr *,
+           const void *, size_t,
+           struct mbuf **, struct mbuf **, register_t *);
 
 int    do_sys_bind(struct lwp *, int, struct sockaddr *);
 int    do_sys_connect(struct lwp *, int, struct sockaddr *);

Reply via email to