Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys Basic register read/write functionality and lwp setting ...



details:   https://anonhg.NetBSD.org/src/rev/737fdfcedf72
branches:  trunk
changeset: 941418:737fdfcedf72
user:      christos <christos%NetBSD.org@localhost>
date:      Tue Oct 20 20:28:55 2020 +0000

description:
Basic register read/write functionality and lwp setting are always provided
by the kernel because they are needed by multiple things
(ptrace/procfs/coredump), so move them to sys_process_lwpstatus (this file
should be renamed to sys_process_common.c?)

diffstat:

 sys/kern/sys_process_lwpstatus.c |  219 ++++++++++++++++++++++++++++++++++++++-
 sys/kern/sys_ptrace_common.c     |  216 +--------------------------------------
 sys/sys/ptrace.h                 |   11 +-
 3 files changed, 229 insertions(+), 217 deletions(-)

diffs (truncated from 520 to 300 lines):

diff -r fa681564d8f4 -r 737fdfcedf72 sys/kern/sys_process_lwpstatus.c
--- a/sys/kern/sys_process_lwpstatus.c  Tue Oct 20 18:17:58 2020 +0000
+++ b/sys/kern/sys_process_lwpstatus.c  Tue Oct 20 20:28:55 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: sys_process_lwpstatus.c,v 1.1 2020/01/04 03:46:19 kamil Exp $  */
+/*     $NetBSD: sys_process_lwpstatus.c,v 1.2 2020/10/20 20:28:55 christos Exp $       */
 
 /*-
  * Copyright (c) 2019 The NetBSD Foundation, Inc.
@@ -27,7 +27,19 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sys_process_lwpstatus.c,v 1.1 2020/01/04 03:46:19 kamil Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sys_process_lwpstatus.c,v 1.2 2020/10/20 20:28:55 christos Exp $");
+
+#ifdef _KERNEL_OPT
+#include "opt_ptrace.h"
+#include "opt_ktrace.h"
+#include "opt_pax.h"
+#include "opt_compat_netbsd32.h"
+#endif
+
+#if defined(__HAVE_COMPAT_NETBSD32) && !defined(COMPAT_NETBSD32) \
+    && !defined(_RUMPKERNEL)
+#define COMPAT_NETBSD32
+#endif
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -35,6 +47,9 @@
 #include <sys/lwp.h>
 #include <sys/ptrace.h>
 
+#ifndef PTRACE_REGS_ALIGN
+#define PTRACE_REGS_ALIGN /* nothing */
+#endif
 
 void
 ptrace_read_lwpstatus(struct lwp *l, struct ptrace_lwpstatus *pls)
@@ -67,3 +82,203 @@
 
        ptrace_read_lwpstatus(l, pls);
 }
