1: /*
   2:  * Copyright (c) 1982, 1986 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.1 (Berkeley) 6/5/86
   7:  */
   8: 
   9: #include "../machine/reg.h"
  10: #include "../machine/psl.h"
  11: #include "../machine/pte.h"
  12: 
  13: #include "param.h"
  14: #include "systm.h"
  15: #include "dir.h"
  16: #include "user.h"
  17: #include "proc.h"
  18: #include "inode.h"
  19: #include "text.h"
  20: #include "seg.h"
  21: #include "vm.h"
  22: #include "buf.h"
  23: #include "acct.h"
  24: #include "ptrace.h"
  25: 
  26: /*
  27:  * Priority for tracing
  28:  */
  29: #define IPCPRI  PZERO
  30: 
  31: /*
  32:  * Tracing variables.
  33:  * Used to pass trace command from
  34:  * parent to child being traced.
  35:  * This data base cannot be
  36:  * shared and is locked
  37:  * per user.
  38:  */
  39: struct {
  40:     int ip_lock;
  41:     int ip_req;
  42:     int *ip_addr;
  43:     int ip_data;
  44: } ipc;
  45: 
  46: /*
  47:  * sys-trace system call.
  48:  */
  49: ptrace()
  50: {
  51:     register struct proc *p;
  52:     register struct a {
  53:         int req;
  54:         int pid;
  55:         int *addr;
  56:         int data;
  57:     } *uap;
  58: 
  59:     uap = (struct a *)u.u_ap;
  60:     if (uap->req <= 0) {
  61:         u.u_procp->p_flag |= STRC;
  62:         return;
  63:     }
  64:     p = pfind(uap->pid);
  65:     if (p == 0 || p->p_stat != SSTOP || p->p_ppid != u.u_procp->p_pid ||
  66:         !(p->p_flag & STRC)) {
  67:         u.u_error = ESRCH;
  68:         return;
  69:     }
  70:     while (ipc.ip_lock)
  71:         sleep((caddr_t)&ipc, IPCPRI);
  72:     ipc.ip_lock = p->p_pid;
  73:     ipc.ip_data = uap->data;
  74:     ipc.ip_addr = uap->addr;
  75:     ipc.ip_req = uap->req;
  76:     p->p_flag &= ~SWTED;
  77:     while (ipc.ip_req > 0) {
  78:         if (p->p_stat==SSTOP)
  79:             setrun(p);
  80:         sleep((caddr_t)&ipc, IPCPRI);
  81:     }
  82:     u.u_r.r_val1 = ipc.ip_data;
  83:     if (ipc.ip_req < 0)
  84:         u.u_error = EIO;
  85:     ipc.ip_lock = 0;
  86:     wakeup((caddr_t)&ipc);
  87: }
  88: 
  89: #if defined(vax)
  90: #define NIPCREG 16
  91: int ipcreg[NIPCREG] =
  92:     {R0,R1,R2,R3,R4,R5,R6,R7,R8,R9,R10,R11,AP,FP,SP,PC};
  93: #endif
  94: 
  95: #define PHYSOFF(p, o) \
  96:     ((physadr)(p)+((o)/sizeof(((physadr)0)->r[0])))
  97: 
  98: /*
  99:  * Code that the child process
 100:  * executes to implement the command
 101:  * of the parent process in tracing.
 102:  */
 103: procxmt()
 104: {
 105:     register int i;
 106:     register *p;
 107:     register struct text *xp;
 108: 
 109:     if (ipc.ip_lock != u.u_procp->p_pid)
 110:         return (0);
 111:     u.u_procp->p_slptime = 0;
 112:     i = ipc.ip_req;
 113:     ipc.ip_req = 0;
 114:     switch (i) {
 115: 
 116:     case PT_READ_I:         /* read the child's text space */
 117:         if (!useracc((caddr_t)ipc.ip_addr, 4, B_READ))
 118:             goto error;
 119:         ipc.ip_data = fuiword((caddr_t)ipc.ip_addr);
 120:         break;
 121: 
 122:     case PT_READ_D:         /* read the child's data space */
 123:         if (!useracc((caddr_t)ipc.ip_addr, 4, B_READ))
 124:             goto error;
 125:         ipc.ip_data = fuword((caddr_t)ipc.ip_addr);
 126:         break;
 127: 
 128:     case PT_READ_U:         /* read the child's u. */
 129:         i = (int)ipc.ip_addr;
 130:         if (i<0 || i >= ctob(UPAGES))
 131:             goto error;
 132:         ipc.ip_data = *(int *)PHYSOFF(&u, i);
 133:         break;
 134: 
 135:     case PT_WRITE_I:        /* write the child's text space */
 136:         /*
 137: 		 * If text, must assure exclusive use
 138: 		 */
 139:         if (xp = u.u_procp->p_textp) {
 140:             if (xp->x_count!=1 || xp->x_iptr->i_mode&ISVTX)
 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 (xp)
 155:             xp->x_flag |= XWRIT;
 156:         break;
 157: 
 158:     case PT_WRITE_D:        /* write the child's data space */
 159:         if (suword((caddr_t)ipc.ip_addr, 0) < 0)
 160:             goto error;
 161:         (void) suword((caddr_t)ipc.ip_addr, ipc.ip_data);
 162:         break;
 163: 
 164:     case PT_WRITE_U:        /* write the child's u. */
 165:         i = (int)ipc.ip_addr;
 166:         p = (int *)PHYSOFF(&u, i);
 167:         for (i=0; i<NIPCREG; i++)
 168:             if (p == &u.u_ar0[ipcreg[i]])
 169:                 goto ok;
 170:         if (p == &u.u_ar0[PS]) {
 171:             ipc.ip_data |= PSL_USERSET;
 172:             ipc.ip_data &=  ~PSL_USERCLR;
 173:             goto ok;
 174:         }
 175:         goto error;
 176: 
 177:     ok:
 178:         *p = ipc.ip_data;
 179:         break;
 180: 
 181:     case PT_STEP:           /* single step the child */
 182:     case PT_CONTINUE:       /* continue the child */
 183:         if ((int)ipc.ip_addr != 1)
 184:             u.u_ar0[PC] = (int)ipc.ip_addr;
 185:         if ((unsigned)ipc.ip_data > NSIG)
 186:             goto error;
 187:         u.u_procp->p_cursig = ipc.ip_data;  /* see issig */
 188:         if (i == PT_STEP)
 189:             u.u_ar0[PS] |= PSL_T;
 190:         wakeup((caddr_t)&ipc);
 191:         return (1);
 192: 
 193:     case PT_KILL:           /* kill the child process */
 194:         wakeup((caddr_t)&ipc);
 195:         exit(u.u_procp->p_cursig);
 196: 
 197:     default:
 198:     error:
 199:         ipc.ip_req = -1;
 200:     }
 201:     wakeup((caddr_t)&ipc);
 202:     return (0);
 203: }

Defined functions

procxmt defined in line 103; used 1 times
ptrace defined in line 49; used 2 times

Defined variables

ipcreg defined in line 91; used 1 times

Defined struct's

a defined in line 52; used 2 times
  • in line 59(2)

Defined macros

IPCPRI defined in line 29; used 2 times
NIPCREG defined in line 90; used 2 times
PHYSOFF defined in line 95; used 2 times
Last modified: 1986-06-05
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1023
Valid CSS Valid XHTML 1.0 Strict