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
Defined variables
Defined struct's
a
defined in line
52; used 2 times
Defined macros