Refactor ptrace() ABI compatibility.

Add a freebsd32_ptrace() and move as many freebsd32 shims as possible
to freebsd32_ptrace().  Aside from register sets, freebsd32 passes
pointers to native structures to kern_ptrace() and converts to/from
native/32-bit structure formats in freebsd32_ptrace() outside of
kern_ptrace().

Reviewed by:	kib
Obtained from:	CheriBSD
Sponsored by:	DARPA
Differential Revision:	https://reviews.freebsd.org/D25195
This commit is contained in:
John Baldwin 2020-06-09 16:43:23 +00:00
parent b6f7bae402
commit 58b552dcec
8 changed files with 252 additions and 231 deletions

View File

@ -63,6 +63,7 @@ __FBSDID("$FreeBSD$");
#include <sys/namei.h>
#include <sys/proc.h>
#include <sys/procctl.h>
#include <sys/ptrace.h>
#include <sys/reboot.h>
#include <sys/resource.h>
#include <sys/resourcevar.h>
@ -121,6 +122,31 @@ __FBSDID("$FreeBSD$");
FEATURE(compat_freebsd_32bit, "Compatible with 32-bit FreeBSD");
struct ptrace_io_desc32 {
int piod_op;
uint32_t piod_offs;
uint32_t piod_addr;
uint32_t piod_len;
};
struct ptrace_sc_ret32 {
uint32_t sr_retval[2];
int sr_error;
};
struct ptrace_vm_entry32 {
int pve_entry;
int pve_timestamp;
uint32_t pve_start;
uint32_t pve_end;
uint32_t pve_offset;
u_int pve_prot;
u_int pve_pathlen;
int32_t pve_fileid;
u_int pve_fsid;
uint32_t pve_path;
};
#ifdef __amd64__
CTASSERT(sizeof(struct timeval32) == 8);
CTASSERT(sizeof(struct timespec32) == 8);
@ -856,6 +882,192 @@ freebsd32_getrusage(struct thread *td, struct freebsd32_getrusage_args *uap)
return (error);
}
static void
ptrace_lwpinfo_to32(const struct ptrace_lwpinfo *pl,
struct ptrace_lwpinfo32 *pl32)
{
bzero(pl32, sizeof(*pl32));
pl32->pl_lwpid = pl->pl_lwpid;
pl32->pl_event = pl->pl_event;
pl32->pl_flags = pl->pl_flags;
pl32->pl_sigmask = pl->pl_sigmask;
pl32->pl_siglist = pl->pl_siglist;
siginfo_to_siginfo32(&pl->pl_siginfo, &pl32->pl_siginfo);
strcpy(pl32->pl_tdname, pl->pl_tdname);
pl32->pl_child_pid = pl->pl_child_pid;
pl32->pl_syscall_code = pl->pl_syscall_code;
pl32->pl_syscall_narg = pl->pl_syscall_narg;
}
static void
ptrace_sc_ret_to32(const struct ptrace_sc_ret *psr,
struct ptrace_sc_ret32 *psr32)
{
bzero(psr32, sizeof(*psr32));
psr32->sr_retval[0] = psr->sr_retval[0];
psr32->sr_retval[1] = psr->sr_retval[1];
psr32->sr_error = psr->sr_error;
}
int
freebsd32_ptrace(struct thread *td, struct freebsd32_ptrace_args *uap)
{
union {
struct ptrace_io_desc piod;
struct ptrace_lwpinfo pl;
struct ptrace_vm_entry pve;
struct dbreg32 dbreg;
struct fpreg32 fpreg;
struct reg32 reg;
register_t args[nitems(td->td_sa.args)];
struct ptrace_sc_ret psr;
int ptevents;
} r;
union {
struct ptrace_io_desc32 piod;
struct ptrace_lwpinfo32 pl;
struct ptrace_vm_entry32 pve;
uint32_t args[nitems(td->td_sa.args)];
struct ptrace_sc_ret32 psr;
} r32;
void *addr;
int data, error = 0, i;
AUDIT_ARG_PID(uap->pid);
AUDIT_ARG_CMD(uap->req);
AUDIT_ARG_VALUE(uap->data);
addr = &r;
data = uap->data;
switch (uap->req) {
case PT_GET_EVENT_MASK:
case PT_GET_SC_ARGS:
case PT_GET_SC_RET:
break;
case PT_LWPINFO:
if (uap->data > sizeof(r32.pl))
return (EINVAL);
/*
* Pass size of native structure in 'data'. Truncate
* if necessary to avoid siginfo.
*/
data = sizeof(r.pl);
if (uap->data < offsetof(struct ptrace_lwpinfo32, pl_siginfo) +
sizeof(struct siginfo32))
data = offsetof(struct ptrace_lwpinfo, pl_siginfo);
break;
case PT_GETREGS:
bzero(&r.reg, sizeof(r.reg));
break;
case PT_GETFPREGS:
bzero(&r.fpreg, sizeof(r.fpreg));
break;
case PT_GETDBREGS:
bzero(&r.dbreg, sizeof(r.dbreg));
break;
case PT_SETREGS:
error = copyin(uap->addr, &r.reg, sizeof(r.reg));
break;
case PT_SETFPREGS:
error = copyin(uap->addr, &r.fpreg, sizeof(r.fpreg));
break;
case PT_SETDBREGS:
error = copyin(uap->addr, &r.dbreg, sizeof(r.dbreg));
break;
case PT_SET_EVENT_MASK:
if (uap->data != sizeof(r.ptevents))
error = EINVAL;
else
error = copyin(uap->addr, &r.ptevents, uap->data);
break;
case PT_IO:
error = copyin(uap->addr, &r32.piod, sizeof(r32.piod));
if (error)
break;
CP(r32.piod, r.piod, piod_op);
PTRIN_CP(r32.piod, r.piod, piod_offs);
PTRIN_CP(r32.piod, r.piod, piod_addr);
CP(r32.piod, r.piod, piod_len);
break;
case PT_VM_ENTRY:
error = copyin(uap->addr, &r32.pve, sizeof(r32.pve));
if (error)
break;
CP(r32.pve, r.pve, pve_entry);
CP(r32.pve, r.pve, pve_timestamp);
CP(r32.pve, r.pve, pve_start);
CP(r32.pve, r.pve, pve_end);
CP(r32.pve, r.pve, pve_offset);
CP(r32.pve, r.pve, pve_prot);
CP(r32.pve, r.pve, pve_pathlen);
CP(r32.pve, r.pve, pve_fileid);
CP(r32.pve, r.pve, pve_fsid);
PTRIN_CP(r32.pve, r.pve, pve_path);
break;
default:
addr = uap->addr;
break;
}
if (error)
return (error);
error = kern_ptrace(td, uap->req, uap->pid, addr, data);
if (error)
return (error);
switch (uap->req) {
case PT_VM_ENTRY:
CP(r.pve, r32.pve, pve_entry);
CP(r.pve, r32.pve, pve_timestamp);
CP(r.pve, r32.pve, pve_start);
CP(r.pve, r32.pve, pve_end);
CP(r.pve, r32.pve, pve_offset);
CP(r.pve, r32.pve, pve_prot);
CP(r.pve, r32.pve, pve_pathlen);
CP(r.pve, r32.pve, pve_fileid);
CP(r.pve, r32.pve, pve_fsid);
error = copyout(&r32.pve, uap->addr, sizeof(r32.pve));
break;
case PT_IO:
CP(r.piod, r32.piod, piod_len);
error = copyout(&r32.piod, uap->addr, sizeof(r32.piod));
break;
case PT_GETREGS:
error = copyout(&r.reg, uap->addr, sizeof(r.reg));
break;
case PT_GETFPREGS:
error = copyout(&r.fpreg, uap->addr, sizeof(r.fpreg));
break;
case PT_GETDBREGS:
error = copyout(&r.dbreg, uap->addr, sizeof(r.dbreg));
break;
case PT_GET_EVENT_MASK:
/* NB: The size in uap->data is validated in kern_ptrace(). */
error = copyout(&r.ptevents, uap->addr, uap->data);
break;
case PT_LWPINFO:
ptrace_lwpinfo_to32(&r.pl, &r32.pl);
error = copyout(&r32.pl, uap->addr, uap->data);
break;
case PT_GET_SC_ARGS:
for (i = 0; i < nitems(r.args); i++)
r32.args[i] = (uint32_t)r.args[i];
error = copyout(r32.args, uap->addr, MIN(uap->data,
sizeof(r32.args)));
break;
case PT_GET_SC_RET:
ptrace_sc_ret_to32(&r.psr, &r32.psr);
error = copyout(&r32.psr, uap->addr, MIN(uap->data,
sizeof(r32.psr)));
break;
}
return (error);
}
static int
freebsd32_copyinuio(struct iovec32 *iovp, u_int iovcnt, struct uio **uiop)
{

View File

@ -43,6 +43,12 @@ struct freebsd32_wait4_args {
char options_l_[PADL_(int)]; int options; char options_r_[PADR_(int)];
char rusage_l_[PADL_(struct rusage32 *)]; struct rusage32 * rusage; char rusage_r_[PADR_(struct rusage32 *)];
};
struct freebsd32_ptrace_args {
char req_l_[PADL_(int)]; int req; char req_r_[PADR_(int)];
char pid_l_[PADL_(pid_t)]; pid_t pid; char pid_r_[PADR_(pid_t)];
char addr_l_[PADL_(caddr_t)]; caddr_t addr; char addr_r_[PADR_(caddr_t)];
char data_l_[PADL_(int)]; int data; char data_r_[PADR_(int)];
};
struct freebsd32_recvmsg_args {
char s_l_[PADL_(int)]; int s; char s_r_[PADR_(int)];
char msg_l_[PADL_(struct msghdr32 *)]; struct msghdr32 * msg; char msg_r_[PADR_(struct msghdr32 *)];
@ -740,6 +746,7 @@ struct freebsd32___sysctlbyname_args {
#define PAD64_REQUIRED
#endif
int freebsd32_wait4(struct thread *, struct freebsd32_wait4_args *);
int freebsd32_ptrace(struct thread *, struct freebsd32_ptrace_args *);
int freebsd32_recvmsg(struct thread *, struct freebsd32_recvmsg_args *);
int freebsd32_sendmsg(struct thread *, struct freebsd32_sendmsg_args *);
int freebsd32_recvfrom(struct thread *, struct freebsd32_recvfrom_args *);
@ -1293,6 +1300,7 @@ int freebsd11_freebsd32_fstatat(struct thread *, struct freebsd11_freebsd32_fsta
#define FREEBSD32_SYS_AUE_freebsd32_wait4 AUE_WAIT4
#define FREEBSD32_SYS_AUE_freebsd4_freebsd32_getfsstat AUE_GETFSSTAT
#define FREEBSD32_SYS_AUE_ofreebsd32_lseek AUE_LSEEK
#define FREEBSD32_SYS_AUE_freebsd32_ptrace AUE_PTRACE
#define FREEBSD32_SYS_AUE_freebsd32_recvmsg AUE_RECVMSG
#define FREEBSD32_SYS_AUE_freebsd32_sendmsg AUE_SENDMSG
#define FREEBSD32_SYS_AUE_freebsd32_recvfrom AUE_RECVFROM

View File

@ -31,7 +31,7 @@
#define FREEBSD32_SYS_setuid 23
#define FREEBSD32_SYS_getuid 24
#define FREEBSD32_SYS_geteuid 25
#define FREEBSD32_SYS_ptrace 26
#define FREEBSD32_SYS_freebsd32_ptrace 26
#define FREEBSD32_SYS_freebsd32_recvmsg 27
#define FREEBSD32_SYS_freebsd32_sendmsg 28
#define FREEBSD32_SYS_freebsd32_recvfrom 29

View File

@ -35,7 +35,7 @@ const char *freebsd32_syscallnames[] = {
"setuid", /* 23 = setuid */
"getuid", /* 24 = getuid */
"geteuid", /* 25 = geteuid */
"ptrace", /* 26 = ptrace */
"freebsd32_ptrace", /* 26 = freebsd32_ptrace */
"freebsd32_recvmsg", /* 27 = freebsd32_recvmsg */
"freebsd32_sendmsg", /* 28 = freebsd32_sendmsg */
"freebsd32_recvfrom", /* 29 = freebsd32_recvfrom */

View File

@ -88,7 +88,7 @@ struct sysent freebsd32_sysent[] = {
{ AS(setuid_args), (sy_call_t *)sys_setuid, AUE_SETUID, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 23 = setuid */
{ 0, (sy_call_t *)sys_getuid, AUE_GETUID, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 24 = getuid */
{ 0, (sy_call_t *)sys_geteuid, AUE_GETEUID, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 25 = geteuid */
{ AS(ptrace_args), (sy_call_t *)sys_ptrace, AUE_PTRACE, NULL, 0, 0, 0, SY_THR_STATIC }, /* 26 = ptrace */
{ AS(freebsd32_ptrace_args), (sy_call_t *)freebsd32_ptrace, AUE_PTRACE, NULL, 0, 0, 0, SY_THR_STATIC }, /* 26 = freebsd32_ptrace */
{ AS(freebsd32_recvmsg_args), (sy_call_t *)freebsd32_recvmsg, AUE_RECVMSG, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 27 = freebsd32_recvmsg */
{ AS(freebsd32_sendmsg_args), (sy_call_t *)freebsd32_sendmsg, AUE_SENDMSG, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 28 = freebsd32_sendmsg */
{ AS(freebsd32_recvfrom_args), (sy_call_t *)freebsd32_recvfrom, AUE_RECVFROM, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 29 = freebsd32_recvfrom */

View File

@ -168,9 +168,9 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
*n_args = 0;
break;
}
/* ptrace */
/* freebsd32_ptrace */
case 26: {
struct ptrace_args *p = params;
struct freebsd32_ptrace_args *p = params;
iarg[0] = p->req; /* int */
iarg[1] = p->pid; /* pid_t */
uarg[2] = (intptr_t) p->addr; /* caddr_t */
@ -3623,7 +3623,7 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
/* geteuid */
case 25:
break;
/* ptrace */
/* freebsd32_ptrace */
case 26:
switch(ndx) {
case 0:
@ -9228,7 +9228,7 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
case 24:
/* geteuid */
case 25:
/* ptrace */
/* freebsd32_ptrace */
case 26:
if (ndx == 0 || ndx == 1)
p = "int";

View File

@ -103,7 +103,7 @@
23 AUE_SETUID NOPROTO { int setuid(uid_t uid); }
24 AUE_GETUID NOPROTO { uid_t getuid(void); }
25 AUE_GETEUID NOPROTO { uid_t geteuid(void); }
26 AUE_PTRACE NOPROTO { int ptrace(int req, pid_t pid, \
26 AUE_PTRACE STD { int freebsd32_ptrace(int req, pid_t pid, \
caddr_t addr, int data); }
27 AUE_RECVMSG STD { int freebsd32_recvmsg(int s, struct msghdr32 *msg, \
int flags); }

View File

@ -67,32 +67,6 @@ __FBSDID("$FreeBSD$");
#ifdef COMPAT_FREEBSD32
#include <sys/procfs.h>
#include <compat/freebsd32/freebsd32_signal.h>
struct ptrace_io_desc32 {
int piod_op;
uint32_t piod_offs;
uint32_t piod_addr;
uint32_t piod_len;
};
struct ptrace_sc_ret32 {
uint32_t sr_retval[2];
int sr_error;
};
struct ptrace_vm_entry32 {
int pve_entry;
int pve_timestamp;
uint32_t pve_start;
uint32_t pve_end;
uint32_t pve_offset;
u_int pve_prot;
u_int pve_pathlen;
int32_t pve_fileid;
u_int pve_fsid;
uint32_t pve_path;
};
#endif
/*
@ -472,64 +446,6 @@ ptrace_vm_entry(struct thread *td, struct proc *p, struct ptrace_vm_entry *pve)
return (error);
}
#ifdef COMPAT_FREEBSD32
static int
ptrace_vm_entry32(struct thread *td, struct proc *p,
struct ptrace_vm_entry32 *pve32)
{
struct ptrace_vm_entry pve;
int error;
pve.pve_entry = pve32->pve_entry;
pve.pve_pathlen = pve32->pve_pathlen;
pve.pve_path = (void *)(uintptr_t)pve32->pve_path;
error = ptrace_vm_entry(td, p, &pve);
if (error == 0) {
pve32->pve_entry = pve.pve_entry;
pve32->pve_timestamp = pve.pve_timestamp;
pve32->pve_start = pve.pve_start;
pve32->pve_end = pve.pve_end;
pve32->pve_offset = pve.pve_offset;
pve32->pve_prot = pve.pve_prot;
pve32->pve_fileid = pve.pve_fileid;
pve32->pve_fsid = pve.pve_fsid;
}
pve32->pve_pathlen = pve.pve_pathlen;
return (error);
}
static void
ptrace_lwpinfo_to32(const struct ptrace_lwpinfo *pl,
struct ptrace_lwpinfo32 *pl32)
{
bzero(pl32, sizeof(*pl32));
pl32->pl_lwpid = pl->pl_lwpid;
pl32->pl_event = pl->pl_event;
pl32->pl_flags = pl->pl_flags;
pl32->pl_sigmask = pl->pl_sigmask;
pl32->pl_siglist = pl->pl_siglist;
siginfo_to_siginfo32(&pl->pl_siginfo, &pl32->pl_siginfo);
strcpy(pl32->pl_tdname, pl->pl_tdname);
pl32->pl_child_pid = pl->pl_child_pid;
pl32->pl_syscall_code = pl->pl_syscall_code;
pl32->pl_syscall_narg = pl->pl_syscall_narg;
}
static void
ptrace_sc_ret_to32(const struct ptrace_sc_ret *psr,
struct ptrace_sc_ret32 *psr32)
{
bzero(psr32, sizeof(*psr32));
psr32->sr_retval[0] = psr->sr_retval[0];
psr32->sr_retval[1] = psr->sr_retval[1];
psr32->sr_error = psr->sr_error;
}
#endif /* COMPAT_FREEBSD32 */
/*
* Process debugging system call.
*/
@ -542,31 +458,6 @@ struct ptrace_args {
};
#endif
#ifdef COMPAT_FREEBSD32
/*
* This CPP subterfuge is to try and reduce the number of ifdefs in
* the body of the code.
* COPYIN(uap->addr, &r.reg, sizeof r.reg);
* becomes either:
* copyin(uap->addr, &r.reg, sizeof r.reg);
* or
* copyin(uap->addr, &r.reg32, sizeof r.reg32);
* .. except this is done at runtime.
*/
#define BZERO(a, s) wrap32 ? \
bzero(a ## 32, s ## 32) : \
bzero(a, s)
#define COPYIN(u, k, s) wrap32 ? \
copyin(u, k ## 32, s ## 32) : \
copyin(u, k, s)
#define COPYOUT(k, u, s) wrap32 ? \
copyout(k ## 32, u, s ## 32) : \
copyout(k, u, s)
#else
#define BZERO(a, s) bzero(a, s)
#define COPYIN(u, k, s) copyin(u, k, s)
#define COPYOUT(k, u, s) copyout(k, u, s)
#endif
int
sys_ptrace(struct thread *td, struct ptrace_args *uap)
{
@ -581,26 +472,13 @@ sys_ptrace(struct thread *td, struct ptrace_args *uap)
struct dbreg dbreg;
struct fpreg fpreg;
struct reg reg;
#ifdef COMPAT_FREEBSD32
struct dbreg32 dbreg32;
struct fpreg32 fpreg32;
struct reg32 reg32;
struct ptrace_io_desc32 piod32;
struct ptrace_lwpinfo32 pl32;
struct ptrace_vm_entry32 pve32;
#endif
char args[sizeof(td->td_sa.args)];
struct ptrace_sc_ret psr;
int ptevents;
} r;
void *addr;
int error = 0;
#ifdef COMPAT_FREEBSD32
int wrap32 = 0;
if (SV_CURPROC_FLAG(SV_ILP32))
wrap32 = 1;
#endif
AUDIT_ARG_PID(uap->pid);
AUDIT_ARG_CMD(uap->req);
AUDIT_ARG_VALUE(uap->data);
@ -612,22 +490,22 @@ sys_ptrace(struct thread *td, struct ptrace_args *uap)
case PT_GET_SC_RET:
break;
case PT_GETREGS:
BZERO(&r.reg, sizeof r.reg);
bzero(&r.reg, sizeof(r.reg));
break;
case PT_GETFPREGS:
BZERO(&r.fpreg, sizeof r.fpreg);
bzero(&r.fpreg, sizeof(r.fpreg));
break;
case PT_GETDBREGS:
BZERO(&r.dbreg, sizeof r.dbreg);
bzero(&r.dbreg, sizeof(r.dbreg));
break;
case PT_SETREGS:
error = COPYIN(uap->addr, &r.reg, sizeof r.reg);
error = copyin(uap->addr, &r.reg, sizeof(r.reg));
break;
case PT_SETFPREGS:
error = COPYIN(uap->addr, &r.fpreg, sizeof r.fpreg);
error = copyin(uap->addr, &r.fpreg, sizeof(r.fpreg));
break;
case PT_SETDBREGS:
error = COPYIN(uap->addr, &r.dbreg, sizeof r.dbreg);
error = copyin(uap->addr, &r.dbreg, sizeof(r.dbreg));
break;
case PT_SET_EVENT_MASK:
if (uap->data != sizeof(r.ptevents))
@ -636,10 +514,10 @@ sys_ptrace(struct thread *td, struct ptrace_args *uap)
error = copyin(uap->addr, &r.ptevents, uap->data);
break;
case PT_IO:
error = COPYIN(uap->addr, &r.piod, sizeof r.piod);
error = copyin(uap->addr, &r.piod, sizeof(r.piod));
break;
case PT_VM_ENTRY:
error = COPYIN(uap->addr, &r.pve, sizeof r.pve);
error = copyin(uap->addr, &r.pve, sizeof(r.pve));
break;
default:
addr = uap->addr;
@ -654,19 +532,19 @@ sys_ptrace(struct thread *td, struct ptrace_args *uap)
switch (uap->req) {
case PT_VM_ENTRY:
error = COPYOUT(&r.pve, uap->addr, sizeof r.pve);
error = copyout(&r.pve, uap->addr, sizeof(r.pve));
break;
case PT_IO:
error = COPYOUT(&r.piod, uap->addr, sizeof r.piod);
error = copyout(&r.piod, uap->addr, sizeof(r.piod));
break;
case PT_GETREGS:
error = COPYOUT(&r.reg, uap->addr, sizeof r.reg);
error = copyout(&r.reg, uap->addr, sizeof(r.reg));
break;
case PT_GETFPREGS:
error = COPYOUT(&r.fpreg, uap->addr, sizeof r.fpreg);
error = copyout(&r.fpreg, uap->addr, sizeof(r.fpreg));
break;
case PT_GETDBREGS:
error = COPYOUT(&r.dbreg, uap->addr, sizeof r.dbreg);
error = copyout(&r.dbreg, uap->addr, sizeof(r.dbreg));
break;
case PT_GET_EVENT_MASK:
/* NB: The size in uap->data is validated in kern_ptrace(). */
@ -688,9 +566,6 @@ sys_ptrace(struct thread *td, struct ptrace_args *uap)
return (error);
}
#undef COPYIN
#undef COPYOUT
#undef BZERO
#ifdef COMPAT_FREEBSD32
/*
@ -741,13 +616,6 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
lwpid_t tid = 0, *buf;
#ifdef COMPAT_FREEBSD32
int wrap32 = 0, safe = 0;
struct ptrace_io_desc32 *piod32 = NULL;
struct ptrace_lwpinfo32 *pl32 = NULL;
struct ptrace_sc_ret32 *psr32 = NULL;
union {
struct ptrace_lwpinfo pl;
struct ptrace_sc_ret psr;
} r;
#endif
curp = td->td_proc;
@ -1057,15 +925,8 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
break;
}
bzero(addr, sizeof(td2->td_sa.args));
#ifdef COMPAT_FREEBSD32
if (wrap32)
for (num = 0; num < nitems(td2->td_sa.args); num++)
((uint32_t *)addr)[num] = (uint32_t)
td2->td_sa.args[num];
else
#endif
bcopy(td2->td_sa.args, addr, td2->td_sa.narg *
sizeof(register_t));
bcopy(td2->td_sa.args, addr, td2->td_sa.narg *
sizeof(register_t));
break;
case PT_GET_SC_RET:
@ -1077,12 +938,6 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
error = EINVAL;
break;
}
#ifdef COMPAT_FREEBSD32
if (wrap32) {
psr = &r.psr;
psr32 = addr;
} else
#endif
psr = addr;
bzero(psr, sizeof(*psr));
psr->sr_error = td2->td_errno;
@ -1090,10 +945,6 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
psr->sr_retval[0] = td2->td_retval[0];
psr->sr_retval[1] = td2->td_retval[1];
}
#ifdef COMPAT_FREEBSD32
if (wrap32)
ptrace_sc_ret_to32(psr, psr32);
#endif
CTR4(KTR_PTRACE,
"PT_GET_SC_RET: pid %d error %d retval %#lx,%#lx",
p->p_pid, psr->sr_error, psr->sr_retval[0],
@ -1274,32 +1125,16 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
break;
case PT_IO:
#ifdef COMPAT_FREEBSD32
if (wrap32) {
piod32 = addr;
iov.iov_base = (void *)(uintptr_t)piod32->piod_addr;
iov.iov_len = piod32->piod_len;
uio.uio_offset = (off_t)(uintptr_t)piod32->piod_offs;
uio.uio_resid = piod32->piod_len;
} else
#endif
{
piod = addr;
iov.iov_base = piod->piod_addr;
iov.iov_len = piod->piod_len;
uio.uio_offset = (off_t)(uintptr_t)piod->piod_offs;
uio.uio_resid = piod->piod_len;
}
piod = addr;
iov.iov_base = piod->piod_addr;
iov.iov_len = piod->piod_len;
uio.uio_offset = (off_t)(uintptr_t)piod->piod_offs;
uio.uio_resid = piod->piod_len;
uio.uio_iov = &iov;
uio.uio_iovcnt = 1;
uio.uio_segflg = UIO_USERSPACE;
uio.uio_td = td;
#ifdef COMPAT_FREEBSD32
tmp = wrap32 ? piod32->piod_op : piod->piod_op;
#else
tmp = piod->piod_op;
#endif
switch (tmp) {
switch (piod->piod_op) {
case PIOD_READ_D:
case PIOD_READ_I:
CTR3(KTR_PTRACE, "PT_IO: pid %d: READ (%p, %#x)",
@ -1319,12 +1154,7 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
}
PROC_UNLOCK(p);
error = proc_rwmem(p, &uio);
#ifdef COMPAT_FREEBSD32
if (wrap32)
piod32->piod_len -= uio.uio_resid;
else
#endif
piod->piod_len -= uio.uio_resid;
piod->piod_len -= uio.uio_resid;
PROC_LOCK(p);
break;
@ -1373,22 +1203,10 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
break;
case PT_LWPINFO:
if (data <= 0 ||
#ifdef COMPAT_FREEBSD32
(!wrap32 && data > sizeof(*pl)) ||
(wrap32 && data > sizeof(*pl32))) {
#else
data > sizeof(*pl)) {
#endif
if (data <= 0 || data > sizeof(*pl)) {
error = EINVAL;
break;
}
#ifdef COMPAT_FREEBSD32
if (wrap32) {
pl = &r.pl;
pl32 = addr;
} else
#endif
pl = addr;
bzero(pl, sizeof(*pl));
pl->pl_lwpid = td2->td_tid;
@ -1397,16 +1215,8 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
if (td2->td_dbgflags & TDB_XSIG) {
pl->pl_event = PL_EVENT_SIGNAL;
if (td2->td_si.si_signo != 0 &&
#ifdef COMPAT_FREEBSD32
((!wrap32 && data >= offsetof(struct ptrace_lwpinfo,
pl_siginfo) + sizeof(pl->pl_siginfo)) ||
(wrap32 && data >= offsetof(struct ptrace_lwpinfo32,
pl_siginfo) + sizeof(struct siginfo32)))
#else
data >= offsetof(struct ptrace_lwpinfo, pl_siginfo)
+ sizeof(pl->pl_siginfo)
#endif
){
+ sizeof(pl->pl_siginfo)){
pl->pl_flags |= PL_FLAG_SI;
pl->pl_siginfo = td2->td_si;
}
@ -1441,10 +1251,6 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
pl->pl_syscall_code = 0;
pl->pl_syscall_narg = 0;
}
#ifdef COMPAT_FREEBSD32
if (wrap32)
ptrace_lwpinfo_to32(pl, pl32);
#endif
CTR6(KTR_PTRACE,
"PT_LWPINFO: tid %d (pid %d) event %d flags %#x child pid %d syscall %d",
td2->td_tid, p->p_pid, pl->pl_event, pl->pl_flags,
@ -1490,11 +1296,6 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
case PT_VM_ENTRY:
PROC_UNLOCK(p);
#ifdef COMPAT_FREEBSD32
if (wrap32)
error = ptrace_vm_entry32(td, p, addr);
else
#endif
error = ptrace_vm_entry(td, p, addr);
PROC_LOCK(p);
break;