Implement PT_IO (read / write arbitrary amounts of data or text).

Submitted by:	Artur Grabowski <art@{blahonga,openbsd}.org>
Obtained from:	OpenBSD
This commit is contained in:
des 2002-03-16 02:40:02 +00:00
parent 68af895b30
commit c4091faff5
2 changed files with 47 additions and 0 deletions

View File

@ -327,6 +327,7 @@ ptrace(struct thread *td, struct ptrace_args *uap)
* structs may be too large to put on the stack anyway.
*/
union {
struct ptrace_io_desc piod;
struct dbreg dbreg;
struct fpreg fpreg;
struct reg reg;
@ -390,6 +391,7 @@ ptrace(struct thread *td, struct ptrace_args *uap)
case PT_READ_D:
case PT_WRITE_I:
case PT_WRITE_D:
case PT_IO:
case PT_CONTINUE:
case PT_KILL:
case PT_STEP:
@ -568,6 +570,35 @@ ptrace(struct thread *td, struct ptrace_args *uap)
}
return (error);
case PT_IO:
error = copyin(uap->addr, &r.piod, sizeof r.piod);
if (error)
return (error);
iov.iov_base = r.piod.piod_addr;
iov.iov_len = r.piod.piod_len;
uio.uio_iov = &iov;
uio.uio_iovcnt = 1;
uio.uio_offset = (off_t)(uintptr_t)r.piod.piod_offs;
uio.uio_resid = r.piod.piod_len;
uio.uio_segflg = UIO_USERSPACE;
uio.uio_td = td;
switch (r.piod.piod_op) {
case PIOD_READ_D:
case PIOD_READ_I:
uio.uio_rw = UIO_READ;
break;
case PIOD_WRITE_D:
case PIOD_WRITE_I:
uio.uio_rw = UIO_WRITE;
break;
default:
return (EINVAL);
}
error = proc_rwmem(p, &uio);
r.piod.piod_len -= uio.uio_resid;
(void)copyout(&r.piod, uap->addr, sizeof r.piod);
return (error);
case PT_KILL:
uap->data = SIGKILL;
goto sendsig; /* in PT_CONTINUE above */

View File

@ -50,6 +50,7 @@
#define PT_ATTACH 10 /* trace some running process */
#define PT_DETACH 11 /* stop tracing a process */
#define PT_IO 12 /* do I/O to/from stopped process. */
#define PT_GETREGS 33 /* get general-purpose registers */
#define PT_SETREGS 34 /* set general-purpose registers */
@ -61,6 +62,21 @@
#define PT_FIRSTMACH 64 /* for machine-specific requests */
#include <machine/ptrace.h> /* machine-specific requests, if any */
struct ptrace_io_desc {
int piod_op; /* I/O operation */
void *piod_offs; /* child offset */
void *piod_addr; /* parent offset */
size_t piod_len; /* request length */
};
/*
* Operations in piod_op.
*/
#define PIOD_READ_D 1 /* Read from D space */
#define PIOD_WRITE_D 2 /* Write to D space */
#define PIOD_READ_I 3 /* Read from I space */
#define PIOD_WRITE_I 4 /* Write to I space */
#ifdef _KERNEL
int ptrace_set_pc(struct thread *_td, unsigned long _addr);
int ptrace_single_step(struct thread *_td);