summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/kern/sys_process.c31
-rw-r--r--sys/sys/ptrace.h16
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);
OpenPOWER on IntegriCloud