BSD 4_4_Lite1 release
[unix-history] / usr / src / sys / kern / sys_process.c
index 25240c2..4cc40ba 100644 (file)
@@ -7,44 +7,40 @@
  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
  * the permission of UNIX System Laboratories, Inc.
  *
  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
  * the permission of UNIX System Laboratories, Inc.
  *
- * %sccs.include.proprietary.c%
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
  *
  *
- *     @(#)sys_process.c       8.5 (Berkeley) %G%
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *     from: @(#)sys_process.c 8.1 (Berkeley) 6/10/93
  */
 
  */
 
-#define IPCREG
 #include <sys/param.h>
 #include <sys/proc.h>
 #include <sys/param.h>
 #include <sys/proc.h>
-#include <sys/vnode.h>
-#include <sys/buf.h>
-#include <sys/ptrace.h>
-
-#include <machine/reg.h>
-#include <machine/psl.h>
-#include <vm/vm.h>
-#include <vm/vm_page.h>
-
-#include <sys/user.h>
-
-/*
- * Priority for tracing
- */
-#define        IPCPRI  PZERO
-
-/*
- * Tracing variables.
- * Used to pass trace command from
- * parent to child being traced.
- * This data base cannot be
- * shared and is locked
- * per user.
- */
-struct {
-       int     ip_lock;
-       int     ip_req;
-       caddr_t ip_addr;
-       int     ip_data;
-} ipc;
+#include <sys/errno.h>
 
 /*
  * Process debugging system call.
 
 /*
  * Process debugging system call.
@@ -55,247 +51,24 @@ struct ptrace_args {
        caddr_t addr;
        int     data;
 };
        caddr_t addr;
        int     data;
 };
-ptrace(curp, uap, retval)
-       struct proc *curp;
-       register struct ptrace_args *uap;
-       int *retval;
+ptrace(a1, a2, a3)
+       struct proc *a1;
+       struct ptrace_args *a2;
+       int *a3;
 {
 {
-       register struct proc *p;
-       int error;
 
 
-       if (uap->req <= 0) {
-               curp->p_flag |= P_TRACED;
-               return (0);
-       }
-       p = pfind(uap->pid);
-       if (p == 0)
-               return (ESRCH);
-       if (uap->req == PT_ATTACH) {
-               /*
-                * Must be root if the process has used set user or group
-                * privileges or does not belong to the real user.  Must
-                * not be already traced.  Can't attach to ourselves.
-                */
-               if ((p->p_flag & P_SUGID ||
-                   p->p_cred->p_ruid != curp->p_cred->p_ruid) &&
-                   (error = suser(p->p_ucred, &p->p_acflag)) != 0)
-                       return (error);
-               if (p->p_flag & P_TRACED)
-                       return (EALREADY);      /* ??? */
-               if (p->p_pid == curp->p_pid)
-                       return (EINVAL);
-               /*
-                * It would be nice if the tracing relationship was separate
-                * from the parent relationship but that would require
-                * another set of links in the proc struct or for "wait"
-                * to scan the entire proc table.  To make life easier,
-                * we just re-parent the process we're trying to trace.
-                * The old parent is remembered so we can put things back
-                * on a "detach".
-                */
-               p->p_flag |= P_TRACED;
-               p->p_oppid = p->p_pptr->p_pid;
-               proc_reparent(p, curp);
-               psignal(p, SIGSTOP);
-               return (0);
-       }
-       if (p->p_stat != SSTOP || p->p_pptr != curp || !(p->p_flag & P_TRACED))
-               return (ESRCH);
-       while (ipc.ip_lock)
-               sleep((caddr_t)&ipc, IPCPRI);
-       ipc.ip_lock = p->p_pid;
-       ipc.ip_data = uap->data;
-       ipc.ip_addr = uap->addr;
-       ipc.ip_req = uap->req;
-       p->p_flag &= ~P_WAITED;
-       while (ipc.ip_req > 0) {
-               if (p->p_stat==SSTOP)
-                       setrunnable(p);
-               sleep((caddr_t)&ipc, IPCPRI);
-       }
-       *retval = ipc.ip_data;
-       ipc.ip_lock = 0;
-       wakeup((caddr_t)&ipc);
-       if (ipc.ip_req < 0)
-               return (EIO);
-       return (0);
+       /*
+        * Body deleted.
+        */
+       return (ENOSYS);
 }
 
 }
 
-#define        PHYSOFF(p, o) ((caddr_t)(p) + (o))
-#if defined(hp300) || defined(luna68k)
-#define PHYSALIGNED(a) (((int)(a) & (sizeof(short) - 1)) == 0)
-#else
-#define PHYSALIGNED(a) (((int)(a) & (sizeof(int) - 1)) == 0)
-#endif
-
-#if defined(i386)
-#undef        PC
-#undef        SP
-#undef        PS
-#undef        R0
-#undef        R1
-
-#define       PC      tEIP
-#define       SP      tESP
-#define       PS      tEFLAGS
-#define       R0      tEDX
-#define       R1      tECX
-#endif
-
-/*
- * Transmit a tracing request from the parent to the child process
- * being debugged. This code runs in the context of the child process
- * to fulfill the command requested by the parent.
- */
-trace_req(p)
-       register struct proc *p;
+trace_req(a1)
+       struct proc *a1;
 {
 {
-       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 == &regs[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 == &regs[PC])
-                       goto ok;
-#endif
-               if (poff == &regs[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);
 
 
-       default:
-       error:
-               ipc.ip_req = -1;
-       }
-       wakeup((caddr_t)&ipc);
+       /*
+        * Body deleted.
+        */
        return (0);
 }
        return (0);
 }