PR kern/51514: ptrace(2) fails for 32-bit process on 64-bit kernel
Updated from the original patch in the PR by me.
This commit is contained in:
parent
3dcd57986a
commit
f2ef31cb48
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 reg32 *regs)
|
|||
{
|
||||
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, struct reg32 *regs)
|
|||
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, struct reg32 *regs)
|
|||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
int
|
||||
netbsd32_process_write_fpregs(struct lwp *l, const struct fpreg32 *regs,
|
||||
size_t sz)
|
||||
{
|
||||
|
||||
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);
|
||||
|
||||
return (0);
|
||||
process_write_fpregs_s87(l, (const struct save87 *)regs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 *, netbsd32_u_long, void *, struct lwp *);
|
|||
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_ */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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, struct reg32 *regs)
|
|||
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 *l, const struct reg32 *regs)
|
|||
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 *l, struct fpreg32 *regs, size_t *sz)
|
|||
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 *l, const struct fpreg32 *regs)
|
|||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 32-bit version of cpu_coredump.
|
||||
|
|
|
@ -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 compat_netbsd32
|
|||
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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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"
|
||||
|
@ -405,25 +405,6 @@ netbsd32_setuid(struct lwp *l, const struct netbsd32_setuid_args *uap, register_
|
|||
return (sys_setuid(l, &ua, retval));
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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); }
|
||||
|
|
|
@ -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 sys_ptrace_args *uap, register_t *retval)
|
|||
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 sys_ptrace_args *uap, register_t *retval)
|
|||
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 sys_ptrace_args *uap, register_t *retval)
|
|||
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 sys_ptrace_args *uap, register_t *retval)
|
|||
/*
|
||||
* 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 sys_ptrace_args *uap, register_t *retval)
|
|||
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 sys_ptrace_args *uap, register_t *retval)
|
|||
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 sys_ptrace_args *uap, register_t *retval)
|
|||
/*
|
||||
* 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 sys_ptrace_args *uap, register_t *retval)
|
|||
|
||||
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 sys_ptrace_args *uap, register_t *retval)
|
|||
* 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 sys_ptrace_args *uap, register_t *retval)
|
|||
}
|
||||
|
||||
/* 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 sys_ptrace_args *uap, register_t *retval)
|
|||
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 sys_ptrace_args *uap, register_t *retval)
|
|||
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 sys_ptrace_args *uap, register_t *retval)
|
|||
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 sys_ptrace_args *uap, register_t *retval)
|
|||
}
|
||||
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 sys_ptrace_args *uap, register_t *retval)
|
|||
/* 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 sys_ptrace_args *uap, register_t *retval)
|
|||
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 sys_ptrace_args *uap, register_t *retval)
|
|||
/* 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 sys_ptrace_args *uap, register_t *retval)
|
|||
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 sys_ptrace_args *uap, register_t *retval)
|
|||
|
||||
#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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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>
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue