X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/c66bde989c72461b5ca17917a47f91441a3f3347..ed554bc5e4201344d7eaad78263566e79428759c:/usr/src/sys/kern/sys_process.c diff --git a/usr/src/sys/kern/sys_process.c b/usr/src/sys/kern/sys_process.c index 25240c2594..4cc40baf58 100644 --- a/usr/src/sys/kern/sys_process.c +++ b/usr/src/sys/kern/sys_process.c @@ -7,44 +7,40 @@ * 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 #include -#include -#include -#include - -#include -#include -#include -#include - -#include - -/* - * 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 /* * Process debugging system call. @@ -55,247 +51,24 @@ struct ptrace_args { 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= (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); }