|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1982, 1986, 1989 Regents of the University of California. ! 3: * All rights reserved. The Berkeley software License Agreement ! 4: * specifies the terms and conditions for redistribution. ! 5: * ! 6: * @(#)sys_process.c 7.12 (Berkeley) 6/28/90 ! 7: */ ! 8: ! 9: #define IPCREG ! 10: #include "param.h" ! 11: #include "user.h" ! 12: #include "proc.h" ! 13: #include "vnode.h" ! 14: #include "text.h" ! 15: #include "seg.h" ! 16: #include "buf.h" ! 17: #include "ptrace.h" ! 18: ! 19: #include "machine/reg.h" ! 20: #include "machine/psl.h" ! 21: #include "machine/pte.h" ! 22: ! 23: /* ! 24: * Priority for tracing ! 25: */ ! 26: #define IPCPRI PZERO ! 27: ! 28: /* ! 29: * Tracing variables. ! 30: * Used to pass trace command from ! 31: * parent to child being traced. ! 32: * This data base cannot be ! 33: * shared and is locked ! 34: * per user. ! 35: */ ! 36: struct { ! 37: int ip_lock; ! 38: int ip_req; ! 39: int *ip_addr; ! 40: int ip_data; ! 41: } ipc; ! 42: ! 43: /* ! 44: * sys-trace system call. ! 45: */ ! 46: ptrace(curp, uap, retval) ! 47: struct proc *curp; ! 48: register struct args { ! 49: int req; ! 50: int pid; ! 51: int *addr; ! 52: int data; ! 53: } *uap; ! 54: int *retval; ! 55: { ! 56: register struct proc *p; ! 57: ! 58: if (uap->req <= 0) { ! 59: curp->p_flag |= STRC; ! 60: return (0); ! 61: } ! 62: p = pfind(uap->pid); ! 63: if (p == 0 || p->p_stat != SSTOP || p->p_ppid != curp->p_pid || ! 64: !(p->p_flag & STRC)) ! 65: return (ESRCH); ! 66: while (ipc.ip_lock) ! 67: sleep((caddr_t)&ipc, IPCPRI); ! 68: ipc.ip_lock = p->p_pid; ! 69: ipc.ip_data = uap->data; ! 70: ipc.ip_addr = uap->addr; ! 71: ipc.ip_req = uap->req; ! 72: p->p_flag &= ~SWTED; ! 73: while (ipc.ip_req > 0) { ! 74: if (p->p_stat==SSTOP) ! 75: setrun(p); ! 76: sleep((caddr_t)&ipc, IPCPRI); ! 77: } ! 78: *retval = ipc.ip_data; ! 79: ipc.ip_lock = 0; ! 80: wakeup((caddr_t)&ipc); ! 81: if (ipc.ip_req < 0) ! 82: return (EIO); ! 83: return (0); ! 84: } ! 85: ! 86: #define PHYSOFF(p, o) \ ! 87: ((physadr)(p)+((o)/sizeof(((physadr)0)->r[0]))) ! 88: ! 89: /* ! 90: * Code that the child process ! 91: * executes to implement the command ! 92: * of the parent process in tracing. ! 93: */ ! 94: procxmt(p) ! 95: register struct proc *p; ! 96: { ! 97: register int i, *poff; ! 98: register struct text *xp; ! 99: struct vattr vattr; ! 100: struct vnode *vp; ! 101: ! 102: if (ipc.ip_lock != p->p_pid) ! 103: return (0); ! 104: p->p_slptime = 0; ! 105: i = ipc.ip_req; ! 106: ipc.ip_req = 0; ! 107: switch (i) { ! 108: ! 109: case PT_READ_I: /* read the child's text space */ ! 110: if (!useracc((caddr_t)ipc.ip_addr, 4, B_READ)) ! 111: goto error; ! 112: ipc.ip_data = fuiword((caddr_t)ipc.ip_addr); ! 113: break; ! 114: ! 115: case PT_READ_D: /* read the child's data space */ ! 116: if (!useracc((caddr_t)ipc.ip_addr, 4, B_READ)) ! 117: goto error; ! 118: ipc.ip_data = fuword((caddr_t)ipc.ip_addr); ! 119: break; ! 120: ! 121: case PT_READ_U: /* read the child's u. */ ! 122: #ifdef HPUXCOMPAT ! 123: if (u.u_pcb.pcb_flags & PCB_HPUXTRACE) ! 124: i = hpuxtobsduoff(ipc.ip_addr); ! 125: else ! 126: #endif ! 127: i = (int)ipc.ip_addr; ! 128: if (i<0 || i > ctob(UPAGES)-sizeof(int)) ! 129: goto error; ! 130: ipc.ip_data = *(int *)PHYSOFF(&u, i); ! 131: break; ! 132: ! 133: case PT_WRITE_I: /* write the child's text space */ ! 134: /* ! 135: * If text, must assure exclusive use ! 136: */ ! 137: if (xp = p->p_textp) { ! 138: vp = xp->x_vptr; ! 139: VOP_GETATTR(vp, &vattr, u.u_cred); ! 140: if (xp->x_count!=1 || (vattr.va_mode & VSVTX)) ! 141: goto error; ! 142: xp->x_flag |= XTRC; ! 143: } ! 144: i = -1; ! 145: if ((i = suiword((caddr_t)ipc.ip_addr, ipc.ip_data)) < 0) { ! 146: if (!chgprot((caddr_t)ipc.ip_addr, RW) && ! 147: !chgprot((caddr_t)ipc.ip_addr+(sizeof(int)-1), RW)) ! 148: i = suiword((caddr_t)ipc.ip_addr, ipc.ip_data); ! 149: (void) chgprot((caddr_t)ipc.ip_addr, RO); ! 150: (void) chgprot((caddr_t)ipc.ip_addr+(sizeof(int)-1), RO); ! 151: } ! 152: if (i < 0) ! 153: goto error; ! 154: #if defined(tahoe) ! 155: /* make sure the old value is not in cache */ ! 156: ckeyrelease(p->p_ckey); ! 157: p->p_ckey = getcodekey(); ! 158: #endif ! 159: if (xp) { ! 160: xp->x_flag |= XWRIT; ! 161: #if defined(tahoe) ! 162: xp->x_ckey = p->p_ckey; ! 163: #endif ! 164: } ! 165: break; ! 166: ! 167: case PT_WRITE_D: /* write the child's data space */ ! 168: if (suword((caddr_t)ipc.ip_addr, 0) < 0) ! 169: goto error; ! 170: (void) suword((caddr_t)ipc.ip_addr, ipc.ip_data); ! 171: break; ! 172: ! 173: case PT_WRITE_U: /* write the child's u. */ ! 174: #ifdef HPUXCOMPAT ! 175: if (u.u_pcb.pcb_flags & PCB_HPUXTRACE) ! 176: i = hpuxtobsduoff(ipc.ip_addr); ! 177: else ! 178: #endif ! 179: i = (int)ipc.ip_addr; ! 180: poff = (int *)PHYSOFF(&u, i); ! 181: for (i=0; i<NIPCREG; i++) ! 182: if (poff == &u.u_ar0[ipcreg[i]]) ! 183: goto ok; ! 184: if (poff == &u.u_ar0[PS]) { ! 185: ipc.ip_data |= PSL_USERSET; ! 186: ipc.ip_data &= ~PSL_USERCLR; ! 187: #ifdef PSL_CM_CLR ! 188: if (ipc.ip_data & PSL_CM) ! 189: ipc.ip_data &= ~PSL_CM_CLR; ! 190: #endif ! 191: goto ok; ! 192: } ! 193: #if defined(hp300) ! 194: #ifdef FPCOPROC ! 195: if (poff >= (int *)u.u_pcb.pcb_fpregs.fpf_regs && ! 196: poff <= (int *)&u.u_pcb.pcb_fpregs.fpf_fpiar) ! 197: goto ok; ! 198: #endif ! 199: #endif ! 200: goto error; ! 201: ! 202: ok: ! 203: *poff = ipc.ip_data; ! 204: break; ! 205: ! 206: case PT_STEP: /* single step the child */ ! 207: case PT_CONTINUE: /* continue the child */ ! 208: if ((int)ipc.ip_addr != 1) ! 209: u.u_ar0[PC] = (int)ipc.ip_addr; ! 210: if ((unsigned)ipc.ip_data > NSIG) ! 211: goto error; ! 212: p->p_xstat = ipc.ip_data; /* see issig */ ! 213: if (i == PT_STEP) ! 214: u.u_ar0[PS] |= PSL_T; ! 215: wakeup((caddr_t)&ipc); ! 216: return (1); ! 217: ! 218: case PT_KILL: /* kill the child process */ ! 219: wakeup((caddr_t)&ipc); ! 220: exit(p, p->p_xstat); ! 221: ! 222: default: ! 223: error: ! 224: ipc.ip_req = -1; ! 225: } ! 226: wakeup((caddr_t)&ipc); ! 227: return (0); ! 228: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.