summaryrefslogtreecommitdiff
path: root/sys/arch/amd64
diff options
context:
space:
mode:
authormgorny <mgorny@NetBSD.org>2019-06-04 16:29:53 +0000
committermgorny <mgorny@NetBSD.org>2019-06-04 16:29:53 +0000
commitb98b74f8a435c19d49380c0673eb6523bad10617 (patch)
treecbfb4afe15acad70b638f0584f1dcadaa93a3fb1 /sys/arch/amd64
parent47857fd4cf4779bb36c06adc47137232fce37791 (diff)
compat32: Translate userland PT_* request values into kernel codes
Currently, the compat32 passes PT_* request values to kernel functions without translation. This works fine for low PT_* requests that happen to have the same values both on i386 and amd64. However, for requests higher than PT_SETFPREGS, the value passed from userland (matching i386 const) does not match the correct kernel (amd64) request. As a result, e.g. when compat32 process calls PT_GETDBREGS, kernel actually processes it as PT_SETSTEP. To resolve this, introduce support for compat32 PT_* request translation. The interface is based on PTRACE_TRANSLATE_REQUEST32 macro that is defined to a mapping function on architectures needing it. In case of amd64, this function maps userland i386 PT_* values into appropriate amd64 PT_* values. For the time being, the two additional PT_GETXMMREGS and PT_SETXMMREGS requests are unsupported due to lack of matching free amd64 constant.
Diffstat (limited to 'sys/arch/amd64')
-rw-r--r--sys/arch/amd64/amd64/netbsd32_machdep.c26
-rw-r--r--sys/arch/amd64/include/netbsd32_machdep.h21
-rw-r--r--sys/arch/amd64/include/ptrace.h4
3 files changed, 47 insertions, 4 deletions
diff --git a/sys/arch/amd64/amd64/netbsd32_machdep.c b/sys/arch/amd64/amd64/netbsd32_machdep.c
index 39d671a4b9b..6d71b176cbf 100644
--- a/sys/arch/amd64/amd64/netbsd32_machdep.c
+++ b/sys/arch/amd64/amd64/netbsd32_machdep.c
@@ -1,4 +1,4 @@
-/* $NetBSD: netbsd32_machdep.c,v 1.121 2019/05/19 08:46:15 maxv Exp $ */
+/* $NetBSD: netbsd32_machdep.c,v 1.122 2019/06/04 16:29:53 mgorny Exp $ */
/*
* Copyright (c) 2001 Wasabi Systems, Inc.
@@ -36,7 +36,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: netbsd32_machdep.c,v 1.121 2019/05/19 08:46:15 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: netbsd32_machdep.c,v 1.122 2019/06/04 16:29:53 mgorny Exp $");
#ifdef _KERNEL_OPT
#include "opt_compat_netbsd.h"
@@ -336,6 +336,28 @@ cpu_coredump32(struct lwp *l, struct coredump_iostate *iocookie,
#endif
int
+netbsd32_ptrace_translate_request(int req)
+{
+
+ switch (req)
+ {
+ case 0 ... PT_FIRSTMACH - 1: return req;
+ case PT32_STEP: return PT_STEP;
+ case PT32_GETREGS: return PT_GETREGS;
+ case PT32_SETREGS: return PT_SETREGS;
+ case PT32_GETFPREGS: return PT_GETFPREGS;
+ case PT32_SETFPREGS: return PT_SETFPREGS;
+ case PT32_GETXMMREGS: return -1;
+ case PT32_SETXMMREGS: return -1;
+ case PT32_GETDBREGS: return PT_GETDBREGS;
+ case PT32_SETDBREGS: return PT_SETDBREGS;
+ case PT32_SETSTEP: return PT_SETSTEP;
+ case PT32_CLEARSTEP: return PT_CLEARSTEP;
+ default: return -1;
+ }
+}
+
+int
netbsd32_process_read_regs(struct lwp *l, struct reg32 *regs)
{
struct trapframe *tf = l->l_md.md_regs;
diff --git a/sys/arch/amd64/include/netbsd32_machdep.h b/sys/arch/amd64/include/netbsd32_machdep.h
index 51691eb7c90..e7f018708c2 100644
--- a/sys/arch/amd64/include/netbsd32_machdep.h
+++ b/sys/arch/amd64/include/netbsd32_machdep.h
@@ -1,4 +1,4 @@
-/* $NetBSD: netbsd32_machdep.h,v 1.22 2017/02/23 03:34:22 kamil Exp $ */
+/* $NetBSD: netbsd32_machdep.h,v 1.23 2019/06/04 16:29:53 mgorny Exp $ */
#ifndef _MACHINE_NETBSD32_H_
#define _MACHINE_NETBSD32_H_
@@ -7,6 +7,22 @@
#include <compat/sys/ucontext.h>
#include <compat/sys/siginfo.h>
+/*
+ * i386 ptrace constants
+ * Please keep in sync with sys/arch/i386/include/ptrace.h.
+ */
+#define PT32_STEP (PT_FIRSTMACH + 0)
+#define PT32_GETREGS (PT_FIRSTMACH + 1)
+#define PT32_SETREGS (PT_FIRSTMACH + 2)
+#define PT32_GETFPREGS (PT_FIRSTMACH + 3)
+#define PT32_SETFPREGS (PT_FIRSTMACH + 4)
+#define PT32_GETXMMREGS (PT_FIRSTMACH + 5)
+#define PT32_SETXMMREGS (PT_FIRSTMACH + 6)
+#define PT32_GETDBREGS (PT_FIRSTMACH + 7)
+#define PT32_SETDBREGS (PT_FIRSTMACH + 8)
+#define PT32_SETSTEP (PT_FIRSTMACH + 9)
+#define PT32_CLEARSTEP (PT_FIRSTMACH + 10)
+
#define NETBSD32_POINTER_TYPE uint32_t
typedef struct { NETBSD32_POINTER_TYPE i32; } netbsd32_pointer_t;
@@ -151,6 +167,9 @@ struct x86_64_set_mtrr_args32 {
#define NETBSD32_MID_MACHINE MID_I386
+/* Translate ptrace() PT_* request from 32-bit userland to kernel. */
+int netbsd32_ptrace_translate_request(int);
+
int netbsd32_process_read_regs(struct lwp *, struct reg32 *);
int netbsd32_process_read_fpregs(struct lwp *, struct fpreg32 *, size_t *);
int netbsd32_process_read_dbregs(struct lwp *, struct dbreg32 *, size_t *);
diff --git a/sys/arch/amd64/include/ptrace.h b/sys/arch/amd64/include/ptrace.h
index c5cef941fd1..799f32ec775 100644
--- a/sys/arch/amd64/include/ptrace.h
+++ b/sys/arch/amd64/include/ptrace.h
@@ -1,4 +1,4 @@
-/* $NetBSD: ptrace.h,v 1.13 2019/02/07 00:19:54 kamil Exp $ */
+/* $NetBSD: ptrace.h,v 1.14 2019/06/04 16:29:53 mgorny Exp $ */
/*
* Copyright (c) 1993 Christopher G. Demetriou
@@ -87,6 +87,8 @@
#define process_reg32 struct reg32
#define process_fpreg32 struct fpreg32
#define process_dbreg32 struct dbreg32
+
+#define PTRACE_TRANSLATE_REQUEST32(x) netbsd32_ptrace_translate_request(x)
#endif /* COMPAT_NETBSD32 */
#endif /* _KERNEL_OPT */