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/48fc2bd6e43d
branches: trunk
changeset: 945089:48fc2bd6e43d
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 0b2f210e1a85 -r 48fc2bd6e43d 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 0b2f210e1a85 -r 48fc2bd6e43d 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