+
+int
+ptrace_update_lwp(struct proc *t, struct lwp **lt, lwpid_t lid)
+{
+       if (lid == 0 || lid == (*lt)->l_lid || t->p_nlwps == 1)
+               return 0;
+
+       mutex_enter(t->p_lock);
+       lwp_delref2(*lt);
+
+       *lt = lwp_find(t, lid);
+       if (*lt == NULL) {
+               mutex_exit(t->p_lock);
+               return ESRCH;
+       }
+
+       if ((*lt)->l_flag & LW_SYSTEM) {
+               mutex_exit(t->p_lock);
+               *lt = NULL;
+               return EINVAL;
+       }
+
+       lwp_addref(*lt);
+       mutex_exit(t->p_lock);
+
+       return 0;
+}
+
+int
+process_validfpregs(struct lwp *l)
+{
+
+#if defined(PT_SETFPREGS) || defined(PT_GETFPREGS)
+       return (l->l_flag & LW_SYSTEM) == 0;
+#else
+       return 0;
+#endif
+}
+
+int
+process_validregs(struct lwp *l)
+{
+
+#if defined(PT_SETREGS) || defined(PT_GETREGS)
+       return (l->l_flag & LW_SYSTEM) == 0;
+#else
+       return 0;
+#endif
+}
+
+int
+process_validdbregs(struct lwp *l)
+{
+
+#if defined(PT_SETDBREGS) || defined(PT_GETDBREGS)
+       return (l->l_flag & LW_SYSTEM) == 0;
+#else
+       return 0;
+#endif
+}
+
+#ifdef PT_REGISTERS
+static int
+proc_regio(struct lwp *l, struct uio *uio, size_t ks, ptrace_regrfunc_t r,
+    ptrace_regwfunc_t w)
+{
+       char buf[1024] PTRACE_REGS_ALIGN;
+       int error;
+       char *kv;
+       size_t kl;
+
+       if (ks > sizeof(buf))
+               return E2BIG;
+
+       if (uio->uio_offset < 0 || uio->uio_offset > (off_t)ks)
+               return EINVAL;
+
+       kv = buf + uio->uio_offset;
+       kl = ks - uio->uio_offset;
+
+       if (kl > uio->uio_resid)
+               kl = uio->uio_resid;
+
+       error = (*r)(l, buf, &ks);
+       if (error == 0)
+               error = uiomove(kv, kl, uio);
+       if (error == 0 && uio->uio_rw == UIO_WRITE) {
+               if (l->l_stat != LSSTOP)
+                       error = EBUSY;
+               else
+                       error = (*w)(l, buf, ks);
+       }
+
+       uio->uio_offset = 0;
+       return error;
+}
+#endif
+
+int
+process_doregs(struct lwp *curl /*tracer*/,
+    struct lwp *l /*traced*/,
+    struct uio *uio)
+{
+#if defined(PT_GETREGS) || defined(PT_SETREGS)
+       size_t s;
+       ptrace_regrfunc_t r;
+       ptrace_regwfunc_t w;
+
+#ifdef COMPAT_NETBSD32
+       const bool pk32 = (curl->l_proc->p_flag & PK_32) != 0;
+
+       if (__predict_false(pk32)) {
+               if ((l->l_proc->p_flag & PK_32) == 0) {
+                       // 32 bit tracer can't trace 64 bit process
+                       return EINVAL;
+               }
+               s = sizeof(process_reg32);
+               r = __FPTRCAST(ptrace_regrfunc_t, process_read_regs32);
+               w = __FPTRCAST(ptrace_regwfunc_t, process_write_regs32);
+       } else
+#endif
+       {
+               s = sizeof(struct reg);
+               r = __FPTRCAST(ptrace_regrfunc_t, process_read_regs);
+               w = __FPTRCAST(ptrace_regwfunc_t, process_write_regs);
+       }
+       return proc_regio(l, uio, s, r, w);
+#else
+       return EINVAL;
+#endif
+}
+
+int
+process_dofpregs(struct lwp *curl /*tracer*/,
+    struct lwp *l /*traced*/,
+    struct uio *uio)
+{
+#if defined(PT_GETFPREGS) || defined(PT_SETFPREGS)
+       size_t s;
+       ptrace_regrfunc_t r;
+       ptrace_regwfunc_t w;
+
+#ifdef COMPAT_NETBSD32
+       const bool pk32 = (curl->l_proc->p_flag & PK_32) != 0;
+
+       if (__predict_false(pk32)) {
+               if ((l->l_proc->p_flag & PK_32) == 0) {
+                       // 32 bit tracer can't trace 64 bit process
+                       return EINVAL;
+               }
+               s = sizeof(process_fpreg32);
+               r = (ptrace_regrfunc_t)process_read_fpregs32;
+               w = (ptrace_regwfunc_t)process_write_fpregs32;
+       } else
+#endif
+       {
+               s = sizeof(struct fpreg);
+               r = (ptrace_regrfunc_t)process_read_fpregs;
+               w = (ptrace_regwfunc_t)process_write_fpregs;
+       }
+       return proc_regio(l, uio, s, r, w);
+#else
+       return EINVAL;
+#endif
+}
+
+
+int
+process_dodbregs(struct lwp *curl /*tracer*/,
+    struct lwp *l /*traced*/,
+    struct uio *uio)
+{
+#if defined(PT_GETDBREGS) || defined(PT_SETDBREGS)
+       size_t s;
+       ptrace_regrfunc_t r;
+       ptrace_regwfunc_t w;
+
+#ifdef COMPAT_NETBSD32
+       const bool pk32 = (curl->l_proc->p_flag & PK_32) != 0;
+
+       if (__predict_false(pk32)) {
+               if ((l->l_proc->p_flag & PK_32) == 0) {
+                       // 32 bit tracer can't trace 64 bit process
+                       return EINVAL;
+               }
+               s = sizeof(process_dbreg32);
+               r = (ptrace_regrfunc_t)process_read_dbregs32;
+               w = (ptrace_regwfunc_t)process_write_dbregs32;
+       } else
+#endif
+       {
+               s = sizeof(struct dbreg);
+               r = (ptrace_regrfunc_t)process_read_dbregs;
+               w = (ptrace_regwfunc_t)process_write_dbregs;
+       }
+       return proc_regio(l, uio, s, r, w);
+#else
+       return EINVAL;
+#endif
+}
diff -r fa681564d8f4 -r 737fdfcedf72 sys/kern/sys_ptrace_common.c
--- a/sys/kern/sys_ptrace_common.c      Tue Oct 20 18:17:58 2020 +0000
+++ b/sys/kern/sys_ptrace_common.c      Tue Oct 20 20:28:55 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: sys_ptrace_common.c,v 1.86 2020/10/19 14:52:19 kamil Exp $     */
+/*     $NetBSD: sys_ptrace_common.c,v 1.87 2020/10/20 20:28:55 christos Exp $  */
 
 /*-
  * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
@@ -107,7 +107,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sys_ptrace_common.c,v 1.86 2020/10/19 14:52:19 kamil Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sys_ptrace_common.c,v 1.87 2020/10/20 20:28:55 christos Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_ptrace.h"
@@ -197,16 +197,6 @@
 # define case_PT_SETDBREGS
 #endif
 
-#if defined(PT_SETREGS) || defined(PT_GETREGS) || \
-    defined(PT_SETFPREGS) || defined(PT_GETFPREGS) || \
-    defined(PT_SETDBREGS) || defined(PT_GETDBREGS)
-# define PT_REGISTERS
-#endif
-
-#ifndef PTRACE_REGS_ALIGN
-#define PTRACE_REGS_ALIGN /* nothing */
-#endif
-
 static int
 ptrace_listener_cb(kauth_cred_t cred, kauth_action_t action, void *cookie,
     void *arg0, void *arg1, void *arg2, void *arg3)
@@ -554,33 +544,6 @@
        }
 }
 
-int
-ptrace_update_lwp(struct proc *t, struct lwp **lt, lwpid_t lid)
-{
-       if (lid == 0 || lid == (*lt)->l_lid || t->p_nlwps == 1)
-               return 0;
-
-       mutex_enter(t->p_lock);
-       lwp_delref2(*lt);
-
-       *lt = lwp_find(t, lid);
-       if (*lt == NULL) {
-               mutex_exit(t->p_lock);
-               return ESRCH;
-       }
-
-       if ((*lt)->l_flag & LW_SYSTEM) {
-               mutex_exit(t->p_lock);



Home | Main Index | Thread Index | Old Index