- register int i, *poff, *regs;
- extern char kstack[];
-
- if (ipc.ip_lock != p->p_pid)
- return (0);
- p->p_slptime = 0;
- regs = p->p_md.md_regs;
- p->p_addr->u_kproc.kp_proc.p_md.md_regs = regs; /* u.u_ar0 */
- i = ipc.ip_req;
- ipc.ip_req = 0;
- switch (i) {
-
- case PT_READ_I: /* read the child's text space */
- if (!useracc((caddr_t)ipc.ip_addr, 4, B_READ))
- goto error;
- ipc.ip_data = fuiword((caddr_t)ipc.ip_addr);
- break;
-
- case PT_READ_D: /* read the child's data space */
- if (!useracc((caddr_t)ipc.ip_addr, 4, B_READ))
- goto error;
- ipc.ip_data = fuword((caddr_t)ipc.ip_addr);
- break;
-
- case PT_READ_U: /* read the child's u. */
- i = (int)ipc.ip_addr;
- if ((u_int) i > ctob(UPAGES)-sizeof(int) || !PHYSALIGNED(i))
- goto error;
- ipc.ip_data = *(int *)PHYSOFF(p->p_addr, i);
- break;
-
- case PT_WRITE_I: /* write the child's text space */
- if ((i = suiword((caddr_t)ipc.ip_addr, ipc.ip_data)) < 0) {
- vm_offset_t sa, ea;
- int rv;
-
- sa = trunc_page((vm_offset_t)ipc.ip_addr);
- ea = round_page((vm_offset_t)ipc.ip_addr+sizeof(int));
- rv = vm_map_protect(&p->p_vmspace->vm_map, sa, ea,
- VM_PROT_DEFAULT, FALSE);
- if (rv == KERN_SUCCESS) {
- i = suiword((caddr_t)ipc.ip_addr, ipc.ip_data);
- (void) vm_map_protect(&p->p_vmspace->vm_map,
- sa, ea, VM_PROT_READ|VM_PROT_EXECUTE,
- FALSE);
- }
- }
- if (i < 0)
- goto error;
- break;
-
- case PT_WRITE_D: /* write the child's data space */
- if (suword((caddr_t)ipc.ip_addr, 0) < 0)
- goto error;
- (void) suword((caddr_t)ipc.ip_addr, ipc.ip_data);
- break;
-
- case PT_WRITE_U: /* write the child's u. */
- i = (int)ipc.ip_addr;
-#ifdef mips
- poff = (int *)PHYSOFF(p->p_addr, i);
-#else
- poff = (int *)PHYSOFF(kstack, i);
-#endif
- for (i=0; i<NIPCREG; i++)
- if (poff == ®s[ipcreg[i]])
- goto ok;
-#if defined(hp300) || defined(luna68k)
- /*
- * In the new frame layout, PS/PC are skewed by 2 bytes.
- */
- regs = (int *)((short *)regs + 1);
- if (poff == ®s[PC])
- goto ok;
-#endif
- if (poff == ®s[PS]) {
- ipc.ip_data |= PSL_USERSET;
- ipc.ip_data &= ~PSL_USERCLR;
-#ifdef PSL_CM_CLR
- if (ipc.ip_data & PSL_CM)
- ipc.ip_data &= ~PSL_CM_CLR;
-#endif
- goto ok;
- }
-#if defined(hp300) || defined(luna68k)
-#ifdef FPCOPROC
- if (poff >= (int *)&((struct user *)kstack)->u_pcb.pcb_fpregs.fpf_regs &&
- poff <= (int *)&((struct user *)kstack)->u_pcb.pcb_fpregs.fpf_fpiar)
- goto ok;
-#endif
-#endif
- goto error;
-
- ok:
- *poff = ipc.ip_data;
- break;
-
- case PT_STEP: /* single step the child */
- case PT_CONTINUE: /* continue the child */
-#ifndef mips
- regs = (int *)((short *)regs + 1);
-#endif
- if ((unsigned)ipc.ip_data >= NSIG)
- goto error;
- if ((int)ipc.ip_addr != 1)
- regs[PC] = (int)ipc.ip_addr;
- p->p_xstat = ipc.ip_data; /* see issignal */
-#ifdef mips
- if (i == PT_STEP && cpu_singlestep(p))
- goto error;
-#else
-#ifdef PSL_T
- /* need something more machine independent here... */
- if (i == PT_STEP)
- regs[PS] |= PSL_T;
-#endif
-#endif
- wakeup((caddr_t)&ipc);
- return (1);
-
- case PT_KILL: /* kill the child process */
- wakeup((caddr_t)&ipc);
- exit1(p, (int)p->p_xstat);
-
- case PT_DETACH: /* stop tracing the child */
- regs = (int *)((short *)regs + 1);
- if ((unsigned)ipc.ip_data >= NSIG)
- goto error;
- if ((int)ipc.ip_addr != 1)
- regs[PC] = (int)ipc.ip_addr;
- p->p_xstat = ipc.ip_data; /* see issignal */
- p->p_flag &= ~P_TRACED;
- if (p->p_oppid != p->p_pptr->p_pid) {
- register struct proc *pp = pfind(p->p_oppid);
-
- if (pp)
- proc_reparent(p, pp);
- }
- p->p_oppid = 0;
- wakeup((caddr_t)&ipc);
- return (1);