summaryrefslogtreecommitdiffstats
path: root/sys/kern/sys_process.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/kern/sys_process.c')
-rw-r--r--sys/kern/sys_process.c93
1 files changed, 77 insertions, 16 deletions
diff --git a/sys/kern/sys_process.c b/sys/kern/sys_process.c
index 91ca6d1..ecc3baa 100644
--- a/sys/kern/sys_process.c
+++ b/sys/kern/sys_process.c
@@ -53,34 +53,95 @@
#include <vm/vm_object.h>
#include <vm/vm_page.h>
-#define PROC_REG_ACTION(name, action, type) \
-int \
-proc_##name##_##type##s(struct thread *td, struct type *regs) \
-{ \
+/*
+ * Functions implemented using PROC_ACTION():
+ *
+ * proc_read_regs(proc, regs)
+ * Get the current user-visible register set from the process
+ * and copy it into the regs structure (<machine/reg.h>).
+ * The process is stopped at the time read_regs is called.
+ *
+ * proc_write_regs(proc, regs)
+ * Update the current register set from the passed in regs
+ * structure. Take care to avoid clobbering special CPU
+ * registers or privileged bits in the PSL.
+ * Depending on the architecture this may have fix-up work to do,
+ * especially if the IAR or PCW are modified.
+ * The process is stopped at the time write_regs is called.
+ *
+ * proc_read_fpregs, proc_write_fpregs
+ * deal with the floating point register set, otherwise as above.
+ *
+ * proc_read_dbregs, proc_write_dbregs
+ * deal with the processor debug register set, otherwise as above.
+ *
+ * proc_sstep(proc)
+ * Arrange for the process to trap after executing a single instruction.
+ */
+
+#define PROC_ACTION(action) do { \
int error; \
\
mtx_lock_spin(&sched_lock); \
- error = (action##_##type##s(td, regs)); \
+ if ((td->td_proc->p_sflag & PS_INMEM) == 0) \
+ error = EIO; \
+ else \
+ error = (action); \
mtx_unlock_spin(&sched_lock); \
return (error); \
+} while(0)
+
+int
+proc_read_regs(struct thread *td, struct reg *regs)
+{
+
+ PROC_ACTION(fill_regs(td, regs));
+}
+
+int
+proc_write_regs(struct thread *td, struct reg *regs)
+{
+
+ PROC_ACTION(set_regs(td, regs));
+}
+
+int
+proc_read_dbregs(struct thread *td, struct dbreg *dbregs)
+{
+
+ PROC_ACTION(fill_dbregs(td, dbregs));
+}
+
+int
+proc_write_dbregs(struct thread *td, struct dbreg *dbregs)
+{
+
+ PROC_ACTION(set_dbregs(td, dbregs));
+}
+
+/*
+ * Ptrace doesn't support fpregs at all, and there are no security holes
+ * or translations for fpregs, so we can just copy them.
+ */
+int
+proc_read_fpregs(struct thread *td, struct fpreg *fpregs)
+{
+
+ PROC_ACTION(fill_fpregs(td, fpregs));
}
-PROC_REG_ACTION(read, fill, reg);
-PROC_REG_ACTION(write, set, reg);
-PROC_REG_ACTION(read, fill, dbreg);
-PROC_REG_ACTION(write, set, dbreg);
-PROC_REG_ACTION(read, fill, fpreg);
-PROC_REG_ACTION(write, set, fpreg);
+int
+proc_write_fpregs(struct thread *td, struct fpreg *fpregs)
+{
+
+ PROC_ACTION(set_fpregs(td, fpregs));
+}
int
proc_sstep(struct thread *td)
{
- int error;
- mtx_lock_spin(&sched_lock);
- error = ptrace_single_step(td);
- mtx_unlock_spin(&sched_lock);
- return (error);
+ PROC_ACTION(ptrace_single_step(td));
}
int
OpenPOWER on IntegriCloud