generalize uba code to handle Q bus more gracefully
[unix-history] / usr / src / sys / kern / sys_process.c
CommitLineData
da7c5cc6 1/*
0880b18e 2 * Copyright (c) 1982, 1986 Regents of the University of California.
da7c5cc6
KM
3 * All rights reserved. The Berkeley software License Agreement
4 * specifies the terms and conditions for redistribution.
5 *
0880b18e 6 * @(#)sys_process.c 7.1 (Berkeley) %G%
da7c5cc6 7 */
961945a8
SL
8
9#include "../machine/reg.h"
10#include "../machine/psl.h"
11#include "../machine/pte.h"
9ce4de2d 12
94368568
JB
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"
01b0e233 24#include "ptrace.h"
9ce4de2d 25
4147b3f6
BJ
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 */
39struct {
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 */
49ptrace()
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);
f05cf4fe
SL
65 if (p == 0 || p->p_stat != SSTOP || p->p_ppid != u.u_procp->p_pid ||
66 !(p->p_flag & STRC)) {
4147b3f6
BJ
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
01b0e233 89#if defined(vax)
883d0f83 90#define NIPCREG 16
883d0f83 91int ipcreg[NIPCREG] =
883d0f83
BJ
92 {R0,R1,R2,R3,R4,R5,R6,R7,R8,R9,R10,R11,AP,FP,SP,PC};
93#endif
883d0f83 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 */
103procxmt()
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
01b0e233 116 case PT_READ_I: /* read the child's text space */
4147b3f6
BJ
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
01b0e233 122 case PT_READ_D: /* read the child's data space */
4147b3f6
BJ
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
01b0e233 128 case PT_READ_U: /* read the child's u. */
4147b3f6
BJ
129 i = (int)ipc.ip_addr;
130 if (i<0 || i >= ctob(UPAGES))
131 goto error;
883d0f83 132 ipc.ip_data = *(int *)PHYSOFF(&u, i);
4147b3f6
BJ
133 break;
134
01b0e233 135 case PT_WRITE_I: /* write the child's text space */
4147b3f6
BJ
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;
cdb14d96 142 xp->x_flag |= XTRC;
4147b3f6
BJ
143 }
144 i = -1;
883d0f83
BJ
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 }
4147b3f6
BJ
152 if (i < 0)
153 goto error;
154 if (xp)
155 xp->x_flag |= XWRIT;
156 break;
157
01b0e233 158 case PT_WRITE_D: /* write the child's data space */
4147b3f6
BJ
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
01b0e233 164 case PT_WRITE_U: /* write the child's u. */
4147b3f6 165 i = (int)ipc.ip_addr;
883d0f83
BJ
166 p = (int *)PHYSOFF(&u, i);
167 for (i=0; i<NIPCREG; i++)
4147b3f6
BJ
168 if (p == &u.u_ar0[ipcreg[i]])
169 goto ok;
170 if (p == &u.u_ar0[PS]) {
883d0f83 171 ipc.ip_data |= PSL_USERSET;
4147b3f6
BJ
172 ipc.ip_data &= ~PSL_USERCLR;
173 goto ok;
174 }
175 goto error;
176
177 ok:
178 *p = ipc.ip_data;
179 break;
180
01b0e233
MK
181 case PT_STEP: /* single step the child */
182 case PT_CONTINUE: /* continue the child */
4147b3f6
BJ
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 */
01b0e233 188 if (i == PT_STEP)
4147b3f6
BJ
189 u.u_ar0[PS] |= PSL_T;
190 wakeup((caddr_t)&ipc);
191 return (1);
192
01b0e233 193 case PT_KILL: /* kill the child process */
4147b3f6
BJ
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}