diff options
author | des <des@FreeBSD.org> | 2002-03-16 02:40:02 +0000 |
---|---|---|
committer | des <des@FreeBSD.org> | 2002-03-16 02:40:02 +0000 |
commit | cba4e414333169bc2a820cc5efe9fb4ae0ac2a5f (patch) | |
tree | 149153da8a4a3bf8a43a460521eaa222b227cdf5 | |
parent | a3d902c96d3525c026a5b66ba8228d9254de662f (diff) | |
download | FreeBSD-src-cba4e414333169bc2a820cc5efe9fb4ae0ac2a5f.zip FreeBSD-src-cba4e414333169bc2a820cc5efe9fb4ae0ac2a5f.tar.gz |
Implement PT_IO (read / write arbitrary amounts of data or text).
Submitted by: Artur Grabowski <art@{blahonga,openbsd}.org>
Obtained from: OpenBSD
-rw-r--r-- | sys/kern/sys_process.c | 31 | ||||
-rw-r--r-- | sys/sys/ptrace.h | 16 |
2 files changed, 47 insertions, 0 deletions
diff --git a/sys/kern/sys_process.c b/sys/kern/sys_process.c index e6af165..39ff515 100644 --- a/sys/kern/sys_process.c +++ b/sys/kern/sys_process.c @@ -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 */ diff --git a/sys/sys/ptrace.h b/sys/sys/ptrace.h index 250f2e2..09d8742 100644 --- a/sys/sys/ptrace.h +++ b/sys/sys/ptrace.h @@ -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); |