1 #ifndef lint
2 static char sccsid[] = "@(#)runpcs.c 1.1 (Berkeley) 02/25/86";
3 #endif
4 /*
5 *
6 * UNIX debugger
7 *
8 */
9
10 #include "defs.h"
11
12 extern MAP txtmap;
13
14 MSG NOFORK;
15 MSG ENDPCS;
16 MSG BADWAIT;
17
18 CHAR *lp;
19 SIG sigint;
20 SIG sigqit;
21
22 /* breakpoints */
23 BKPTR bkpthead;
24
25 REGLIST reglist[];
26
27 CHAR lastc;
28
29 INT fcor;
30 INT fsym;
31 STRING errflg;
32 INT errno;
33 INT signo;
34 INT sigcode;
35
36 L_INT dot;
37 STRING symfil;
38 INT wtflag;
39 L_INT pid;
40 L_INT expv;
41 INT adrflg;
42 L_INT loopcnt;
43
44
45
46
47
48 /* service routines for sub process control */
49
getsig(sig)50 getsig(sig)
51 { return(expr(0) ? expv : sig);
52 }
53
54 ADDR userpc = 1;
55
runpcs(runmode,execsig)56 runpcs(runmode,execsig)
57 {
58 REG rc;
59 REG BKPTR bkpt;
60 IF adrflg THEN userpc=dot; FI
61 printf("%s: running\n", symfil);
62
63 WHILE --loopcnt>=0
64 DO
65 #ifdef DEBUG
66 printf("\ncontinue %X %D loopcnt=%D\n",userpc,execsig, loopcnt);
67 #endif
68 IF runmode==SINGLE
69 THEN delbp(); /* hardware handles single-stepping */
70 ELSE /* continuing from a breakpoint is hard */
71 IF bkpt=scanbkpt(userpc)
72 THEN execbkpt(bkpt,execsig); execsig=0;
73 FI
74 setbp();
75 FI
76 ptrace(runmode,pid,userpc,execsig);
77 bpwait(); chkerr(); execsig=0; delbp(); readregs();
78
79 IF (signo==0) ANDF (bkpt=scanbkpt(userpc))
80 THEN /* stopped by BPT instruction */
81 #ifdef DEBUG
82 printf("\n BPT code; '%s'%o'%d",
83 bkpt->comm,bkpt->comm[0],EOR,bkpt->flag);
84 #endif
85 dot=bkpt->loc;
86 IF bkpt->flag==BKPTEXEC
87 ORF ((bkpt->flag=BKPTEXEC)
88 ANDF bkpt->comm[0]!=EOR
89 ANDF command(bkpt->comm,':')
90 ANDF --bkpt->count)
91 THEN execbkpt(bkpt,execsig); execsig=0; loopcnt++;
92 ELSE bkpt->count=bkpt->initcnt; rc=1;
93 FI
94 ELSE execsig=signo; rc=0;
95 FI
96 OD
97 return(rc);
98 }
99
100 #define BPOUT 0
101 #define BPIN 1
102 INT bpstate = BPOUT;
103
endpcs()104 endpcs()
105 {
106 REG BKPTR bkptr;
107 IF pid
108 THEN ptrace(EXIT,pid); pid=0; userpc=1;
109 FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
110 DO IF bkptr->flag
111 THEN bkptr->flag=BKPTSET;
112 FI
113 OD
114 FI
115 bpstate=BPOUT;
116 }
117
118 #ifdef VFORK
nullsig()119 nullsig()
120 {
121
122 }
123 #endif
124
setup()125 setup()
126 {
127 close(fsym); fsym = -1;
128 #ifndef VFORK
129 IF (pid = fork()) == 0
130 #else
131 IF (pid = vfork()) == 0
132 #endif
133 THEN ptrace(SETTRC);
134 #ifdef VFORK
135 signal(SIGTRAP,nullsig);
136 #endif
137 signal(SIGINT,sigint); signal(SIGQUIT,sigqit);
138 doexec(); exit(0);
139 ELIF pid == -1
140 THEN error(NOFORK);
141 ELSE bpwait(); readregs(); lp[0]=EOR; lp[1]=0;
142 fsym=open(symfil,wtflag);
143 IF errflg
144 THEN printf("%s: cannot execute\n",symfil);
145 endpcs(); error(0);
146 FI
147 FI
148 bpstate=BPOUT;
149 }
150
execbkpt(bkptr,execsig)151 execbkpt(bkptr,execsig)
152 BKPTR bkptr;
153 {
154 #ifdef DEBUG
155 printf("exbkpt: %d\n",bkptr->count);
156 #endif
157 delbp();
158 ptrace(SINGLE,pid,bkptr->loc,execsig);
159 bkptr->flag=BKPTSET;
160 bpwait(); chkerr(); readregs();
161 }
162
163
doexec()164 doexec()
165 {
166 STRING argl[MAXARG];
167 CHAR args[LINSIZ];
168 REG STRING p, *ap, filnam;
169 extern STRING environ;
170
171 ap=argl; p=args;
172 *ap++=symfil;
173 REP IF rdc()==EOR THEN break; FI
174 *ap = p;
175 WHILE lastc!=EOR ANDF lastc!=SP ANDF lastc!=TB DO *p++=lastc; readchar(); OD
176 *p++=0; filnam = *ap+1;
177 IF **ap=='<'
178 THEN close(0);
179 IF open(filnam,0)<0
180 THEN printf("%s: cannot open\n",filnam); _exit(0);
181 FI
182 ELIF **ap=='>'
183 THEN close(1);
184 IF creat(filnam,0666)<0
185 THEN printf("%s: cannot create\n",filnam); _exit(0);
186 FI
187 ELSE ap++;
188 FI
189 PER lastc!=EOR DONE
190 *ap++=0;
191 execve(symfil, argl, environ);
192 perror(symfil);
193 }
194
scanbkpt(adr)195 BKPTR scanbkpt(adr)
196 ADDR adr;
197 {
198 REG BKPTR bkptr;
199 FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
200 DO IF bkptr->flag ANDF bkptr->loc==adr
201 THEN break;
202 FI
203 OD
204 return(bkptr);
205 }
206
delbp()207 delbp()
208 {
209 REG ADDR a;
210 REG BKPTR bkptr;
211 IF bpstate!=BPOUT
212 THEN
213 FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
214 DO IF bkptr->flag
215 THEN a=bkptr->loc;
216 IF a < txtmap.e1 THEN
217 ptrace(WIUSER,pid,a,bkptr->ins);
218 ELSE
219 ptrace(WDUSER,pid,a,bkptr->ins);
220 FI
221 FI
222 OD
223 bpstate=BPOUT;
224 FI
225 }
226
227 #if defined(vax)
228 #define SETBP(ins) (BPT | ((ins) &~ 0xff))
229 #else
230 #define SETBP(ins) ((BPT<<24) | ((ins) & 0xffffff))
231 #endif
232
setbp()233 setbp()
234 {
235 REG ADDR a;
236 REG BKPTR bkptr;
237
238 IF bpstate!=BPIN
239 THEN
240 FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt
241 DO IF bkptr->flag
242 THEN a = bkptr->loc;
243 IF a < txtmap.e1 THEN
244 bkptr->ins = ptrace(RIUSER, pid, a);
245 ptrace(WIUSER, pid, a, SETBP(bkptr->ins));
246 ELSE
247 bkptr->ins = ptrace(RDUSER, pid, a);
248 ptrace(WDUSER, pid, a, SETBP(bkptr->ins));
249 FI
250 IF errno
251 THEN printf("cannot set breakpoint: ");
252 psymoff(bkptr->loc,ISYM,"\n");
253 FI
254 FI
255 OD
256 bpstate=BPIN;
257 FI
258 }
259
bpwait()260 bpwait()
261 {
262 REG w;
263 ADDR stat;
264
265 signal(SIGINT, 1);
266 WHILE (w = wait(&stat))!=pid ANDF w != -1 DONE
267 signal(SIGINT,sigint);
268 IF w == -1
269 THEN pid=0;
270 errflg=BADWAIT;
271 ELIF (stat & 0177) != 0177
272 THEN sigcode = 0;
273 IF signo = stat&0177
274 THEN sigprint();
275 FI
276 IF stat&0200
277 THEN printf(" - core dumped");
278 close(fcor);
279 setcor();
280 FI
281 pid=0;
282 errflg=ENDPCS;
283 ELSE signo = stat>>8;
284 sigcode = ptrace(RUREGS, pid, &((struct user *)0)->u_code, 0);
285 IF signo!=SIGTRAP
286 THEN sigprint();
287 ELSE signo=0;
288 FI
289 flushbuf();
290 FI
291 }
292
readregs()293 readregs()
294 {
295 /*get REG values from pcs*/
296 REG REGPTR p;
297
298 FOR p=reglist; p->rname; p++
299 DO *(ADDR *)(((ADDR)&u)+p->roffs) =
300 ptrace(RUREGS, pid, p->roffs, 0);
301 OD
302 userpc= *(ADDR *)(((ADDR)&u)+PC);
303 }
304