Commit | Line | Data |
---|---|---|
961945a8 SL |
1 | /* sys_process.c 5.8 82/12/17 */ |
2 | ||
3 | #include "../machine/reg.h" | |
4 | #include "../machine/psl.h" | |
5 | #include "../machine/pte.h" | |
9ce4de2d BJ |
6 | |
7 | #include "../h/param.h" | |
8 | #include "../h/systm.h" | |
9 | #include "../h/dir.h" | |
10 | #include "../h/user.h" | |
11 | #include "../h/proc.h" | |
12 | #include "../h/inode.h" | |
9ce4de2d BJ |
13 | #include "../h/text.h" |
14 | #include "../h/seg.h" | |
9ce4de2d BJ |
15 | #include "../h/vm.h" |
16 | #include "../h/buf.h" | |
9ce4de2d BJ |
17 | #include "../h/acct.h" |
18 | ||
4147b3f6 BJ |
19 | /* |
20 | * Priority for tracing | |
21 | */ | |
22 | #define IPCPRI PZERO | |
23 | ||
24 | /* | |
25 | * Tracing variables. | |
26 | * Used to pass trace command from | |
27 | * parent to child being traced. | |
28 | * This data base cannot be | |
29 | * shared and is locked | |
30 | * per user. | |
31 | */ | |
32 | struct { | |
33 | int ip_lock; | |
34 | int ip_req; | |
35 | int *ip_addr; | |
36 | int ip_data; | |
37 | } ipc; | |
38 | ||
39 | /* | |
40 | * sys-trace system call. | |
41 | */ | |
42 | ptrace() | |
43 | { | |
44 | register struct proc *p; | |
45 | register struct a { | |
46 | int req; | |
47 | int pid; | |
48 | int *addr; | |
49 | int data; | |
50 | } *uap; | |
51 | ||
52 | uap = (struct a *)u.u_ap; | |
53 | if (uap->req <= 0) { | |
54 | u.u_procp->p_flag |= STRC; | |
55 | return; | |
56 | } | |
57 | p = pfind(uap->pid); | |
58 | if (p == 0 || p->p_stat != SSTOP || p->p_ppid != u.u_procp->p_pid) { | |
59 | u.u_error = ESRCH; | |
60 | return; | |
61 | } | |
62 | while (ipc.ip_lock) | |
63 | sleep((caddr_t)&ipc, IPCPRI); | |
64 | ipc.ip_lock = p->p_pid; | |
65 | ipc.ip_data = uap->data; | |
66 | ipc.ip_addr = uap->addr; | |
67 | ipc.ip_req = uap->req; | |
68 | p->p_flag &= ~SWTED; | |
69 | while (ipc.ip_req > 0) { | |
70 | if (p->p_stat==SSTOP) | |
71 | setrun(p); | |
72 | sleep((caddr_t)&ipc, IPCPRI); | |
73 | } | |
74 | u.u_r.r_val1 = ipc.ip_data; | |
75 | if (ipc.ip_req < 0) | |
76 | u.u_error = EIO; | |
77 | ipc.ip_lock = 0; | |
78 | wakeup((caddr_t)&ipc); | |
79 | } | |
80 | ||
b4e32d36 | 81 | #ifdef vax |
883d0f83 BJ |
82 | #define NIPCREG 16 |
83 | #endif | |
b4e32d36 | 84 | #ifdef sun |
883d0f83 BJ |
85 | #define NIPCREG 17 |
86 | #endif | |
87 | int ipcreg[NIPCREG] = | |
b4e32d36 | 88 | #ifdef vax |
883d0f83 BJ |
89 | {R0,R1,R2,R3,R4,R5,R6,R7,R8,R9,R10,R11,AP,FP,SP,PC}; |
90 | #endif | |
b4e32d36 | 91 | #ifdef sun |
883d0f83 BJ |
92 | {R0,R1,R2,R3,R4,R5,R6,R7,AR0,AR1,AR2,AR3,AR4,AR5,AR6,AR7,PC}; |
93 | #endif | |
94 | ||
fc0890b1 | 95 | #define PHYSOFF(p, o) \ |
883d0f83 BJ |
96 | ((physadr)(p)+((o)/sizeof(((physadr)0)->r[0]))) |
97 | ||
4147b3f6 BJ |
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 | /* read user I */ | |
117 | case 1: | |
118 | if (!useracc((caddr_t)ipc.ip_addr, 4, B_READ)) | |
119 | goto error; | |
120 | ipc.ip_data = fuiword((caddr_t)ipc.ip_addr); | |
121 | break; | |
122 | ||
123 | /* read user D */ | |
124 | case 2: | |
125 | if (!useracc((caddr_t)ipc.ip_addr, 4, B_READ)) | |
126 | goto error; | |
127 | ipc.ip_data = fuword((caddr_t)ipc.ip_addr); | |
128 | break; | |
129 | ||
130 | /* read u */ | |
131 | case 3: | |
132 | i = (int)ipc.ip_addr; | |
133 | if (i<0 || i >= ctob(UPAGES)) | |
134 | goto error; | |
883d0f83 | 135 | ipc.ip_data = *(int *)PHYSOFF(&u, i); |
4147b3f6 BJ |
136 | break; |
137 | ||
138 | /* write user I */ | |
139 | /* Must set up to allow writing */ | |
140 | case 4: | |
141 | /* | |
142 | * If text, must assure exclusive use | |
143 | */ | |
144 | if (xp = u.u_procp->p_textp) { | |
145 | if (xp->x_count!=1 || xp->x_iptr->i_mode&ISVTX) | |
146 | goto error; | |
147 | xp->x_iptr->i_flag &= ~ITEXT; | |
148 | } | |
149 | i = -1; | |
883d0f83 BJ |
150 | if ((i = suiword((caddr_t)ipc.ip_addr, ipc.ip_data)) < 0) { |
151 | if (chgprot((caddr_t)ipc.ip_addr, RW) && | |
152 | chgprot((caddr_t)ipc.ip_addr+(sizeof(int)-1), RW)) | |
153 | i = suiword((caddr_t)ipc.ip_addr, ipc.ip_data); | |
154 | (void) chgprot((caddr_t)ipc.ip_addr, RO); | |
155 | (void) chgprot((caddr_t)ipc.ip_addr+(sizeof(int)-1), RO); | |
156 | } | |
4147b3f6 BJ |
157 | if (i < 0) |
158 | goto error; | |
159 | if (xp) | |
160 | xp->x_flag |= XWRIT; | |
161 | break; | |
162 | ||
163 | /* write user D */ | |
164 | case 5: | |
165 | if (suword((caddr_t)ipc.ip_addr, 0) < 0) | |
166 | goto error; | |
167 | (void) suword((caddr_t)ipc.ip_addr, ipc.ip_data); | |
168 | break; | |
169 | ||
170 | /* write u */ | |
171 | case 6: | |
172 | i = (int)ipc.ip_addr; | |
883d0f83 BJ |
173 | p = (int *)PHYSOFF(&u, i); |
174 | for (i=0; i<NIPCREG; i++) | |
4147b3f6 BJ |
175 | if (p == &u.u_ar0[ipcreg[i]]) |
176 | goto ok; | |
177 | if (p == &u.u_ar0[PS]) { | |
883d0f83 | 178 | ipc.ip_data |= PSL_USERSET; |
4147b3f6 | 179 | ipc.ip_data &= ~PSL_USERCLR; |
961945a8 SL |
180 | #ifdef sun |
181 | if (ipc.ip_data & PSL_T) | |
182 | traceon(); | |
183 | else | |
184 | traceoff(); | |
185 | #endif | |
4147b3f6 BJ |
186 | goto ok; |
187 | } | |
188 | goto error; | |
189 | ||
190 | ok: | |
191 | *p = ipc.ip_data; | |
192 | break; | |
193 | ||
194 | /* set signal and continue */ | |
195 | /* one version causes a trace-trap */ | |
196 | case 9: | |
197 | case 7: | |
198 | if ((int)ipc.ip_addr != 1) | |
199 | u.u_ar0[PC] = (int)ipc.ip_addr; | |
200 | if ((unsigned)ipc.ip_data > NSIG) | |
201 | goto error; | |
202 | u.u_procp->p_cursig = ipc.ip_data; /* see issig */ | |
961945a8 SL |
203 | if (i == 9) |
204 | #ifdef sun | |
205 | traceon(); | |
206 | #else | |
4147b3f6 | 207 | u.u_ar0[PS] |= PSL_T; |
961945a8 | 208 | #endif |
4147b3f6 BJ |
209 | wakeup((caddr_t)&ipc); |
210 | return (1); | |
211 | ||
212 | /* force exit */ | |
213 | case 8: | |
214 | wakeup((caddr_t)&ipc); | |
215 | exit(u.u_procp->p_cursig); | |
216 | ||
217 | default: | |
218 | error: | |
219 | ipc.ip_req = -1; | |
220 | } | |
221 | wakeup((caddr_t)&ipc); | |
222 | return (0); | |
223 | } |