Module Name: src Committed By: skrll Date: Wed Oct 19 09:44:01 UTC 2016
Modified Files: src/distrib/sets/lists/modules: ad.arm ad.mips md.amd64 src/sys/arch/amd64/amd64: netbsd32_machdep.c src/sys/arch/amd64/include: netbsd32_machdep.h ptrace.h src/sys/arch/sparc64/include: netbsd32_machdep.h ptrace.h src/sys/arch/sparc64/sparc64: netbsd32_machdep.c src/sys/compat/netbsd32: files.netbsd32 netbsd32.h netbsd32_fs.c netbsd32_netbsd.c syscalls.master src/sys/kern: sys_process.c src/sys/modules: Makefile src/sys/sys: proc.h ptrace.h Added Files: src/sys/compat/netbsd32: netbsd32_ptrace.c src/sys/modules/compat_netbsd32_ptrace: Makefile Log Message: PR kern/51514: ptrace(2) fails for 32-bit process on 64-bit kernel Updated from the original patch in the PR by me. To generate a diff of this commit: cvs rdiff -u -r1.8 -r1.9 src/distrib/sets/lists/modules/ad.arm \ src/distrib/sets/lists/modules/ad.mips cvs rdiff -u -r1.69 -r1.70 src/distrib/sets/lists/modules/md.amd64 cvs rdiff -u -r1.96 -r1.97 src/sys/arch/amd64/amd64/netbsd32_machdep.c cvs rdiff -u -r1.19 -r1.20 src/sys/arch/amd64/include/netbsd32_machdep.h cvs rdiff -u -r1.6 -r1.7 src/sys/arch/amd64/include/ptrace.h cvs rdiff -u -r1.28 -r1.29 src/sys/arch/sparc64/include/netbsd32_machdep.h cvs rdiff -u -r1.4 -r1.5 src/sys/arch/sparc64/include/ptrace.h cvs rdiff -u -r1.109 -r1.110 src/sys/arch/sparc64/sparc64/netbsd32_machdep.c cvs rdiff -u -r1.38 -r1.39 src/sys/compat/netbsd32/files.netbsd32 cvs rdiff -u -r1.112 -r1.113 src/sys/compat/netbsd32/netbsd32.h cvs rdiff -u -r1.75 -r1.76 src/sys/compat/netbsd32/netbsd32_fs.c cvs rdiff -u -r1.204 -r1.205 src/sys/compat/netbsd32/netbsd32_netbsd.c cvs rdiff -u -r0 -r1.1 src/sys/compat/netbsd32/netbsd32_ptrace.c cvs rdiff -u -r1.114 -r1.115 src/sys/compat/netbsd32/syscalls.master cvs rdiff -u -r1.173 -r1.174 src/sys/kern/sys_process.c cvs rdiff -u -r1.180 -r1.181 src/sys/modules/Makefile cvs rdiff -u -r0 -r1.1 src/sys/modules/compat_netbsd32_ptrace/Makefile cvs rdiff -u -r1.334 -r1.335 src/sys/sys/proc.h cvs rdiff -u -r1.46 -r1.47 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/distrib/sets/lists/modules/ad.arm diff -u src/distrib/sets/lists/modules/ad.arm:1.8 src/distrib/sets/lists/modules/ad.arm:1.9 --- src/distrib/sets/lists/modules/ad.arm:1.8 Thu Dec 3 10:38:21 2015 +++ src/distrib/sets/lists/modules/ad.arm Wed Oct 19 09:44:00 2016 @@ -1,9 +1,11 @@ -# $NetBSD: ad.arm,v 1.8 2015/12/03 10:38:21 pgoyette Exp $ +# $NetBSD: ad.arm,v 1.9 2016/10/19 09:44:00 skrll Exp $ ./@MODULEDIR@/compat_netbsd32 base-kernel-modules kmod ./@MODULEDIR@/compat_netbsd32/compat_netbsd32.kmod base-kernel-modules kmod ./@MODULEDIR@/compat_netbsd32_mqueue base-kernel-modules kmod ./@MODULEDIR@/compat_netbsd32_mqueue/compat_netbsd32_mqueue.kmod base-kernel-modules kmod +./@MODULEDIR@/compat_netbsd32_ptrace base-kernel-modules kmod +./@MODULEDIR@/compat_netbsd32_ptrace/compat_netbsd32_ptrace.kmod base-kernel-modules kmod ./@MODULEDIR@/compat_netbsd32_nfssrv base-kernel-modules kmod ./@MODULEDIR@/compat_netbsd32_nfssrv/compat_netbsd32_nfssrv.kmod base-kernel-modules kmod ./@MODULEDIR@/compat_netbsd32_sysvipc base-kernel-modules kmod Index: src/distrib/sets/lists/modules/ad.mips diff -u src/distrib/sets/lists/modules/ad.mips:1.8 src/distrib/sets/lists/modules/ad.mips:1.9 --- src/distrib/sets/lists/modules/ad.mips:1.8 Thu Dec 3 10:38:21 2015 +++ src/distrib/sets/lists/modules/ad.mips Wed Oct 19 09:44:00 2016 @@ -1,8 +1,10 @@ -# $NetBSD: ad.mips,v 1.8 2015/12/03 10:38:21 pgoyette Exp $ +# $NetBSD: ad.mips,v 1.9 2016/10/19 09:44:00 skrll Exp $ ./@MODULEDIR@/compat_netbsd32 base-kernel-modules kmod,arch64,nocompatmodules ./@MODULEDIR@/compat_netbsd32/compat_netbsd32.kmod base-kernel-modules kmod,arch64,nocompatmodules ./@MODULEDIR@/compat_netbsd32_mqueue base-kernel-modules kmod,arch64,nocompatmodules ./@MODULEDIR@/compat_netbsd32_mqueue/compat_netbsd32_mqueue.kmod base-kernel-modules kmod,arch64,nocompatmodules +./@MODULEDIR@/compat_netbsd32_ptrace base-kernel-modules kmod,arch64,nocompatmodules +./@MODULEDIR@/compat_netbsd32_ptrace/compat_netbsd32_ptrace.kmod base-kernel-modules kmod,arch64,nocompatmodules ./@MODULEDIR@/compat_netbsd32_nfssrv base-kernel-modules kmod,arch64,nocompatmodules ./@MODULEDIR@/compat_netbsd32_nfssrv/compat_netbsd32_nfssrv.kmod base-kernel-modules kmod,arch64,nocompatmodules ./@MODULEDIR@/compat_netbsd32_sysvipc base-kernel-modules kmod,arch64,nocompatmodules Index: src/distrib/sets/lists/modules/md.amd64 diff -u src/distrib/sets/lists/modules/md.amd64:1.69 src/distrib/sets/lists/modules/md.amd64:1.70 --- src/distrib/sets/lists/modules/md.amd64:1.69 Tue Sep 27 20:52:43 2016 +++ src/distrib/sets/lists/modules/md.amd64 Wed Oct 19 09:44:00 2016 @@ -1,4 +1,4 @@ -# $NetBSD: md.amd64,v 1.69 2016/09/27 20:52:43 pgoyette Exp $ +# $NetBSD: md.amd64,v 1.70 2016/10/19 09:44:00 skrll Exp $ # # NOTE that there are two sets of files here: # @MODULEDIR@ and amd64-xen @@ -53,6 +53,8 @@ ./@MODULEDIR@/compat_netbsd32/compat_netbsd32.kmod base-kernel-modules kmod ./@MODULEDIR@/compat_netbsd32_mqueue base-kernel-modules kmod ./@MODULEDIR@/compat_netbsd32_mqueue/compat_netbsd32_mqueue.kmod base-kernel-modules kmod +./@MODULEDIR@/compat_netbsd32_ptrace base-kernel-modules kmod +./@MODULEDIR@/compat_netbsd32_ptrace/compat_netbsd32_ptrace.kmod base-kernel-modules kmod ./@MODULEDIR@/compat_netbsd32_nfssrv base-kernel-modules kmod ./@MODULEDIR@/compat_netbsd32_nfssrv/compat_netbsd32_nfssrv.kmod base-kernel-modules kmod ./@MODULEDIR@/compat_netbsd32_sysvipc base-kernel-modules kmod Index: src/sys/arch/amd64/amd64/netbsd32_machdep.c diff -u src/sys/arch/amd64/amd64/netbsd32_machdep.c:1.96 src/sys/arch/amd64/amd64/netbsd32_machdep.c:1.97 --- src/sys/arch/amd64/amd64/netbsd32_machdep.c:1.96 Fri Sep 2 07:51:05 2016 +++ src/sys/arch/amd64/amd64/netbsd32_machdep.c Wed Oct 19 09:44:00 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: netbsd32_machdep.c,v 1.96 2016/09/02 07:51:05 maxv Exp $ */ +/* $NetBSD: netbsd32_machdep.c,v 1.97 2016/10/19 09:44:00 skrll Exp $ */ /* * Copyright (c) 2001 Wasabi Systems, Inc. @@ -36,7 +36,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: netbsd32_machdep.c,v 1.96 2016/09/02 07:51:05 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: netbsd32_machdep.c,v 1.97 2016/10/19 09:44:00 skrll Exp $"); #ifdef _KERNEL_OPT #include "opt_compat_netbsd.h" @@ -487,12 +487,12 @@ netbsd32_process_read_regs(struct lwp *l { struct trapframe *tf = l->l_md.md_regs; - regs->r_gs = LSEL(LUCODE32_SEL, SEL_UPL); - regs->r_fs = LSEL(LUCODE32_SEL, SEL_UPL); - regs->r_es = LSEL(LUCODE32_SEL, SEL_UPL); - regs->r_ds = LSEL(LUCODE32_SEL, SEL_UPL); - regs->r_eflags = tf->tf_rflags; /* XXX avoid sign extension problems with unknown upper bits? */ + regs->r_gs = tf->tf_gs & 0xffff; + regs->r_fs = tf->tf_fs & 0xffff; + regs->r_es = tf->tf_es & 0xffff; + regs->r_ds = tf->tf_ds & 0xffff; + regs->r_eflags = tf->tf_rflags; regs->r_edi = tf->tf_rdi & 0xffffffff; regs->r_esi = tf->tf_rsi & 0xffffffff; regs->r_ebp = tf->tf_rbp & 0xffffffff; @@ -501,9 +501,9 @@ netbsd32_process_read_regs(struct lwp *l regs->r_ecx = tf->tf_rcx & 0xffffffff; regs->r_eax = tf->tf_rax & 0xffffffff; regs->r_eip = tf->tf_rip & 0xffffffff; - regs->r_cs = tf->tf_cs; + regs->r_cs = tf->tf_cs & 0xffff; regs->r_esp = tf->tf_rsp & 0xffffffff; - regs->r_ss = tf->tf_ss; + regs->r_ss = tf->tf_ss & 0xffff; return (0); } @@ -511,22 +511,52 @@ netbsd32_process_read_regs(struct lwp *l int netbsd32_process_read_fpregs(struct lwp *l, struct fpreg32 *regs, size_t *sz) { - struct fpreg regs64; - int error; - size_t fp_size; + + __CTASSERT(sizeof *regs == sizeof (struct save87)); + process_read_fpregs_s87(l, (struct save87 *)regs); + return 0; +} + +int +netbsd32_process_write_regs(struct lwp *l, const struct reg32 *regs) +{ + struct trapframe *tf = l->l_md.md_regs; /* - * All that stuff makes no sense in i386 code :( + * Check for security violations. Taken from i386/process_machdep.c. */ + if (((regs->r_eflags ^ tf->tf_rflags) & PSL_USERSTATIC) != 0 || + !VALID_USER_CSEL32(regs->r_cs)) + return EINVAL; - fp_size = sizeof regs64; - error = process_read_fpregs(l, ®s64, &fp_size); - if (error) - return error; - __CTASSERT(sizeof *regs == sizeof (struct save87)); - process_xmm_to_s87(®s64.fxstate, (struct save87 *)regs); + tf->tf_rax = regs->r_eax; + tf->tf_rcx = regs->r_ecx; + tf->tf_rdx = regs->r_edx; + tf->tf_rbx = regs->r_ebx; + tf->tf_rsp = regs->r_esp; + tf->tf_rbp = regs->r_ebp; + tf->tf_rsi = regs->r_esi; + tf->tf_rdi = regs->r_edi; + tf->tf_rip = regs->r_eip; + tf->tf_rflags = regs->r_eflags; + tf->tf_cs = regs->r_cs; + tf->tf_ss = regs->r_ss; + tf->tf_ds = regs->r_ds; + tf->tf_es = regs->r_es; + tf->tf_fs = regs->r_fs; + tf->tf_gs = regs->r_gs; - return (0); + return 0; +} + +int +netbsd32_process_write_fpregs(struct lwp *l, const struct fpreg32 *regs, + size_t sz) +{ + + __CTASSERT(sizeof *regs == sizeof (struct save87)); + process_write_fpregs_s87(l, (const struct save87 *)regs); + return 0; } int Index: src/sys/arch/amd64/include/netbsd32_machdep.h diff -u src/sys/arch/amd64/include/netbsd32_machdep.h:1.19 src/sys/arch/amd64/include/netbsd32_machdep.h:1.20 --- src/sys/arch/amd64/include/netbsd32_machdep.h:1.19 Fri Feb 7 22:40:22 2014 +++ src/sys/arch/amd64/include/netbsd32_machdep.h Wed Oct 19 09:44:00 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: netbsd32_machdep.h,v 1.19 2014/02/07 22:40:22 dsl Exp $ */ +/* $NetBSD: netbsd32_machdep.h,v 1.20 2016/10/19 09:44:00 skrll Exp $ */ #ifndef _MACHINE_NETBSD32_H_ #define _MACHINE_NETBSD32_H_ @@ -138,4 +138,7 @@ struct x86_64_set_mtrr_args32 { int netbsd32_process_read_regs(struct lwp *, struct reg32 *); int netbsd32_process_read_fpregs(struct lwp *, struct fpreg32 *, size_t *); +int netbsd32_process_write_regs(struct lwp *, const struct reg32 *); +int netbsd32_process_write_fpregs(struct lwp *, const struct fpreg32 *, size_t); + #endif /* _MACHINE_NETBSD32_H_ */ Index: src/sys/arch/amd64/include/ptrace.h diff -u src/sys/arch/amd64/include/ptrace.h:1.6 src/sys/arch/amd64/include/ptrace.h:1.7 --- src/sys/arch/amd64/include/ptrace.h:1.6 Fri Sep 25 16:05:17 2015 +++ src/sys/arch/amd64/include/ptrace.h Wed Oct 19 09:44:00 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: ptrace.h,v 1.6 2015/09/25 16:05:17 christos Exp $ */ +/* $NetBSD: ptrace.h,v 1.7 2016/10/19 09:44:00 skrll Exp $ */ /* * Copyright (c) 1993 Christopher G. Demetriou @@ -68,6 +68,9 @@ #define process_read_regs32 netbsd32_process_read_regs #define process_read_fpregs32 netbsd32_process_read_fpregs +#define process_write_regs32 netbsd32_process_write_regs +#define process_write_fpregs32 netbsd32_process_write_fpregs + #define process_reg32 struct reg32 #define process_fpreg32 struct fpreg32 #endif /* COMPAT_NETBSD32 */ Index: src/sys/arch/sparc64/include/netbsd32_machdep.h diff -u src/sys/arch/sparc64/include/netbsd32_machdep.h:1.28 src/sys/arch/sparc64/include/netbsd32_machdep.h:1.29 --- src/sys/arch/sparc64/include/netbsd32_machdep.h:1.28 Sat Jan 4 00:10:03 2014 +++ src/sys/arch/sparc64/include/netbsd32_machdep.h Wed Oct 19 09:44:00 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: netbsd32_machdep.h,v 1.28 2014/01/04 00:10:03 dsl Exp $ */ +/* $NetBSD: netbsd32_machdep.h,v 1.29 2016/10/19 09:44:00 skrll Exp $ */ /* * Copyright (c) 1998, 2001 Matthew R. Green @@ -79,4 +79,7 @@ int netbsd32_md_ioctl(struct file *, net int netbsd32_process_read_regs(struct lwp *, struct reg32 *); int netbsd32_process_read_fpregs(struct lwp *, struct fpreg32 *, size_t *); +int netbsd32_process_write_regs(struct lwp *, const struct reg32 *); +int netbsd32_process_write_fpregs(struct lwp *, const struct fpreg32 *, size_t); + #endif /* _MACHINE_NETBSD32_H_ */ Index: src/sys/arch/sparc64/include/ptrace.h diff -u src/sys/arch/sparc64/include/ptrace.h:1.4 src/sys/arch/sparc64/include/ptrace.h:1.5 --- src/sys/arch/sparc64/include/ptrace.h:1.4 Wed Sep 28 11:44:16 2016 +++ src/sys/arch/sparc64/include/ptrace.h Wed Oct 19 09:44:00 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: ptrace.h,v 1.4 2016/09/28 11:44:16 skrll Exp $ */ +/* $NetBSD: ptrace.h,v 1.5 2016/10/19 09:44:00 skrll Exp $ */ #include <sparc/ptrace.h> @@ -11,6 +11,9 @@ #define process_read_regs32 netbsd32_process_read_regs #define process_read_fpregs32 netbsd32_process_read_fpregs +#define process_write_regs32 netbsd32_process_write_regs +#define process_write_fpregs32 netbsd32_process_write_fpregs + #define process_reg32 struct reg32 #define process_fpreg32 struct fpreg32 #endif Index: src/sys/arch/sparc64/sparc64/netbsd32_machdep.c diff -u src/sys/arch/sparc64/sparc64/netbsd32_machdep.c:1.109 src/sys/arch/sparc64/sparc64/netbsd32_machdep.c:1.110 --- src/sys/arch/sparc64/sparc64/netbsd32_machdep.c:1.109 Thu Nov 26 13:15:34 2015 +++ src/sys/arch/sparc64/sparc64/netbsd32_machdep.c Wed Oct 19 09:44:01 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: netbsd32_machdep.c,v 1.109 2015/11/26 13:15:34 martin Exp $ */ +/* $NetBSD: netbsd32_machdep.c,v 1.110 2016/10/19 09:44:01 skrll Exp $ */ /* * Copyright (c) 1998, 2001 Matthew R. Green @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: netbsd32_machdep.c,v 1.109 2015/11/26 13:15:34 martin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: netbsd32_machdep.c,v 1.110 2016/10/19 09:44:01 skrll Exp $"); #ifdef _KERNEL_OPT #include "opt_compat_netbsd.h" @@ -624,16 +624,15 @@ netbsd32_process_read_regs(struct lwp *l return (0); } -#if 0 int netbsd32_process_write_regs(struct lwp *l, const struct reg32 *regs) { - struct trapframe64* tf = p->p_md.md_tf; + struct trapframe64* tf = l->l_md.md_tf; int i; tf->tf_pc = regs->r_pc; tf->tf_npc = regs->r_npc; - tf->tf_y = regs->r_pc; + tf->tf_y = regs->r_y; for (i = 0; i < 8; i++) { tf->tf_global[i] = regs->r_global[i]; tf->tf_out[i] = regs->r_out[i]; @@ -643,7 +642,6 @@ netbsd32_process_write_regs(struct lwp * PSRCC_TO_TSTATE(regs->r_psr); return (0); } -#endif int netbsd32_process_read_fpregs(struct lwp *l, struct fpreg32 *regs, size_t *sz) @@ -661,9 +659,9 @@ netbsd32_process_read_fpregs(struct lwp return 0; } -#if 0 int -netbsd32_process_write_fpregs(struct lwp *l, const struct fpreg32 *regs) +netbsd32_process_write_fpregs(struct lwp *l, const struct fpreg32 *regs, + size_t sz) { struct fpstate64 *statep; int i; @@ -678,7 +676,6 @@ netbsd32_process_write_fpregs(struct lwp return 0; } -#endif /* * 32-bit version of cpu_coredump. Index: src/sys/compat/netbsd32/files.netbsd32 diff -u src/sys/compat/netbsd32/files.netbsd32:1.38 src/sys/compat/netbsd32/files.netbsd32:1.39 --- src/sys/compat/netbsd32/files.netbsd32:1.38 Thu Dec 3 11:25:45 2015 +++ src/sys/compat/netbsd32/files.netbsd32 Wed Oct 19 09:44:01 2016 @@ -1,4 +1,4 @@ -# $NetBSD: files.netbsd32,v 1.38 2015/12/03 11:25:45 pgoyette Exp $ +# $NetBSD: files.netbsd32,v 1.39 2016/10/19 09:44:01 skrll Exp $ # # config file description for machine-independent netbsd32 compat code. # included by ports that need it. @@ -21,6 +21,7 @@ file compat/netbsd32/netbsd32_module.c c file compat/netbsd32/netbsd32_mod.c compat_netbsd32 file compat/netbsd32/netbsd32_mqueue.c compat_netbsd32 & mqueue file compat/netbsd32/netbsd32_nfssvc.c compat_netbsd32 & nfsserver +file compat/netbsd32/netbsd32_ptrace.c compat_netbsd32 & ptrace file compat/netbsd32/netbsd32_select.c compat_netbsd32 file compat/netbsd32/netbsd32_sem.c compat_netbsd32 file compat/netbsd32/netbsd32_signal.c compat_netbsd32 Index: src/sys/compat/netbsd32/netbsd32.h diff -u src/sys/compat/netbsd32/netbsd32.h:1.112 src/sys/compat/netbsd32/netbsd32.h:1.113 --- src/sys/compat/netbsd32/netbsd32.h:1.112 Fri Sep 23 14:16:32 2016 +++ src/sys/compat/netbsd32/netbsd32.h Wed Oct 19 09:44:01 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: netbsd32.h,v 1.112 2016/09/23 14:16:32 skrll Exp $ */ +/* $NetBSD: netbsd32.h,v 1.113 2016/10/19 09:44:01 skrll Exp $ */ /* * Copyright (c) 1998, 2001, 2008, 2015 Matthew R. Green @@ -282,6 +282,16 @@ struct netbsd32_export_args30 { /* from <sys/poll.h> */ typedef netbsd32_pointer_t netbsd32_pollfdp_t; +/* from <sys/ptrace.h> */ +typedef netbsd32_pointer_t netbsd32_ptrace_io_descp_t; +struct netbsd32_ptrace_io_desc { + int piod_op; /* I/O operation */ + netbsd32_voidp piod_offs; /* child offset */ + netbsd32_voidp piod_addr; /* parent offset */ + netbsd32_size_t piod_len; /* request length (in) / + actual count (out) */ +}; + /* from <sys/quotactl.h> */ typedef netbsd32_pointer_t netbsd32_quotactlargsp_t; struct netbsd32_quotactlargs { Index: src/sys/compat/netbsd32/netbsd32_fs.c diff -u src/sys/compat/netbsd32/netbsd32_fs.c:1.75 src/sys/compat/netbsd32/netbsd32_fs.c:1.76 --- src/sys/compat/netbsd32/netbsd32_fs.c:1.75 Sun Oct 16 20:09:53 2016 +++ src/sys/compat/netbsd32/netbsd32_fs.c Wed Oct 19 09:44:01 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: netbsd32_fs.c,v 1.75 2016/10/16 20:09:53 dholland Exp $ */ +/* $NetBSD: netbsd32_fs.c,v 1.76 2016/10/19 09:44:01 skrll Exp $ */ /* * Copyright (c) 1998, 2001 Matthew R. Green @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: netbsd32_fs.c,v 1.75 2016/10/16 20:09:53 dholland Exp $"); +__KERNEL_RCSID(0, "$NetBSD: netbsd32_fs.c,v 1.76 2016/10/19 09:44:01 skrll Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -519,6 +519,7 @@ netbsd32___getdents30(struct lwp *l, } error = vn_readdir(fp, SCARG_P32(uap, buf), UIO_USERSPACE, SCARG(uap, count), &done, l, 0, 0); + ktrgenio(SCARG(uap, fd), UIO_READ, SCARG_P32(uap, buf), done, error); *retval = done; out: fd_putfile(SCARG(uap, fd)); Index: src/sys/compat/netbsd32/netbsd32_netbsd.c diff -u src/sys/compat/netbsd32/netbsd32_netbsd.c:1.204 src/sys/compat/netbsd32/netbsd32_netbsd.c:1.205 --- src/sys/compat/netbsd32/netbsd32_netbsd.c:1.204 Sat Sep 17 02:44:38 2016 +++ src/sys/compat/netbsd32/netbsd32_netbsd.c Wed Oct 19 09:44:01 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: netbsd32_netbsd.c,v 1.204 2016/09/17 02:44:38 christos Exp $ */ +/* $NetBSD: netbsd32_netbsd.c,v 1.205 2016/10/19 09:44:01 skrll Exp $ */ /* * Copyright (c) 1998, 2001, 2008 Matthew R. Green @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: netbsd32_netbsd.c,v 1.204 2016/09/17 02:44:38 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: netbsd32_netbsd.c,v 1.205 2016/10/19 09:44:01 skrll Exp $"); #if defined(_KERNEL_OPT) #include "opt_ddb.h" @@ -406,25 +406,6 @@ netbsd32_setuid(struct lwp *l, const str } int -netbsd32_ptrace(struct lwp *l, const struct netbsd32_ptrace_args *uap, register_t *retval) -{ - /* { - syscallarg(int) req; - syscallarg(pid_t) pid; - syscallarg(netbsd32_voidp) addr; - syscallarg(int) data; - } */ - struct sys_ptrace_args ua; - - NETBSD32TO64_UAP(req); - NETBSD32TO64_UAP(pid); - NETBSD32TOP_UAP(addr, void *); - NETBSD32TO64_UAP(data); - - return (*sysent[SYS_ptrace].sy_call)(l, &ua, retval); -} - -int netbsd32_accept(struct lwp *l, const struct netbsd32_accept_args *uap, register_t *retval) { /* { Index: src/sys/compat/netbsd32/syscalls.master diff -u src/sys/compat/netbsd32/syscalls.master:1.114 src/sys/compat/netbsd32/syscalls.master:1.115 --- src/sys/compat/netbsd32/syscalls.master:1.114 Fri Sep 23 14:10:28 2016 +++ src/sys/compat/netbsd32/syscalls.master Wed Oct 19 09:44:01 2016 @@ -1,4 +1,4 @@ - $NetBSD: syscalls.master,v 1.114 2016/09/23 14:10:28 skrll Exp $ + $NetBSD: syscalls.master,v 1.115 2016/10/19 09:44:01 skrll Exp $ ; from: NetBSD: syscalls.master,v 1.81 1998/07/05 08:49:50 jonathan Exp ; @(#)syscalls.master 8.2 (Berkeley) 1/13/94 @@ -99,7 +99,8 @@ 23 STD { int|netbsd32||setuid(uid_t uid); } 24 NOARGS { uid_t|sys||getuid(void); } 25 NOARGS { uid_t|sys||geteuid(void); } -26 STD { int|netbsd32||ptrace(int req, pid_t pid, \ +26 STD MODULAR compat_netbsd32_ptrace \ + { int|netbsd32||ptrace(int req, pid_t pid, \ netbsd32_voidp addr, int data); } 27 STD { netbsd32_ssize_t|netbsd32||recvmsg(int s, \ netbsd32_msghdrp_t msg, int flags); } Index: src/sys/kern/sys_process.c diff -u src/sys/kern/sys_process.c:1.173 src/sys/kern/sys_process.c:1.174 --- src/sys/kern/sys_process.c:1.173 Sat Oct 15 09:09:55 2016 +++ src/sys/kern/sys_process.c Wed Oct 19 09:44:01 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: sys_process.c,v 1.173 2016/10/15 09:09:55 skrll Exp $ */ +/* $NetBSD: sys_process.c,v 1.174 2016/10/19 09:44:01 skrll Exp $ */ /*- * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc. @@ -118,11 +118,13 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: sys_process.c,v 1.173 2016/10/15 09:09:55 skrll Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sys_process.c,v 1.174 2016/10/19 09:44:01 skrll Exp $"); +#ifdef _KERNEL_OPT #include "opt_ptrace.h" #include "opt_ktrace.h" #include "opt_pax.h" +#endif #include <sys/param.h> #include <sys/systm.h> @@ -231,6 +233,26 @@ ptrace_init(void) ptrace_listener_cb, NULL); } +static int +ptrace_copyinpiod(struct ptrace_io_desc *piod, const void *addr) +{ + return copyin(addr, piod, sizeof(*piod)); +} + +static void +ptrace_copyoutpiod(const struct ptrace_io_desc *piod, void *addr) +{ + (void) copyout(piod, addr, sizeof(*piod)); +} + + +static struct ptrace_methods native_ptm = { + .ptm_copyinpiod = ptrace_copyinpiod, + .ptm_copyoutpiod = ptrace_copyoutpiod, + .ptm_doregs = process_doregs, + .ptm_dofpregs = process_dofpregs, +}; + /* * Process debugging system call. */ @@ -243,6 +265,15 @@ sys_ptrace(struct lwp *l, const struct s syscallarg(void *) addr; syscallarg(int) data; } */ + + return do_ptrace(&native_ptm, l, SCARG(uap, req), SCARG(uap, pid), + SCARG(uap, addr), SCARG(uap, data), retval); +} + +int +do_ptrace(struct ptrace_methods *ptm, struct lwp *l, int req, pid_t pid, + void *addr, int data, register_t *retval) +{ struct proc *p = l->l_proc; struct lwp *lt; #ifdef PT_STEP @@ -256,15 +287,13 @@ sys_ptrace(struct lwp *l, const struct s struct ptrace_state ps; struct ptrace_lwpinfo pl; struct vmspace *vm; - int error, write, tmp, req, pheld; + int error, write, tmp, pheld; int signo = 0; int resume_all; ksiginfo_t ksi; char *path; int len = 0; - error = 0; - req = SCARG(uap, req); /* * If attaching or detaching, we need to get a write hold on the @@ -278,7 +307,7 @@ sys_ptrace(struct lwp *l, const struct s mutex_enter(t->p_lock); } else { /* Find the process we're supposed to be operating on. */ - t = proc_find(SCARG(uap, pid)); + t = proc_find(pid); if (t == NULL) { mutex_exit(proc_lock); return ESRCH; @@ -507,13 +536,13 @@ sys_ptrace(struct lwp *l, const struct s /* * Can't write to a RAS */ - if (ras_lookup(t, SCARG(uap, addr)) != (void *)-1) { + if (ras_lookup(t, addr) != (void *)-1) { error = EACCES; break; } #endif write = 1; - tmp = SCARG(uap, data); + tmp = data; /* FALLTHROUGH */ case PT_READ_I: /* XXX no separate I and D spaces */ @@ -523,7 +552,7 @@ sys_ptrace(struct lwp *l, const struct s iov.iov_len = sizeof(tmp); uio.uio_iov = &iov; uio.uio_iovcnt = 1; - uio.uio_offset = (off_t)(unsigned long)SCARG(uap, addr); + uio.uio_offset = (off_t)(unsigned long)addr; uio.uio_resid = sizeof(tmp); uio.uio_rw = write ? UIO_WRITE : UIO_READ; UIO_SETUP_SYSSPACE(&uio); @@ -534,7 +563,7 @@ sys_ptrace(struct lwp *l, const struct s break; case PT_IO: - error = copyin(SCARG(uap, addr), &piod, sizeof(piod)); + error = ptm->ptm_copyinpiod(&piod, addr); if (error) break; @@ -555,7 +584,7 @@ sys_ptrace(struct lwp *l, const struct s /* * Can't write to a RAS */ - if (ras_lookup(t, SCARG(uap, addr)) != (void *)-1) { + if (ras_lookup(t, addr) != (void *)-1) { return EACCES; } uio.uio_rw = UIO_WRITE; @@ -586,14 +615,15 @@ sys_ptrace(struct lwp *l, const struct s error = process_domem(l, lt, &uio); piod.piod_len -= uio.uio_resid; - (void) copyout(&piod, SCARG(uap, addr), sizeof(piod)); + (void) ptm->ptm_copyoutpiod(&piod, addr); + uvmspace_free(vm); break; case PT_DUMPCORE: - if ((path = SCARG(uap, addr)) != NULL) { + if ((path = addr) != NULL) { char *dst; - len = SCARG(uap, data); + len = data; if (len < 0 || len >= MAXPATHLEN) { error = EINVAL; @@ -648,7 +678,7 @@ sys_ptrace(struct lwp *l, const struct s * For operations other than PT_STEP, data > 0 means * data is the signo to deliver to the process. */ - tmp = SCARG(uap, data); + tmp = data; if (tmp >= 0) { #ifdef PT_STEP if (req == PT_STEP) @@ -697,8 +727,8 @@ sys_ptrace(struct lwp *l, const struct s } /* If the address parameter is not (int *)1, set the pc. */ - if ((int *)SCARG(uap, addr) != (int *)1) { - error = process_set_pc(lt, SCARG(uap, addr)); + if ((int *)addr != (int *)1) { + error = process_set_pc(lt, addr); if (error != 0) break; } @@ -797,26 +827,26 @@ sys_ptrace(struct lwp *l, const struct s goto sendsig; case PT_GET_EVENT_MASK: - if (SCARG(uap, data) != sizeof(pe)) { + if (data != sizeof(pe)) { DPRINTF(("ptrace(%d): %d != %zu\n", req, - SCARG(uap, data), sizeof(pe))); + data, sizeof(pe))); error = EINVAL; break; } memset(&pe, 0, sizeof(pe)); pe.pe_set_event = ISSET(t->p_slflag, PSL_TRACEFORK) ? PTRACE_FORK : 0; - error = copyout(&pe, SCARG(uap, addr), sizeof(pe)); + error = copyout(&pe, addr, sizeof(pe)); break; case PT_SET_EVENT_MASK: - if (SCARG(uap, data) != sizeof(pe)) { - DPRINTF(("ptrace(%d): %d != %zu\n", req, - SCARG(uap, data), sizeof(pe))); + if (data != sizeof(pe)) { + DPRINTF(("ptrace(%d): %d != %zu\n", req, data, + sizeof(pe))); error = EINVAL; break; } - if ((error = copyin(SCARG(uap, addr), &pe, sizeof(pe))) != 0) + if ((error = copyin(addr, &pe, sizeof(pe))) != 0) return error; if (pe.pe_set_event & PTRACE_FORK) SET(t->p_slflag, PSL_TRACEFORK); @@ -825,9 +855,9 @@ sys_ptrace(struct lwp *l, const struct s break; case PT_GET_PROCESS_STATE: - if (SCARG(uap, data) != sizeof(ps)) { - DPRINTF(("ptrace(%d): %d != %zu\n", req, - SCARG(uap, data), sizeof(ps))); + if (data != sizeof(ps)) { + DPRINTF(("ptrace(%d): %d != %zu\n", req, data, + sizeof(ps))); error = EINVAL; break; } @@ -836,17 +866,17 @@ sys_ptrace(struct lwp *l, const struct s ps.pe_report_event = PTRACE_FORK; ps.pe_other_pid = t->p_fpid; } - error = copyout(&ps, SCARG(uap, addr), sizeof(ps)); + error = copyout(&ps, addr, sizeof(ps)); break; case PT_LWPINFO: - if (SCARG(uap, data) != sizeof(pl)) { - DPRINTF(("ptrace(%d): %d != %zu\n", req, - SCARG(uap, data), sizeof(pl))); + if (data != sizeof(pl)) { + DPRINTF(("ptrace(%d): %d != %zu\n", req, data, + sizeof(pl))); error = EINVAL; break; } - error = copyin(SCARG(uap, addr), &pl, sizeof(pl)); + error = copyin(addr, &pl, sizeof(pl)); if (error) break; tmp = pl.pl_lwpid; @@ -875,7 +905,7 @@ sys_ptrace(struct lwp *l, const struct s } mutex_exit(t->p_lock); - error = copyout(&pl, SCARG(uap, addr), sizeof(pl)); + error = copyout(&pl, addr, sizeof(pl)); break; #ifdef PT_SETREGS @@ -887,7 +917,7 @@ sys_ptrace(struct lwp *l, const struct s /* write = 0 done above. */ #endif #if defined(PT_SETREGS) || defined(PT_GETREGS) - tmp = SCARG(uap, data); + tmp = data; if (tmp != 0 && t->p_nlwps > 1) { lwp_delref(lt); mutex_enter(t->p_lock); @@ -903,19 +933,19 @@ sys_ptrace(struct lwp *l, const struct s if (!process_validregs(lt)) error = EINVAL; else { - error = proc_vmspace_getref(l->l_proc, &vm); + error = proc_vmspace_getref(p, &vm); if (error) break; - iov.iov_base = SCARG(uap, addr); - iov.iov_len = sizeof(struct reg); + iov.iov_base = addr; + iov.iov_len = PROC_REGSZ(p); uio.uio_iov = &iov; uio.uio_iovcnt = 1; uio.uio_offset = 0; - uio.uio_resid = sizeof(struct reg); + uio.uio_resid = iov.iov_len; uio.uio_rw = write ? UIO_WRITE : UIO_READ; uio.uio_vmspace = vm; - error = process_doregs(l, lt, &uio); + error = ptm->ptm_doregs(l, lt, &uio); uvmspace_free(vm); } break; @@ -930,7 +960,7 @@ sys_ptrace(struct lwp *l, const struct s /* write = 0 done above. */ #endif #if defined(PT_SETFPREGS) || defined(PT_GETFPREGS) - tmp = SCARG(uap, data); + tmp = data; if (tmp != 0 && t->p_nlwps > 1) { lwp_delref(lt); mutex_enter(t->p_lock); @@ -946,19 +976,19 @@ sys_ptrace(struct lwp *l, const struct s if (!process_validfpregs(lt)) error = EINVAL; else { - error = proc_vmspace_getref(l->l_proc, &vm); + error = proc_vmspace_getref(p, &vm); if (error) break; - iov.iov_base = SCARG(uap, addr); - iov.iov_len = sizeof(struct fpreg); + iov.iov_base = addr; + iov.iov_len = PROC_FPREGSZ(p); uio.uio_iov = &iov; uio.uio_iovcnt = 1; uio.uio_offset = 0; - uio.uio_resid = sizeof(struct fpreg); + uio.uio_resid = iov.iov_len; uio.uio_rw = write ? UIO_WRITE : UIO_READ; uio.uio_vmspace = vm; - error = process_dofpregs(l, lt, &uio); + error = ptm->ptm_dofpregs(l, lt, &uio); uvmspace_free(vm); } break; @@ -966,8 +996,7 @@ sys_ptrace(struct lwp *l, const struct s #ifdef __HAVE_PTRACE_MACHDEP PTRACE_MACHDEP_REQUEST_CASES - error = ptrace_machdep_dorequest(l, lt, - req, SCARG(uap, addr), SCARG(uap, data)); + error = ptrace_machdep_dorequest(l, lt, req, addr, data); break; #endif } Index: src/sys/modules/Makefile diff -u src/sys/modules/Makefile:1.180 src/sys/modules/Makefile:1.181 --- src/sys/modules/Makefile:1.180 Sat Oct 15 12:38:03 2016 +++ src/sys/modules/Makefile Wed Oct 19 09:44:01 2016 @@ -1,4 +1,4 @@ -# $NetBSD: Makefile,v 1.180 2016/10/15 12:38:03 skrll Exp $ +# $NetBSD: Makefile,v 1.181 2016/10/19 09:44:01 skrll Exp $ .include <bsd.own.mk> @@ -236,6 +236,7 @@ SUBDIR+= wmimsi SUBDIR+= compat_netbsd32 SUBDIR+= compat_netbsd32_mqueue SUBDIR+= compat_netbsd32_nfssrv +SUBDIR+= compat_netbsd32_ptrace SUBDIR+= compat_netbsd32_sysvipc .endif @@ -244,6 +245,7 @@ SUBDIR+= compat_linux32 SUBDIR+= compat_netbsd32 SUBDIR+= compat_netbsd32_mqueue SUBDIR+= compat_netbsd32_nfssrv +SUBDIR+= compat_netbsd32_ptrace SUBDIR+= compat_netbsd32_sysvipc .endif Index: src/sys/sys/proc.h diff -u src/sys/sys/proc.h:1.334 src/sys/sys/proc.h:1.335 --- src/sys/sys/proc.h:1.334 Thu Sep 29 20:40:53 2016 +++ src/sys/sys/proc.h Wed Oct 19 09:44:01 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: proc.h,v 1.334 2016/09/29 20:40:53 christos Exp $ */ +/* $NetBSD: proc.h,v 1.335 2016/10/19 09:44:01 skrll Exp $ */ /*- * Copyright (c) 2006, 2007, 2008 The NetBSD Foundation, Inc. @@ -557,6 +557,10 @@ _proclist_skipmarker(struct proc *p0) } #define PROC_PTRSZ(p) (((p)->p_flag & PK_32) ? sizeof(int) : sizeof(void *)) +#define PROC_REGSZ(p) (((p)->p_flag & PK_32) ? \ + sizeof(process_reg32) : sizeof(struct reg)) +#define PROC_FPREGSZ(p) (((p)->p_flag & PK_32) ? \ + sizeof(process_fpreg32) : sizeof(struct fpreg)) /* * PROCLIST_FOREACH: iterate on the given proclist, skipping PK_MARKER ones. Index: src/sys/sys/ptrace.h diff -u src/sys/sys/ptrace.h:1.46 src/sys/sys/ptrace.h:1.47 --- src/sys/sys/ptrace.h:1.46 Thu Jul 2 03:47:54 2015 +++ src/sys/sys/ptrace.h Wed Oct 19 09:44:01 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: ptrace.h,v 1.46 2015/07/02 03:47:54 christos Exp $ */ +/* $NetBSD: ptrace.h,v 1.47 2016/10/19 09:44:01 skrll Exp $ */ /*- * Copyright (c) 1984, 1993 @@ -139,6 +139,13 @@ struct fpreg; #endif #endif +struct ptrace_methods { + int (*ptm_copyinpiod)(struct ptrace_io_desc *, const void *); + void (*ptm_copyoutpiod)(const struct ptrace_io_desc *, void *); + int (*ptm_doregs)(struct lwp *, struct lwp *, struct uio *); + int (*ptm_dofpregs)(struct lwp *, struct lwp *, struct uio *); +}; + void ptrace_init(void); int process_doregs(struct lwp *, struct lwp *, struct uio *); @@ -153,6 +160,10 @@ void process_stoptrace(void); void proc_reparent(struct proc *, struct proc *); + +int do_ptrace(struct ptrace_methods *, struct lwp *, int, pid_t, void *, + int, register_t *); + /* * 64bit architectures that support 32bit emulation (amd64 and sparc64) * will #define process_read_regs32 to netbsd32_process_read_regs (etc). @@ -180,9 +191,21 @@ int process_set_pc(struct lwp *, void *) int process_sstep(struct lwp *, int); #ifdef PT_SETFPREGS int process_write_fpregs(struct lwp *, const struct fpreg *, size_t); +#ifndef process_write_fpregs32 +#define process_write_fpregs32 process_write_fpregs +#endif +#ifndef process_write_fpregs64 +#define process_write_fpregs64 process_write_fpregs +#endif #endif #ifdef PT_SETREGS int process_write_regs(struct lwp *, const struct reg *); +#ifndef process_write_regs32 +#define process_write_regs32 process_write_regs +#endif +#ifndef process_write_regs64 +#define process_write_regs64 process_write_regs +#endif #endif #ifdef __HAVE_PROCFS_MACHDEP Added files: Index: src/sys/compat/netbsd32/netbsd32_ptrace.c diff -u /dev/null src/sys/compat/netbsd32/netbsd32_ptrace.c:1.1 --- /dev/null Wed Oct 19 09:44:01 2016 +++ src/sys/compat/netbsd32/netbsd32_ptrace.c Wed Oct 19 09:44:01 2016 @@ -0,0 +1,217 @@ +/* $NetBSD: netbsd32_ptrace.c,v 1.1 2016/10/19 09:44:01 skrll Exp $ */ + +/* + * Copyright (c) 2016 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Nick Hudson + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__KERNEL_RCSID(0, "$NetBSD: netbsd32_ptrace.c,v 1.1 2016/10/19 09:44:01 skrll Exp $"); + +#if defined(_KERNEL_OPT) +#include "opt_ptrace.h" +#include "opt_compat_netbsd.h" +#endif + +#include <sys/param.h> +#include <sys/module.h> +#include <sys/ptrace.h> +#include <sys/syscallvar.h> + +#include <compat/netbsd32/netbsd32.h> +#include <compat/netbsd32/netbsd32_syscall.h> +#include <compat/netbsd32/netbsd32_syscallargs.h> +#include <compat/netbsd32/netbsd32_conv.h> + +extern struct emul emul_netbsd32; + + +/* + * PTRACE methods + */ + +static int netbsd32_copyinpiod(struct ptrace_io_desc *, const void *); +static void netbsd32_copyoutpiod(const struct ptrace_io_desc *, void *); +static int netbsd32_doregs(struct lwp *, struct lwp *, struct uio *); +static int netbsd32_dofpregs(struct lwp *, struct lwp *, struct uio *); + + +static int +netbsd32_copyinpiod(struct ptrace_io_desc *piod, const void *addr) +{ + struct netbsd32_ptrace_io_desc piod32; + + int error = copyin(addr, &piod32, sizeof(piod32)); + if (error) + return error; + piod->piod_op = piod32.piod_op; + piod->piod_offs = NETBSD32PTR64(piod32.piod_offs); + piod->piod_addr = NETBSD32PTR64(piod32.piod_addr); + piod->piod_len = (size_t)piod32.piod_len; + + return 0; +} + +static void +netbsd32_copyoutpiod(const struct ptrace_io_desc *piod, void *addr) +{ + struct netbsd32_ptrace_io_desc piod32; + + piod32.piod_op = piod->piod_op; + NETBSD32PTR32(piod32.piod_offs, piod->piod_offs); + NETBSD32PTR32(piod32.piod_addr, piod->piod_addr); + piod32.piod_len = (netbsd32_size_t)piod->piod_len; + (void) copyout(&piod32, addr, sizeof(piod32)); +} + + +static int +netbsd32_doregs(struct lwp *curl /*tracer*/, + struct lwp *l /*traced*/, + struct uio *uio) +{ +#if defined(PT_GETREGS) || defined(PT_SETREGS) + process_reg32 r32; + int error; + char *kv; + int kl; + + if (uio->uio_offset < 0 || uio->uio_offset > (off_t)sizeof(r32)) + return EINVAL; + + kl = sizeof(r32); + kv = (char *)&r32; + + kv += uio->uio_offset; + kl -= uio->uio_offset; + if ((size_t)kl > uio->uio_resid) + kl = uio->uio_resid; + error = process_read_regs32(l, &r32); + 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 = process_write_regs32(l, &r32); + } + + uio->uio_offset = 0; + return error; +#else + return EINVAL; +#endif +} + +static int +netbsd32_dofpregs(struct lwp *curl /*tracer*/, + struct lwp *l /*traced*/, + struct uio *uio) +{ +#if defined(PT_GETFPREGS) || defined(PT_SETFPREGS) + process_fpreg32 r32; + int error; + char *kv; + size_t kl; + + KASSERT(l->l_proc->p_flag & PK_32); + if (uio->uio_offset < 0 || uio->uio_offset > (off_t)sizeof(r32)) + return EINVAL; + kl = sizeof(r32); + kv = (char *)&r32; + + kv += uio->uio_offset; + kl -= uio->uio_offset; + if (kl > uio->uio_resid) + kl = uio->uio_resid; + + error = process_read_fpregs32(l, &r32, &kl); + 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 = process_write_fpregs32(l, &r32, kl); + } + uio->uio_offset = 0; + return error; +#else + return EINVAL; +#endif +} + +static struct ptrace_methods netbsd32_ptm = { + .ptm_copyinpiod = netbsd32_copyinpiod, + .ptm_copyoutpiod = netbsd32_copyoutpiod, + .ptm_doregs = netbsd32_doregs, + .ptm_dofpregs = netbsd32_dofpregs +}; + + +int +netbsd32_ptrace(struct lwp *l, const struct netbsd32_ptrace_args *uap, + register_t *retval) +{ + /* { + syscallarg(int) req; + syscallarg(pid_t) pid; + syscallarg(netbsd32_voidp *) addr; + syscallarg(int) data; + } */ + + return do_ptrace(&netbsd32_ptm, l, SCARG(uap, req), SCARG(uap, pid), + SCARG_P32(uap, addr), SCARG(uap, data), retval); +} + +static const struct syscall_package compat_ptrace_syscalls[] = { + { NETBSD32_SYS_netbsd32_ptrace, 0, (sy_call_t *)netbsd32_ptrace }, + { 0, 0, NULL }, +}; + +MODULE(MODULE_CLASS_EXEC, compat_netbsd32_ptrace, "compat_netbsd32"); + +static int +compat_netbsd32_ptrace_modcmd(modcmd_t cmd, void *arg) +{ + int error; + + switch (cmd) { + case MODULE_CMD_INIT: + error = syscall_establish(&emul_netbsd32, + compat_ptrace_syscalls); + break; + case MODULE_CMD_FINI: + error = syscall_disestablish(&emul_netbsd32, + compat_ptrace_syscalls); + break; + default: + error = ENOTTY; + break; + } + return error; +} Index: src/sys/modules/compat_netbsd32_ptrace/Makefile diff -u /dev/null src/sys/modules/compat_netbsd32_ptrace/Makefile:1.1 --- /dev/null Wed Oct 19 09:44:01 2016 +++ src/sys/modules/compat_netbsd32_ptrace/Makefile Wed Oct 19 09:44:01 2016 @@ -0,0 +1,15 @@ +# $NetBSD: Makefile,v 1.1 2016/10/19 09:44:01 skrll Exp $ + +.include "../Makefile.inc" +.include "../Makefile.assym" + +KMOD= compat_netbsd32_ptrace + +CPPFLAGS+= -DCOMPAT_NETBSD32 +CPPFLAGS+= -DPTRACE +CPPFLAGS+= -DPT_SETREGS -DPT_GETREGS + +.PATH: ${S}/compat/netbsd32 +SRCS+= netbsd32_ptrace.c + +.include <bsd.kmodule.mk>