Module Name:    src
Committed By:   christos
Date:           Tue Oct 20 20:28:55 UTC 2020

Modified Files:
        src/sys/kern: sys_process_lwpstatus.c sys_ptrace_common.c
        src/sys/sys: ptrace.h

Log Message:
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?)


To generate a diff of this commit:
cvs rdiff -u -r1.1 -r1.2 src/sys/kern/sys_process_lwpstatus.c
cvs rdiff -u -r1.86 -r1.87 src/sys/kern/sys_ptrace_common.c
cvs rdiff -u -r1.71 -r1.72 src/sys/sys/ptrace.h

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/sys_process_lwpstatus.c
diff -u src/sys/kern/sys_process_lwpstatus.c:1.1 src/sys/kern/sys_process_lwpstatus.c:1.2
--- src/sys/kern/sys_process_lwpstatus.c:1.1	Fri Jan  3 22:46:19 2020
+++ src/sys/kern/sys_process_lwpstatus.c	Tue Oct 20 16:28:55 2020
@@ -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 @@ __KERNEL_RCSID(0, "$NetBSD: sys_process_
 #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 @@ process_read_lwpstatus(struct lwp *l, st
 
 	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
+}

Index: src/sys/kern/sys_ptrace_common.c
diff -u src/sys/kern/sys_ptrace_common.c:1.86 src/sys/kern/sys_ptrace_common.c:1.87
--- src/sys/kern/sys_ptrace_common.c:1.86	Mon Oct 19 10:52:19 2020
+++ src/sys/kern/sys_ptrace_common.c	Tue Oct 20 16:28:55 2020
@@ -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 @@ static kcondvar_t ptrace_cv;
 # 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 @@ ptrace_needs_hold(int req)
 	}
 }
 
-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;
-}
-
 static int
 ptrace_get_siginfo(struct proc *t, struct ptrace_methods *ptm, void *addr,
     size_t data)
@@ -1576,181 +1539,6 @@ out:
 	return error;
 }
 
-typedef int (*regrfunc_t)(struct lwp *, void *, size_t *);
-typedef int (*regwfunc_t)(struct lwp *, void *, size_t);
-
-#ifdef PT_REGISTERS
-static int
-proc_regio(struct lwp *l, struct uio *uio, size_t ks, regrfunc_t r,
-    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;
-	regrfunc_t r;
-	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(regrfunc_t, process_read_regs32);
-		w = __FPTRCAST(regwfunc_t, process_write_regs32);
-	} else
-#endif
-	{
-		s = sizeof(struct reg);
-		r = __FPTRCAST(regrfunc_t, process_read_regs);
-		w = __FPTRCAST(regwfunc_t, process_write_regs);
-	}
-	return proc_regio(l, uio, s, r, w);
-#else
-	return EINVAL;
-#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_dofpregs(struct lwp *curl /*tracer*/,
-    struct lwp *l /*traced*/,
-    struct uio *uio)
-{
-#if defined(PT_GETFPREGS) || defined(PT_SETFPREGS)
-	size_t s;
-	regrfunc_t r;
-	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 = (regrfunc_t)process_read_fpregs32;
-		w = (regwfunc_t)process_write_fpregs32;
-	} else
-#endif
-	{
-		s = sizeof(struct fpreg);
-		r = (regrfunc_t)process_read_fpregs;
-		w = (regwfunc_t)process_write_fpregs;
-	}
-	return proc_regio(l, uio, s, r, w);
-#else
-	return EINVAL;
-#endif
-}
-
-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_dodbregs(struct lwp *curl /*tracer*/,
-    struct lwp *l /*traced*/,
-    struct uio *uio)
-{
-#if defined(PT_GETDBREGS) || defined(PT_SETDBREGS)
-	size_t s;
-	regrfunc_t r;
-	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 = (regrfunc_t)process_read_dbregs32;
-		w = (regwfunc_t)process_write_dbregs32;
-	} else
-#endif
-	{
-		s = sizeof(struct dbreg);
-		r = (regrfunc_t)process_read_dbregs;
-		w = (regwfunc_t)process_write_dbregs;
-	}
-	return proc_regio(l, uio, s, r, w);
-#else
-	return EINVAL;
-#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
-}
-
 static int
 process_auxv_offset(struct proc *p, struct uio *uio)
 {

Index: src/sys/sys/ptrace.h
diff -u src/sys/sys/ptrace.h:1.71 src/sys/sys/ptrace.h:1.72
--- src/sys/sys/ptrace.h:1.71	Thu Oct 15 13:37:36 2020
+++ src/sys/sys/ptrace.h	Tue Oct 20 16:28:55 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: ptrace.h,v 1.71 2020/10/15 17:37:36 mgorny Exp $	*/
+/*	$NetBSD: ptrace.h,v 1.72 2020/10/20 20:28:55 christos Exp $	*/
 
 /*-
  * Copyright (c) 1984, 1993
@@ -345,6 +345,15 @@ int	ptrace_machdep_dorequest(struct lwp 
 #define FIX_SSTEP(p)
 #endif
 
+typedef int (*ptrace_regrfunc_t)(struct lwp *, void *, size_t *);
+typedef int (*ptrace_regwfunc_t)(struct lwp *, void *, size_t);
+
+#if defined(PT_SETREGS) || defined(PT_GETREGS) || \
+    defined(PT_SETFPREGS) || defined(PT_GETFPREGS) || \
+    defined(PT_SETDBREGS) || defined(PT_GETDBREGS)
+# define PT_REGISTERS
+#endif
+
 #else /* !_KERNEL */
 
 #include <sys/cdefs.h>

Reply via email to